[gtk+/wip/otte/shader: 12/12] gskslprogram: Allow variables to have constant initializers



commit 40b8e9fe60264b45e86957266111158dfca27719
Author: Benjamin Otte <otte redhat com>
Date:   Tue Sep 26 18:08:05 2017 +0200

    gskslprogram: Allow variables to have constant initializers
    
    Technically, all intiializers should be allowed, but for now we're happy
    we can do const ones.
    
    Also store them properly in the SPIR-V output.

 gsk/gskslnode.c     |    2 +-
 gsk/gskslprogram.c  |   50 ++++++++++++++++++++++++++++++++++++++++++++++++--
 gsk/gskslvariable.c |   13 +++++++++----
 3 files changed, 58 insertions(+), 7 deletions(-)
---
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index b4c56ce..2cc1e1a 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -132,7 +132,7 @@ gsk_sl_node_declaration_write_spv (const GskSlNode *node,
 
   variable_id = gsk_spv_writer_get_id_for_variable (writer, declaration->variable);
   
-  if (declaration->initial)
+  if (declaration->initial && ! gsk_sl_variable_get_initial_value (declaration->variable))
     {
       gsk_spv_writer_add (writer,
                           GSK_SPV_WRITER_SECTION_CODE,
diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c
index 9845433..e3a3d3a 100644
--- a/gsk/gskslprogram.c
+++ b/gsk/gskslprogram.c
@@ -20,6 +20,7 @@
 
 #include "gskslprogramprivate.h"
 
+#include "gskslexpressionprivate.h"
 #include "gskslfunctionprivate.h"
 #include "gskslnodeprivate.h"
 #include "gskslpointertypeprivate.h"
@@ -27,6 +28,7 @@
 #include "gskslscopeprivate.h"
 #include "gsksltokenizerprivate.h"
 #include "gsksltypeprivate.h"
+#include "gskslvalueprivate.h"
 #include "gskslvariableprivate.h"
 #include "gskspvwriterprivate.h"
 
@@ -76,15 +78,52 @@ gsk_sl_program_parse_variable (GskSlProgram      *program,
 {
   GskSlVariable *variable;
   const GskSlToken *token;
+  GskSlValue *value = NULL;
   GskSlPointerType *pointer_type;
 
   token = gsk_sl_preprocessor_get (preproc);
+  if (gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
+    {
+      GskSlValue *unconverted;
+      GskSlExpression *initial;
+
+      gsk_sl_preprocessor_consume (preproc, program);
+
+      initial = gsk_sl_expression_parse_assignment (scope, preproc);
+      if (!gsk_sl_type_can_convert (type, gsk_sl_expression_get_return_type (initial)))
+        {
+          gsk_sl_preprocessor_error (preproc, "Cannot convert from initializer type %s to variable type %s",
+                                              gsk_sl_type_get_name (gsk_sl_expression_get_return_type 
(initial)),
+                                              gsk_sl_type_get_name (type));
+          gsk_sl_expression_unref (initial);
+          return NULL;
+        }
+
+      unconverted = gsk_sl_expression_get_constant (initial);
+      gsk_sl_expression_unref (initial);
+      if (unconverted)
+        {
+          value = gsk_sl_value_new_convert (unconverted, type);
+          gsk_sl_value_free (unconverted);
+        }
+      else 
+        {
+          gsk_sl_preprocessor_error (preproc, "Initializer is not constant.");
+          return FALSE;
+        }
+
+      token = gsk_sl_preprocessor_get (preproc);
+    }
+
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
-    return FALSE;
+    {
+      gsk_sl_preprocessor_error (preproc, "No semicolon at end of variable declaration.");
+      return FALSE;
+    }
   gsk_sl_preprocessor_consume (preproc, NULL);
 
   pointer_type = gsk_sl_pointer_type_new (type, FALSE, 
decoration->values[GSK_SL_DECORATION_CALLER_ACCESS].value);
-  variable = gsk_sl_variable_new (pointer_type, g_strdup (name), NULL, 
decoration->values[GSK_SL_DECORATION_CONST].set);
+  variable = gsk_sl_variable_new (pointer_type, g_strdup (name), value, 
decoration->values[GSK_SL_DECORATION_CONST].set);
   gsk_sl_pointer_type_unref (pointer_type);
       
   program->variables = g_slist_append (program->variables, variable);
@@ -192,7 +231,14 @@ gsk_sl_program_print (GskSlProgram *program,
 
   for (l = program->variables; l; l = l->next)
     {
+      const GskSlValue *value;
       gsk_sl_variable_print (l->data, string);
+      value = gsk_sl_variable_get_initial_value (l->data);
+      if (value)
+        {
+          g_string_append (string, " = ");
+          gsk_sl_value_print (value, string);
+        }
       g_string_append (string, ";\n");
     }
 
diff --git a/gsk/gskslvariable.c b/gsk/gskslvariable.c
index c4cc57e..71bf9a4 100644
--- a/gsk/gskslvariable.c
+++ b/gsk/gskslvariable.c
@@ -124,16 +124,21 @@ guint32
 gsk_sl_variable_write_spv (const GskSlVariable *variable,
                            GskSpvWriter        *writer)
 {
-  guint32 pointer_type_id, variable_id;
+  guint32 pointer_type_id, variable_id, value_id;
 
   pointer_type_id = gsk_spv_writer_get_id_for_pointer_type (writer, variable->type);
   variable_id = gsk_spv_writer_next_id (writer);
+  if (variable->initial_value)
+    value_id = gsk_spv_writer_get_id_for_value (writer, variable->initial_value);
+  else
+    value_id = 0;
   gsk_spv_writer_add (writer,
                       GSK_SPV_WRITER_SECTION_CODE,
-                      4, GSK_SPV_OP_VARIABLE,
-                      (guint32[3]) { pointer_type_id,
+                      variable->initial_value ? 5 : 4, GSK_SPV_OP_VARIABLE,
+                      (guint32[4]) { pointer_type_id,
                                      variable_id,
-                                     gsk_sl_pointer_type_get_storage_class (variable->type)});
+                                     gsk_sl_pointer_type_get_storage_class (variable->type),
+                                     value_id });
 
   return variable_id;
 }


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