[gtk+/wip/otte/shader: 1/33] gsksltype: Add support for vector types



commit 6ab479a542a9543fb0fcc1ac6d26a0fba94937ad
Author: Benjamin Otte <otte redhat com>
Date:   Sun Sep 17 14:32:04 2017 +0200

    gsksltype: Add support for vector types

 gsk/gskslnode.c        |   12 +++
 gsk/gsksltype.c        |  179 +++++++++++++++++++++++++++++++++++++++++++++---
 gsk/gsksltypeprivate.h |    2 +
 3 files changed, 184 insertions(+), 9 deletions(-)
---
diff --git a/gsk/gskslnode.c b/gsk/gskslnode.c
index 81ad9da..179a5a6 100644
--- a/gsk/gskslnode.c
+++ b/gsk/gskslnode.c
@@ -1056,9 +1056,21 @@ gsk_sl_node_parse_function_definition (GskSlNodeProgram  *program,
       case GSK_SL_TOKEN_INT:
       case GSK_SL_TOKEN_UINT:
       case GSK_SL_TOKEN_BOOL:
+      case GSK_SL_TOKEN_BVEC2:
+      case GSK_SL_TOKEN_BVEC3:
+      case GSK_SL_TOKEN_BVEC4:
+      case GSK_SL_TOKEN_IVEC2:
+      case GSK_SL_TOKEN_IVEC3:
+      case GSK_SL_TOKEN_IVEC4:
+      case GSK_SL_TOKEN_UVEC2:
+      case GSK_SL_TOKEN_UVEC3:
+      case GSK_SL_TOKEN_UVEC4:
       case GSK_SL_TOKEN_VEC2:
       case GSK_SL_TOKEN_VEC3:
       case GSK_SL_TOKEN_VEC4:
+      case GSK_SL_TOKEN_DVEC2:
+      case GSK_SL_TOKEN_DVEC3:
+      case GSK_SL_TOKEN_DVEC4:
         node = gsk_sl_node_parse_declaration (program, function->scope, stream);
         if (node)
           {
diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c
index 8b3e720..1c436f6 100644
--- a/gsk/gsksltype.c
+++ b/gsk/gsksltype.c
@@ -145,14 +145,84 @@ static const GskSlTypeClass GSK_SL_TYPE_SCALAR = {
   gsk_sl_type_scalar_can_convert
 };
 
-static GskSlTypeScalar
-builtin_types[N_SCALAR_TYPES] = {
-  [GSK_SL_VOID] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_VOID },
-  [GSK_SL_FLOAT] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_FLOAT },
-  [GSK_SL_DOUBLE] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_DOUBLE },
-  [GSK_SL_INT] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_INT },
-  [GSK_SL_UINT] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_UINT },
-  [GSK_SL_BOOL] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_BOOL },
+/* VECTOR */
+
+typedef struct _GskSlTypeVector GskSlTypeVector;
+
+struct _GskSlTypeVector {
+  GskSlType parent;
+
+  GskSlScalarType scalar;
+  guint length;
+};
+
+static void
+gsk_sl_type_vector_free (GskSlType *type)
+{
+  g_assert_not_reached ();
+}
+
+static void
+gsk_sl_type_vector_print (GskSlType *type,
+                          GString   *string)
+{
+  GskSlTypeVector *vector = (GskSlTypeVector *) type;
+
+  switch (vector->scalar)
+  {
+    case GSK_SL_FLOAT:
+      g_string_append (string, "vec");
+      break;
+    case GSK_SL_DOUBLE:
+      g_string_append (string, "dvec");
+      break;
+    case GSK_SL_INT:
+      g_string_append (string, "ivec");
+      break;
+    case GSK_SL_UINT:
+      g_string_append (string, "uvec");
+      break;
+    case GSK_SL_BOOL:
+      g_string_append (string, "bvec");
+      break;
+    case GSK_SL_VOID:
+    default:
+      g_assert_not_reached ();
+      break;
+  }
+
+  g_string_append_printf (string, "%u", vector->length);
+}
+
+static GskSlScalarType
+gsk_sl_type_vector_get_scalar_type (GskSlType *type)
+{
+  GskSlTypeVector *vector = (GskSlTypeVector *) type;
+
+  return vector->scalar;
+}
+
+static gboolean
+gsk_sl_type_vector_can_convert (GskSlType *target,
+                                GskSlType *source)
+{
+  GskSlTypeVector *target_vector = (GskSlTypeVector *) target;
+  GskSlTypeVector *source_vector = (GskSlTypeVector *) source;
+
+  if (target->class != source->class)
+    return FALSE;
+  
+  if (target_vector->length != source_vector->length)
+    return FALSE;
+
+  return gsk_sl_scalar_type_can_convert (target_vector->scalar, source_vector->scalar);
+}
+
+static const GskSlTypeClass GSK_SL_TYPE_VECTOR = {
+  gsk_sl_type_vector_free,
+  gsk_sl_type_vector_print,
+  gsk_sl_type_vector_get_scalar_type,
+  gsk_sl_type_vector_can_convert
 };
 
 GskSlType *
