[gtk+/wip/otte/shader: 46/127] 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: 46/127] gsksl: Add support for parsing members of struct variables
- Date: Fri, 13 Oct 2017 00:00:17 +0000 (UTC)
commit e13859aeac8a446c124493c65cb4154197a0df8b
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 | 198 +++++++++++++++++++++++++++++++++++++++--------
gsk/gsksltypeprivate.h | 12 +++
gsk/gskslvalue.c | 12 +++
gsk/gskslvalueprivate.h | 2 +
5 files changed, 293 insertions(+), 31 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index b8f23f0..9ea7cdb 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -794,6 +794,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 {
@@ -1268,6 +1357,7 @@ gsk_sl_expression_parse_field_selection (GskSlScope *scope,
const char *name)
{
GskSlType *type;
+ guint n;
if (g_str_equal (name, "length"))
{
@@ -1327,6 +1417,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 1f1d7b0..18c30ba 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;
@@ -42,13 +50,15 @@ struct _GskSlType
struct _GskSlTypeClass {
void (* free) (GskSlType *type);
-
const char * (* get_name) (const GskSlType *type);
GskSlScalarType (* get_scalar_type) (const GskSlType *type);
GskSlType * (* get_index_type) (const GskSlType *type);
gsize (* get_index_stride) (const GskSlType *type);
guint (* get_length) (const GskSlType *type);
gsize (* get_size) (const GskSlType *type);
+ guint (* get_n_members) (const GskSlType *type);
+ const GskSlTypeMember * (* get_member) (const GskSlType *type,
+ guint i);
gboolean (* can_convert) (const GskSlType *target,
const GskSlType *source);
guint32 (* write_spv) (GskSlType *type,
@@ -387,6 +397,19 @@ gsk_sl_type_scalar_get_size (const GskSlType *type)
return scalar_infos[scalar->scalar].size;
}
+static guint
+gsk_sl_type_scalar_get_n_members (const GskSlType *type)
+{
+ return 0;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_scalar_get_member (const GskSlType *type,
+ guint n)
+{
+ return NULL;
+}
+
static gboolean
gsk_sl_type_scalar_can_convert (const GskSlType *target,
const GskSlType *source)
@@ -499,6 +522,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,
@@ -571,6 +596,19 @@ gsk_sl_type_vector_get_size (const GskSlType *type)
return vector->length * scalar_infos[vector->scalar].size;
}
+static guint
+gsk_sl_type_vector_get_n_members (const GskSlType *type)
+{
+ return 0;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_vector_get_member (const GskSlType *type,
+ guint n)
+{
+ return NULL;
+}
+
static gboolean
gsk_sl_type_vector_can_convert (const GskSlType *target,
const GskSlType *source)
@@ -672,6 +710,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,
@@ -745,6 +785,19 @@ gsk_sl_type_matrix_get_size (const GskSlType *type)
return matrix->columns * matrix->rows * scalar_infos[matrix->scalar].size;
}
+static guint
+gsk_sl_type_matrix_get_n_members (const GskSlType *type)
+{
+ return 0;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_matrix_get_member (const GskSlType *type,
+ guint n)
+{
+ return NULL;
+}
+
static gboolean
gsk_sl_type_matrix_can_convert (const GskSlType *target,
const GskSlType *source)
@@ -847,6 +900,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,
@@ -855,15 +910,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;
@@ -893,55 +941,72 @@ gsk_sl_type_struct_free (GskSlType *type)
}
static const char *
-gsk_sl_type_struct_get_name (GskSlType *type)
+gsk_sl_type_struct_get_name (const GskSlType *type)
{
- GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
+ const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
return struc->name;
}
static GskSlScalarType
-gsk_sl_type_struct_get_scalar_type (GskSlType *type)
+gsk_sl_type_struct_get_scalar_type (const GskSlType *type)
{
return GSK_SL_VOID;
}
static GskSlType *
-gsk_sl_type_struct_get_index_type (GskSlType *type)
+gsk_sl_type_struct_get_index_type (const GskSlType *type)
{
return NULL;
}
static gsize
-gsk_sl_type_struct_get_index_stride (GskSlType *type)
+gsk_sl_type_struct_get_index_stride (const GskSlType *type)
{
return 0;
}
static guint
-gsk_sl_type_struct_get_length (GskSlType *type)
+gsk_sl_type_struct_get_length (const GskSlType *type)
{
return 0;
}
static gsize
-gsk_sl_type_struct_get_size (GskSlType *type)
+gsk_sl_type_struct_get_size (const GskSlType *type)
{
- GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
+ const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
return struc->size;
}
+static guint
+gsk_sl_type_struct_get_n_members (const GskSlType *type)
+{
+ const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
+
+ return struc->n_members;
+}
+
+static const GskSlTypeMember *
+gsk_sl_type_struct_get_member (const GskSlType *type,
+ guint n)
+{
+ const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
+
+ return &struc->members[n];
+}
+
static gboolean
-gsk_sl_type_struct_can_convert (GskSlType *target,
- GskSlType *source)
+gsk_sl_type_struct_can_convert (const GskSlType *target,
+ const GskSlType *source)
{
return gsk_sl_type_equal (target, source);
}
static guint32
-gsk_sl_type_struct_write_spv (const GskSlType *type,
- GskSpvWriter *writer)
+gsk_sl_type_struct_write_spv (GskSlType *type,
+ GskSpvWriter *writer)
{
GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
guint32 ids[struc->n_members + 1];
@@ -965,9 +1030,9 @@ gsk_sl_type_struct_write_spv (const GskSlType *type,
static void
gsk_sl_type_struct_print_value (const GskSlType *type,
GString *string,
- gpointer value)
+ gconstpointer value)
{
- GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
+ const GskSlTypeStruct *struc = (const GskSlTypeStruct *) type;
guint i;
g_string_append (string, struc->name);
@@ -986,20 +1051,15 @@ gsk_sl_type_struct_print_value (const GskSlType *type,
}
static guint32
-gsk_sl_type_struct_write_value_spv (GskSlType *type,
- GskSpvWriter *writer,
- gpointer value)
+gsk_sl_type_struct_write_value_spv (GskSlType *type,
+ GskSpvWriter *writer,
+ gconstpointer value)
{
GskSlTypeStruct *struc = (GskSlTypeStruct *) type;
guint32 ids[struc->n_members + 2];
- GskSlType *vector_type;
GskSlValue *v;
- guchar *data;
guint i;
- data = value;
- vector_type = gsk_sl_type_get_index_type (type);
-
ids[0] = gsk_spv_writer_get_id_for_type (writer, type);
for (i = 0; i < struc->n_members; i++)
{
@@ -1008,7 +1068,6 @@ gsk_sl_type_struct_write_value_spv (GskSlType *type,
NULL, NULL);
ids[2 + i] = gsk_spv_writer_get_id_for_value (writer, v);
gsk_sl_value_free (v);
- data += gsk_sl_type_get_size (vector_type);
}
ids[1] = gsk_spv_writer_next_id (writer);
@@ -1030,6 +1089,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,
@@ -1482,6 +1543,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 c07d8d6..592d524 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 4049730..6972ff7 100644
--- a/gsk/gskslvalue.c
+++ b/gsk/gskslvalue.c
@@ -159,6 +159,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 (const GskSlValue *source)
{
gpointer data;
diff --git a/gsk/gskslvalueprivate.h b/gsk/gskslvalueprivate.h
index afd81b5..c4e7c59 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 (const GskSlValue *source);
void gsk_sl_value_free (GskSlValue *value);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]