[gtk+/wip/otte/shader: 27/55] gsksl: Add support for parsing members of struct variables
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/shader: 27/55] gsksl: Add support for parsing members of struct variables
- Date: Mon, 2 Oct 2017 03:37:58 +0000 (UTC)
commit 7cafc85307b976806a5c4d92349c503a15203718
Author: Benjamin Otte <otte redhat com>
Date: Thu Sep 28 03:38:56 2017 +0200
gsksl: Add support for parsing members of struct variables
This includes adding the concept of members to GskSlType.
gsk/gskslexpression.c | 100 ++++++++++++++++++++++++++++++
gsk/gsksltype.c | 157 ++++++++++++++++++++++++++++++++++++++++++++--
gsk/gsksltypeprivate.h | 12 ++++
gsk/gskslvalue.c | 12 ++++
gsk/gskslvalueprivate.h | 2 +
5 files changed, 276 insertions(+), 7 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 2c0a285..041b7b8 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -795,6 +795,95 @@ static const GskSlExpressionClass GSK_SL_EXPRESSION_FUNCTION_CALL = {
gsk_sl_expression_function_call_write_spv
};
+/* MEMBER */
+
+typedef struct _GskSlExpressionMember GskSlExpressionMember;
+
+struct _GskSlExpressionMember {
+ GskSlExpression parent;
+
+ GskSlExpression *expr;
+ guint id;
+};
+
+static void
+gsk_sl_expression_member_free (GskSlExpression *expression)
+{
+ GskSlExpressionMember *member = (GskSlExpressionMember *) expression;
+
+ gsk_sl_expression_unref (member->expr);
+
+ g_slice_free (GskSlExpressionMember, member);
+}
+
+static void
+gsk_sl_expression_member_print (const GskSlExpression *expression,
+ GString *string)
+{
+ const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
+
+ gsk_sl_expression_print (member->expr, string);
+ g_string_append (string, ".");
+ g_string_append (string, gsk_sl_type_get_member_name (gsk_sl_expression_get_return_type (member->expr),
member->id));
+}
+
+static GskSlType *
+gsk_sl_expression_member_get_return_type (const GskSlExpression *expression)
+{
+ const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
+
+ return gsk_sl_type_get_member_type (gsk_sl_expression_get_return_type (member->expr), member->id);
+}
+
+static GskSlValue *
+gsk_sl_expression_member_get_constant (const GskSlExpression *expression)
+{
+ const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
+ GskSlValue *result, *value;
+
+ value = gsk_sl_expression_get_constant (member->expr);
+ if (value == NULL)
+ return NULL;
+
+ result = gsk_sl_value_new_member (value, member->id);
+
+ gsk_sl_value_free (value);
+
+ return result;
+}
+
+static guint32
+gsk_sl_expression_member_write_spv (const GskSlExpression *expression,
+ GskSpvWriter *writer)
+{
+ const GskSlExpressionMember *member = (const GskSlExpressionMember *) expression;
+ GskSlType *type;
+ guint32 expr_id, type_id, result_id;
+
+ type = gsk_sl_expression_get_return_type (member->expr);
+ type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_member_type (type, member->id));
+ expr_id = gsk_sl_expression_write_spv (member->expr, writer);
+ result_id = gsk_spv_writer_next_id (writer);
+
+ gsk_spv_writer_add (writer,
+ GSK_SPV_WRITER_SECTION_CODE,
+ 5, GSK_SPV_OP_ACCESS_CHAIN,
+ (guint32[4]) { type_id,
+ result_id,
+ expr_id,
+ member->id });
+
+ return result_id;
+}
+
+static const GskSlExpressionClass GSK_SL_EXPRESSION_MEMBER = {
+ gsk_sl_expression_member_free,
+ gsk_sl_expression_member_print,
+ gsk_sl_expression_member_get_return_type,
+ gsk_sl_expression_member_get_constant,
+ gsk_sl_expression_member_write_spv
+};
+
/* SWIZZLE */
typedef enum {
@@ -1269,6 +1358,7 @@ gsk_sl_expression_parse_field_selection (GskSlScope *scope,
const char *name)
{
GskSlType *type;
+ guint n;
if (g_str_equal (name, "length"))
{
@@ -1328,6 +1418,16 @@ gsk_sl_expression_parse_field_selection (GskSlScope *scope,
return (GskSlExpression *) swizzle;
}
+ else if (gsk_sl_type_find_member (type, name, &n, NULL, NULL))
+ {
+ GskSlExpressionMember *member;
+
+ member = gsk_sl_expression_new (GskSlExpressionMember, &GSK_SL_EXPRESSION_MEMBER);
+ member->expr = expr;
+ member->id = n;
+
+ return (GskSlExpression *) member;
+ }
else
{
gsk_sl_preprocessor_error (stream, TYPE_MISMATCH, "Type %s has no fields to select.",
gsk_sl_type_get_name (type));
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index 06d8944..74404ac 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -31,8 +31,16 @@
#define N_SCALAR_TYPES 6
+typedef struct _GskSlTypeMember GskSlTypeMember;
typedef struct _GskSlTypeClass GskSlTypeClass;
+struct _GskSlTypeMember {
+ GskSlType *type;
+ char *name;
+ gsize offset;
+};
+
+
struct _GskSlType
{
const GskSlTypeClass *class;
@@ -49,6 +57,9 @@ struct _GskSlTypeClass {
gsize (* get_index_stride) (GskSlType *type);
guint (* get_length) (GskSlType *type);
gsize (* get_size) (GskSlType *type);
+ guint (* get_n_members) (GskSlType *type);
+ const GskSlTypeMember * (* get_member) (GskSlType *type,
+ guint n);
gboolean (* can_convert) (GskSlType *target,
GskSlType *source);
guint32 (* write_spv) (const GskSlType *type,
@@ -381,6 +392,19 @@ gsk_sl_type_scalar_get_size (GskSlType *type)
return scalar_infos[scalar->scalar].size;
}
+static guint
+gsk_sl_type_scalar_get_n_members (GskSlType *type)
+{
+ return 0;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_scalar_get_member (GskSlType *type,
+ guint n)
+{
+ return NULL;
+}
+
static gboolean
gsk_sl_type_scalar_can_convert (GskSlType *target,
GskSlType *source)
@@ -493,6 +517,8 @@ static const GskSlTypeClass GSK_SL_TYPE_SCALAR = {
gsk_sl_type_scalar_get_index_stride,
gsk_sl_type_scalar_get_length,
gsk_sl_type_scalar_get_size,
+ gsk_sl_type_scalar_get_n_members,
+ gsk_sl_type_scalar_get_member,
gsk_sl_type_scalar_can_convert,
gsk_sl_type_scalar_write_spv,
gsk_sl_type_scalar_print_value,
@@ -565,6 +591,19 @@ gsk_sl_type_vector_get_size (GskSlType *type)
return vector->length * scalar_infos[vector->scalar].size;
}
+static guint
+gsk_sl_type_vector_get_n_members (GskSlType *type)
+{
+ return 0;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_vector_get_member (GskSlType *type,
+ guint n)
+{
+ return NULL;
+}
+
static gboolean
gsk_sl_type_vector_can_convert (GskSlType *target,
GskSlType *source)
@@ -666,6 +705,8 @@ static const GskSlTypeClass GSK_SL_TYPE_VECTOR = {
gsk_sl_type_vector_get_index_stride,
gsk_sl_type_vector_get_length,
gsk_sl_type_vector_get_size,
+ gsk_sl_type_vector_get_n_members,
+ gsk_sl_type_vector_get_member,
gsk_sl_type_vector_can_convert,
gsk_sl_type_vector_write_spv,
gsk_sl_type_vector_print_value,
@@ -739,6 +780,19 @@ gsk_sl_type_matrix_get_size (GskSlType *type)
return matrix->columns * matrix->rows * scalar_infos[matrix->scalar].size;
}
+static guint
+gsk_sl_type_matrix_get_n_members (GskSlType *type)
+{
+ return 0;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_matrix_get_member (GskSlType *type,
+ guint n)
+{
+ return NULL;
+}
+
static gboolean
gsk_sl_type_matrix_can_convert (GskSlType *target,
GskSlType *source)
@@ -841,6 +895,8 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = {
gsk_sl_type_matrix_get_index_stride,
gsk_sl_type_matrix_get_length,
gsk_sl_type_matrix_get_size,
+ gsk_sl_type_matrix_get_n_members,
+ gsk_sl_type_matrix_get_member,
gsk_sl_type_matrix_can_convert,
gsk_sl_type_matrix_write_spv,
gsk_sl_type_matrix_print_value,
@@ -849,15 +905,8 @@ static const GskSlTypeClass GSK_SL_TYPE_MATRIX = {
/* STRUCT */
-typedef struct _GskSlTypeMember GskSlTypeMember;
typedef struct _GskSlTypeStruct GskSlTypeStruct;
-struct _GskSlTypeMember {
- GskSlType *type;
- char *name;
- gsize offset;
-};
-
struct _GskSlTypeStruct {
GskSlType parent;
@@ -926,6 +975,23 @@ gsk_sl_type_struct_get_size (GskSlType *type)
return struc->size;
}
+static guint
+gsk_sl_type_struct_get_n_members (GskSlType *type)
+{
+ GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
+
+ return struc->n_members;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_struct_get_member (GskSlType *type,
+ guint n)
+{
+ GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
+
+ return &struc->members[n];
+}
+
static gboolean
gsk_sl_type_struct_can_convert (GskSlType *target,
GskSlType *source)
@@ -1024,6 +1090,8 @@ static const GskSlTypeClass GSK_SL_TYPE_STRUCT = {
gsk_sl_type_struct_get_index_stride,
gsk_sl_type_struct_get_length,
gsk_sl_type_struct_get_size,
+ gsk_sl_type_struct_get_n_members,
+ gsk_sl_type_struct_get_member,
gsk_sl_type_struct_can_convert,
gsk_sl_type_struct_write_spv,
gsk_sl_type_struct_print_value,
@@ -1476,6 +1544,81 @@ gsk_sl_type_get_size (const GskSlType *type)
return type->class->get_size (type);
}
+guint
+gsk_sl_type_get_n_members (const GskSlType *type)
+{
+ return type->class->get_n_members (type);
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_get_member (const GskSlType *type,
+ guint n)
+{
+ return type->class->get_member (type, n);
+}
+
+GskSlType *
+gsk_sl_type_get_member_type (const GskSlType *type,
+ guint n)
+{
+ const GskSlTypeMember *member;
+
+ member = gsk_sl_type_get_member (type, n);
+
+ return member->type;
+}
+
+const char *
+gsk_sl_type_get_member_name (const GskSlType *type,
+ guint n)
+{
+ const GskSlTypeMember *member;
+
+ member = gsk_sl_type_get_member (type, n);
+
+ return member->name;
+}
+
+gsize
+gsk_sl_type_get_member_offset (const GskSlType *type,
+ guint n)
+{
+ const GskSlTypeMember *member;
+
+ member = gsk_sl_type_get_member (type, n);
+
+ return member->offset;
+}
+
+gboolean
+gsk_sl_type_find_member (const GskSlType *type,
+ const char *name,
+ guint *out_index,
+ GskSlType **out_type,
+ gsize *out_offset)
+{
+ const GskSlTypeMember *member;
+ guint i, n;
+
+ n = gsk_sl_type_get_n_members (type);
+ for (i = 0; i < n; i++)
+ {
+ member = gsk_sl_type_get_member (type, i);
+ if (g_str_equal (member->name, name))
+ {
+ if (out_index)
+ *out_index = i;
+ if (out_type)
+ *out_type = member->type;
+ if (out_offset)
+ *out_offset = member->offset;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
gboolean
gsk_sl_scalar_type_can_convert (GskSlScalarType target,
GskSlScalarType source)
diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h
index 7f3bfa4..ddefc06 100644
--- a/gsk/gsksltypeprivate.h
+++ b/gsk/gsksltypeprivate.h
@@ -59,6 +59,18 @@ GskSlType * gsk_sl_type_get_index_type (const GskSlType
gsize gsk_sl_type_get_index_stride (const GskSlType *type);
guint gsk_sl_type_get_length (const GskSlType *type);
gsize gsk_sl_type_get_size (const GskSlType *type);
+guint gsk_sl_type_get_n_members (const GskSlType *type);
+GskSlType * gsk_sl_type_get_member_type (const GskSlType *type,
+ guint n);
+const char * gsk_sl_type_get_member_name (const GskSlType *type,
+ guint n);
+gsize gsk_sl_type_get_member_offset (const GskSlType *type,
+ guint n);
+gboolean gsk_sl_type_find_member (const GskSlType *type,
+ const char *name,
+ guint *out_index,
+ GskSlType **out_type,
+ gsize *out_offset);
gboolean gsk_sl_scalar_type_can_convert (GskSlScalarType target,
GskSlScalarType source);
gboolean gsk_sl_type_can_convert (const GskSlType *target,
diff --git a/gsk/gskslvalue.c b/gsk/gskslvalue.c
index 15e2411..bee1c26 100644
--- a/gsk/gskslvalue.c
+++ b/gsk/gskslvalue.c
@@ -155,6 +155,18 @@ gsk_sl_value_new_convert (GskSlValue *source,
}
GskSlValue *
+gsk_sl_value_new_member (GskSlValue *value,
+ guint n)
+{
+ gpointer data;
+
+ 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)));
+
+ return gsk_sl_value_new_for_data (value->type, data, g_free, data);
+}
+
+GskSlValue *
gsk_sl_value_copy (GskSlValue *source)
{
gpointer data;
diff --git a/gsk/gskslvalueprivate.h b/gsk/gskslvalueprivate.h
index dec0b87..aa261a1 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_member (GskSlValue *value,
+ guint n);
GskSlValue * gsk_sl_value_copy (GskSlValue *source);
void gsk_sl_value_free (GskSlValue *value);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]