[gtk+/wip/otte/shader: 37/71] gskspv: Allow writing function calls



commit 1eb01d0a803d578de1de6abdc3fc4e87b3d42016
Author: Benjamin Otte <otte redhat com>
Date:   Sat Oct 7 17:19:31 2017 +0200

    gskspv: Allow writing function calls
    
    The code is all very wonky still in the way it orders instructions
    and needs some reorganization to consistently do the right thing.

 gsk/gskslexpression.c      |   15 +++++++++-
 gsk/gskslfunction.c        |   50 +++++++++++++++++++++++++++++++++-
 gsk/gskslfunctionprivate.h |    3 ++
 gsk/gskslprogram.c         |    4 +-
 gsk/gskslqualifier.c       |    8 +++---
 gsk/gskspvwriter.c         |   64 +++++++++++++++++++++++++++++++++++++------
 gsk/gskspvwriterprivate.h  |    4 ++-
 7 files changed, 129 insertions(+), 19 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 3ca64a6..f4f878d 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -1838,9 +1838,20 @@ static guint32
 gsk_sl_expression_function_call_write_spv (const GskSlExpression *expression,
                                            GskSpvWriter          *writer)
 {
-  g_assert_not_reached ();
+  const GskSlExpressionFunctionCall *function_call = (const GskSlExpressionFunctionCall *) expression;
+  guint arguments[function_call->n_arguments];
+  gsize i;
 
-  return 0;
+  for (i = 0; i < function_call->n_arguments; i++)
+    {
+      arguments[i] = gsk_sl_expression_write_spv (function_call->arguments[i], writer);
+      arguments[i] = gsk_spv_writer_convert (writer, 
+                                             arguments[i],
+                                             gsk_sl_expression_get_return_type (function_call->arguments[i]),
+                                             gsk_sl_function_get_argument_type (function_call->function, i));
+    }
+
+  return gsk_sl_function_write_call_spv (function_call->function, writer, arguments);
 }
 
 static const GskSlExpressionClass GSK_SL_EXPRESSION_FUNCTION_CALL = {
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 0f26119..1c9d55c 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -57,6 +57,9 @@ struct _GskSlFunctionClass {
                                                                  GskSlPrinter           *printer);
   guint32               (* write_spv)                           (const GskSlFunction    *function,
                                                                  GskSpvWriter           *writer);
+  guint32               (* write_call_spv)                      (GskSlFunction          *function,
+                                                                 GskSpvWriter           *writer,
+                                                                 guint32                *arguments);
 };
 
 static GskSlFunction *
@@ -148,6 +151,16 @@ gsk_sl_function_constructor_write_spv (const GskSlFunction *function,
   return 0;
 }
 
