[gtk+/wip/otte/shader: 176/176] gsksl: Add support for native blocks



commit f261a22af56d9d713da6667e15e540cda62bd64e
Author: Benjamin Otte <otte redhat com>
Date:   Wed Oct 25 04:43:35 2017 +0200

    gsksl: Add support for native blocks
    
    and implement gl_PerVertex's gl_Position and gl_PointSize with it.

 gsk/gskslnativevariable.c |   91 ++++++++++++++++++++++++++++++++++++++++++--
 gsk/gsksltype.c           |   58 +++++++++++++++++++---------
 gsk/gsksltypeprivate.h    |    5 ++
 3 files changed, 130 insertions(+), 24 deletions(-)
---
diff --git a/gsk/gskslnativevariable.c b/gsk/gskslnativevariable.c
index d26e894..4c99101 100644
--- a/gsk/gskslnativevariable.c
+++ b/gsk/gskslnativevariable.c
@@ -26,34 +26,115 @@
 #include "gsksltypeprivate.h"
 #include "gskslvariableprivate.h"
 
+typedef struct _NativeVariable NativeVariable;
+struct _NativeVariable {
+  const char *name;
+  GskSlType *type;
+  GskSpvBuiltIn builtin;
+};
+
+static void
+gsk_sl_native_variable_add_block (GskSlScope           *scope,
+                                  const char           *block_name,
+                                  const char           *block_instance_name,
+                                  GskSlStorage          storage,
+                                  const NativeVariable *variables,
+                                  gsize                 n_variables)
+{
+  GskSlQualifier qualifier;
+  GskSlVariable *variable;
+  GskSlTypeBuilder *builder;
+  GskSlType *type;
+  gsize i;
+
+  gsk_sl_qualifier_init (&qualifier);
+  qualifier.storage = storage;
+
+  builder = gsk_sl_type_builder_new_block (block_name);
+  for (i = 0; i < n_variables; i++)
+    {
+      gsk_sl_type_builder_add_builtin_member (builder,
+                                              variables[i].type,
+                                              variables[i].name,
+                                              variables[i].builtin);
+    }
+  type = gsk_sl_type_builder_free (builder);
+
+  variable = gsk_sl_variable_new (block_instance_name,
+                                  type,
+                                  &qualifier,
+                                  NULL);
+  if (block_instance_name)
+    {
+      gsk_sl_scope_add_variable (scope, variable);
+    }
+  else
+    {
+      for (i = 0; i < n_variables; i++)
+        {
+          GskSlVariable *sub;
+
+          sub = gsk_sl_variable_new_block_member (variable, i);
+          gsk_sl_scope_add_variable (scope, sub);
+          gsk_sl_variable_unref (sub);
+        }
+    }
+  gsk_sl_variable_unref (variable);
+}
+
 static void
 gsk_sl_native_variable_add (GskSlScope      *scope,
                             const char      *name,
-                            GskSlScalarType  scalar,
+                            GskSlStorage     storage,
+                            GskSlType       *type,
                             GskSpvBuiltIn    builtin)
 {
   GskSlQualifier qualifier;
   GskSlVariable *variable;
 
   gsk_sl_qualifier_init (&qualifier);
-  qualifier.storage = GSK_SL_STORAGE_GLOBAL_IN;
+  qualifier.storage = storage;
 
   variable = gsk_sl_variable_new_builtin (name,
-                                          gsk_sl_type_get_scalar (scalar),
+                                          type,
                                           &qualifier,
                                           builtin);
   gsk_sl_scope_add_variable (scope, variable);
   gsk_sl_variable_unref (variable);
 }
 
