[gtk+/wip/otte/shader: 52/98] gskspv: Pass inout parameters by reference



commit c3a30b20cd1705884e8fa9412f72798cc86de467
Author: Benjamin Otte <otte redhat com>
Date:   Tue Oct 10 04:06:52 2017 +0200

    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.

 gsk/gskslfunction.c                |   26 +++++++++++++++++-
 gsk/gskslfunctiontype.c            |   35 +++++++++++++++++++++++-
 gsk/gskslfunctiontypeprivate.h     |    6 ++++
 gsk/gskslvariable.c                |   52 +++++++++++++++++++++++++++++++++---
 gsk/gskspvwritergeneratedprivate.h |    5 +--
 gsk/spirv.js                       |    3 +-
 6 files changed, 117 insertions(+), 10 deletions(-)
---
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 2e0ab08..a94b7e6 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -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;
diff --git a/gsk/gskslfunctiontype.c b/gsk/gskslfunctiontype.c
index 3b59241..5edbac6 100644
--- a/gsk/gskslfunctiontype.c
+++ b/gsk/gskslfunctiontype.c
@@ -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);
diff --git a/gsk/gskslfunctiontypeprivate.h b/gsk/gskslfunctiontypeprivate.h
index 4355d76..31c9380 100644
--- a/gsk/gskslfunctiontypeprivate.h
+++ b/gsk/gskslfunctiontypeprivate.h
@@ -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);
diff --git a/gsk/gskslvariable.c b/gsk/gskslvariable.c
index 1093398..f17bf59 100644
--- a/gsk/gskslvariable.c
+++ b/gsk/gskslvariable.c
@@ -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 ();
diff --git a/gsk/gskspvwritergeneratedprivate.h b/gsk/gskspvwritergeneratedprivate.h
index f2ab69e..dccd93d 100644
--- a/gsk/gskspvwritergeneratedprivate.h
+++ b/gsk/gskspvwritergeneratedprivate.h
@@ -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;
 
diff --git a/gsk/spirv.js b/gsk/spirv.js
index 9f1fb03..2a8fbd9 100644
--- a/gsk/spirv.js
+++ b/gsk/spirv.js
@@ -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 */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]