[gtk+/wip/otte/shader: 15/151] gsksl: Add GskSlVariable



commit cf89e5a17c91da111b95715fa1b7f090a2e5d91d
Author: Benjamin Otte <otte redhat com>
Date:   Sun Sep 24 19:35:27 2017 +0200

    gsksl: Add GskSlVariable
    
    A variable is the abstraction used for declarations of variables.
    
    I chose the name Variable over Declaration because it's the result of
    the SPIRV instruction OpVariable.

 gsk/gskslnode.c            |   75 +++++++++++------------------
 gsk/gskslscope.c           |   15 +++---
 gsk/gskslscopeprivate.h    |    5 +-
 gsk/gsksltypesprivate.h    |    1 +
 gsk/gskslvariable.c        |  114 ++++++++++++++++++++++++++++++++++++++++++++
 gsk/gskslvariableprivate.h |   45 +++++++++++++++++
 gsk/gskspvwriter.c         |   29 ++++++-----
 gsk/gskspvwriterprivate.h  |    7 +--
 gsk/meson.build            |    1 +
 9 files changed, 216 insertions(+), 76 deletions(-)
---
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index eed3d28..dfb6e58 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -26,6 +26,7 @@
 #include "gskslscopeprivate.h"
 #include "gsksltokenizerprivate.h"
 #include "gsksltypeprivate.h"
+#include "gskslvariableprivate.h"
 #include "gskspvwriterprivate.h"
 
 #include <string.h>
@@ -732,8 +733,7 @@ typedef struct _GskSlNodeDeclaration GskSlNodeDeclaration;
 struct _GskSlNodeDeclaration {
   GskSlNode parent;
 
-  char *name;
-  GskSlPointerType *type;
+  GskSlVariable *variable;
   GskSlNode *initial;
   guint constant :1;
 };