+static void
+gsk_sl_native_variable_add_simple (GskSlScope      *scope,
+                                   const char      *name,
+                                   GskSlScalarType  scalar,
+                                   GskSpvBuiltIn    builtin)
+{
+  gsk_sl_native_variable_add (scope, name, GSK_SL_STORAGE_GLOBAL_IN, gsk_sl_type_get_scalar (scalar), 
builtin);
+}
+
 void
 gsk_sl_native_variables_add (GskSlScope       *scope,
                              GskSlEnvironment *environment)
 {
   if (gsk_sl_environment_get_stage (environment) == GSK_SL_SHADER_VERTEX)
     {
-      gsk_sl_native_variable_add (scope, "gl_VertexIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_VERTEX_INDEX);
-      gsk_sl_native_variable_add (scope, "gl_InstanceIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_INSTANCE_INDEX);
+      gsk_sl_native_variable_add_simple (scope, "gl_VertexIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_VERTEX_INDEX);
+      gsk_sl_native_variable_add_simple (scope, "gl_InstanceIndex", GSK_SL_INT, 
GSK_SPV_BUILT_IN_INSTANCE_INDEX);
+      if (gsk_sl_environment_get_version (environment) >= 150)
+        {
+          gsk_sl_native_variable_add_block (scope,
+                                            "gl_PerVertex", NULL,
+                                            GSK_SL_STORAGE_GLOBAL_OUT,
+                                            (NativeVariable[2]) {
+                                                { "gl_Position", gsk_sl_type_get_vector (GSK_SL_FLOAT, 4), 
GSK_SPV_BUILT_IN_POSITION },
+                                                { "gl_PointSize", gsk_sl_type_get_scalar (GSK_SL_FLOAT), 
GSK_SPV_BUILT_IN_POINT_SIZE }
+                                            }, 2);
+        }
+      else
+        {
+          gsk_sl_native_variable_add (scope, "gl_Position", GSK_SL_STORAGE_GLOBAL_OUT, 
gsk_sl_type_get_vector (GSK_SL_FLOAT, 4), GSK_SPV_BUILT_IN_POSITION);
+          gsk_sl_native_variable_add (scope, "gl_PointSize", GSK_SL_STORAGE_GLOBAL_OUT, 
gsk_sl_type_get_scalar (GSK_SL_FLOAT), GSK_SPV_BUILT_IN_POINT_SIZE);
+        }
     }
 }
 
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index 45d9a97..34382a4 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -40,6 +40,7 @@ typedef struct _GskSlTypeClass GskSlTypeClass;
 struct _GskSlTypeMember {
   GskSlType *type;
   char *name;
+  GskSpvBuiltIn builtin;
   gsize offset;
 };
 
@@ -1606,27 +1607,30 @@ gsk_sl_type_struct_has_name (const GskSlTypeStruct *struc)
 }
 
 static void
-gsk_sl_type_write_member_decoration (GskSpvWriter *writer,
-                                     guint32       type_id,
-                                     gsize         index,
-                                     GskSlType    *member_type,
-                                     const char   *member_name,
-                                     gsize         member_offset)
+gsk_sl_type_write_member_decoration (GskSpvWriter          *writer,
+                                     guint32                type_id,
+                                     gsize                  index,
+                                     const GskSlTypeMember *member)
 {
-  gsk_spv_writer_member_name (writer, type_id, index, member_name);
+  gsk_spv_writer_member_name (writer, type_id, index, member->name);
 
-  gsk_spv_writer_member_decorate (writer, type_id, index,
-                                  GSK_SPV_DECORATION_OFFSET,
-                                  (guint32[1]) { member_offset }, 1);
+  if (member->builtin != -1)
+    gsk_spv_writer_member_decorate (writer, type_id, index,
+                                    GSK_SPV_DECORATION_BUILT_IN,
+                                    (guint32[1]) { member->builtin }, 1);
+  else
+    gsk_spv_writer_member_decorate (writer, type_id, index,
+                                    GSK_SPV_DECORATION_OFFSET,
+                                    (guint32[1]) { member->offset }, 1);
 
-  if (gsk_sl_type_is_matrix (member_type))
+  if (gsk_sl_type_is_matrix (member->type))
     {
       gsk_spv_writer_member_decorate (writer, type_id, index,
                                       GSK_SPV_DECORATION_COL_MAJOR,
                                       NULL, 0);
       gsk_spv_writer_member_decorate (writer, type_id, index,
                                       GSK_SPV_DECORATION_MATRIX_STRIDE,
-                                      (guint32[1]) { gsk_sl_type_get_size (gsk_sl_type_get_index_type 
(member_type)) }, 1);
+                                      (guint32[1]) { gsk_sl_type_get_size (gsk_sl_type_get_index_type 
(member->type)) }, 1);
     }
 }
 
@@ -1656,8 +1660,7 @@ gsk_sl_type_struct_write_spv (GskSlType    *type,
 
   for (i = 0; i < struc->n_members; i++)
     {
-      gsk_sl_type_write_member_decoration (writer, result_id, i, struc->members[i].type,
-          struc->members[i].name, struc->members[i].offset);
+      gsk_sl_type_write_member_decoration (writer, result_id, i, &struc->members[i]);
     }
 
   return result_id;
@@ -1885,8 +1888,7 @@ gsk_sl_type_block_write_spv (GskSlType    *type,
 
   for (i = 0; i < block->n_members; i++)
     {
-      gsk_sl_type_write_member_decoration (writer, result_id, i, block->members[i].type,
-          block->members[i].name, block->members[i].offset);
+      gsk_sl_type_write_member_decoration (writer, result_id, i, &block->members[i]);
     }
 
   return result_id;
@@ -2432,6 +2434,14 @@ gsk_sl_type_new_parse (GskSlScope        *scope,
       break;
     case GSK_SL_TOKEN_STRUCT:
       return gsk_sl_type_parse_struct (scope, preproc);
+    case GSK_SL_TOKEN_IDENTIFIER:
+      type = gsk_sl_scope_lookup_type (scope, token->str);
+      if (type)
+        {
+          type = gsk_sl_type_ref (type);
+          break;
+        }
+      /* fall through */
     default:
       gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected type specifier");
       return gsk_sl_type_ref (gsk_sl_type_get_scalar (GSK_SL_FLOAT));
@@ -3044,18 +3054,28 @@ gsk_sl_type_builder_free (GskSlTypeBuilder *builder)
 }
 
 void
-gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder,
-                                GskSlType        *type,
-                                const char       *name)
+gsk_sl_type_builder_add_builtin_member (GskSlTypeBuilder *builder,
+                                        GskSlType        *type,
+                                        const char       *name,
+                                        GskSpvBuiltIn     builtin)
 {
   g_array_append_vals (builder->members,
                        &(GskSlTypeMember) {
                            gsk_sl_type_ref (type),
                            g_strdup (name),
+                           builtin,
                            builder->size }, 1);
   builder->size += gsk_sl_type_get_size (type);
 }
 
+void
+gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder,
+                                GskSlType        *type,
+                                const char       *name)
+{
+  gsk_sl_type_builder_add_builtin_member (builder, type, name, -1);
+}
+
 gboolean
 gsk_sl_type_builder_has_member (GskSlTypeBuilder *builder,
                                 const char       *name)
diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h
index ee3f0d7..151dcb8 100644
--- a/gsk/gsksltypeprivate.h
+++ b/gsk/gsksltypeprivate.h
@@ -22,6 +22,7 @@
 #include <glib.h>
 
 #include "gsksltypesprivate.h"
+#include "gskspvenumsprivate.h"
 
 G_BEGIN_DECLS
 
@@ -115,6 +116,10 @@ GskSlType *             gsk_sl_type_builder_free                (GskSlTypeBuilde
 void                    gsk_sl_type_builder_add_member          (GskSlTypeBuilder    *builder,
                                                                  GskSlType           *type,
                                                                  const char          *name);
+void                    gsk_sl_type_builder_add_builtin_member  (GskSlTypeBuilder    *builder,
+                                                                 GskSlType           *type,
+                                                                 const char          *name,
+                                                                 GskSpvBuiltIn        builtin);
 gboolean                gsk_sl_type_builder_has_member          (GskSlTypeBuilder    *builder,
                                                                  const char          *name);
 


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