+static guint32
+gsk_sl_function_constructor_write_call_spv (GskSlFunction *function,
+                                            GskSpvWriter  *writer,
+                                            guint32       *arguments)
+{
+  g_assert_not_reached ();
+
+  return 0;
+}
+
 static const GskSlFunctionClass GSK_SL_FUNCTION_CONSTRUCTOR = {
   gsk_sl_function_constructor_free,
   gsk_sl_function_constructor_get_return_type,
@@ -157,6 +170,7 @@ static const GskSlFunctionClass GSK_SL_FUNCTION_CONSTRUCTOR = {
   gsk_sl_function_constructor_get_constant,
   gsk_sl_function_constructor_print,
   gsk_sl_function_constructor_write_spv,
+  gsk_sl_function_constructor_write_call_spv
 };
 
 /* NATIVE */
@@ -231,6 +245,16 @@ gsk_sl_function_native_write_spv (const GskSlFunction *function,
   return 0;
 }
 
+static guint32
+gsk_sl_function_native_write_call_spv (GskSlFunction *function,
+                                       GskSpvWriter  *writer,
+                                       guint32       *arguments)
+{
+  g_assert_not_reached ();
+
+  return 0;
+}
+
 static const GskSlFunctionClass GSK_SL_FUNCTION_NATIVE = {
   gsk_sl_function_native_free,
   gsk_sl_function_native_get_return_type,
@@ -239,7 +263,8 @@ static const GskSlFunctionClass GSK_SL_FUNCTION_NATIVE = {
   gsk_sl_function_native_get_argument_type,
   gsk_sl_function_native_get_constant,
   gsk_sl_function_native_print,
-  gsk_sl_function_native_write_spv
+  gsk_sl_function_native_write_spv,
+  gsk_sl_function_native_write_call_spv
 };
 
 /* DECLARED */
@@ -395,6 +420,20 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
   return function_id;
 }
 
+static guint32
+gsk_sl_function_declared_write_call_spv (GskSlFunction *function,
+                                         GskSpvWriter  *writer,
+                                         guint32       *arguments)
+{
+  GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
+
+  return gsk_spv_writer_function_call (writer,
+                                       declared->return_type,
+                                       gsk_spv_writer_get_id_for_function (writer, function),
+                                       arguments,
+                                       declared->n_arguments);
+}
+
 static const GskSlFunctionClass GSK_SL_FUNCTION_DECLARED = {
   gsk_sl_function_declared_free,
   gsk_sl_function_declared_get_return_type,
@@ -404,6 +443,7 @@ static const GskSlFunctionClass GSK_SL_FUNCTION_DECLARED = {
   gsk_sl_function_declared_get_constant,
   gsk_sl_function_declared_print,
   gsk_sl_function_declared_write_spv,
+  gsk_sl_function_declared_write_call_spv
 };
 
 /* API */
@@ -619,6 +659,14 @@ gsk_sl_function_write_spv (const GskSlFunction *function,
   return function->class->write_spv (function, writer);
 }
 
+guint32
+gsk_sl_function_write_call_spv (GskSlFunction *function,
+                                GskSpvWriter  *writer,
+                                guint32       *arguments)
+{
+  return function->class->write_call_spv (function, writer, arguments);
+}
+
 void
 gsk_sl_function_matcher_init (GskSlFunctionMatcher *matcher,
                               GList                *list)
diff --git a/gsk/gskslfunctionprivate.h b/gsk/gskslfunctionprivate.h
index 5ca1933..9752d44 100644
--- a/gsk/gskslfunctionprivate.h
+++ b/gsk/gskslfunctionprivate.h
@@ -48,6 +48,9 @@ GskSlValue *            gsk_sl_function_get_constant            (const GskSlFunc
                                                                  gsize                   n_values);
 guint32                 gsk_sl_function_write_spv               (const GskSlFunction    *function,
                                                                  GskSpvWriter           *writer);
+guint32                 gsk_sl_function_write_call_spv          (GskSlFunction          *function,
+                                                                 GskSpvWriter           *writer,
+                                                                 guint32                *arguments);
 
 struct _GskSlFunctionMatcher
 {
diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c
index 503b535..16e1906 100644
--- a/gsk/gskslprogram.c
+++ b/gsk/gskslprogram.c
@@ -266,10 +266,10 @@ gsk_sl_program_write_spv (GskSlProgram *program,
 
   for (l = program->functions; l; l = l->next)
     {
-      guint32 id = gsk_sl_function_write_spv (l->data, writer);
+      gsk_spv_writer_get_id_for_function (writer, l->data);
 
       if (g_str_equal (gsk_sl_function_get_name (l->data), "main"))
-        gsk_spv_writer_set_entry_point (writer, id);
+        gsk_spv_writer_set_entry_point (writer, l->data);
     }
 }
 
diff --git a/gsk/gskslqualifier.c b/gsk/gskslqualifier.c
index 9db2e80..ca07e74 100644
--- a/gsk/gskslqualifier.c
+++ b/gsk/gskslqualifier.c
@@ -547,10 +547,6 @@ gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier)
   switch (qualifier->storage)
     {
     case GSK_SL_STORAGE_DEFAULT:
-    case GSK_SL_STORAGE_PARAMETER_IN:
-    case GSK_SL_STORAGE_PARAMETER_OUT:
-    case GSK_SL_STORAGE_PARAMETER_INOUT:
-    case GSK_SL_STORAGE_PARAMETER_CONST:
     default:
       g_assert_not_reached ();
       return GSK_SPV_STORAGE_CLASS_FUNCTION;
@@ -573,6 +569,10 @@ gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier)
 
     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:
       return GSK_SPV_STORAGE_CLASS_FUNCTION;
     }
 }
diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c
index 20ce62c..f676b6e 100644
--- a/gsk/gskspvwriter.c
+++ b/gsk/gskspvwriter.c
@@ -20,6 +20,7 @@
 
 #include "gskspvwriterprivate.h"
 
+#include "gskslfunctionprivate.h"
 #include "gskslpointertypeprivate.h"
 #include "gsksltypeprivate.h"
 #include "gskslvalueprivate.h"
@@ -39,14 +40,25 @@ struct _GskSpvWriter
   guint32 last_id;
   GArray *code[GSK_SPV_WRITER_N_SECTIONS];
   GSList *blocks;
+  GSList *pending_blocks;
+
+  GskSlFunction *entry_point;
 
-  guint32 entry_point;
   GHashTable *types;
   GHashTable *pointer_types;
   GHashTable *values;
   GHashTable *variables;
+  GHashTable *functions;
 };
 
+static void
+gsk_spv_code_block_free (GskSpvCodeBlock *block)
+{
+  g_array_free (block->code, TRUE);
+
+  g_slice_free (GskSpvCodeBlock, block);
+}
+
 GskSpvWriter *
 gsk_spv_writer_new (void)
 {
@@ -69,6 +81,8 @@ gsk_spv_writer_new (void)
                                           (GDestroyNotify) gsk_sl_value_free, NULL);
   writer->variables = g_hash_table_new_full (g_direct_hash, g_direct_equal,
                                              (GDestroyNotify) gsk_sl_variable_unref, NULL);
+  writer->functions = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+                                             (GDestroyNotify) gsk_sl_function_unref, NULL);
   /* the ID 1 is reserved for the GLSL instruction set (for now) */
   writer->last_id = 1;
 
@@ -97,6 +111,8 @@ gsk_spv_writer_unref (GskSpvWriter *writer)
   if (writer->ref_count > 0)
     return;
 
+  g_slist_free_full (writer->pending_blocks, (GDestroyNotify) gsk_spv_code_block_free);
+
   for (i = 0; i < GSK_SPV_WRITER_N_SECTIONS; i++)
     {
       g_array_free (writer->code[i], TRUE);
@@ -106,6 +122,7 @@ gsk_spv_writer_unref (GskSpvWriter *writer)
   g_hash_table_destroy (writer->types);
   g_hash_table_destroy (writer->values);
   g_hash_table_destroy (writer->variables);
+  g_hash_table_destroy (writer->functions);
 
   g_slice_free (GskSpvWriter, writer);
 }
@@ -114,20 +131,23 @@ gsk_spv_writer_unref (GskSpvWriter *writer)
 static void
 gsk_spv_writer_write_header (GskSpvWriter *writer)
 {
+  guint32 entry_point;
+
   gsk_spv_writer_capability (writer, GSK_SPV_CAPABILITY_SHADER);
   gsk_spv_writer_ext_inst_import (writer,
                                   "GLSL.std.450");
   gsk_spv_writer_memory_model (writer,
                                GSK_SPV_ADDRESSING_MODEL_LOGICAL,
                                GSK_SPV_MEMORY_MODEL_GLSL450);
+  entry_point = gsk_spv_writer_get_id_for_function (writer, writer->entry_point);
   gsk_spv_writer_entry_point (writer,
                               GSK_SPV_EXECUTION_MODEL_FRAGMENT,
-                              writer->entry_point,
+                              entry_point,
                               "main",
                               NULL,
                               0);
   gsk_spv_writer_execution_mode (writer,
-                                 writer->entry_point,
+                                 entry_point,
                                  GSK_SPV_EXECUTION_MODE_ORIGIN_UPPER_LEFT);
 }
 