@@ -743,8 +743,7 @@ gsk_sl_node_declaration_free (GskSlNode *node)
 {
   GskSlNodeDeclaration *declaration = (GskSlNodeDeclaration *) node;
 
-  g_free (declaration->name);
-  gsk_sl_pointer_type_unref (declaration->type);
+  gsk_sl_variable_unref (declaration->variable);
   if (declaration->initial)
     gsk_sl_node_unref (declaration->initial);
 
@@ -757,16 +756,11 @@ gsk_sl_node_declaration_print (GskSlNode *node,
 {
   GskSlNodeDeclaration *declaration = (GskSlNodeDeclaration *) node;
 
-  gsk_sl_pointer_type_print (declaration->type, string);
-  if (declaration->name)
+  gsk_sl_variable_print (declaration->variable, string);
+  if (declaration->initial)
     {
-      g_string_append (string, " ");
-      g_string_append (string, declaration->name);
-      if (declaration->initial)
-        {
-          g_string_append (string, " = ");
-          gsk_sl_node_print (declaration->initial, string);
-        }
+      g_string_append (string, " = ");
+      gsk_sl_node_print (declaration->initial, string);
     }
 }
 
@@ -775,7 +769,7 @@ gsk_sl_node_declaration_get_return_type (GskSlNode *node)
 {
   GskSlNodeDeclaration *declaration = (GskSlNodeDeclaration *) node;
 
-  return gsk_sl_pointer_type_get_type (declaration->type);
+  return gsk_sl_pointer_type_get_type (gsk_sl_variable_get_type (declaration->variable));
 }
 
 static gboolean
@@ -791,28 +785,20 @@ gsk_sl_node_declaration_write_spv (const GskSlNode *node,
                                    GskSpvWriter    *writer)
 {
   GskSlNodeDeclaration *declaration = (GskSlNodeDeclaration *) node;
-  guint32 pointer_type_id, declaration_id;
+  guint32 variable_id;
 
-  pointer_type_id = gsk_spv_writer_get_id_for_pointer_type (writer, declaration->type);
-  declaration_id = gsk_spv_writer_next_id (writer);
-  gsk_spv_writer_add (writer,
-                      GSK_SPV_WRITER_SECTION_CODE,
-                      4, GSK_SPV_OP_VARIABLE,
-                      (guint32[3]) { pointer_type_id,
-                                     declaration_id,
-                                     gsk_sl_pointer_type_get_storage_class (declaration->type)});
-  gsk_spv_writer_set_id_for_declaration (writer, (GskSlNode *) node, declaration_id);
+  variable_id = gsk_spv_writer_get_id_for_variable (writer, declaration->variable);
   
   if (declaration->initial)
     {
       gsk_spv_writer_add (writer,
                           GSK_SPV_WRITER_SECTION_CODE,
                           3, GSK_SPV_OP_STORE,
-                          (guint32[2]) { declaration_id,
+                          (guint32[2]) { variable_id,
                                          gsk_sl_node_write_spv (declaration->initial, writer)});
     }
 
-  return declaration_id;
+  return variable_id;
 }
 
 static const GskSlNodeClass GSK_SL_NODE_DECLARATION = {
@@ -830,8 +816,7 @@ typedef struct _GskSlNodeReference GskSlNodeReference;
 struct _GskSlNodeReference {
   GskSlNode parent;
 
-  char *name;
-  GskSlNode *declaration;
+  GskSlVariable *variable;
 };
 
 static void
@@ -839,8 +824,7 @@ gsk_sl_node_reference_free (GskSlNode *node)
 {
   GskSlNodeReference *reference = (GskSlNodeReference *) node;
 
-  g_free (reference->name);
-  gsk_sl_node_unref (reference->declaration);
+  gsk_sl_variable_unref (reference->variable);
 
   g_slice_free (GskSlNodeReference, reference);
 }
@@ -851,7 +835,7 @@ gsk_sl_node_reference_print (GskSlNode *node,
 {
   GskSlNodeReference *reference = (GskSlNodeReference *) node;
 
-  g_string_append (string, reference->name);
+  g_string_append (string, gsk_sl_variable_get_name (reference->variable));
 }
 
 static GskSlType *
@@ -859,15 +843,13 @@ gsk_sl_node_reference_get_return_type (GskSlNode *node)
 {
   GskSlNodeReference *reference = (GskSlNodeReference *) node;
 
-  return gsk_sl_node_get_return_type (reference->declaration);
+  return gsk_sl_pointer_type_get_type (gsk_sl_variable_get_type (reference->variable));
 }
 
 static gboolean
 gsk_sl_node_reference_is_constant (GskSlNode *node)
 {
-  GskSlNodeReference *reference = (GskSlNodeReference *) node;
-
-  return gsk_sl_node_is_constant (reference->declaration);
+  return FALSE;
 }
 
 static guint32
@@ -877,8 +859,8 @@ gsk_sl_node_reference_write_spv (const GskSlNode *node,
   GskSlNodeReference *reference = (GskSlNodeReference *) node;
   guint32 declaration_id, result_id, type_id;
 
-  type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_node_get_return_type (reference->declaration));
-  declaration_id = gsk_spv_writer_get_id_for_declaration (writer, reference->declaration);
+  type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_pointer_type_get_type (gsk_sl_variable_get_type 
(reference->variable)));
+  declaration_id = gsk_spv_writer_get_id_for_variable (writer, reference->variable);
   result_id = gsk_spv_writer_next_id (writer);
   gsk_spv_writer_add (writer,
                       GSK_SPV_WRITER_SECTION_CODE,
@@ -1357,10 +1339,10 @@ gsk_sl_node_parse_primary_expression (GskSlScope        *scope,
     case GSK_SL_TOKEN_IDENTIFIER:
       {
         GskSlNodeReference *reference;
-        GskSlNode *decl;
+        GskSlVariable *variable;
 
-        decl = gsk_sl_scope_lookup_variable (scope, token->str);
-        if (decl == NULL)
+        variable = gsk_sl_scope_lookup_variable (scope, token->str);
+        if (variable == NULL)
           {
             gsk_sl_preprocessor_error (stream, "No variable named \"%s\".", token->str);
             gsk_sl_preprocessor_consume (stream, NULL);
@@ -1368,8 +1350,7 @@ gsk_sl_node_parse_primary_expression (GskSlScope        *scope,
           }
 
         reference = gsk_sl_node_new (GskSlNodeReference, &GSK_SL_NODE_REFERENCE);
-        reference->name = g_strdup (token->str);
-        reference->declaration = gsk_sl_node_ref (decl);
+        reference->variable = gsk_sl_variable_ref (variable);
         gsk_sl_preprocessor_consume (stream, (GskSlNode *) reference);
         return (GskSlNode *) reference;
       }
@@ -2114,13 +2095,15 @@ gsk_sl_node_parse_declaration (GskSlScope        *scope,
   const GskSlToken *token;
 
   declaration = gsk_sl_node_new (GskSlNodeDeclaration, &GSK_SL_NODE_DECLARATION);
-  declaration->type = gsk_sl_pointer_type_ref (type);
   
   token = gsk_sl_preprocessor_get (stream);
   if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
-    return (GskSlNode *) declaration;
+    {
+      declaration->variable = gsk_sl_variable_new (type, NULL);
+      return (GskSlNode *) declaration;
+    }
 
-  declaration->name = g_strdup (token->str);
+  declaration->variable = gsk_sl_variable_new (type, token->str);
   gsk_sl_preprocessor_consume (stream, (GskSlNode *) declaration);
 
   token = gsk_sl_preprocessor_get (stream);
@@ -2130,7 +2113,7 @@ gsk_sl_node_parse_declaration (GskSlScope        *scope,
       declaration->initial = gsk_sl_node_parse_assignment_expression (scope, stream);
     }
 
-  gsk_sl_scope_add_variable (scope, declaration->name, (GskSlNode *) declaration);
+  gsk_sl_scope_add_variable (scope, declaration->variable);
 
   return (GskSlNode *) declaration;
 }
diff --git a/gsk/gskslscope.c b/gsk/gskslscope.c
index edc9276..0a7b03f 100644
--- a/gsk/gskslscope.c
+++ b/gsk/gskslscope.c
@@ -20,7 +20,7 @@
 
 #include "gskslscopeprivate.h"
 
-#include "gskslnodeprivate.h"
+#include "gskslvariableprivate.h"
 
 #include <string.h>
 
@@ -43,7 +43,7 @@ gsk_sl_scope_new (GskSlScope *parent)
 
   if (parent)
     scope->parent = gsk_sl_scope_ref (parent);
-  scope->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) 
gsk_sl_node_unref);
+  scope->variables = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) 
gsk_sl_variable_unref);
 
   return scope;
 }
@@ -77,18 +77,17 @@ gsk_sl_scope_unref (GskSlScope *scope)
 }
 
 void
-gsk_sl_scope_add_variable (GskSlScope *scope,
-                           const char *name,
-                           GskSlNode  *declaration)
+gsk_sl_scope_add_variable (GskSlScope    *scope,
+                           GskSlVariable *variable)
 {
-  g_hash_table_replace (scope->variables, (gpointer) name, gsk_sl_node_ref (declaration));
+  g_hash_table_replace (scope->variables, (gpointer) gsk_sl_variable_get_name (variable), 
gsk_sl_variable_ref (variable));
 }
 
-GskSlNode *
+GskSlVariable *
 gsk_sl_scope_lookup_variable (GskSlScope *scope,
                               const char *name)
 {
-  GskSlNode *result;
+  GskSlVariable *result;
 
   for (;
        scope != NULL;
diff --git a/gsk/gskslscopeprivate.h b/gsk/gskslscopeprivate.h
index 1c69848..1106075 100644
--- a/gsk/gskslscopeprivate.h
+++ b/gsk/gskslscopeprivate.h
@@ -31,9 +31,8 @@ GskSlScope *            gsk_sl_scope_ref                        (GskSlScope
 void                    gsk_sl_scope_unref                      (GskSlScope           *scope);
 
 void                    gsk_sl_scope_add_variable               (GskSlScope           *scope,
-                                                                 const char           *name,
-                                                                 GskSlNode            *declaration);
-GskSlNode *             gsk_sl_scope_lookup_variable            (GskSlScope           *scope,
+                                                                 GskSlVariable        *variable);
+GskSlVariable *         gsk_sl_scope_lookup_variable            (GskSlScope           *scope,
                                                                  const char           *name);
 
 G_END_DECLS
diff --git a/gsk/gsksltypesprivate.h b/gsk/gsksltypesprivate.h
index f9d82ea..f02703b 100644
--- a/gsk/gsksltypesprivate.h
+++ b/gsk/gsksltypesprivate.h
@@ -28,6 +28,7 @@ typedef struct _GskSlPointerType        GskSlPointerType;
 typedef struct _GskSlScope              GskSlScope;
 typedef struct _GskSlToken              GskSlToken;
 typedef struct _GskSlType               GskSlType;
+typedef struct _GskSlVariable           GskSlVariable;
 
 typedef struct _GskSpvWriter            GskSpvWriter;
 
diff --git a/gsk/gskslvariable.c b/gsk/gskslvariable.c
new file mode 100644
index 0000000..faa3521
--- /dev/null
+++ b/gsk/gskslvariable.c
@@ -0,0 +1,114 @@
+/* GTK - The GIMP Toolkit
+ *   
+ * Copyright © 2017 Benjamin Otte <otte gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "gskslvariableprivate.h"
+
+#include "gskslpointertypeprivate.h"
+#include "gskspvwriterprivate.h"
+
+struct _GskSlVariable {
+  guint ref_count;
+
+  GskSlPointerType *type;
+  char *name;
+};
+
+GskSlVariable *
+gsk_sl_variable_new (GskSlPointerType *type,
+                     const char       *name)
+{
+  GskSlVariable *variable;
+
+  variable = g_slice_new0 (GskSlVariable);
+
+  variable->ref_count = 1;
+  variable->type = gsk_sl_pointer_type_ref (type);
+  variable->name = g_strdup (name);
+
+  return variable;
+}
+
+GskSlVariable *
+gsk_sl_variable_ref (GskSlVariable *variable)
+{
+  g_return_val_if_fail (variable != NULL, NULL);
+
+  variable->ref_count += 1;
+
+  return variable;
+}
+
+void
+gsk_sl_variable_unref (GskSlVariable *variable)
+{
+  if (variable == NULL)
+    return;
+
+  variable->ref_count -= 1;
+  if (variable->ref_count > 0)
+    return;
+
+  gsk_sl_pointer_type_unref (variable->type);
+  g_free (variable->name);
+
+  g_slice_free (GskSlVariable, variable);
+}
+
+void
+gsk_sl_variable_print (const GskSlVariable *variable,
+                       GString             *string)
+{
+  gsk_sl_pointer_type_print (variable->type, string);
+  if (variable->name)
+    {
+      g_string_append (string, " ");
+      g_string_append (string, variable->name);
+    }
+}
+
+GskSlPointerType *
+gsk_sl_variable_get_type (const GskSlVariable *variable)
+{
+  return variable->type;
+}
+
+const char *
+gsk_sl_variable_get_name (const GskSlVariable *variable)
+{
+  return variable->name;
+}
+
+guint32
+gsk_sl_variable_write_spv (const GskSlVariable *variable,
+                           GskSpvWriter        *writer)
+{
+  guint32 pointer_type_id, variable_id;
+
+  pointer_type_id = gsk_spv_writer_get_id_for_pointer_type (writer, variable->type);
+  variable_id = gsk_spv_writer_next_id (writer);
+  gsk_spv_writer_add (writer,
+                      GSK_SPV_WRITER_SECTION_CODE,
+                      4, GSK_SPV_OP_VARIABLE,
+                      (guint32[3]) { pointer_type_id,
+                                     variable_id,
+                                     gsk_sl_pointer_type_get_storage_class (variable->type)});
+
+  return variable_id;
+}
diff --git a/gsk/gskslvariableprivate.h b/gsk/gskslvariableprivate.h
new file mode 100644
index 0000000..bfb7be9
--- /dev/null
+++ b/gsk/gskslvariableprivate.h
@@ -0,0 +1,45 @@
+/* GTK - The GIMP Toolkit
+ *
+ * Copyright © 2017 Benjamin Otte <otte gnome org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __GSK_SL_VARIABLE_PRIVATE_H__
+#define __GSK_SL_VARIABLE_PRIVATE_H__
+
+#include <glib.h>
+
+#include "gsk/gsksltypesprivate.h"
+
+G_BEGIN_DECLS
+
+GskSlVariable *         gsk_sl_variable_new                     (GskSlPointerType       *type,
+                                                                 const char             *name);
+
+GskSlVariable *         gsk_sl_variable_ref                     (GskSlVariable          *variable);
+void                    gsk_sl_variable_unref                   (GskSlVariable          *variable);
+
+void                    gsk_sl_variable_print                   (const GskSlVariable    *variable,
+                                                                 GString                *string);
+
+GskSlPointerType *      gsk_sl_variable_get_type                (const GskSlVariable    *variable);
+const char *            gsk_sl_variable_get_name                (const GskSlVariable    *variable);
+
+guint32                 gsk_sl_variable_write_spv               (const GskSlVariable    *variable,
+                                                                 GskSpvWriter           *writer);
+
+G_END_DECLS
+
+#endif /* __GSK_SL_VARIABLE_PRIVATE_H__ */
diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c
index dda6402..a514b15 100644
--- a/gsk/gskspvwriter.c
+++ b/gsk/gskspvwriter.c
@@ -23,6 +23,7 @@
 #include "gskslnodeprivate.h"
 #include "gskslpointertypeprivate.h"
 #include "gsksltypeprivate.h"
+#include "gskslvariableprivate.h"
 
 struct _GskSpvWriter
 {
@@ -34,7 +35,7 @@ struct _GskSpvWriter
   guint32 entry_point;
   GHashTable *types;
   GHashTable *pointer_types;
-  GHashTable *declarations;
+  GHashTable *variables;
 };
 
 GskSpvWriter *
@@ -55,8 +56,8 @@ gsk_spv_writer_new (void)
                                          (GDestroyNotify) gsk_sl_type_unref, NULL);
   writer->pointer_types = g_hash_table_new_full (gsk_sl_pointer_type_hash, gsk_sl_pointer_type_equal,
                                                  (GDestroyNotify) gsk_sl_pointer_type_unref, NULL);
-  writer->declarations = g_hash_table_new_full (g_direct_hash, g_direct_equal,
-                                                (GDestroyNotify) gsk_sl_node_unref, NULL);
+  writer->variables = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+                                             (GDestroyNotify) gsk_sl_variable_unref, NULL);
   /* the ID 1 is reserved for the GLSL instruction set (for now) */
   writer->last_id = 1;
 
@@ -92,7 +93,7 @@ gsk_spv_writer_unref (GskSpvWriter *writer)
 
   g_hash_table_destroy (writer->pointer_types);
   g_hash_table_destroy (writer->types);
-  g_hash_table_destroy (writer->declarations);
+  g_hash_table_destroy (writer->variables);
 
   g_slice_free (GskSpvWriter, writer);
 }
@@ -196,18 +197,18 @@ gsk_spv_writer_get_id_for_pointer_type (GskSpvWriter       *writer,
 }
 
 guint32
-gsk_spv_writer_get_id_for_declaration (GskSpvWriter *writer,
-                                       GskSlNode    *node)
+gsk_spv_writer_get_id_for_variable (GskSpvWriter  *writer,
+                                    GskSlVariable *variable)
 {
-  return GPOINTER_TO_UINT (g_hash_table_lookup (writer->declarations, node));
-}
+  guint32 result;
 
-void
-gsk_spv_writer_set_id_for_declaration (GskSpvWriter *writer,
-                                       GskSlNode    *node,
-                                       guint32       id)
-{
-  g_hash_table_insert (writer->declarations, gsk_sl_node_ref (node), GUINT_TO_POINTER (id));
+  result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->variables, variable));
+  if (result != 0)
+    return result;
+
+  result = gsk_sl_variable_write_spv (variable, writer);
+  g_hash_table_insert (writer->variables, gsk_sl_variable_ref (variable), GUINT_TO_POINTER (result));
+  return result;
 }
 
 guint32
diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h
index 39d561a..8c699f3 100644
--- a/gsk/gskspvwriterprivate.h
+++ b/gsk/gskspvwriterprivate.h
@@ -182,11 +182,8 @@ guint32                 gsk_spv_writer_get_id_for_type          (GskSpvWriter
                                                                  GskSlType              *type);
 guint32                 gsk_spv_writer_get_id_for_pointer_type  (GskSpvWriter           *writer,
                                                                  GskSlPointerType       *type);
-guint32                 gsk_spv_writer_get_id_for_declaration   (GskSpvWriter           *writer,
-                                                                 GskSlNode              *node);
-void                    gsk_spv_writer_set_id_for_declaration   (GskSpvWriter           *writer,
-                                                                 GskSlNode              *node,
-                                                                 guint32                 id);
+guint32                 gsk_spv_writer_get_id_for_variable      (GskSpvWriter           *writer,
+                                                                 GskSlVariable          *variable);
 
 guint32                 gsk_spv_writer_next_id                  (GskSpvWriter           *writer);
 void                    gsk_spv_writer_add                      (GskSpvWriter           *writer,
diff --git a/gsk/meson.build b/gsk/meson.build
index 292b67f..cda34e5 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -42,6 +42,7 @@ gsk_private_sources = files([
   'gskslscope.c',
   'gsksltokenizer.c',
   'gsksltype.c',
+  'gskslvariable.c',
   'gskspvwriter.c'
 ])
 


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