[gtk+/wip/otte/shader: 145/176] gsksl: Check qualifier/type combinations are valid



commit 51c3fcb16d4b3e38c9f6f1fc6649a2cb1d2b4195
Author: Benjamin Otte <otte redhat com>
Date:   Tue Oct 17 03:22:43 2017 +0200

    gsksl: Check qualifier/type combinations are valid
    
    So far, this is only implemented for in variables.

 gsk/gsksldeclaration.c                             |    2 +
 gsk/gskslpreprocessorprivate.h                     |    2 +
 gsk/gskslqualifier.c                               |   61 ++++++++++++++++++++
 gsk/gskslqualifierprivate.h                        |    3 +
 gsk/gsksltype.c                                    |    6 ++
 gsk/gsksltypeprivate.h                             |    1 +
 testsuite/gsksl/errors/no-bool-in-variables.frag   |    6 ++
 .../gsksl/errors/no-sampler-in-variables.frag      |    6 ++
 .../no-struct-in-variables-in-vertex-shader.vert   |    6 ++
 9 files changed, 93 insertions(+), 0 deletions(-)
---
diff --git a/gsk/gsksldeclaration.c b/gsk/gsksldeclaration.c
index 6894864..ca2edea 100644
--- a/gsk/gsksldeclaration.c
+++ b/gsk/gsksldeclaration.c
@@ -226,6 +226,8 @@ gsk_sl_declaration_parse_variable (GskSlScope           *scope,
   GskSlExpression *initial = NULL;
   const GskSlToken *token;
 
+  gsk_sl_qualifier_check_type (qualifier, preproc, type);
+
   token = gsk_sl_preprocessor_get (preproc);
   if (gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
     {
diff --git a/gsk/gskslpreprocessorprivate.h b/gsk/gskslpreprocessorprivate.h
index 29def72..f8d1301 100644
--- a/gsk/gskslpreprocessorprivate.h
+++ b/gsk/gskslpreprocessorprivate.h
@@ -20,6 +20,7 @@
 #define __GSK_SL_PREPROCESSOR_PRIVATE_H__
 
 #include "gskslcompilerprivate.h"
+#include "gskslenvironmentprivate.h"
 #include "gsksltypesprivate.h"
 #include "gsksltokenizerprivate.h"
 
@@ -38,6 +39,7 @@ const GskSlToken *      gsk_sl_preprocessor_get                 (GskSlPreprocess
 const GskCodeLocation * gsk_sl_preprocessor_get_location        (GskSlPreprocessor   *preproc);
 void                    gsk_sl_preprocessor_consume             (GskSlPreprocessor   *preproc,
                                                                  gpointer             consumer);
+#define gsk_sl_preprocessor_is_stage(preproc,stage) (gsk_sl_environment_get_stage 
(gsk_sl_preprocessor_get_environment (preproc)) == (stage))
 
 void                    gsk_sl_preprocessor_sync                (GskSlPreprocessor   *preproc,
                                                                  GskSlTokenType       token);
diff --git a/gsk/gskslqualifier.c b/gsk/gskslqualifier.c
index 049242a..7d7bc25 100644
--- a/gsk/gskslqualifier.c
+++ b/gsk/gskslqualifier.c
@@ -577,6 +577,67 @@ gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier)
     }
 }
 
