gskspv: Pass inout parameters by reference

We can't just pass the value, SPIRV expects to be able to write to the
parameter if it's not const.

This does not yet do the right thing for for out variables. They are not
copied back to the caller.
This commit is contained in:
Benjamin Otte
2017-10-10 04:06:52 +02:00
parent 9aa73600f1
commit 1d5ac3b892
6 changed files with 117 additions and 10 deletions

View File

@@ -438,12 +438,36 @@ gsk_sl_function_declared_write_call_spv (GskSlFunction *function,
guint32 *arguments)
{
GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
gsize n = gsk_sl_function_type_get_n_arguments (declared->function_type);
guint32 real_args[n];
guint32 result;
gsize i;
for (i = 0; i < gsk_sl_function_type_get_n_arguments (declared->function_type); i++)
{
if (gsk_sl_function_type_is_argument_const (declared->function_type, i))
{
real_args[i] = arguments[i];
}
else
{
real_args[i] = gsk_spv_writer_variable (writer,
GSK_SPV_WRITER_SECTION_DECLARE,
gsk_sl_function_type_get_argument_type (declared->function_type, i),
GSK_SPV_STORAGE_CLASS_FUNCTION,
GSK_SPV_STORAGE_CLASS_FUNCTION,
0);
if (gsk_sl_function_type_is_argument_in (declared->function_type, i))
{
gsk_spv_writer_store (writer, real_args[i], arguments[i], 0);
}
}
}
result = gsk_spv_writer_function_call (writer,
gsk_sl_function_type_get_return_type (declared->function_type),
gsk_spv_writer_get_id_for_function (writer, function),
arguments,
real_args,
gsk_sl_function_type_get_n_arguments (declared->function_type));
return result;

View File

@@ -148,6 +148,29 @@ gsk_sl_function_type_get_argument_storage (const GskSlFunctionType *function_typ
return function_type->arguments[i].storage;
}
gboolean
gsk_sl_function_type_is_argument_const (const GskSlFunctionType *function_type,
gsize i)
{
return function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_CONST;
}
gboolean
gsk_sl_function_type_is_argument_in (const GskSlFunctionType *function_type,
gsize i)
{
return function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_IN
|| function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_INOUT;
}
gboolean
gsk_sl_function_type_is_argument_out (const GskSlFunctionType *function_type,
gsize i)
{
return function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_OUT
|| function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_INOUT;
}
guint32
gsk_sl_function_type_write_spv (const GskSlFunctionType *function_type,
GskSpvWriter *writer)
@@ -158,7 +181,17 @@ gsk_sl_function_type_write_spv (const GskSlFunctionType *function_type,
return_type_id = gsk_spv_writer_get_id_for_type (writer, function_type->return_type);
for (i = 0; i < function_type->n_arguments; i++)
{
argument_types[i] = gsk_spv_writer_get_id_for_type (writer, function_type->arguments[i].type);
if (function_type->arguments[i].storage == GSK_SL_STORAGE_PARAMETER_CONST)
{
argument_types[i] = gsk_spv_writer_get_id_for_type (writer,
function_type->arguments[i].type);
}
else
{
argument_types[i] = gsk_spv_writer_get_id_for_pointer_type (writer,
function_type->arguments[i].type,
GSK_SPV_STORAGE_CLASS_FUNCTION);
}
}
return gsk_spv_writer_type_function (writer, return_type_id, argument_types, function_type->n_arguments);

View File

@@ -39,6 +39,12 @@ GskSlType * gsk_sl_function_type_get_argument_type (const GskSlFunc
gsize i);
GskSlStorage gsk_sl_function_type_get_argument_storage (const GskSlFunctionType*function_type,
gsize i);
gboolean gsk_sl_function_type_is_argument_const (const GskSlFunctionType*function_type,
gsize i);
gboolean gsk_sl_function_type_is_argument_in (const GskSlFunctionType*function_type,
gsize i);
gboolean gsk_sl_function_type_is_argument_out (const GskSlFunctionType*function_type,
gsize i);
guint32 gsk_sl_function_type_write_spv (const GskSlFunctionType*function_type,
GskSpvWriter *writer);

View File

@@ -176,10 +176,12 @@ static guint32
gsk_sl_variable_parameter_write_spv (const GskSlVariable *variable,
GskSpvWriter *writer)
{
guint32 result_id;
guint32 type_id, result_id;
result_id = gsk_spv_writer_function_parameter (writer,
variable->type);
type_id = gsk_spv_writer_get_id_for_pointer_type (writer,
variable->type,
GSK_SPV_STORAGE_CLASS_FUNCTION);
result_id = gsk_spv_writer_function_parameter (writer, type_id);
if (variable->name)
gsk_spv_writer_name (writer, result_id, variable->name);
@@ -217,6 +219,46 @@ static const GskSlVariableClass GSK_SL_VARIABLE_PARAMETER = {
gsk_sl_variable_parameter_store_spv,
};
/* CONST_PARAMETER */
static guint32
gsk_sl_variable_const_parameter_write_spv (const GskSlVariable *variable,
GskSpvWriter *writer)
{
guint32 result_id, type_id;
type_id = gsk_spv_writer_get_id_for_type (writer, variable->type);
result_id = gsk_spv_writer_function_parameter (writer, type_id);
if (variable->name)
gsk_spv_writer_name (writer, result_id, variable->name);
return result_id;
}
static guint32
gsk_sl_variable_const_parameter_load_spv (GskSlVariable *variable,
GskSpvWriter *writer)
{
return gsk_spv_writer_get_id_for_variable (writer, variable);
}
static void
gsk_sl_variable_const_parameter_store_spv (GskSlVariable *variable,
GskSpvWriter *writer,
guint32 value)
{
g_assert_not_reached ();
}
static const GskSlVariableClass GSK_SL_VARIABLE_CONST_PARAMETER = {
sizeof (GskSlVariable),
gsk_sl_variable_free,
gsk_sl_variable_const_parameter_write_spv,
gsk_sl_variable_const_parameter_load_spv,
gsk_sl_variable_const_parameter_store_spv,
};
/* API */
static const GskSlVariableClass *
@@ -243,9 +285,11 @@ gsk_sl_variable_select_class (const GskSlQualifier *qualifier,
case GSK_SL_STORAGE_PARAMETER_IN:
case GSK_SL_STORAGE_PARAMETER_OUT:
case GSK_SL_STORAGE_PARAMETER_INOUT:
case GSK_SL_STORAGE_PARAMETER_CONST:
return &GSK_SL_VARIABLE_PARAMETER;
case GSK_SL_STORAGE_PARAMETER_CONST:
return &GSK_SL_VARIABLE_CONST_PARAMETER;
case GSK_SL_STORAGE_DEFAULT:
default:
g_assert_not_reached ();

View File

@@ -865,15 +865,14 @@ gsk_spv_writer_function (GskSpvWriter *writer,
static inline guint32
gsk_spv_writer_function_parameter (GskSpvWriter *writer,
GskSlType *result_type)
guint32 result_type)
{
GArray *bytes = gsk_spv_writer_get_bytes (writer, GSK_SPV_WRITER_SECTION_DECLARE);
guint32 result_type_id = gsk_spv_writer_get_id_for_type (writer, result_type);
guint32 result_id = gsk_spv_writer_make_id (writer);
guint start_index = bytes->len;
g_array_append_val (bytes, (guint32) { 0 });
g_array_append_val (bytes, result_type_id);
g_array_append_val (bytes, result_type);
g_array_append_val (bytes, result_id);
g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | GSK_SPV_OP_FUNCTION_PARAMETER;

View File

@@ -82,7 +82,8 @@ var SpecialTypes = {
"OpConvertUToPtr": { "result_type": "IdResultPointerType" },
"OpPtrCastToGeneric": { "result_type": "IdResultPointerType" },
"OpGenericCastToPtr": { "result_type": "IdResultPointerType" },
"OpGenericCastToPtrExplicit": { "result_type": "IdResultPointerType" }
"OpGenericCastToPtrExplicit": { "result_type": "IdResultPointerType" },
"OpFunctionParameter": { "result_type": "IdRef" }
};
/* maps opcodes to section in file they appear in */