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:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user