+#define ERROR(...) G_STMT_START{\
+  gsk_sl_preprocessor_error (preproc, DECLARATION, __VA_ARGS__); \
+  result = FALSE; \
+}G_STMT_END
+
+static gboolean
+gsk_sl_qualifier_check_type_for_input (const GskSlQualifier *qualifier,
+                                       GskSlPreprocessor    *preproc,
+                                       GskSlType            *type)
+{
+  gboolean result = TRUE;
+  gsize i;
+
+  if (gsk_sl_type_is_struct (type) && gsk_sl_preprocessor_is_stage (preproc, GSK_SL_SHADER_VERTEX))
+    ERROR ("In variables in vertex shaders must not contain structs");
+  if (gsk_sl_type_is_opaque (type))
+    ERROR ("In variables must not contain opaque types");
+  if (gsk_sl_type_get_scalar_type (type) == GSK_SL_BOOL)
+    ERROR ("In variables must not contain boolean types");
+
+  for (i = 0; i < gsk_sl_type_get_n_members (type); i++)
+    {
+      result &= gsk_sl_qualifier_check_type_for_input (qualifier,
+                                                       preproc,
+                                                       gsk_sl_type_get_member_type (type, i));
+    }
+
+  return result;
+}
+
+gboolean
+gsk_sl_qualifier_check_type (const GskSlQualifier *qualifier,
+                             GskSlPreprocessor    *preproc,
+                             GskSlType            *type)
+{
+  switch (qualifier->storage)
+    {
+    case GSK_SL_STORAGE_DEFAULT:
+    default:
+      g_assert_not_reached ();
+      return FALSE;
+
+    case GSK_SL_STORAGE_GLOBAL:
+    case GSK_SL_STORAGE_GLOBAL_CONST:
+      return TRUE;
+
+    case GSK_SL_STORAGE_GLOBAL_IN:
+      return gsk_sl_qualifier_check_type_for_input (qualifier, preproc, type);
+
+    case GSK_SL_STORAGE_GLOBAL_OUT:
+    case GSK_SL_STORAGE_GLOBAL_UNIFORM:
+    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 TRUE;
+    }
+}
+
 static void
 gsk_sl_qualifier_write_inout_decorations (const GskSlQualifier *qualifier,
                                           GskSpvWriter         *writer,
diff --git a/gsk/gskslqualifierprivate.h b/gsk/gskslqualifierprivate.h
index 12e9e41..3eceb71 100644
--- a/gsk/gskslqualifierprivate.h
+++ b/gsk/gskslqualifierprivate.h
@@ -66,6 +66,9 @@ gboolean                gsk_sl_qualifier_is_constant                    (const G
 GskSlQualifierLocation  gsk_sl_qualifier_get_location                   (const GskSlQualifier       
*qualifier);
 GskSpvStorageClass      gsk_sl_qualifier_get_storage_class              (const GskSlQualifier       
*qualifier);
 
+gboolean                gsk_sl_qualifier_check_type                     (const GskSlQualifier       
*qualifier,
+                                                                         GskSlPreprocessor          *preproc,
+                                                                         GskSlType                  *type);
 void                    gsk_sl_qualifier_write_spv_decorations          (const GskSlQualifier       
*qualifier,
                                                                          GskSpvWriter               *writer,
                                                                          guint32                     
value_id);
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index e513c05..c4050de 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -2068,6 +2068,12 @@ gsk_sl_type_is_block (const GskSlType *type)
   return type->class == &GSK_SL_TYPE_BLOCK;
 }
 
+gboolean
+gsk_sl_type_is_opaque (const GskSlType *type)
+{
+  return FALSE;
+}
+
 GskSlScalarType
 gsk_sl_type_get_scalar_type (const GskSlType *type)
 {
diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h
index 5c5d765..55b6956 100644
--- a/gsk/gsksltypeprivate.h
+++ b/gsk/gsksltypeprivate.h
@@ -50,6 +50,7 @@ gboolean                gsk_sl_type_is_vector                   (const GskSlType
 gboolean                gsk_sl_type_is_matrix                   (const GskSlType     *type);
 gboolean                gsk_sl_type_is_struct                   (const GskSlType     *type);
 gboolean                gsk_sl_type_is_block                    (const GskSlType     *type);
+gboolean                gsk_sl_type_is_opaque                   (const GskSlType     *type);
 
 const char *            gsk_sl_type_get_name                    (const GskSlType     *type);
 GskSlScalarType         gsk_sl_type_get_scalar_type             (const GskSlType     *type);
diff --git a/testsuite/gsksl/errors/no-bool-in-variables.frag 
b/testsuite/gsksl/errors/no-bool-in-variables.frag
new file mode 100644
index 0000000..47e1be8
--- /dev/null
+++ b/testsuite/gsksl/errors/no-bool-in-variables.frag
@@ -0,0 +1,6 @@
+in bool b;
+
+void
+main ()
+{
+}
diff --git a/testsuite/gsksl/errors/no-sampler-in-variables.frag 
b/testsuite/gsksl/errors/no-sampler-in-variables.frag
new file mode 100644
index 0000000..6153938
--- /dev/null
+++ b/testsuite/gsksl/errors/no-sampler-in-variables.frag
@@ -0,0 +1,6 @@
+in sampler2D t;
+
+void
+main ()
+{
+}
diff --git a/testsuite/gsksl/errors/no-struct-in-variables-in-vertex-shader.vert 
b/testsuite/gsksl/errors/no-struct-in-variables-in-vertex-shader.vert
new file mode 100644
index 0000000..b535e1b
--- /dev/null
+++ b/testsuite/gsksl/errors/no-struct-in-variables-in-vertex-shader.vert
@@ -0,0 +1,6 @@
+in struct {int x; int y; } s;
+
+void
+main ()
+{
+}


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