diff --git a/gsk/gskslqualifier.c b/gsk/gskslqualifier.c index ca07e74557..049242acf4 100644 --- a/gsk/gskslqualifier.c +++ b/gsk/gskslqualifier.c @@ -576,3 +576,47 @@ gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier) return GSK_SPV_STORAGE_CLASS_FUNCTION; } } + +static void +gsk_sl_qualifier_write_inout_decorations (const GskSlQualifier *qualifier, + GskSpvWriter *writer, + guint32 value_id) +{ + if (qualifier->layout.set >= 0) + gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.set }, 1); + if (qualifier->layout.binding >= 0) + gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.binding }, 1); + if (qualifier->layout.location >= 0) + gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.location }, 1); + if (qualifier->layout.component >= 0) + gsk_spv_writer_decorate (writer, value_id, GSK_SPV_DECORATION_LOCATION, (guint32[1]) { qualifier->layout.component }, 1); +} + +void +gsk_sl_qualifier_write_spv_decorations (const GskSlQualifier *qualifier, + GskSpvWriter *writer, + guint32 value_id) +{ + switch (qualifier->storage) + { + case GSK_SL_STORAGE_DEFAULT: + default: + g_assert_not_reached (); + case GSK_SL_STORAGE_LOCAL: + case GSK_SL_STORAGE_LOCAL_CONST: + case GSK_SL_STORAGE_PARAMETER_IN: + case GSK_SL_STORAGE_PARAMETER_OUT: + case GSK_SL_STORAGE_PARAMETER_INOUT: + case GSK_SL_STORAGE_PARAMETER_CONST: + case GSK_SL_STORAGE_GLOBAL: + case GSK_SL_STORAGE_GLOBAL_CONST: + return; + + case GSK_SL_STORAGE_GLOBAL_IN: + case GSK_SL_STORAGE_GLOBAL_OUT: + case GSK_SL_STORAGE_GLOBAL_UNIFORM: + gsk_sl_qualifier_write_inout_decorations (qualifier, writer, value_id); + } + +} + diff --git a/gsk/gskslqualifierprivate.h b/gsk/gskslqualifierprivate.h index b44c1aecdd..12e9e413cf 100644 --- a/gsk/gskslqualifierprivate.h +++ b/gsk/gskslqualifierprivate.h @@ -66,6 +66,10 @@ gboolean gsk_sl_qualifier_is_constant (const G GskSlQualifierLocation gsk_sl_qualifier_get_location (const GskSlQualifier *qualifier); GskSpvStorageClass gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier); +void gsk_sl_qualifier_write_spv_decorations (const GskSlQualifier *qualifier, + GskSpvWriter *writer, + guint32 value_id); + G_END_DECLS #endif /* __GSK_SL_QUALIFIER_PRIVATE_H__ */ diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c index 91a0f32586..2023877310 100644 --- a/gsk/gsksltype.c +++ b/gsk/gsksltype.c @@ -1395,7 +1395,7 @@ gsk_sl_type_block_write_spv (GskSlType *type, ids, block->n_members); - gsk_spv_writer_decorate (writer, result_id, GSK_SPV_DECORATION_BLOCK); + gsk_spv_writer_decorate (writer, result_id, GSK_SPV_DECORATION_BLOCK, NULL, 0); return result_id; } diff --git a/gsk/gskslvariable.c b/gsk/gskslvariable.c index 5092603e4b..ff01fe33cf 100644 --- a/gsk/gskslvariable.c +++ b/gsk/gskslvariable.c @@ -105,6 +105,8 @@ gsk_sl_variable_standard_write_spv (const GskSlVariable *variable, if (variable->name) gsk_spv_writer_name (writer, result_id, variable->name); + gsk_sl_qualifier_write_spv_decorations (&variable->qualifier, writer, result_id); + return result_id; } diff --git a/gsk/gskspvwritergeneratedprivate.h b/gsk/gskspvwritergeneratedprivate.h index dccd93dd7c..b9746b1ac2 100644 --- a/gsk/gskspvwritergeneratedprivate.h +++ b/gsk/gskspvwritergeneratedprivate.h @@ -1168,7 +1168,9 @@ gsk_spv_writer_in_bounds_ptr_access_chain (GskSpvWriter *writer, static inline void gsk_spv_writer_decorate (GskSpvWriter *writer, guint32 target, - GskSpvDecoration decoration) + GskSpvDecoration decoration, + guint32 *values, + gsize n_values) { GArray *bytes = gsk_spv_writer_get_bytes (writer, GSK_SPV_WRITER_SECTION_DECORATE); guint start_index = bytes->len; @@ -1176,6 +1178,7 @@ gsk_spv_writer_decorate (GskSpvWriter *writer, g_array_append_val (bytes, (guint32) { 0 }); g_array_append_val (bytes, target); g_array_append_val (bytes, (guint32) { decoration }); + g_array_append_vals (bytes, values, n_values); g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | GSK_SPV_OP_DECORATE; } @@ -1183,7 +1186,9 @@ static inline void gsk_spv_writer_member_decorate (GskSpvWriter *writer, guint32 structure_type, guint32 member, - GskSpvDecoration decoration) + GskSpvDecoration decoration, + guint32 *values, + gsize n_values) { GArray *bytes = gsk_spv_writer_get_bytes (writer, GSK_SPV_WRITER_SECTION_DECORATE); guint start_index = bytes->len; @@ -1192,6 +1197,7 @@ gsk_spv_writer_member_decorate (GskSpvWriter *writer, g_array_append_val (bytes, structure_type); g_array_append_val (bytes, member); g_array_append_val (bytes, (guint32) { decoration }); + g_array_append_vals (bytes, values, n_values); g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | GSK_SPV_OP_MEMBER_DECORATE; } diff --git a/gsk/spirv.js b/gsk/spirv.js index 2a8fbd90c5..3ffb85d305 100644 --- a/gsk/spirv.js +++ b/gsk/spirv.js @@ -86,6 +86,11 @@ var SpecialTypes = { "OpFunctionParameter": { "result_type": "IdRef" } }; +var ExtraOperands = { + "OpDecorate": [ { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } ], + "OpMemberDecorate": [ { "kind" : "LiteralContextDependentNumber", "name" : "'Value'" } ] +}; + /* maps opcodes to section in file they appear in */ var Sections = { "OpNop": "", @@ -532,16 +537,15 @@ for (let i in spirv.instructions) let ins = spirv.instructions[i]; ins.result = false; ins.enum_value = "GSK_SPV_OP_" + all_upper (ins.opname.substr(2)); - if (ins.operands) - { - for (let o in ins.operands) - { - o = ins.operands[o]; - fix_operand (ins, o); - } - } - else + if (!ins.operands) ins.operands = []; + if (ExtraOperands[ins.opname]) + ins.operands = ins.operands.concat (ExtraOperands[ins.opname]); + for (let o in ins.operands) + { + o = ins.operands[o]; + fix_operand (ins, o); + } if (Sections[ins.opname]) { ins.section = Sections[ins.opname];