gsksl: Emit decorations for variables

This requires some changes to the generated code from the SPIRV spec,
because the grammar does not list the optional argument for OpDecorate.

Bad spec!
This commit is contained in:
Benjamin Otte
2017-10-11 16:28:48 +02:00
parent bde7a1f51c
commit 3124dffa37
6 changed files with 72 additions and 12 deletions

View File

@@ -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);
}
}

View File

@@ -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__ */

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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];