[gtk+/wip/otte/shader: 48/55] gsksl: Redo qualifier handling
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 48/55] gsksl: Redo qualifier handling
- Date: Mon, 2 Oct 2017 03:39:45 +0000 (UTC)
commit 4bd800b1f8d21f9a3810a53915863b59462d3143
Author: Benjamin Otte <otte redhat com>
Date: Sun Oct 1 20:06:53 2017 +0200
gsksl: Redo qualifier handling
This is the 3rd time at least that I've rewritten it. This time, I've
added a GskSlQualifier struct that contains all the information relevant
to qualifiers. It replaces the previous GskSlDecorationList.
gsk/gskslfunction.c | 11 +-
gsk/gskslpointertype.c | 334 +--------------------------
gsk/gskslpointertypeprivate.h | 41 +---
gsk/gskslprogram.c | 29 ++--
gsk/gskslqualifier.c | 511 +++++++++++++++++++++++++++++++++++++++++
gsk/gskslqualifierprivate.h | 86 +++++++
gsk/gskslstatement.c | 21 +-
gsk/gsksltypesprivate.h | 1 +
gsk/gskslvariable.c | 12 +-
gsk/gskslvariableprivate.h | 3 +-
gsk/meson.build | 1 +
11 files changed, 648 insertions(+), 402 deletions(-)
---
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index bd9a0f3..c5f724e 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -25,6 +25,7 @@
#include "gskslpointertypeprivate.h"
#include "gskslpreprocessorprivate.h"
#include "gskslprinterprivate.h"
+#include "gskslqualifierprivate.h"
#include "gskslscopeprivate.h"
#include "gsksltokenizerprivate.h"
#include "gsksltypeprivate.h"
@@ -530,13 +531,11 @@ gsk_sl_function_new_parse (GskSlScope *scope,
while (TRUE)
{
- GskSlDecorations decoration;
+ GskSlQualifier qualifier;
GskSlType *type;
GskSlVariable *variable;
- gsk_sl_decoration_list_parse (scope,
- preproc,
- &decoration);
+ gsk_sl_qualifier_parse (&qualifier, scope, preproc, GSK_SL_QUALIFIER_PARAMETER);
type = gsk_sl_type_new_parse (scope, preproc);
@@ -560,8 +559,8 @@ gsk_sl_function_new_parse (GskSlScope *scope,
gsk_sl_preprocessor_warn (preproc, SHADOW, "Function argument \"%s\" shadows global
variable of same name.", token->str);
}
- pointer_type = gsk_sl_pointer_type_new (type, TRUE,
decoration.values[GSK_SL_DECORATION_CALLER_ACCESS].value);
- variable = gsk_sl_variable_new (pointer_type, g_strdup (token->str), NULL,
decoration.values[GSK_SL_DECORATION_CONST].set);
+ pointer_type = gsk_sl_pointer_type_new (type, &qualifier);
+ variable = gsk_sl_variable_new (pointer_type, g_strdup (token->str), NULL);
gsk_sl_pointer_type_unref (pointer_type);
g_ptr_array_add (arguments, variable);
diff --git a/gsk/gskslpointertype.c b/gsk/gskslpointertype.c
index 9c2b08a..e96c88a 100644
--- a/gsk/gskslpointertype.c
+++ b/gsk/gskslpointertype.c
@@ -23,6 +23,7 @@
#include "gskslexpressionprivate.h"
#include "gskslpreprocessorprivate.h"
#include "gskslprinterprivate.h"
+#include "gskslqualifierprivate.h"
#include "gsksltokenizerprivate.h"
#include "gsksltypeprivate.h"
#include "gskslvalueprivate.h"
@@ -32,15 +33,12 @@ struct _GskSlPointerType {
int ref_count;
GskSlType *type;
-
- gboolean local;
- GskSlDecorationAccess access;
+ GskSlQualifier qualifier;
};
GskSlPointerType *
gsk_sl_pointer_type_new (GskSlType *type,
- gboolean local,
- GskSlDecorationAccess access)
+ const GskSlQualifier *qualifier)
{
GskSlPointerType *result;
@@ -48,303 +46,11 @@ gsk_sl_pointer_type_new (GskSlType *type,
result->ref_count = 1;
result->type = gsk_sl_type_ref (type);
- result->local = local;
- result->access = access;
+ result->qualifier = *qualifier;
return result;
}
-static void
-gsk_sl_decoration_list_set (GskSlPreprocessor *preproc,
- GskSlDecorations *list,
- GskSlDecoration decoration,
- gint value)
-{
- list->values[decoration].set = TRUE;
- list->values[decoration].value = value;
-}
-
-static void
-gsk_sl_decoration_list_add_simple (GskSlPreprocessor *preproc,
- GskSlDecorations *list,
- GskSlDecoration decoration)
-{
- if (list->values[decoration].set)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate qualifier.");
- return;
- }
-
- gsk_sl_decoration_list_set (preproc, list, decoration, 1);
-}
-
-static void
-gsk_sl_decoration_list_parse_assignment (GskSlPreprocessor *preproc,
- GskSlScope *scope,
- GskSlDecorations *list,
- GskSlDecoration decoration)
-{
- GskSlExpression *expression;
- const GskSlToken *token;
- GskSlValue *value;
- GskSlType *type;
-
- gsk_sl_preprocessor_consume (preproc, NULL);
-
- token = gsk_sl_preprocessor_get (preproc);
- if (!gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected \"=\" sign to assign a value.");
- return;
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
-
- expression = gsk_sl_expression_parse_constant (scope, preproc);
- if (expression == NULL)
- return;
-
- value = gsk_sl_expression_get_constant (expression);
- gsk_sl_expression_unref (expression);
-
- if (value == NULL)
- {
- gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression is not constant.");
- return;
- }
-
- type = gsk_sl_value_get_type (value);
- if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_INT)
- {
- gsk_sl_decoration_list_set (preproc, list, decoration, *(gint32 *) gsk_sl_value_get_data (value));
- }
- else if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_UINT)
- {
- gsk_sl_decoration_list_set (preproc, list, decoration, *(guint32 *) gsk_sl_value_get_data (value));
- }
- else
- {
- gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Type of expression is not an integer type, but
%s", gsk_sl_type_get_name (type));
- }
- gsk_sl_value_free (value);
-}
-
-static void
-gsk_sl_decoration_list_parse_layout (GskSlPreprocessor *preproc,
- GskSlScope *scope,
- GskSlDecorations *list)
-{
- const GskSlToken *token;
-
- memset (list, 0, sizeof (GskSlDecorations));
-
- while (TRUE)
- {
- token = gsk_sl_preprocessor_get (preproc);
-
- if (gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
- break;
- }
- else if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
- {
- if (g_str_equal (token->str, "location"))
- {
- gsk_sl_decoration_list_parse_assignment (preproc,
- scope,
- list,
- GSK_SL_DECORATION_LAYOUT_LOCATION);
- }
- else if (g_str_equal (token->str, "component"))
- {
- gsk_sl_decoration_list_parse_assignment (preproc,
- scope,
- list,
- GSK_SL_DECORATION_LAYOUT_COMPONENT);
- }
- else if (g_str_equal (token->str, "binding"))
- {
- gsk_sl_decoration_list_parse_assignment (preproc,
- scope,
- list,
- GSK_SL_DECORATION_LAYOUT_BINDING);
- }
- else if (g_str_equal (token->str, "set"))
- {
- gsk_sl_decoration_list_parse_assignment (preproc,
- scope,
- list,
- GSK_SL_DECORATION_LAYOUT_SET);
- }
- else
- {
- gsk_sl_preprocessor_error (preproc, UNSUPPORTED, "Unknown layout identifier.");
- gsk_sl_preprocessor_consume (preproc, NULL);
- }
- }
- else
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
- gsk_sl_preprocessor_consume (preproc, NULL);
- }
-
- token = gsk_sl_preprocessor_get (preproc);
- if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
- break;
-
- gsk_sl_preprocessor_consume (preproc, NULL);
- }
-}
-
-void
-gsk_sl_decoration_list_parse (GskSlScope *scope,
- GskSlPreprocessor *preproc,
- GskSlDecorations *list)
-{
- const GskSlToken *token;
-
- memset (list, 0, sizeof (GskSlDecorations));
-
- while (TRUE)
- {
- token = gsk_sl_preprocessor_get (preproc);
- switch (token->type)
- {
- case GSK_SL_TOKEN_CONST:
- gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_CONST);
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_IN:
- if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"in\" qualifier specified twice.");
- }
- else
- {
- gsk_sl_decoration_list_set (preproc, list,
- GSK_SL_DECORATION_CALLER_ACCESS,
- list->values[GSK_SL_DECORATION_CALLER_ACCESS].value |
GSK_SL_DECORATION_ACCESS_READ);
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_OUT:
- if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"out\" qualifier specified twice.");
- }
- else
- {
- gsk_sl_decoration_list_set (preproc, list,
- GSK_SL_DECORATION_CALLER_ACCESS,
- list->values[GSK_SL_DECORATION_CALLER_ACCESS].value |
GSK_SL_DECORATION_ACCESS_WRITE);
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_INOUT:
- if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"in\" qualifier already used.");
- }
- else if (list->values[GSK_SL_DECORATION_CALLER_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"out\" qualifier already used.");
- }
- else
- {
- gsk_sl_decoration_list_set (preproc, list,
- GSK_SL_DECORATION_CALLER_ACCESS,
- GSK_SL_DECORATION_ACCESS_READWRITE);
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_INVARIANT:
- gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_INVARIANT);
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_COHERENT:
- gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_COHERENT);
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_VOLATILE:
- gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_VOLATILE);
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_RESTRICT:
- gsk_sl_decoration_list_add_simple (preproc, list, GSK_SL_DECORATION_RESTRICT);
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
-
- case GSK_SL_TOKEN_READONLY:
- if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"readonly\" qualifier specified twice.");
- }
- else if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"writeonly\" qualifier already used.");
- }
- else
- {
- gsk_sl_decoration_list_set (preproc, list,
- GSK_SL_DECORATION_ACCESS,
- GSK_SL_DECORATION_ACCESS_READ);
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_WRITEONLY:
- if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_READ)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"readonly\" qualifier already used.");
- }
- else if (list->values[GSK_SL_DECORATION_ACCESS].value & GSK_SL_DECORATION_ACCESS_WRITE)
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "\"writeonly\" qualifier specified twice.");
- }
- else
- {
- gsk_sl_decoration_list_set (preproc, list,
- GSK_SL_DECORATION_ACCESS,
- GSK_SL_DECORATION_ACCESS_WRITE);
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- case GSK_SL_TOKEN_LAYOUT:
- gsk_sl_preprocessor_consume (preproc, NULL);
- token = gsk_sl_preprocessor_get (preproc);
- if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected opening \"(\" after layout specifier");
- break;
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
-
- gsk_sl_decoration_list_parse_layout (preproc, scope, list);
-
- token = gsk_sl_preprocessor_get (preproc);
- if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
- {
- gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \")\" at end of layout
specifier");
- gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN);
- }
- gsk_sl_preprocessor_consume (preproc, NULL);
- break;
-
- default:
- return;
- }
- }
-}
-
GskSlPointerType *
gsk_sl_pointer_type_ref (GskSlPointerType *type)
{
@@ -374,13 +80,8 @@ void
gsk_sl_pointer_type_print (const GskSlPointerType *type,
GskSlPrinter *printer)
{
- if (type->access == GSK_SL_DECORATION_ACCESS_READWRITE)
- gsk_sl_printer_append (printer, "inout ");
- else if (type->access == GSK_SL_DECORATION_ACCESS_READ)
- gsk_sl_printer_append (printer, "in ");
- else if (type->access == GSK_SL_DECORATION_ACCESS_WRITE)
- gsk_sl_printer_append (printer, "out ");
-
+ if (gsk_sl_qualifier_print (&type->qualifier, printer))
+ gsk_sl_printer_append (printer, " ");
gsk_sl_printer_append (printer, gsk_sl_type_get_name (type->type));
}
@@ -390,19 +91,10 @@ gsk_sl_pointer_type_get_type (const GskSlPointerType *type)
return type->type;
}
-GskSpvStorageClass
-gsk_sl_pointer_type_get_storage_class (const GskSlPointerType *type)
+const GskSlQualifier *
+gsk_sl_pointer_type_get_qualifier (const GskSlPointerType *type)
{
- if (type->local)
- return GSK_SPV_STORAGE_CLASS_FUNCTION;
-
- if (type->access & GSK_SL_DECORATION_ACCESS_WRITE)
- return GSK_SPV_STORAGE_CLASS_OUTPUT;
-
- if (type->access & GSK_SL_DECORATION_ACCESS_READ)
- return GSK_SPV_STORAGE_CLASS_INPUT;
-
- return GSK_SPV_STORAGE_CLASS_PRIVATE;
+ return &type->qualifier;
}
gboolean
@@ -415,8 +107,8 @@ gsk_sl_pointer_type_equal (gconstpointer a,
if (!gsk_sl_type_equal (typea->type, typeb->type))
return FALSE;
- return gsk_sl_pointer_type_get_storage_class (typea)
- == gsk_sl_pointer_type_get_storage_class (typeb);
+ return gsk_sl_qualifier_get_storage_class (&typea->qualifier)
+ == gsk_sl_qualifier_get_storage_class (&typeb->qualifier);
}
guint
@@ -425,7 +117,7 @@ gsk_sl_pointer_type_hash (gconstpointer t)
const GskSlPointerType *type = t;
return gsk_sl_type_hash (type->type)
- ^ gsk_sl_pointer_type_get_storage_class (type);
+ ^ gsk_sl_qualifier_get_storage_class (&type->qualifier);
}
guint32
@@ -441,7 +133,7 @@ gsk_sl_pointer_type_write_spv (const GskSlPointerType *type,
GSK_SPV_WRITER_SECTION_DECLARE,
4, GSK_SPV_OP_TYPE_POINTER,
(guint32[3]) { result_id,
- gsk_sl_pointer_type_get_storage_class (type),
+ gsk_sl_qualifier_get_storage_class (&type->qualifier),
type_id });
return result_id;
diff --git a/gsk/gskslpointertypeprivate.h b/gsk/gskslpointertypeprivate.h
index 1a891a2..444089f 100644
--- a/gsk/gskslpointertypeprivate.h
+++ b/gsk/gskslpointertypeprivate.h
@@ -26,45 +26,8 @@
G_BEGIN_DECLS
-typedef enum {
- GSK_SL_DECORATION_CONST,
- GSK_SL_DECORATION_CALLER_ACCESS,
- GSK_SL_DECORATION_INVARIANT,
- GSK_SL_DECORATION_COHERENT,
- GSK_SL_DECORATION_VOLATILE,
- GSK_SL_DECORATION_RESTRICT,
- GSK_SL_DECORATION_ACCESS,
- GSK_SL_DECORATION_LAYOUT_LOCATION,
- GSK_SL_DECORATION_LAYOUT_COMPONENT,
- GSK_SL_DECORATION_LAYOUT_SET,
- GSK_SL_DECORATION_LAYOUT_BINDING,
- /* add */
- GSK_SL_N_DECORATIONS
-} GskSlDecoration;
-
-typedef enum {
- GSK_SL_DECORATION_ACCESS_READ = (1 << 0),
- GSK_SL_DECORATION_ACCESS_WRITE = (2 << 0),
- GSK_SL_DECORATION_ACCESS_READWRITE = GSK_SL_DECORATION_ACCESS_READ | GSK_SL_DECORATION_ACCESS_WRITE,
-} GskSlDecorationAccess;
-
-typedef struct _GskSlDecorations GskSlDecorations;
-
-struct _GskSlDecorations
-{
- struct {
- gboolean set;
- gint value;
- } values[GSK_SL_N_DECORATIONS];
-};
-
-void gsk_sl_decoration_list_parse (GskSlScope *scope,
- GskSlPreprocessor *stream,
- GskSlDecorations *list);
-
GskSlPointerType * gsk_sl_pointer_type_new (GskSlType *type,
- gboolean local,
- GskSlDecorationAccess access);
+ const GskSlQualifier
*qualifier);
GskSlPointerType * gsk_sl_pointer_type_ref (GskSlPointerType *type);
void gsk_sl_pointer_type_unref (GskSlPointerType *type);
@@ -73,12 +36,12 @@ void gsk_sl_pointer_type_print (const G
GskSlPrinter
*printer);
GskSlType * gsk_sl_pointer_type_get_type (const GskSlPointerType *type);
+const GskSlQualifier * gsk_sl_pointer_type_get_qualifier (const GskSlPointerType *type);
gboolean gsk_sl_pointer_type_equal (gconstpointer a,
gconstpointer b);
guint gsk_sl_pointer_type_hash (gconstpointer type);
-GskSpvStorageClass gsk_sl_pointer_type_get_storage_class (const GskSlPointerType *type);
guint32 gsk_sl_pointer_type_write_spv (const GskSlPointerType *type,
GskSpvWriter *writer);
diff --git a/gsk/gskslprogram.c b/gsk/gskslprogram.c
index f149d82..503b535 100644
--- a/gsk/gskslprogram.c
+++ b/gsk/gskslprogram.c
@@ -26,6 +26,7 @@
#include "gskslpreprocessorprivate.h"
#include "gskslprinterprivate.h"
#include "gskslscopeprivate.h"
+#include "gskslqualifierprivate.h"
#include "gsksltokenizerprivate.h"
#include "gsksltypeprivate.h"
#include "gskslvalueprivate.h"
@@ -69,12 +70,12 @@ gsk_sl_program_init (GskSlProgram *program)
}
static void
-gsk_sl_program_parse_variable (GskSlProgram *program,
- GskSlScope *scope,
- GskSlPreprocessor *preproc,
- GskSlDecorations *decoration,
- GskSlType *type,
- const char *name)
+gsk_sl_program_parse_variable (GskSlProgram *program,
+ GskSlScope *scope,
+ GskSlPreprocessor *preproc,
+ const GskSlQualifier *qualifier,
+ GskSlType *type,
+ const char *name)
{
GskSlVariable *variable;
const GskSlToken *token;
@@ -125,8 +126,8 @@ gsk_sl_program_parse_variable (GskSlProgram *program,
}
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), value,
decoration->values[GSK_SL_DECORATION_CONST].set);
+ pointer_type = gsk_sl_pointer_type_new (type, qualifier);
+ variable = gsk_sl_variable_new (pointer_type, g_strdup (name), value);
gsk_sl_pointer_type_unref (pointer_type);
program->variables = g_slist_append (program->variables, variable);
@@ -140,20 +141,18 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
{
GskSlType *type;
const GskSlToken *token;
- GskSlDecorations decoration;
+ GskSlQualifier qualifier;
char *name;
- gsk_sl_decoration_list_parse (scope,
- preproc,
- &decoration);
+ gsk_sl_qualifier_parse (&qualifier, scope, preproc, GSK_SL_QUALIFIER_GLOBAL);
type = gsk_sl_type_new_parse (scope, preproc);
token = gsk_sl_preprocessor_get (preproc);
if (gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
{
- GskSlPointerType *ptype = gsk_sl_pointer_type_new (type, FALSE,
decoration.values[GSK_SL_DECORATION_CALLER_ACCESS].value);
- GskSlVariable *variable = gsk_sl_variable_new (ptype, NULL, NULL,
decoration.values[GSK_SL_DECORATION_CONST].set);
+ GskSlPointerType *ptype = gsk_sl_pointer_type_new (type, &qualifier);
+ GskSlVariable *variable = gsk_sl_variable_new (ptype, NULL, NULL);
gsk_sl_pointer_type_unref (ptype);
program->variables = g_slist_append (program->variables, variable);
gsk_sl_preprocessor_consume (preproc, program);
@@ -193,7 +192,7 @@ gsk_sl_program_parse_declaration (GskSlProgram *program,
}
else
{
- gsk_sl_program_parse_variable (program, scope, preproc, &decoration, type, name);
+ gsk_sl_program_parse_variable (program, scope, preproc, &qualifier, type, name);
}
g_free (name);
diff --git a/gsk/gskslqualifier.c b/gsk/gskslqualifier.c
new file mode 100644
index 0000000..dbf441b
--- /dev/null
+++ b/gsk/gskslqualifier.c
@@ -0,0 +1,511 @@
+/* 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 "gskslqualifierprivate.h"
+
+#include "gskslexpressionprivate.h"
+#include "gskslpreprocessorprivate.h"
+#include "gskslprinterprivate.h"
+#include "gsksltokenizerprivate.h"
+#include "gsksltypeprivate.h"
+#include "gskslvalueprivate.h"
+
+void
+gsk_sl_qualifier_init (GskSlQualifier *qualifier)
+{
+ *qualifier = (GskSlQualifier) { .storage = GSK_SL_STORAGE_DEFAULT,
+ .layout = { -1, -1, -1, -1 },
+ };
+}
+
+static void
+gsk_sl_qualifier_parse_layout_assignment (GskSlPreprocessor *preproc,
+ GskSlScope *scope,
+ int *target)
+{
+ GskSlExpression *expression;
+ const GskSlToken *token;
+ GskSlValue *value;
+ GskSlType *type;
+
+ gsk_sl_preprocessor_consume (preproc, NULL);
+
+ token = gsk_sl_preprocessor_get (preproc);
+ if (!gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
+ {
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected \"=\" sign to assign a value.");
+ return;
+ }
+ gsk_sl_preprocessor_consume (preproc, NULL);
+
+ expression = gsk_sl_expression_parse_constant (scope, preproc);
+ if (expression == NULL)
+ return;
+
+ value = gsk_sl_expression_get_constant (expression);
+ gsk_sl_expression_unref (expression);
+
+ if (value == NULL)
+ {
+ gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression is not constant.");
+ return;
+ }
+
+ type = gsk_sl_value_get_type (value);
+ if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_INT)
+ {
+ gint32 i = *(gint32 *) gsk_sl_value_get_data (value);
+
+ if (i < 0)
+ gsk_sl_preprocessor_error (preproc, CONSTANT, "Expression may not be negative.");
+ else
+ *target = i;
+ }
+ else if (gsk_sl_type_is_scalar (type) && gsk_sl_type_get_scalar_type (type) == GSK_SL_UINT)
+ {
+ *target = *(guint32 *) gsk_sl_value_get_data (value);
+ }
+ else
+ {
+ gsk_sl_preprocessor_error (preproc, TYPE_MISMATCH, "Type of expression is not an integer type, but
%s", gsk_sl_type_get_name (type));
+ }
+ gsk_sl_value_free (value);
+}
+
+static void
+gsk_sl_qualifier_parse_layout (GskSlQualifier *qualifier,
+ GskSlPreprocessor *preproc,
+ GskSlScope *scope)
+{
+ const GskSlToken *token;
+
+ while (TRUE)
+ {
+ token = gsk_sl_preprocessor_get (preproc);
+
+ if (gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
+ {
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
+ break;
+ }
+ else if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
+ {
+ if (g_str_equal (token->str, "location"))
+ gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.location);
+ else if (g_str_equal (token->str, "component"))
+ gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.component);
+ else if (g_str_equal (token->str, "binding"))
+ gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.binding);
+ else if (g_str_equal (token->str, "set"))
+ gsk_sl_qualifier_parse_layout_assignment (preproc, scope, &qualifier->layout.set);
+ else
+ {
+ gsk_sl_preprocessor_error (preproc, UNSUPPORTED, "Unknown layout identifier.");
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ }
+ }
+ else
+ {
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected layout identifier.");
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ }
+
+ token = gsk_sl_preprocessor_get (preproc);
+ if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
+ break;
+
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ }
+}
+
+static const char *
+gsk_sl_storage_get_name (GskSlStorage storage)
+{
+ switch (storage)
+ {
+ default:
+ case GSK_SL_STORAGE_DEFAULT:
+ g_assert_not_reached ();
+ return "???";
+ case GSK_SL_STORAGE_GLOBAL:
+ case GSK_SL_STORAGE_LOCAL:
+ return "";
+ case GSK_SL_STORAGE_GLOBAL_CONST:
+ case GSK_SL_STORAGE_LOCAL_CONST:
+ return "const";
+ case GSK_SL_STORAGE_GLOBAL_IN:
+ case GSK_SL_STORAGE_PARAMETER_IN:
+ return "in";
+ case GSK_SL_STORAGE_GLOBAL_OUT:
+ case GSK_SL_STORAGE_PARAMETER_OUT:
+ return "out";
+ case GSK_SL_STORAGE_PARAMETER_INOUT:
+ return "inout";
+ case GSK_SL_STORAGE_PARAMETER_CONST:
+ return "const in";
+ }
+}
+
+static gboolean
+gsk_sl_storage_allows_const (GskSlStorage storage)
+{
+ switch (storage)
+ {
+ case GSK_SL_STORAGE_GLOBAL_CONST:
+ case GSK_SL_STORAGE_LOCAL_CONST:
+ case GSK_SL_STORAGE_PARAMETER_CONST:
+ default:
+ g_assert_not_reached ();
+ case GSK_SL_STORAGE_GLOBAL_OUT:
+ case GSK_SL_STORAGE_PARAMETER_OUT:
+ case GSK_SL_STORAGE_PARAMETER_INOUT:
+ return FALSE;
+ case GSK_SL_STORAGE_DEFAULT:
+ case GSK_SL_STORAGE_GLOBAL_IN:
+ case GSK_SL_STORAGE_LOCAL:
+ case GSK_SL_STORAGE_PARAMETER_IN:
+ return TRUE;
+ }
+}
+
+void
+gsk_sl_qualifier_parse (GskSlQualifier *qualifier,
+ GskSlScope *scope,
+ GskSlPreprocessor *preproc,
+ GskSlQualifierLocation location)
+{
+ const GskSlToken *token;
+ gboolean seen_const = FALSE;
+
+ gsk_sl_qualifier_init (qualifier);
+
+ while (TRUE)
+ {
+ token = gsk_sl_preprocessor_get (preproc);
+ switch (token->type)
+ {
+ case GSK_SL_TOKEN_CONST:
+ if (seen_const)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"const\" qualifier.");
+ if (!gsk_sl_storage_allows_const (qualifier->storage))
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "\"%s\" qualifier cannot be const.",
gsk_sl_storage_get_name (qualifier->storage));
+ else
+ seen_const = TRUE;
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_IN:
+ if (qualifier->storage == GSK_SL_STORAGE_DEFAULT)
+ {
+ if (location == GSK_SL_QUALIFIER_LOCAL)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Local variables cannot have \"in\" qualifier.");
+ else
+ qualifier->storage = location == GSK_SL_QUALIFIER_GLOBAL ? GSK_SL_STORAGE_GLOBAL_IN
+ : GSK_SL_STORAGE_PARAMETER_IN;
+ }
+ else if (qualifier->storage == GSK_SL_STORAGE_PARAMETER_OUT)
+ qualifier->storage = GSK_SL_STORAGE_PARAMETER_INOUT;
+ else
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Qualifiers \"%s\" and \"in\" cannot be combined.",
gsk_sl_storage_get_name (qualifier->storage));
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_OUT:
+ if (seen_const)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Const variables cannot have \"out\" qualifier.");
+ else if (qualifier->storage == GSK_SL_STORAGE_DEFAULT)
+ {
+ if (location == GSK_SL_QUALIFIER_LOCAL)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Local variables cannot have \"out\"
qualifier.");
+ else
+ qualifier->storage = location == GSK_SL_QUALIFIER_GLOBAL ? GSK_SL_STORAGE_GLOBAL_OUT
+ : GSK_SL_STORAGE_PARAMETER_OUT;
+ }
+ else if (qualifier->storage == GSK_SL_STORAGE_PARAMETER_IN)
+ qualifier->storage = GSK_SL_STORAGE_PARAMETER_INOUT;
+ else
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Qualifiers \"%s\" and \"out\" cannot be combined.",
gsk_sl_storage_get_name (qualifier->storage));
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_INOUT:
+ if (seen_const)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Const variables cannot have \"inout\" qualifier.");
+ else if (qualifier->storage == GSK_SL_STORAGE_DEFAULT)
+ {
+ if (location != GSK_SL_QUALIFIER_PARAMETER)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "\"inout\" can only be used on parameters.");
+ else
+ qualifier->storage = GSK_SL_STORAGE_PARAMETER_INOUT;
+ }
+ else
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Qualifiers \"%s\" and \"inout\" cannot be
combined.", gsk_sl_storage_get_name (qualifier->storage));
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_INVARIANT:
+ if (qualifier->invariant)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"invariant\" qualifier.");
+ qualifier->invariant = TRUE;
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_COHERENT:
+ if (qualifier->coherent)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"coherent\" qualifier.");
+ qualifier->coherent = TRUE;
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_VOLATILE:
+ if (qualifier->volatile_)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"volatile\" qualifier.");
+ qualifier->volatile_ = TRUE;
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_RESTRICT:
+ if (qualifier->restrict_)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"restrict\" qualifier.");
+ qualifier->restrict_ = TRUE;
+ break;
+
+ case GSK_SL_TOKEN_READONLY:
+ if (qualifier->readonly)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"readonly\" qualifier.");
+ qualifier->readonly = TRUE;
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_WRITEONLY:
+ if (qualifier->writeonly)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Duplicate \"writeonly\" qualifier.");
+ qualifier->writeonly = TRUE;
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ case GSK_SL_TOKEN_LAYOUT:
+ if (location != GSK_SL_QUALIFIER_GLOBAL)
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Only global variables can have layout qualifiers.");
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ token = gsk_sl_preprocessor_get (preproc);
+ if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_PAREN))
+ {
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected opening \"(\" after layout specifier");
+ break;
+ }
+ gsk_sl_preprocessor_consume (preproc, NULL);
+
+ gsk_sl_qualifier_parse_layout (qualifier, preproc, scope);
+
+ token = gsk_sl_preprocessor_get (preproc);
+ if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_PAREN))
+ {
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \")\" at end of layout
specifier");
+ gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_PAREN);
+ }
+ gsk_sl_preprocessor_consume (preproc, NULL);
+ break;
+
+ default:
+ goto out;
+ }
+ }
+
+out:
+ /* fixup storage qualifier */
+ switch (qualifier->storage)
+ {
+ case GSK_SL_STORAGE_DEFAULT:
+ if (location == GSK_SL_QUALIFIER_GLOBAL)
+ qualifier->storage = seen_const ? GSK_SL_STORAGE_GLOBAL_CONST : GSK_SL_STORAGE_GLOBAL;
+ else if (location == GSK_SL_QUALIFIER_LOCAL)
+ qualifier->storage = seen_const ? GSK_SL_STORAGE_LOCAL_CONST : GSK_SL_STORAGE_LOCAL;
+ else if (location == GSK_SL_QUALIFIER_PARAMETER)
+ qualifier->storage = seen_const ? GSK_SL_STORAGE_PARAMETER_CONST : GSK_SL_STORAGE_PARAMETER_IN;
+ else
+ {
+ g_assert_not_reached ();
+ }
+ break;
+
+ case GSK_SL_STORAGE_GLOBAL:
+ if (seen_const)
+ qualifier->storage = GSK_SL_STORAGE_GLOBAL_CONST;
+ break;
+
+ case GSK_SL_STORAGE_LOCAL:
+ if (seen_const)
+ qualifier->storage = GSK_SL_STORAGE_LOCAL_CONST;
+ break;
+
+ case GSK_SL_STORAGE_PARAMETER_IN:
+ if (seen_const)
+ qualifier->storage = GSK_SL_STORAGE_PARAMETER_CONST;
+ break;
+
+ case GSK_SL_STORAGE_GLOBAL_IN:
+ case GSK_SL_STORAGE_GLOBAL_OUT:
+ case GSK_SL_STORAGE_PARAMETER_OUT:
+ case GSK_SL_STORAGE_PARAMETER_INOUT:
+ g_assert (!seen_const);
+ break;
+
+ case GSK_SL_STORAGE_GLOBAL_CONST:
+ case GSK_SL_STORAGE_LOCAL_CONST:
+ case GSK_SL_STORAGE_PARAMETER_CONST:
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+}
+
+static gboolean
+gsk_sl_qualifier_has_layout (const GskSlQualifier *qualifier)
+{
+ return qualifier->layout.set >= 0
+ || qualifier->layout.binding >= 0
+ || qualifier->layout.location >= 0
+ || qualifier->layout.component >= 0;
+}
+
+static gboolean
+print_qualifier (GskSlPrinter *printer,
+ const char *name,
+ gint value,
+ gboolean needs_comma)
+{
+ if (value < 0)
+ return needs_comma;
+
+ if (needs_comma)
+ gsk_sl_printer_append (printer, ", ");
+ gsk_sl_printer_append (printer, name);
+ gsk_sl_printer_append (printer, "=");
+ gsk_sl_printer_append_uint (printer, value);
+
+ return TRUE;
+}
+
+static gboolean
+append_with_space (GskSlPrinter *printer,
+ const char *s,
+ gboolean need_space)
+{
+ if (s[0] == '\0')
+ return need_space;
+
+ if (need_space)
+ gsk_sl_printer_append_c (printer, ' ');
+ gsk_sl_printer_append (printer, s);
+ return TRUE;
+}
+
+gboolean
+gsk_sl_qualifier_print (const GskSlQualifier *qualifier,
+ GskSlPrinter *printer)
+{
+ gboolean need_space = FALSE;
+
+ if (qualifier->invariant)
+ need_space = append_with_space (printer, "invariant ", need_space);
+ if (qualifier->volatile_)
+ need_space = append_with_space (printer, "volatile ", need_space);
+ if (qualifier->restrict_)
+ need_space = append_with_space (printer, "restrict ", need_space);
+ if (qualifier->coherent)
+ need_space = append_with_space (printer, "coherent ", need_space);
+ if (qualifier->readonly)
+ need_space = append_with_space (printer, "readonly ", need_space);
+ if (qualifier->writeonly)
+ need_space = append_with_space (printer, "writeonly ", need_space);
+
+ if (gsk_sl_qualifier_has_layout (qualifier))
+ {
+ gboolean had_value;
+ gsk_sl_printer_append (printer, "layout(");
+ had_value = print_qualifier (printer, "set", qualifier->layout.set, FALSE);
+ had_value = print_qualifier (printer, "binding", qualifier->layout.binding, had_value);
+ had_value = print_qualifier (printer, "location", qualifier->layout.location, had_value);
+ had_value = print_qualifier (printer, "component", qualifier->layout.component, had_value);
+ gsk_sl_printer_append (printer, ")");
+ need_space = TRUE;
+ }
+
+ need_space = append_with_space (printer, gsk_sl_storage_get_name (qualifier->storage), need_space);
+
+ return need_space;
+}
+
+gboolean
+gsk_sl_qualifier_is_constant (const GskSlQualifier *qualifier)
+{
+ switch (qualifier->storage)
+ {
+ case GSK_SL_STORAGE_DEFAULT:
+ default:
+ g_assert_not_reached ();
+ return TRUE;
+
+ case GSK_SL_STORAGE_GLOBAL_CONST:
+ case GSK_SL_STORAGE_LOCAL_CONST:
+ case GSK_SL_STORAGE_PARAMETER_CONST:
+ return TRUE;
+
+ case GSK_SL_STORAGE_GLOBAL:
+ case GSK_SL_STORAGE_GLOBAL_IN:
+ case GSK_SL_STORAGE_GLOBAL_OUT:
+ case GSK_SL_STORAGE_LOCAL:
+ case GSK_SL_STORAGE_PARAMETER_IN:
+ case GSK_SL_STORAGE_PARAMETER_OUT:
+ case GSK_SL_STORAGE_PARAMETER_INOUT:
+ return FALSE;
+ }
+}
+
+GskSpvStorageClass
+gsk_sl_qualifier_get_storage_class (const GskSlQualifier *qualifier)
+{
+ switch (qualifier->storage)
+ {
+ case GSK_SL_STORAGE_DEFAULT:
+ case GSK_SL_STORAGE_PARAMETER_IN:
+ case GSK_SL_STORAGE_PARAMETER_OUT:
+ case GSK_SL_STORAGE_PARAMETER_INOUT:
+ case GSK_SL_STORAGE_PARAMETER_CONST:
+ default:
+ g_assert_not_reached ();
+ return GSK_SPV_STORAGE_CLASS_FUNCTION;
+
+ case GSK_SL_STORAGE_GLOBAL:
+ case GSK_SL_STORAGE_GLOBAL_CONST:
+ return GSK_SPV_STORAGE_CLASS_PRIVATE;
+
+ case GSK_SL_STORAGE_GLOBAL_IN:
+ return GSK_SPV_STORAGE_CLASS_INPUT;
+
+ case GSK_SL_STORAGE_GLOBAL_OUT:
+ return GSK_SPV_STORAGE_CLASS_OUTPUT;
+
+ case GSK_SL_STORAGE_LOCAL:
+ case GSK_SL_STORAGE_LOCAL_CONST:
+ return GSK_SPV_STORAGE_CLASS_FUNCTION;
+ }
+}
diff --git a/gsk/gskslqualifierprivate.h b/gsk/gskslqualifierprivate.h
new file mode 100644
index 0000000..a11f08a
--- /dev/null
+++ b/gsk/gskslqualifierprivate.h
@@ -0,0 +1,86 @@
+/* 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_QUALIFIER_PRIVATE_H__
+#define __GSK_SL_QUALIFIER_PRIVATE_H__
+
+#include <glib.h>
+
+#include "gsksltypesprivate.h"
+#include "gskslqualifierprivate.h"
+#include "gskspvwriterprivate.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+ GSK_SL_QUALIFIER_GLOBAL,
+ GSK_SL_QUALIFIER_PARAMETER,
+ GSK_SL_QUALIFIER_LOCAL
+} GskSlQualifierLocation;
+
+typedef enum {
+ GSK_SL_STORAGE_DEFAULT,
+
+ GSK_SL_STORAGE_GLOBAL,
+ GSK_SL_STORAGE_GLOBAL_CONST,
+ GSK_SL_STORAGE_GLOBAL_IN,
+ GSK_SL_STORAGE_GLOBAL_OUT,
+
+ GSK_SL_STORAGE_LOCAL,
+ GSK_SL_STORAGE_LOCAL_CONST,
+
+ GSK_SL_STORAGE_PARAMETER_IN,
+ GSK_SL_STORAGE_PARAMETER_OUT,
+ GSK_SL_STORAGE_PARAMETER_INOUT,
+ GSK_SL_STORAGE_PARAMETER_CONST
+} GskSlStorage;
+
+struct _GskSlQualifier
+{
+ GskSlStorage storage;
+
+ struct {
+ gint set;
+ gint binding;
+ gint location;
+ gint component;
+ } layout;
+
+ guint invariant :1;
+ guint volatile_ :1;
+ guint restrict_ :1;
+ guint coherent :1;
+ guint readonly :1;
+ guint writeonly :1;
+};
+
+void gsk_sl_qualifier_init (GskSlQualifier
*qualifier);
+void gsk_sl_qualifier_parse (GskSlQualifier
*qualifier,
+ GskSlScope *scope,
+ GskSlPreprocessor *stream,
+ GskSlQualifierLocation
location);
+
+gboolean gsk_sl_qualifier_print (const GskSlQualifier
*qualifier,
+ GskSlPrinter
*printer);
+
+gboolean gsk_sl_qualifier_is_constant (const GskSlQualifier
*qualifier);
+GskSpvStorageClass gsk_sl_qualifier_get_storage_class (const GskSlQualifier
*qualifier);
+
+G_END_DECLS
+
+#endif /* __GSK_SL_QUALIFIER_PRIVATE_H__ */
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index 6cb8ad8..bccefea 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -28,6 +28,7 @@
#include "gskslscopeprivate.h"
#include "gsksltokenizerprivate.h"
#include "gsksltypeprivate.h"
+#include "gskslqualifierprivate.h"
#include "gskslvalueprivate.h"
#include "gskslvariableprivate.h"
#include "gskspvwriterprivate.h"
@@ -496,10 +497,10 @@ static const GskSlStatementClass GSK_SL_STATEMENT_EXPRESSION = {
/* API */
static GskSlStatement *
-gsk_sl_statement_parse_declaration (GskSlScope *scope,
- GskSlPreprocessor *stream,
- GskSlDecorations *decoration,
- GskSlType *type)
+gsk_sl_statement_parse_declaration (GskSlScope *scope,
+ GskSlPreprocessor *stream,
+ const GskSlQualifier *qualifier,
+ GskSlType *type)
{
GskSlStatementDeclaration *declaration;
GskSlPointerType *pointer_type;
@@ -548,8 +549,8 @@ gsk_sl_statement_parse_declaration (GskSlScope *scope,
value = NULL;
}
- pointer_type = gsk_sl_pointer_type_new (type, TRUE,
decoration->values[GSK_SL_DECORATION_CALLER_ACCESS].value);
- declaration->variable = gsk_sl_variable_new (pointer_type, name, value,
decoration->values[GSK_SL_DECORATION_CONST].set);
+ pointer_type = gsk_sl_pointer_type_new (type, qualifier);
+ declaration->variable = gsk_sl_variable_new (pointer_type, name, value);
gsk_sl_pointer_type_unref (pointer_type);
gsk_sl_scope_add_variable (scope, declaration->variable);
@@ -744,12 +745,10 @@ gsk_sl_statement_parse (GskSlScope *scope,
case GSK_SL_TOKEN_STRUCT:
{
GskSlType *type;
- GskSlDecorations decoration;
+ GskSlQualifier qualifier;
its_a_type:
- gsk_sl_decoration_list_parse (scope,
- preproc,
- &decoration);
+ gsk_sl_qualifier_parse (&qualifier, scope, preproc, GSK_SL_QUALIFIER_LOCAL);
type = gsk_sl_type_new_parse (scope, preproc);
@@ -778,7 +777,7 @@ its_a_type:
}
else
{
- statement = gsk_sl_statement_parse_declaration (scope, preproc, &decoration, type);
+ statement = gsk_sl_statement_parse_declaration (scope, preproc, &qualifier, type);
}
gsk_sl_type_unref (type);
diff --git a/gsk/gsksltypesprivate.h b/gsk/gsksltypesprivate.h
index c1c3329..ff379cc 100644
--- a/gsk/gsksltypesprivate.h
+++ b/gsk/gsksltypesprivate.h
@@ -28,6 +28,7 @@ typedef struct _GskSlNativeFunction GskSlNativeFunction;
typedef struct _GskSlPreprocessor GskSlPreprocessor;
typedef struct _GskSlPointerType GskSlPointerType;
typedef struct _GskSlPrinter GskSlPrinter;
+typedef struct _GskSlQualifier GskSlQualifier;
typedef struct _GskSlScope GskSlScope;
typedef struct _GskSlStatement GskSlStatement;
typedef struct _GskSlToken GskSlToken;
diff --git a/gsk/gskslvariable.c b/gsk/gskslvariable.c
index 5dc722f..fa7ca24 100644
--- a/gsk/gskslvariable.c
+++ b/gsk/gskslvariable.c
@@ -22,6 +22,7 @@
#include "gskslpointertypeprivate.h"
#include "gskslprinterprivate.h"
+#include "gskslqualifierprivate.h"
#include "gsksltypeprivate.h"
#include "gskslvalueprivate.h"
#include "gskspvwriterprivate.h"
@@ -32,14 +33,12 @@ struct _GskSlVariable {
GskSlPointerType *type;
char *name;
GskSlValue *initial_value;
- gboolean constant;
};
GskSlVariable *
gsk_sl_variable_new (GskSlPointerType *type,
char *name,
- GskSlValue *initial_value,
- gboolean constant)
+ GskSlValue *initial_value)
{
GskSlVariable *variable;
@@ -50,7 +49,6 @@ gsk_sl_variable_new (GskSlPointerType *type,
variable->type = gsk_sl_pointer_type_ref (type);
variable->name = name;
variable->initial_value = initial_value;
- variable->constant = constant;
return variable;
}
@@ -87,8 +85,6 @@ void
gsk_sl_variable_print (const GskSlVariable *variable,
GskSlPrinter *printer)
{
- if (variable->constant)
- gsk_sl_printer_append (printer, "const ");
gsk_sl_pointer_type_print (variable->type, printer);
if (variable->name)
{
@@ -118,7 +114,7 @@ gsk_sl_variable_get_initial_value (const GskSlVariable *variable)
gboolean
gsk_sl_variable_is_constant (const GskSlVariable *variable)
{
- return variable->constant;
+ return gsk_sl_qualifier_is_constant (gsk_sl_pointer_type_get_qualifier (variable->type));
}
guint32
@@ -138,7 +134,7 @@ gsk_sl_variable_write_spv (const GskSlVariable *variable,
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_qualifier_get_storage_class (gsk_sl_pointer_type_get_qualifier
(variable->type)),
value_id });
return variable_id;
diff --git a/gsk/gskslvariableprivate.h b/gsk/gskslvariableprivate.h
index cc24660..2c169ff 100644
--- a/gsk/gskslvariableprivate.h
+++ b/gsk/gskslvariableprivate.h
@@ -27,8 +27,7 @@ G_BEGIN_DECLS
GskSlVariable * gsk_sl_variable_new (GskSlPointerType *type,
char *name,
- GskSlValue *initial_value,
- gboolean constant);
+ GskSlValue *initial_value);
GskSlVariable * gsk_sl_variable_ref (GskSlVariable *variable);
void gsk_sl_variable_unref (GskSlVariable *variable);
diff --git a/gsk/meson.build b/gsk/meson.build
index 3e70a9f..fd3ffbe 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -41,6 +41,7 @@ gsk_private_sources = files([
'gskslpreprocessor.c',
'gskslpointertype.c',
'gskslprinter.c',
+ 'gskslqualifier.c',
'gskslscope.c',
'gskslstatement.c',
'gsksltokenizer.c',
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]