From dcd2c565c1c5513d9a9343bbfa6ce831fe6a8c66 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 25 Jan 2025 19:32:12 +0900 Subject: [PATCH] [qfcc] Emit struct member decorations They're not enough yet as offsets and strides need to be emitted. --- tools/qfcc/source/target_spirv.c | 55 ++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tools/qfcc/source/target_spirv.c b/tools/qfcc/source/target_spirv.c index 9b2b0a74c..c00cbec14 100644 --- a/tools/qfcc/source/target_spirv.c +++ b/tools/qfcc/source/target_spirv.c @@ -270,6 +270,36 @@ spirv_DecorateLiteral (unsigned id, SpvDecoration decoration, void *literal, } } +static void +spirv_MemberDecorate (unsigned id, unsigned member, + SpvDecoration decoration, spirvctx_t *ctx) +{ + auto decorations = ctx->module->decorations; + auto insn = spirv_new_insn (SpvOpMemberDecorate, 4, decorations); + INSN (insn, 1) = id; + INSN (insn, 2) = member; + INSN (insn, 3) = decoration; +} + +static void +spirv_MemberDecorateLiteral (unsigned id, unsigned member, + SpvDecoration decoration, + void *literal, etype_t type, spirvctx_t *ctx) +{ + if (type != ev_int) { + internal_error (0, "unexpected type"); + } + int size = pr_type_size[type]; + auto decorations = ctx->module->decorations; + auto insn = spirv_new_insn (SpvOpMemberDecorate, 4 + size, decorations); + INSN (insn, 1) = id; + INSN (insn, 2) = member; + INSN (insn, 3) = decoration; + if (type == ev_int) { + INSN (insn, 4) = *(int *)literal; + } +} + static void spirv_decorate_id (unsigned id, attribute_t *attributes, spirvctx_t *ctx) { @@ -292,6 +322,30 @@ spirv_decorate_id (unsigned id, attribute_t *attributes, spirvctx_t *ctx) } } +static void +spirv_member_decorate_id (unsigned id, int member, attribute_t *attributes, + spirvctx_t *ctx) +{ + for (auto attr = attributes; attr; attr = attr->next) { + unsigned decoration = spirv_enum_val ("Decoration", attr->name); + if (attr->params) { + //FIXME some decorations have more than one parameter (rare) + int val; + if (is_string_val (attr->params)) { + //FIXME should get kind from decoration + const char *name = expr_string (attr->params); + val = spirv_enum_val (attr->name, name); + } else { + val = expr_integral (attr->params); + } + spirv_MemberDecorateLiteral (id, member, decoration, + &val, ev_int, ctx); + } else { + spirv_MemberDecorate (id, member, decoration, ctx); + } + } +} + static void spirv_MemberName (unsigned id, unsigned member, const char *name, spirvctx_t *ctx) @@ -408,6 +462,7 @@ spirv_TypeStruct (const type_t *type, spirvctx_t *ctx) for (auto s = symtab->symbols; s; s = s->next) { int m = num_members++; spirv_MemberName (id, m, s->name, ctx); + spirv_member_decorate_id (id, m, s->attributes, ctx); } return id; }