[gtk+/wip/otte/shader: 27/55] gsksl: Add support for parsing members of struct variables



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]