diff options
author | Benjamin Otte <otte@redhat.com> | 2017-10-17 03:22:43 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-10-30 02:58:03 +0100 |
commit | 5472458e6b14c9bf06ee42e4a2deccc2f2c840f8 (patch) | |
tree | f0bc9d16775b1f582861a9a50c5bb6f0d6269de9 | |
parent | 8431b63b5d0fde9a66110579a4d70bb811342d53 (diff) | |
download | gtk+-5472458e6b14c9bf06ee42e4a2deccc2f2c840f8.tar.gz |
gsksl: Check qualifier/type combinations are valid
So far, this is only implemented for in variables.
-rw-r--r-- | gsk/gsksldeclaration.c | 2 | ||||
-rw-r--r-- | gsk/gskslpreprocessorprivate.h | 2 | ||||
-rw-r--r-- | gsk/gskslqualifier.c | 61 | ||||
-rw-r--r-- | gsk/gskslqualifierprivate.h | 3 | ||||
-rw-r--r-- | gsk/gsksltype.c | 6 | ||||
-rw-r--r-- | gsk/gsksltypeprivate.h | 1 | ||||
-rw-r--r-- | testsuite/gsksl/errors/no-bool-in-variables.frag | 6 | ||||
-rw-r--r-- | testsuite/gsksl/errors/no-sampler-in-variables.frag | 6 | ||||
-rw-r--r-- | testsuite/gsksl/errors/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 68948647f7..ca2edeae11 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 29def725c8..f8d13010dd 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 049242acf4..7d7bc25a38 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 12e9e413cf..3eceb712ce 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 e513c05f85..c4050de4d1 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 5c5d765eb4..55b6956d5d 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 0000000000..47e1be8242 --- /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 0000000000..61539380b2 --- /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 0000000000..b535e1bee5 --- /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 () +{ +} |