[gtk+/wip/otte/shader: 202/226] gsksltype: Implement arrays
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 202/226] gsksltype: Implement arrays
- Date: Mon, 30 Oct 2017 02:17:30 +0000 (UTC)
commit d33881e0ec3b02738fc23e4b5634f21d13472c20
Author: Benjamin Otte <otte redhat com>
Date: Sun Oct 22 04:29:36 2017 +0200
gsksltype: Implement arrays
This is incomplete as we can only declare variables using array types
but not as arrays of static types yet.
gsk/gskslexpression.c | 191 +++++++++++++
gsk/gsksltype.c | 286 ++++++++++++++++++++
gsk/gsksltypeprivate.h | 7 +
gsk/gskslvalue.c | 25 ++-
gsk/gskslvalueprivate.h | 2 +
gsk/gskspvwriter.c | 47 ++++
gsk/gskspvwriterprivate.h | 4 +
.../errors/array-of-array-indexing-order.glsl | 8 +
8 files changed, 568 insertions(+), 2 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 5b2c7bb..fcbeb3c 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -1200,6 +1200,154 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_FUNCTION_CALL = {
gsk_sl_expression_default_get_spv_access_chain
};
+/* INDEX */
+
+typedef struct _GskSlExpressionIndex GskSlExpressionIndex;
+
+struct _GskSlExpressionIndex {
+ GskSlExpression parent;
+
+ GskSlExpression *expr;
+ GskSlExpression *index_expr;
+};
+
+static void
+gsk_sl_expression_index_free (GskSlExpression *expression)
+{
+ GskSlExpressionIndex *index = (GskSlExpressionIndex *) expression;
+
+ gsk_sl_expression_unref (index->expr);
+ gsk_sl_expression_unref (index->index_expr);
+
+ g_slice_free (GskSlExpressionIndex, index);
+}
+
+static void
+gsk_sl_expression_index_print (const GskSlExpression *expression,
+ GskSlPrinter *printer)
+{
+ const GskSlExpressionIndex *index = (const GskSlExpressionIndex *) expression;
+
+ gsk_sl_expression_print (index->expr, printer);
+ gsk_sl_printer_append (printer, "[");
+ gsk_sl_expression_print (index->index_expr, printer);
+ gsk_sl_printer_append (printer, "]");
+}
+
+static gboolean
+gsk_sl_expression_index_is_assignable (const GskSlExpression *expression,
+ GError **error)
+{
+ const GskSlExpressionIndex *index = (const GskSlExpressionIndex *) expression;
+
+ return gsk_sl_expression_is_assignable (index->expr, error);
+}
+
+static GskSlType *
+gsk_sl_expression_index_get_return_type (const GskSlExpression *expression)
+{
+ const GskSlExpressionIndex *index = (const GskSlExpressionIndex *) expression;
+
+ return gsk_sl_type_get_index_type (gsk_sl_expression_get_return_type (index->expr));
+}
+
+static GskSlValue *
+gsk_sl_expression_index_get_constant (const GskSlExpression *expression)
+{
+ const GskSlExpressionIndex *index = (const GskSlExpressionIndex *) expression;
+ GskSlValue *result, *value, *index_value;
+
+ value = gsk_sl_expression_get_constant (index->expr);
+ if (value == NULL)
+ return NULL;
+
+ index_value = gsk_sl_expression_get_constant (index->index_expr);
+ if (index_value == NULL)
+ {
+ gsk_sl_value_free (value);
+ return NULL;
+ }
+
+ result = gsk_sl_value_new_index (value, *(guint32 *) gsk_sl_value_get_data (index_value));
+
+ gsk_sl_value_free (index_value);
+ gsk_sl_value_free (value);
+
+ return result;
+}
+
+static guint32
+gsk_sl_expression_index_write_spv (const GskSlExpression *expression,
+ GskSpvWriter *writer)
+{
+ const GskSlExpressionIndex *index = (const GskSlExpressionIndex *) expression;
+ guint32 value_id, index_id, variable_id;
+ GskSlType *type;
+
+ type = gsk_sl_expression_get_return_type (index->expr);
+ index_id = gsk_sl_expression_write_spv (index->index_expr, writer);
+ value_id = gsk_sl_expression_write_spv (index->expr, writer);
+ if (gsk_sl_type_is_vector (type))
+ {
+ return gsk_spv_writer_vector_extract_dynamic (writer,
+ gsk_sl_type_get_index_type (type),
+ value_id,
+ index_id);
+ }
+
+ /* we get here when we can't use an access chain on index->expr.
+ * So we create a temporary variable and use an access chain on that one */
+ variable_id = gsk_spv_writer_variable (writer,
+ GSK_SPV_WRITER_SECTION_DECLARE,
+ type,
+ GSK_SPV_STORAGE_CLASS_FUNCTION,
+ GSK_SPV_STORAGE_CLASS_FUNCTION,
+ value_id);
+ variable_id = gsk_spv_writer_access_chain (writer,
+ gsk_sl_type_get_index_type (type),
+ GSK_SPV_STORAGE_CLASS_FUNCTION,
+ variable_id,
+ (guint32[1]) { index_id },
+ 1);
+ return gsk_spv_writer_load (writer,
+ gsk_sl_type_get_index_type (type),
+ variable_id,
+ 0);
+}
+
+static GskSpvAccessChain *
+gsk_sl_expression_index_get_spv_access_chain (const GskSlExpression *expression,
+ GskSpvWriter *writer)
+{
+ const GskSlExpressionIndex *index = (const GskSlExpressionIndex *) expression;
+ GskSpvAccessChain *chain;
+
+ chain = gsk_sl_expression_get_spv_access_chain (index->expr, writer);
+ if (chain == NULL)
+ return NULL;
+ if (gsk_spv_access_chain_has_swizzle (chain))
+ {
+ gsk_spv_access_chain_free (chain);
+ return NULL;
+ }
+
+ gsk_spv_access_chain_add_dynamic_index (chain,
+ gsk_sl_type_get_index_type (gsk_sl_expression_get_return_type
(index->expr)),
+ index->index_expr);
+
+ return chain;
+}
+
+static const GskSlExpressionClass GSK_SL_EXPRESSION_INDEX = {
+ gsk_sl_expression_index_free,
+ gsk_sl_expression_index_print,
+ gsk_sl_expression_index_is_assignable,
+ gsk_sl_expression_index_get_return_type,
+ gsk_sl_expression_index_get_constant,
+ gsk_sl_expression_index_write_spv,
+ gsk_sl_expression_index_get_spv_access_chain
+};
+
/* MEMBER */
typedef struct _GskSlExpressionMember GskSlExpressionMember;
@@ -2298,6 +2446,49 @@ gsk_sl_expression_parse_postfix (GskSlScope *scope,
continue;
}
}
+ else if (gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACKET))
+ {
+ GskSlExpressionIndex *index;
+ GskSlExpression *index_expr;
+ GskSlType *type;
+
+ gsk_sl_preprocessor_consume (stream, NULL);
+
+ index_expr = gsk_sl_expression_parse (scope, stream);
+
+ token = gsk_sl_preprocessor_get (stream);
+ if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACKET))
+ {
+ gsk_sl_preprocessor_error (stream, SYNTAX, "Expected closing \"]\" after array index.");
+ gsk_sl_expression_unref (index_expr);
+ continue;
+ }
+ gsk_sl_preprocessor_consume (stream, NULL);
+
+ type = gsk_sl_expression_get_return_type (index_expr);
+ if (!gsk_sl_type_equal (type, gsk_sl_type_get_scalar (GSK_SL_INT)) &&
+ !gsk_sl_type_equal (type, gsk_sl_type_get_scalar (GSK_SL_UINT)))
+ {
+ gsk_sl_preprocessor_error (stream, SYNTAX, "Array index must be an integer type, not %s.",
gsk_sl_type_get_name (type));
+ gsk_sl_expression_unref (index_expr);
+ continue;
+ }
+
+ type = gsk_sl_expression_get_return_type (expr);
+ if (gsk_sl_type_get_length (type) == 0)
+ {
+ gsk_sl_preprocessor_error (stream, SYNTAX, "Cannot index values of type %s.",
gsk_sl_type_get_name (type));
+ gsk_sl_expression_unref (index_expr);
+ continue;
+ }
+ /* XXX: do range check for constants here */
+
+ index = gsk_sl_expression_new (GskSlExpressionIndex, &GSK_SL_EXPRESSION_INDEX);
+ index->expr = expr;
+ index->index_expr = index_expr;
+
+ expr = (GskSlExpression *) index;
+ }
else if (gsk_sl_token_is (token, GSK_SL_TOKEN_INC_OP) ||
gsk_sl_token_is (token, GSK_SL_TOKEN_DEC_OP))
{
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index 2ebfce5..f74f3f7 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -20,6 +20,7 @@
#include "gsksltypeprivate.h"
+#include "gskslexpressionprivate.h"
#include "gskslfunctionprivate.h"
#include "gskslimagetypeprivate.h"
#include "gskslpreprocessorprivate.h"
@@ -1077,6 +1078,219 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = {
gsk_sl_type_matrix_write_value_spv
};
+/* ARRAY */
+
+typedef struct _GskSlTypeArray GskSlTypeArray;
+
+struct _GskSlTypeArray {
+ GskSlType parent;
+
+ char *name;
+ GskSlType *type;
+ gsize length;
+};
+
+static void
+gsk_sl_type_array_free (GskSlType *type)
+{
+ GskSlTypeArray *array = (GskSlTypeArray *) type;
+
+ gsk_sl_type_unref (array->type);
+ g_free (array->name);
+
+ g_slice_free (GskSlTypeArray, array);
+}
+
+static const char *
+gsk_sl_type_array_get_name (const GskSlType *type)
+{
+ const GskSlTypeArray *array = (const GskSlTypeArray *) type;
+
+ return array->name;
+}
+
+static GskSlScalarType
+gsk_sl_type_array_get_scalar_type (const GskSlType *type)
+{
+ const GskSlTypeArray *array = (const GskSlTypeArray *) type;
+
+ return gsk_sl_type_get_scalar_type (array->type);
+}
+
+static const GskSlImageType *
+gsk_sl_type_array_get_image_type (const GskSlType *type)
+{
+ return NULL;
+}
+
+static GskSlType *
+gsk_sl_type_array_get_index_type (const GskSlType *type)
+{
+ const GskSlTypeArray *array = (const GskSlTypeArray *) type;
+
+ return array->type;
+}
+
+static gsize
+gsk_sl_type_array_get_index_stride (const GskSlType *type)
+{
+ const GskSlTypeArray *array = (const GskSlTypeArray *) type;
+
+ return gsk_sl_type_get_size (array->type);
+}
+
+static guint
+gsk_sl_type_array_get_length (const GskSlType *type)
+{
+ const GskSlTypeArray *array = (const GskSlTypeArray *) type;
+
+ return array->length;
+}
+
+static gsize
+gsk_sl_type_array_get_size (const GskSlType *type)
+{
+ const GskSlTypeArray *array = (const GskSlTypeArray *) type;
+
+ return array->length * gsk_sl_type_get_size (array->type);
+}
+
+static gsize
+gsk_sl_type_array_get_n_components (const GskSlType *type)
+{
+ const GskSlTypeArray *array = (const GskSlTypeArray *) type;
+
+ return gsk_sl_type_array_get_n_components (array->type) * array->length;
+}
+
+static guint
+gsk_sl_type_array_get_n_members (const GskSlType *type)
+{
+ return 0;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_array_get_member (const GskSlType *type,
+ guint n)
+{
+ return NULL;
+}
+
+static gboolean
+gsk_sl_type_array_can_convert (const GskSlType *target,
+ const GskSlType *source)
+{
+ return gsk_sl_type_equal (target, source);
+}
+
+static guint32
+gsk_sl_type_array_write_spv (GskSlType *type,
+ GskSpvWriter *writer)
+{
+ GskSlTypeArray *array = (GskSlTypeArray *) type;
+ GskSlValue *value;
+ guint32 type_id, length_id;
+
+ type_id = gsk_spv_writer_get_id_for_type (writer, array->type);
+ value = gsk_sl_value_new (gsk_sl_type_get_scalar (GSK_SL_INT));
+ *(gint32 *) gsk_sl_value_get_data (value) = array->length;
+ length_id = gsk_spv_writer_get_id_for_value (writer, value);
+ gsk_sl_value_free (value);
+
+ return gsk_spv_writer_type_array (writer,
+ type_id,
+ length_id);
+}
+
+static void
+gsk_sl_type_array_print_value (const GskSlType *type,
+ GskSlPrinter *printer,
+ gconstpointer value)
+{
+ GskSlTypeArray *array = (GskSlTypeArray *) type;
+ gsize i, stride;
+ const guchar *data;
+
+ data = value;
+ stride = gsk_sl_type_array_get_index_stride (type);
+ gsk_sl_printer_append (printer, array->name);
+ gsk_sl_printer_append (printer, " (");
+
+ for (i = 0; i < array->length; i++)
+ {
+ if (i > 0)
+ gsk_sl_printer_append (printer, ", ");
+ gsk_sl_type_print_value (array->type, printer, data + i * stride);
+ }
+
+ gsk_sl_printer_append (printer, ")");
+}
+
+static gboolean
+gsk_sl_type_array_value_equal (const GskSlType *type,
+ gconstpointer a,
+ gconstpointer b)
+{
+ GskSlTypeArray *array = (GskSlTypeArray *) type;
+ gsize i, stride;
+ const guchar *adata;
+ const guchar *bdata;
+
+ adata = a;
+ bdata = b;
+ stride = gsk_sl_type_array_get_index_stride (type);
+ for (i = 0; i < array->length; i++)
+ {
+ if (!gsk_sl_type_value_equal (array->type, adata + i * stride, bdata + i * stride))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static guint32
+gsk_sl_type_array_write_value_spv (GskSlType *type,
+ GskSpvWriter *writer,
+ gconstpointer value)
+{
+ GskSlTypeArray *array = (GskSlTypeArray *) type;
+ guint32 value_ids[array->length];
+ gsize i, stride;
+ const guchar *data;
+
+ data = value;
+ stride = gsk_sl_type_array_get_index_stride (type);
+
+ for (i = 0; i < array->length; i++)
+ {
+ value_ids[i] = gsk_sl_type_write_value_spv (array->type, writer, data + i * stride);
+ }
+
+ return gsk_spv_writer_constant_composite (writer,
+ type,
+ value_ids,
+ array->length);
+}
+
+static const GskSlTypeClass GSK_SL_TYPE_ARRAY = {
+ gsk_sl_type_array_free,
+ gsk_sl_type_array_get_name,
+ gsk_sl_type_array_get_scalar_type,
+ gsk_sl_type_array_get_image_type,
+ gsk_sl_type_array_get_index_type,
+ gsk_sl_type_array_get_index_stride,
+ gsk_sl_type_array_get_length,
+ gsk_sl_type_array_get_size,
+ gsk_sl_type_array_get_n_components,
+ gsk_sl_type_array_get_n_members,
+ gsk_sl_type_array_get_member,
+ gsk_sl_type_array_can_convert,
+ gsk_sl_type_array_write_spv,
+ gsk_sl_type_array_print_value,
+ gsk_sl_type_array_value_equal,
+ gsk_sl_type_array_write_value_spv
+};
+
/* SAMPLER */
typedef struct _GskSlTypeSampler GskSlTypeSampler;
@@ -1916,6 +2130,70 @@ gsk_sl_type_get_matching (GskSlType *type,
}
}
+static char *
+gsk_sl_array_type_generate_name (GskSlType *type)
+{
+ GString *string = g_string_new (NULL);
+
+ for (; gsk_sl_type_is_array (type); type = gsk_sl_type_get_index_type (type))
+ {
+ g_string_append_printf (string, "[%u]", gsk_sl_type_get_length (type));
+ }
+
+ g_string_prepend (string, gsk_sl_type_get_name (type));
+
+ return g_string_free (string, FALSE);
+}
+
+GskSlType *
+gsk_sl_type_new_array (GskSlType *type,
+ gsize length)
+{
+ GskSlTypeArray *result;
+
+ result = gsk_sl_type_new (GskSlTypeArray, &GSK_SL_TYPE_ARRAY);
+
+ result->type = gsk_sl_type_ref (type);
+ result->length = length;
+
+ result->name = gsk_sl_array_type_generate_name (&result->parent);
+
+ return &result->parent;
+}
+
+GskSlType *
+gsk_sl_type_parse_array (GskSlType *type,
+ GskSlScope *scope,
+ GskSlPreprocessor *preproc)
+{
+ GskSlType *array;
+ const GskSlToken *token;
+ gsize length;
+
+ token = gsk_sl_preprocessor_get (preproc);
+ if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACKET))
+ return type;
+
+ gsk_sl_preprocessor_consume (preproc, NULL);
+
+ length = gsk_sl_expression_parse_integral_constant (scope, preproc, 1, G_MAXINT);
+
+ token = gsk_sl_preprocessor_get (preproc);
+ if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACKET))
+ {
+ gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \"]\"");
+ return type;
+ }
+ gsk_sl_preprocessor_consume (preproc, NULL);
+
+ type = gsk_sl_type_parse_array (type, scope, preproc);
+
+ array = gsk_sl_type_new_array (type, length);
+ gsk_sl_type_unref (type);
+
+ return array;
+}
+
GskSlType *
gsk_sl_type_new_parse (GskSlScope *scope,
GskSlPreprocessor *preproc)
@@ -2191,6 +2469,8 @@ gsk_sl_type_new_parse (GskSlScope *scope,
gsk_sl_preprocessor_consume (preproc, NULL);
+ type = gsk_sl_type_parse_array (type, scope, preproc);
+
return type;
}
@@ -2426,6 +2706,12 @@ gsk_sl_type_is_basic (const GskSlType *type)
}
gboolean
+gsk_sl_type_is_array (const GskSlType *type)
+{
+ return type->class == &GSK_SL_TYPE_ARRAY;
+}
+
+gboolean
gsk_sl_type_is_struct (const GskSlType *type)
{
return type->class == &GSK_SL_TYPE_STRUCT;
diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h
index da3871b..ee3f0d7 100644
--- a/gsk/gsksltypeprivate.h
+++ b/gsk/gsksltypeprivate.h
@@ -29,8 +29,14 @@ typedef struct _GskSlTypeBuilder GskSlTypeBuilder;
gsize gsk_sl_scalar_type_get_size (GskSlScalarType type);
+GskSlType * gsk_sl_type_new_array (GskSlType *type,
+ gsize length);
GskSlType * gsk_sl_type_new_parse (GskSlScope *scope,
GskSlPreprocessor *preproc);
+GskSlType * gsk_sl_type_parse_array (GskSlType *type,
+ GskSlScope *scope,
+ GskSlPreprocessor *preproc);
+
GskSlType * gsk_sl_type_get_void (void);
GskSlType * gsk_sl_type_get_scalar (GskSlScalarType scalar);
GskSlType * gsk_sl_type_get_vector (GskSlScalarType scalar,
@@ -50,6 +56,7 @@ gboolean gsk_sl_type_is_scalar (const GskSlType
gboolean gsk_sl_type_is_vector (const GskSlType *type);
gboolean gsk_sl_type_is_matrix (const GskSlType *type);
gboolean gsk_sl_type_is_basic (const GskSlType *type);
+gboolean gsk_sl_type_is_array (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_sampler (const GskSlType *type);
diff --git a/gsk/gskslvalue.c b/gsk/gskslvalue.c
index f930f98..475b460 100644
--- a/gsk/gskslvalue.c
+++ b/gsk/gskslvalue.c
@@ -160,15 +160,36 @@ gsk_sl_value_new_convert (GskSlValue *source,
}
GskSlValue *
+gsk_sl_value_new_index (GskSlValue *value,
+ gsize n)
+{
+ GskSlType *index_type;
+ gpointer data;
+
+ if (n >= gsk_sl_type_get_length (value->type))
+ return NULL;
+
+ index_type = gsk_sl_type_get_index_type (value->type);
+
+ data = g_memdup ((guchar *) value->data + gsk_sl_type_get_index_stride (value->type) * n,
+ gsk_sl_type_get_size (index_type));
+
+ return gsk_sl_value_new_for_data (index_type, data, g_free, data);
+}
+
+GskSlValue *
gsk_sl_value_new_member (GskSlValue *value,
guint n)
{
+ GskSlType *member_type;
gpointer data;
+ member_type = gsk_sl_type_get_member_type (value->type, n);
+
data = g_memdup ((guchar *) value->data + gsk_sl_type_get_member_offset (value->type, n),
- gsk_sl_type_get_size (gsk_sl_type_get_member_type (value->type, n)));
+ gsk_sl_type_get_size (member_type));
- return gsk_sl_value_new_for_data (value->type, data, g_free, data);
+ return gsk_sl_value_new_for_data (member_type, data, g_free, data);
}
/**
diff --git a/gsk/gskslvalueprivate.h b/gsk/gskslvalueprivate.h
index 0ce2637..4e32c5c 100644
--- a/gsk/gskslvalueprivate.h
+++ b/gsk/gskslvalueprivate.h
@@ -30,6 +30,8 @@ GskSlValue * gsk_sl_value_new_for_data (GskSlType
gpointer user_data);
GskSlValue * gsk_sl_value_new_convert (GskSlValue *source,
GskSlType *new_type);
+GskSlValue * gsk_sl_value_new_index (GskSlValue *value,
+ gsize n);
GskSlValue * gsk_sl_value_new_member (GskSlValue *value,
guint n);
GskSlValue * gsk_sl_value_copy (const GskSlValue *source);
diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c
index a197d5a..8ac7e02 100644
--- a/gsk/gskspvwriter.c
+++ b/gsk/gskspvwriter.c
@@ -20,6 +20,7 @@
#include "gskspvwriterprivate.h"
+#include "gskslexpressionprivate.h"
#include "gskslfunctionprivate.h"
#include "gskslfunctiontypeprivate.h"
#include "gskslimagetypeprivate.h"
@@ -813,6 +814,7 @@ struct _GskSpvAccessChain
GskSlVariable *variable;
GskSlType *type;
GArray *chain;
+ GSList *pending_indexes;
guint32 swizzle[4];
guint swizzle_length;
};
@@ -840,6 +842,7 @@ gsk_spv_access_chain_free (GskSpvAccessChain *chain)
{
if (chain->chain)
g_array_free (chain->chain, TRUE);
+ g_slist_free_full (chain->pending_indexes, (GDestroyNotify) gsk_sl_expression_unref);
gsk_sl_type_unref (chain->type);
gsk_sl_variable_unref (chain->variable);
gsk_spv_writer_unref (chain->writer);
@@ -852,6 +855,8 @@ gsk_spv_access_chain_add_index (GskSpvAccessChain *chain,
GskSlType *type,
guint32 index_id)
{
+ g_assert (!gsk_spv_access_chain_has_swizzle (chain));
+
if (chain->chain == NULL)
chain->chain = g_array_new (FALSE, FALSE, sizeof (guint32));
gsk_sl_type_unref (chain->type);
@@ -861,6 +866,22 @@ gsk_spv_access_chain_add_index (GskSpvAccessChain *chain,
}
void
+gsk_spv_access_chain_add_dynamic_index (GskSpvAccessChain *chain,
+ GskSlType *type,
+ GskSlExpression *expr)
+{
+ gsk_spv_access_chain_add_index (chain, type, 0);
+
+ chain->pending_indexes = g_slist_prepend (chain->pending_indexes, gsk_sl_expression_ref (expr));
+}
+
+gboolean
+gsk_spv_access_chain_has_swizzle (GskSpvAccessChain *chain)
+{
+ return chain->swizzle_length > 0;
+}
+
+void
gsk_spv_access_chain_swizzle (GskSpvAccessChain *chain,
const guint *indexes,
guint length)
@@ -917,11 +938,37 @@ gsk_spv_access_chain_swizzle (GskSpvAccessChain *chain,
}
}
+static void
+gsk_spv_access_resolve_pending (GskSpvAccessChain *chain)
+{
+ GSList *l;
+ guint i;
+
+ if (chain->pending_indexes == NULL)
+ return;
+
+ i = chain->chain->len;
+ l = chain->pending_indexes;
+ while (i-- > 0)
+ {
+ if (g_array_index (chain->chain, guint32, i) != 0)
+ continue;
+
+ g_array_index (chain->chain, guint32, i) = gsk_sl_expression_write_spv (l->data, chain->writer);
+ l = l->next;
+ }
+
+ g_slist_free_full (chain->pending_indexes, (GDestroyNotify) gsk_sl_expression_unref);
+ chain->pending_indexes = NULL;
+}
+
static guint32
gsk_spv_access_get_variable (GskSpvAccessChain *chain)
{
guint32 variable_id;
+ gsk_spv_access_resolve_pending (chain);
+
variable_id = gsk_spv_writer_get_id_for_variable (chain->writer,
chain->variable);
diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h
index 4d7e1d3..bf84788 100644
--- a/gsk/gskspvwriterprivate.h
+++ b/gsk/gskspvwriterprivate.h
@@ -104,9 +104,13 @@ void gsk_spv_access_chain_free (GskSpvAccessCha
void gsk_spv_access_chain_add_index (GskSpvAccessChain *chain,
GskSlType *type,
guint32 index_id);
+void gsk_spv_access_chain_add_dynamic_index (GskSpvAccessChain *chain,
+ GskSlType *type,
+ GskSlExpression *expr);
void gsk_spv_access_chain_swizzle (GskSpvAccessChain *chain,
const guint *indexes,
guint n_indexes);
+gboolean gsk_spv_access_chain_has_swizzle (GskSpvAccessChain *chain);
guint32 gsk_spv_access_chain_load (GskSpvAccessChain *chain);
void gsk_spv_access_chain_store (GskSpvAccessChain *chain,
guint32 value);
diff --git a/testsuite/gsksl/errors/array-of-array-indexing-order.glsl
b/testsuite/gsksl/errors/array-of-array-indexing-order.glsl
new file mode 100644
index 0000000..fe6048e
--- /dev/null
+++ b/testsuite/gsksl/errors/array-of-array-indexing-order.glsl
@@ -0,0 +1,8 @@
+void
+main ()
+{
+ float[2][3] x;
+ float[2] y;
+
+ bool b = x[1] == y;
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]