[gtk+/wip/otte/shader: 170/226] gsksl: Implement subtraction



commit 4e61c71a5ae6f7a83f2188b1819dd30007e9b433
Author: Benjamin Otte <otte redhat com>
Date:   Wed Oct 11 17:33:55 2017 +0200

    gsksl: Implement subtraction

 gsk/gskslbinary.c |  239 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 232 insertions(+), 7 deletions(-)
---
diff --git a/gsk/gskslbinary.c b/gsk/gskslbinary.c
index 1b11a76..445723a 100644
--- a/gsk/gskslbinary.c
+++ b/gsk/gskslbinary.c
@@ -964,6 +964,238 @@ static const GskSlBinary GSK_SL_BINARY_ADDITION = {
   gsk_sl_addition_write_spv
 };
 
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_int, gint32, x -= y;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_uint, guint32, x -= y;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_float, float, x -= y;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_double, double, x -= y;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_int_inv, gint32, x = y - x;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_uint_inv, guint32, x = y - x;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_float_inv, float, x = y - x;)
+GSK_SL_BINARY_FUNC_SCALAR(gsk_sl_expression_subtraction_double_inv, double, x = y - x;)
+static void (* subtraction_funcs[]) (gpointer, gpointer) = {
+  [GSK_SL_INT] = gsk_sl_expression_subtraction_int,
+  [GSK_SL_UINT] = gsk_sl_expression_subtraction_uint,
+  [GSK_SL_FLOAT] = gsk_sl_expression_subtraction_float,
+  [GSK_SL_DOUBLE] = gsk_sl_expression_subtraction_double,
+};
+static void (* subtraction_inv_funcs[]) (gpointer, gpointer) = {
+  [GSK_SL_INT] = gsk_sl_expression_subtraction_int_inv,
+  [GSK_SL_UINT] = gsk_sl_expression_subtraction_uint_inv,
+  [GSK_SL_FLOAT] = gsk_sl_expression_subtraction_float_inv,
+  [GSK_SL_DOUBLE] = gsk_sl_expression_subtraction_double_inv,
+};
+
+static GskSlValue *
+gsk_sl_subtraction_get_constant (GskSlType  *type,
+                                 GskSlValue *lvalue,
+                                 GskSlValue *rvalue)
+{
+  GskSlValue *result;
+  GskSlType *ltype, *rtype;
+  GskSlScalarType scalar;
+  gsize ln, rn;
+
+  scalar = gsk_sl_type_get_scalar_type (type);
+  lvalue = gsk_sl_value_convert_components (lvalue, scalar);
+  rvalue = gsk_sl_value_convert_components (rvalue, scalar);
+  ltype = gsk_sl_value_get_type (lvalue);
+  rtype = gsk_sl_value_get_type (rvalue);
+
+  ln = gsk_sl_type_get_n_components (ltype);
+  rn = gsk_sl_type_get_n_components (rtype);
+  if (ln == 1)
+    {
+      gsk_sl_value_componentwise (rvalue, subtraction_inv_funcs[scalar], gsk_sl_value_get_data (lvalue));
+      gsk_sl_value_free (lvalue);
+      result = rvalue;
+    }
+  else if (rn == 1)
+    {
+      gsk_sl_value_componentwise (lvalue, subtraction_funcs[scalar], gsk_sl_value_get_data (rvalue));
+      gsk_sl_value_free (rvalue);
+      result = lvalue;
+    }
+  else
+    {
+      guchar *ldata, *rdata;
+      gsize i, stride;
+
+      stride = gsk_sl_scalar_type_get_size (scalar);
+      ldata = gsk_sl_value_get_data (lvalue);
+      rdata = gsk_sl_value_get_data (rvalue);
+      for (i = 0; i < ln; i++)
+        {
+          subtraction_funcs[scalar] (ldata + i * stride, rdata + i * stride);
+        }
+      gsk_sl_value_free (rvalue);
+      result = lvalue;
+    }
+
+  return result;
+}
+
+static guint32
+gsk_sl_subtraction_write_spv (GskSpvWriter *writer,
+                              GskSlType    *type,
+                              GskSlType    *ltype,
+                              guint32       left_id,
+                              GskSlType    *rtype,
+                              guint32       right_id)
+{
+  if (gsk_sl_type_get_scalar_type (ltype) != gsk_sl_type_get_scalar_type (type))
+    {
+      GskSlType *new_type = gsk_sl_type_get_matching (ltype, gsk_sl_type_get_scalar_type (type));
+      left_id = gsk_spv_writer_convert (writer, left_id, ltype, new_type);
+      ltype = new_type;
+    }
+  if (gsk_sl_type_get_scalar_type (rtype) != gsk_sl_type_get_scalar_type (type))
+    {
+      GskSlType *new_type = gsk_sl_type_get_matching (rtype, gsk_sl_type_get_scalar_type (type));
+      right_id = gsk_spv_writer_convert (writer, right_id, rtype, new_type);
+      rtype = new_type;
+    }
+
+  if (gsk_sl_type_is_matrix (ltype))
+    {
+      if (gsk_sl_type_is_matrix (rtype))
+        {
+          GskSlType *col_type = gsk_sl_type_get_index_type (ltype);
+          gsize cols = gsk_sl_type_get_length (ltype);
+          gsize c;
+          guint32 left_part_id, right_part_id, ids[cols];
+
+          for (c = 0; c < cols; c++)
+            {
+              left_part_id = gsk_spv_writer_composite_extract (writer, 
+                                                               col_type,
+                                                               left_id,
+                                                               (guint32[1]) { c }, 1);
+              right_part_id = gsk_spv_writer_composite_extract (writer, 
+                                                                col_type,
+                                                                right_id,
+                                                                (guint32[1]) { c }, 1);
+              ids[c] = gsk_spv_writer_f_sub (writer,
+                                             col_type,
+                                             left_part_id,
+                                             right_part_id);
+            }
+
+          return gsk_spv_writer_composite_construct (writer, 
+                                                     type,
+                                                     ids,
+                                                     cols);
+        }
+      else if (gsk_sl_type_is_scalar (rtype))
+        {
+          GskSlType *col_type = gsk_sl_type_get_index_type (ltype);
+          gsize cols = gsk_sl_type_get_length (ltype);
+          gsize c;
+          guint32 left_part_id, right_part_id, ids[cols];
+
+          right_part_id = gsk_spv_writer_composite_construct (writer,
+                                                              col_type,
+                                                              (guint32[4]) { right_id, right_id, right_id, 
right_id },
+                                                              gsk_sl_type_get_length (col_type));
+          for (c = 0; c < cols; c++)
+            {
+              left_part_id = gsk_spv_writer_composite_extract (writer, 
+                                                               col_type,
+                                                               left_id,
+                                                               (guint32[1]) { c }, 1);
+              ids[c] = gsk_spv_writer_f_sub (writer,
+                                             col_type,
+                                             left_part_id,
+                                             right_part_id);
+            }
+
+          return gsk_spv_writer_composite_construct (writer, 
+                                                     type,
+                                                     ids,
+                                                     cols);
+        }
+      else
+        {
+          g_assert_not_reached ();
+          return 0;
+        }
+    }
+  else if (gsk_sl_type_is_matrix (rtype))
+    {
+      GskSlType *col_type = gsk_sl_type_get_index_type (rtype);
+      gsize cols = gsk_sl_type_get_length (rtype);
+      gsize c;
+      guint32 left_part_id, right_part_id, ids[cols];
+
+      left_part_id = gsk_spv_writer_composite_construct (writer,
+                                                          col_type,
+                                                          (guint32[4]) { left_id, left_id, left_id, left_id 
},
+                                                          gsk_sl_type_get_length (col_type));
+      for (c = 0; c < cols; c++)
+        {
+          right_part_id = gsk_spv_writer_composite_extract (writer, 
+                                                            col_type,
+                                                            right_id,
+                                                            (guint32[1]) { c }, 1);
+          ids[c] = gsk_spv_writer_f_sub (writer,
+                                         col_type,
+                                         left_part_id,
+                                         right_part_id);
+        }
+
+      return gsk_spv_writer_composite_construct (writer, 
+                                                 type,
+                                                 ids,
+                                                 cols);
+    }
+  else
+    {
+      /* ltype and rtype are not matrices */
+
+      if (gsk_sl_type_is_scalar (ltype) && gsk_sl_type_is_vector (rtype))
+        {
+           guint32 tmp_id = gsk_spv_writer_composite_construct (writer,
+                                                                type,
+                                                                (guint32[4]) { left_id, left_id, left_id, 
left_id },
+                                                                gsk_sl_type_get_length (rtype));
+           left_id = tmp_id;
+        }
+      else if (gsk_sl_type_is_scalar (rtype) && gsk_sl_type_is_vector (ltype))
+        {
+           guint32 tmp_id = gsk_spv_writer_composite_construct (writer,
+                                                                type,
+                                                                (guint32[4]) { right_id, right_id, right_id, 
right_id },
+                                                                gsk_sl_type_get_length (ltype));
+           right_id = tmp_id;
+        }
+
+      /* ltype and rtype have the same number of components now */
+
+      switch (gsk_sl_type_get_scalar_type (type))
+        {
+        case GSK_SL_FLOAT:
+        case GSK_SL_DOUBLE:
+          return gsk_spv_writer_f_sub (writer, type, left_id, right_id);
+
+        case GSK_SL_INT:
+        case GSK_SL_UINT:
+          return gsk_spv_writer_i_sub (writer, type, left_id, right_id);
+
+        case GSK_SL_VOID:
+        case GSK_SL_BOOL:
+        default:
+          g_assert_not_reached ();
+          return 0;
+        }
+    }
+}
+
+static const GskSlBinary GSK_SL_BINARY_SUBTRACTION = {
+  "-",
+  gsk_sl_arithmetic_check_type,
+  gsk_sl_subtraction_get_constant,
+  gsk_sl_subtraction_write_spv
+};
+
 /* UNIMPLEMENTED */
 
 static GskSlType *
@@ -1159,13 +1391,6 @@ static const GskSlBinary GSK_SL_BINARY_MODULO = {
   gsk_sl_unimplemented_write_spv
 };
 
-static const GskSlBinary GSK_SL_BINARY_SUBTRACTION = {
-  "-",
-  gsk_sl_arithmetic_check_type,
-  gsk_sl_unimplemented_get_constant,
-  gsk_sl_unimplemented_write_spv
-};
-
 static const GskSlBinary GSK_SL_BINARY_LSHIFT = {
   "<<",
   gsk_sl_shift_check_type,


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