@@ -142,6 +162,7 @@ gsk_spv_writer_write (GskSpvWriter *writer)
 {
   GArray *array;
   gsize size;
+  GSList *l;
   guint i;
 
   gsk_spv_writer_write_header (writer);
@@ -159,6 +180,13 @@ gsk_spv_writer_write (GskSpvWriter *writer)
       g_array_append_vals (array, writer->code[i]->data, writer->code[i]->len);
     }
 
+  for (l = writer->pending_blocks; l; l = l->next)
+    {
+      GskSpvCodeBlock *block = l->data;
+
+      g_array_append_vals (array, block->code->data, block->code->len);
+    }
+
   gsk_spv_writer_clear_header (writer);
 
   size = array->len * sizeof (guint32);
@@ -283,6 +311,26 @@ gsk_spv_writer_get_id_for_variable (GskSpvWriter  *writer,
 }
 
 guint32
+gsk_spv_writer_get_id_for_function (GskSpvWriter  *writer,
+                                    GskSlFunction *function)
+{
+  GskSpvCodeBlock *block;
+  guint32 result;
+
+  result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->functions, function));
+  if (result != 0)
+    return result;
+
+  gsk_spv_writer_push_new_code_block (writer);
+  result = gsk_sl_function_write_spv (function, writer);
+  g_hash_table_insert (writer->functions, gsk_sl_function_ref (function), GUINT_TO_POINTER (result));
+  block = gsk_spv_writer_pop_code_block (writer);
+  writer->pending_blocks = g_slist_prepend (writer->pending_blocks, block);
+
+  return result;
+}
+
+guint32
 gsk_spv_writer_make_id (GskSpvWriter *writer)
 {
   writer->last_id++;
@@ -291,10 +339,10 @@ gsk_spv_writer_make_id (GskSpvWriter *writer)
 }
 
 void
-gsk_spv_writer_set_entry_point (GskSpvWriter *writer,
-                                guint32       entry_point)
+gsk_spv_writer_set_entry_point (GskSpvWriter  *writer,
+                                GskSlFunction *function)
 {
-  writer->entry_point = entry_point;
+  writer->entry_point = gsk_sl_function_ref (function);
 }
 
 GArray *
@@ -352,9 +400,7 @@ gsk_spv_writer_commit_code_block (GskSpvWriter *writer)
   commit_target = gsk_spv_writer_get_bytes (writer, GSK_SPV_WRITER_SECTION_CODE);
   g_array_append_vals (commit_target, block->code->data, block->code->len);
 
-  g_array_free (block->code, TRUE);
-
-  g_slice_free (GskSpvCodeBlock, block);
+  gsk_spv_code_block_free (block);
 }
 
 guint32
diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h
index 29e430a..419a663 100644
--- a/gsk/gskspvwriterprivate.h
+++ b/gsk/gskspvwriterprivate.h
@@ -51,7 +51,7 @@ void                    gsk_spv_writer_unref                    (GskSpvWriter
 
 GBytes *                gsk_spv_writer_write                    (GskSpvWriter           *writer);
 void                    gsk_spv_writer_set_entry_point          (GskSpvWriter           *writer,
-                                                                 guint32                 entry_point);
+                                                                 GskSlFunction          *function);
 
 guint32                 gsk_spv_writer_get_id_for_type          (GskSpvWriter           *writer,
                                                                  GskSlType              *type);
@@ -65,6 +65,8 @@ guint32                 gsk_spv_writer_get_id_for_one           (GskSpvWriter
                                                                  GskSlScalarType         scalar);
 guint32                 gsk_spv_writer_get_id_for_variable      (GskSpvWriter           *writer,
                                                                  GskSlVariable          *variable);
+guint32                 gsk_spv_writer_get_id_for_function      (GskSpvWriter           *writer,
+                                                                 GskSlFunction          *function);
 
 guint32                 gsk_spv_writer_make_id                  (GskSpvWriter           *writer);
 GArray *                gsk_spv_writer_get_bytes                (GskSpvWriter           *writer,


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