@@ -183,6 +253,51 @@ gsk_sl_type_new_parse (GskSlPreprocessor *stream)
     case GSK_SL_TOKEN_BOOL:
       type = gsk_sl_type_ref (gsk_sl_type_get_scalar (GSK_SL_BOOL));
       break;
+    case GSK_SL_TOKEN_BVEC2:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_BOOL, 2));
+      break;
+    case GSK_SL_TOKEN_BVEC3:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_BOOL, 3));
+      break;
+    case GSK_SL_TOKEN_BVEC4:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_BOOL, 4));
+      break;
+    case GSK_SL_TOKEN_IVEC2:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_INT, 2));
+      break;
+    case GSK_SL_TOKEN_IVEC3:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_INT, 3));
+      break;
+    case GSK_SL_TOKEN_IVEC4:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_INT, 4));
+      break;
+    case GSK_SL_TOKEN_UVEC2:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_UINT, 2));
+      break;
+    case GSK_SL_TOKEN_UVEC3:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_UINT, 3));
+      break;
+    case GSK_SL_TOKEN_UVEC4:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_UINT, 4));
+      break;
+    case GSK_SL_TOKEN_VEC2:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_FLOAT, 2));
+      break;
+    case GSK_SL_TOKEN_VEC3:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_FLOAT, 3));
+      break;
+    case GSK_SL_TOKEN_VEC4:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_FLOAT, 4));
+      break;
+    case GSK_SL_TOKEN_DVEC2:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_DOUBLE, 2));
+      break;
+    case GSK_SL_TOKEN_DVEC3:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_DOUBLE, 3));
+      break;
+    case GSK_SL_TOKEN_DVEC4:
+      type = gsk_sl_type_ref (gsk_sl_type_get_vector (GSK_SL_DOUBLE, 4));
+      break;
     default:
       gsk_sl_preprocessor_error (stream, "Expected type specifier");
       return NULL;
@@ -193,12 +308,58 @@ gsk_sl_type_new_parse (GskSlPreprocessor *stream)
   return type;
 }
 
+static GskSlTypeScalar
+builtin_scalar_types[N_SCALAR_TYPES] = {
+  [GSK_SL_VOID] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_VOID },
+  [GSK_SL_FLOAT] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_FLOAT },
+  [GSK_SL_DOUBLE] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_DOUBLE },
+  [GSK_SL_INT] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_INT },
+  [GSK_SL_UINT] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_UINT },
+  [GSK_SL_BOOL] = { { &GSK_SL_TYPE_SCALAR, 1 }, GSK_SL_BOOL },
+};
+
 GskSlType *
 gsk_sl_type_get_scalar (GskSlScalarType scalar)
 {
   g_assert (scalar < N_SCALAR_TYPES);
 
-  return &builtin_types[scalar].parent;
+  return &builtin_scalar_types[scalar].parent;
+}
+
+static GskSlTypeVector
+builtin_vector_types[3][N_SCALAR_TYPES] = {
+  {
+    [GSK_SL_FLOAT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_FLOAT, 2 },
+    [GSK_SL_DOUBLE] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_DOUBLE, 2 },
+    [GSK_SL_INT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_INT, 2 },
+    [GSK_SL_UINT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_UINT, 2 },
+    [GSK_SL_BOOL] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_BOOL, 2 },
+  },
+  {
+    [GSK_SL_FLOAT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_FLOAT, 3 },
+    [GSK_SL_DOUBLE] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_DOUBLE, 3 },
+    [GSK_SL_INT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_INT, 3 },
+    [GSK_SL_UINT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_UINT, 3 },
+    [GSK_SL_BOOL] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_BOOL, 3 },
+  },
+  {
+    [GSK_SL_FLOAT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_FLOAT, 4 },
+    [GSK_SL_DOUBLE] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_DOUBLE, 4 },
+    [GSK_SL_INT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_INT, 4 },
+    [GSK_SL_UINT] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_UINT, 4 },
+    [GSK_SL_BOOL] = { { &GSK_SL_TYPE_VECTOR, 1 }, GSK_SL_BOOL, 4 },
+  }
+};
+
+GskSlType *
+gsk_sl_type_get_vector (GskSlScalarType scalar,
+                        guint           length)
+{
+  g_assert (scalar < N_SCALAR_TYPES);
+  g_assert (scalar != GSK_SL_VOID);
+  g_assert (length >= 2 && length <= 4);
+
+  return &builtin_vector_types[length - 2][scalar].parent;
 }
 
 GskSlType *
diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h
index 238db3e..5f66763 100644
--- a/gsk/gsksltypeprivate.h
+++ b/gsk/gsksltypeprivate.h
@@ -36,6 +36,8 @@ typedef enum {
 
 GskSlType *             gsk_sl_type_new_parse                   (GskSlPreprocessor   *stream);
 GskSlType *             gsk_sl_type_get_scalar                  (GskSlScalarType      scalar);
+GskSlType *             gsk_sl_type_get_vector                  (GskSlScalarType      scalar,
+                                                                 guint                length);
 
 GskSlType *             gsk_sl_type_ref                         (GskSlType           *type);
 void                    gsk_sl_type_unref                       (GskSlType           *type);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]