[gtk+/wip/otte/shader: 138/176] gskspv: Change the way we deal with labels



commit 213e4038be17f217ab6b3caf6443c26c13de9248
Author: Benjamin Otte <otte redhat com>
Date:   Mon Oct 16 22:15:27 2017 +0200

    gskspv: Change the way we deal with labels
    
    Instead of having a code block abstraction, just make code deal with
    label ids instead. that way, code can just use gsk_spv_writer_make_id()
    and pass that ID to the label func.
    
    This simplifies code a lot as it allows special treatment of those
    labels at eg the beginning of functions which can be kept local to where
    it happens.

 gsk/gskslexpression.c              |   42 ++++++------------
 gsk/gskslfunction.c                |    8 ++--
 gsk/gskslstatement.c               |   52 ++++++++---------------
 gsk/gskspvwriter.c                 |   81 +++++++++++++----------------------
 gsk/gskspvwritergeneratedprivate.h |   10 ++---
 gsk/gskspvwriterprivate.h          |   16 +++----
 gsk/spirv.js                       |   16 ++++----
 7 files changed, 84 insertions(+), 141 deletions(-)
---
diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c
index 148acd2..a4593f0 100644
--- a/gsk/gskslexpression.c
+++ b/gsk/gskslexpression.c
@@ -362,32 +362,25 @@ gsk_sl_expression_logical_and_write_spv (const GskSlExpression *expression,
                                         GskSpvWriter          *writer)
 {
   const GskSlExpressionLogicalAnd *logical_and = (const GskSlExpressionLogicalAnd *) expression;
-  GskSpvCodeBlock *current_block, *after_block, *and_block;
   guint32 current_id, after_id, and_id, left_id, right_id, result_id;
 
   left_id = gsk_sl_expression_write_spv (logical_and->left, writer);
 
-  current_block = gsk_spv_writer_pop_code_block (writer);
-  current_id = gsk_spv_code_block_get_label (current_block);
-  gsk_spv_writer_push_code_block (writer, current_block);
-
-  and_id = gsk_spv_writer_push_new_code_block (writer);
-  and_block = gsk_spv_writer_pop_code_block (writer);
-
-  after_id = gsk_spv_writer_push_new_code_block (writer);
-  after_block = gsk_spv_writer_pop_code_block (writer);
+  current_id = gsk_spv_writer_get_label_id (writer);
+  and_id = gsk_spv_writer_make_id (writer);
+  after_id = gsk_spv_writer_make_id (writer);
 
   /* mirror glslang */
   gsk_spv_writer_selection_merge (writer, after_id, 0);
   gsk_spv_writer_branch_conditional (writer, left_id, and_id, after_id, NULL, 0);
 
-  gsk_spv_writer_push_code_block (writer, and_block);
+  gsk_spv_writer_start_code_block (writer, and_id, 0, 0);
+  gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, and_id);
   right_id = gsk_sl_expression_write_spv (logical_and->right, writer);
   gsk_spv_writer_branch (writer, after_id);
-  gsk_spv_writer_commit_code_block (writer);
 
-  gsk_spv_writer_push_code_block (writer, after_block);
-  gsk_spv_writer_commit_code_block (writer);
+  gsk_spv_writer_start_code_block (writer, after_id, 0, 0);
+  gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, after_id);
 
   result_id = gsk_spv_writer_phi (writer, 
                                   gsk_sl_type_get_scalar (GSK_SL_BOOL),
@@ -482,33 +475,26 @@ gsk_sl_expression_logical_or_write_spv (const GskSlExpression *expression,
                                         GskSpvWriter          *writer)
 {
   const GskSlExpressionLogicalOr *logical_or = (const GskSlExpressionLogicalOr *) expression;
-  GskSpvCodeBlock *current_block, *after_block, *or_block;
   guint32 current_id, condition_id, after_id, or_id, left_id, right_id, result_id;
 
   left_id = gsk_sl_expression_write_spv (logical_or->left, writer);
 
-  current_block = gsk_spv_writer_pop_code_block (writer);
-  current_id = gsk_spv_code_block_get_label (current_block);
-  gsk_spv_writer_push_code_block (writer, current_block);
-
-  or_id = gsk_spv_writer_push_new_code_block (writer);
-  or_block = gsk_spv_writer_pop_code_block (writer);
-
-  after_id = gsk_spv_writer_push_new_code_block (writer);
-  after_block = gsk_spv_writer_pop_code_block (writer);
+  current_id = gsk_spv_writer_get_label_id (writer);
+  or_id = gsk_spv_writer_make_id (writer);
+  after_id = gsk_spv_writer_make_id (writer);
 
   /* mirror glslang */
   condition_id = gsk_spv_writer_logical_not (writer, gsk_sl_type_get_scalar (GSK_SL_BOOL), left_id);
   gsk_spv_writer_selection_merge (writer, after_id, 0);
   gsk_spv_writer_branch_conditional (writer, condition_id, or_id, after_id, NULL, 0);
 
-  gsk_spv_writer_push_code_block (writer, or_block);
+  gsk_spv_writer_start_code_block (writer, or_id, 0, 0);
+  gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, or_id);
   right_id = gsk_sl_expression_write_spv (logical_or->right, writer);
   gsk_spv_writer_branch (writer, after_id);
-  gsk_spv_writer_commit_code_block (writer);
 
-  gsk_spv_writer_push_code_block (writer, after_block);
-  gsk_spv_writer_commit_code_block (writer);
+  gsk_spv_writer_start_code_block (writer, after_id, 0, 0);
+  gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, after_id);
 
   result_id = gsk_spv_writer_phi (writer, 
                                   gsk_sl_type_get_scalar (GSK_SL_BOOL),
diff --git a/gsk/gskslfunction.c b/gsk/gskslfunction.c
index 7696b09..c64b7af 100644
--- a/gsk/gskslfunction.c
+++ b/gsk/gskslfunction.c
@@ -424,7 +424,7 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
                                     gpointer             initializer_data)
 {
   GskSlFunctionDeclared *declared = (GskSlFunctionDeclared *) function;
-  guint32 function_type_id, function_id;
+  guint32 function_type_id, function_id, label_id;
   GskSlType *return_type;
   gsize i;
 
@@ -447,7 +447,9 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
   gsk_spv_writer_name (writer, function_id, declared->name);
 
   /* add function body */
-  gsk_spv_writer_push_new_code_block (writer);
+  label_id = gsk_spv_writer_make_id (writer);
+  gsk_spv_writer_start_code_block (writer, label_id, 0, 0);
+  gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_DECLARE, label_id);
 
   if (initializer)
     initializer (writer, initializer_data);
@@ -457,8 +459,6 @@ gsk_sl_function_declared_write_spv (const GskSlFunction *function,
 
   gsk_spv_writer_function_end (writer);
 
-  gsk_spv_writer_commit_code_block (writer);
-
   return function_id;
 }
 
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index f230dfe..cc54593 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -403,53 +403,35 @@ gsk_sl_statement_if_write_spv (const GskSlStatement *statement,
                                GskSpvWriter         *writer)
 {
   GskSlStatementIf *if_stmt = (GskSlStatementIf *) statement;
-  guint32 if_id, else_id, condition_id;
-  GskSpvCodeBlock *if_block, *else_block, *after_block;
+  guint32 if_id, else_id, after_id, condition_id;
 
   condition_id = gsk_sl_expression_write_spv (if_stmt->condition, writer);
 
-  gsk_spv_writer_push_new_code_block (writer);
-  if_block  = gsk_spv_writer_pop_code_block (writer);
-  if_id = gsk_spv_code_block_get_label (if_block);
-  gsk_spv_writer_push_new_code_block (writer);
-  after_block = gsk_spv_writer_pop_code_block (writer);
-
-  gsk_spv_writer_push_code_block (writer, if_block);
-  if (!gsk_sl_statement_write_spv (if_stmt->if_part, writer))
-    gsk_spv_writer_branch (writer,
-                           gsk_spv_code_block_get_label (after_block));
-  gsk_spv_writer_pop_code_block (writer);
-
+  if_id = gsk_spv_writer_make_id (writer);
+  after_id = gsk_spv_writer_make_id (writer);
   if (if_stmt->else_part)
-    {
-      else_id = gsk_spv_writer_push_new_code_block (writer);
-      if (!gsk_sl_statement_write_spv (if_stmt->else_part, writer))
-        gsk_spv_writer_branch (writer, 
-                               gsk_spv_code_block_get_label (after_block));
-      else_block = gsk_spv_writer_pop_code_block (writer);
-    }
+    else_id = gsk_spv_writer_make_id (writer);
   else
-    {
-      else_id = gsk_spv_code_block_get_label (after_block);
-      else_block = NULL;
-    }
+    else_id = after_id;
 
-  gsk_spv_writer_selection_merge (writer,
-                                  gsk_spv_code_block_get_label (after_block),
-                                  0);
+  gsk_spv_writer_selection_merge (writer, after_id, 0);
   gsk_spv_writer_branch_conditional (writer, condition_id, if_id, else_id, NULL, 0);
 
-  gsk_spv_writer_push_code_block (writer, if_block);
-  gsk_spv_writer_commit_code_block (writer);
+  gsk_spv_writer_start_code_block (writer, if_id, 0, 0);
+  gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, if_id);
+  if (!gsk_sl_statement_write_spv (if_stmt->if_part, writer))
+    gsk_spv_writer_branch (writer, after_id);
 
-  if (else_block)
+  if (if_stmt->else_part)
     {
-      gsk_spv_writer_push_code_block (writer, else_block);
-      gsk_spv_writer_commit_code_block (writer);
+      gsk_spv_writer_start_code_block (writer, else_id, 0, 0);
+      gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, else_id);
+      if (!gsk_sl_statement_write_spv (if_stmt->else_part, writer))
+        gsk_spv_writer_branch (writer, after_id);
     }
 
-  gsk_spv_writer_push_code_block (writer, after_block);
-  gsk_spv_writer_commit_code_block (writer);
+  gsk_spv_writer_start_code_block (writer, after_id, 0, 0);
+  gsk_spv_writer_label (writer, GSK_SPV_WRITER_SECTION_CODE, after_id);
 
   return FALSE;
 }
diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c
index 3bfb3de..625d1eb 100644
--- a/gsk/gskspvwriter.c
+++ b/gsk/gskspvwriter.c
@@ -27,6 +27,7 @@
 #include "gskslvalueprivate.h"
 #include "gskslvariableprivate.h"
 
+typedef struct _GskSpvCodeBlock GskSpvCodeBlock;
 typedef struct _GskSpvPointerType GskSpvPointerType;
 
 struct _GskSpvPointerType
@@ -39,7 +40,9 @@ struct _GskSpvCodeBlock
 {
   GArray *code[GSK_SPV_WRITER_N_BLOCK_SECTIONS];
 
-  guint32 label;
+  guint32 label_id;
+  guint32 continue_id;
+  guint32 break_id;
 };
 
 struct _GskSpvWriter
@@ -199,13 +202,11 @@ gsk_spv_writer_write_function (GskSpvWriter     *writer,
   g_assert (g_hash_table_lookup (writer->functions, function) == NULL);
 
   block = gsk_spv_code_block_new ();
-  gsk_spv_writer_push_code_block (writer, block);
+  writer->blocks = g_slist_prepend (writer->blocks, block);
   result = gsk_sl_function_write_spv (function, writer, initializer, initializer_data);
   g_hash_table_insert (writer->functions, gsk_sl_function_ref (function), GUINT_TO_POINTER (result));
-  if (block != gsk_spv_writer_pop_code_block (writer))
-    {
-      g_assert_not_reached ();
-    }
+  g_assert (writer->blocks->data == block);
+  writer->blocks = g_slist_remove (writer->blocks, block);
   writer->pending_blocks = g_slist_prepend (writer->pending_blocks, block);
 
   return result;
@@ -544,67 +545,45 @@ gsk_spv_writer_get_bytes (GskSpvWriter        *writer,
   return ((GskSpvCodeBlock *) writer->blocks->data)->code[section - GSK_SPV_WRITER_SECTION_BLOCK_FIRST];
 }
 
-guint32
-gsk_spv_writer_push_new_code_block (GskSpvWriter *writer)
+void
+gsk_spv_writer_start_code_block (GskSpvWriter *writer,
+                                 guint32       label_id,
+                                 guint32       continue_id,
+                                 guint32       break_id)
 {
   GskSpvCodeBlock *block;
-  GskSpvWriterSection label_section;
-
-  block = gsk_spv_code_block_new ();
-  /* This is ugly code that ensures the function block label
-   * goes before variables but subblock labels do not.
-   */
-  if (writer->blocks && writer->blocks->next)
-    label_section = GSK_SPV_WRITER_SECTION_CODE;
-  else
-    label_section = GSK_SPV_WRITER_SECTION_DECLARE;
-
-  gsk_spv_writer_push_code_block (writer, block);
 
-  block->label = gsk_spv_writer_label (writer, label_section);
+  block = writer->blocks->data;
 
-  return block->label;
+  block->label_id = label_id;
+  if (continue_id != 0)
+    block->continue_id = continue_id;
+  if (break_id != 0)
+    block->break_id = break_id;
 }
 
-void
-gsk_spv_writer_push_code_block (GskSpvWriter    *writer,
-                                GskSpvCodeBlock *block)
-{
-  writer->blocks = g_slist_prepend (writer->blocks, block);
-}
-
-GskSpvCodeBlock *
-gsk_spv_writer_pop_code_block (GskSpvWriter *writer)
+guint32
+gsk_spv_writer_get_label_id (GskSpvWriter *writer)
 {
-  GskSpvCodeBlock *result;
-
-  result = writer->blocks->data;
-  g_assert (result);
+  GskSpvCodeBlock *block = writer->blocks->data;
 
-  writer->blocks = g_slist_remove (writer->blocks, result);
-
-  return result;
+  return block->label_id;
 }
 
-void
-gsk_spv_writer_commit_code_block (GskSpvWriter *writer)
+guint32
+gsk_spv_writer_get_continue_id (GskSpvWriter *writer)
 {
-  GskSpvCodeBlock *block, *target;
-  guint i;
-
-  block = gsk_spv_writer_pop_code_block (writer);
-  target = writer->blocks->data;
+  GskSpvCodeBlock *block = writer->blocks->data;
 
-  for (i = 0; i < GSK_SPV_WRITER_N_BLOCK_SECTIONS; i++)
-    g_array_append_vals (target->code[i], block->code[i]->data, block->code[i]->len);
-
-  gsk_spv_code_block_free (block);
+  return block->continue_id;
 }
 
 guint32
-gsk_spv_code_block_get_label (GskSpvCodeBlock *block)
+gsk_spv_writer_get_break_id (GskSpvWriter *writer)
 {
-  return block->label;
+  GskSpvCodeBlock *block = writer->blocks->data;
+
+  return block->break_id;
 }
 
 static void
diff --git a/gsk/gskspvwritergeneratedprivate.h b/gsk/gskspvwritergeneratedprivate.h
index 5985b01..469ba56 100644
--- a/gsk/gskspvwritergeneratedprivate.h
+++ b/gsk/gskspvwritergeneratedprivate.h
@@ -4511,19 +4511,17 @@ gsk_spv_writer_selection_merge (GskSpvWriter *writer,
   g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | 
GSK_SPV_OP_SELECTION_MERGE;
 }
 
-static inline guint32
+static inline void
 gsk_spv_writer_label (GskSpvWriter *writer,
-                      GskSpvWriterSection section)
+                      GskSpvWriterSection section,
+                      guint32 result)
 {
   GArray *bytes = gsk_spv_writer_get_bytes (writer, section);
-  guint32 result_id = gsk_spv_writer_make_id (writer);
   guint start_index = bytes->len;
 
   g_array_append_val (bytes, (guint32) { 0 });
-  g_array_append_val (bytes, result_id);
+  g_array_append_val (bytes, result);
   g_array_index (bytes, guint32, start_index) = (bytes->len - start_index) << 16 | GSK_SPV_OP_LABEL;
-
-  return result_id;
 }
 
 static inline void
diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h
index e7b541b..f745362 100644
--- a/gsk/gskspvwriterprivate.h
+++ b/gsk/gskspvwriterprivate.h
@@ -32,8 +32,6 @@ G_BEGIN_DECLS
 #define GSK_SPV_VERSION_MINOR 0
 #define GSK_SPV_GENERATOR 0
 
-typedef struct _GskSpvCodeBlock GskSpvCodeBlock;
-
 typedef enum {
   GSK_SPV_WRITER_SECTION_HEADER,
   GSK_SPV_WRITER_SECTION_DEBUG,
@@ -88,13 +86,13 @@ guint32                 gsk_spv_writer_convert                  (GskSpvWriter
                                                                  GskSlType              *type,
                                                                  GskSlType              *new_type);
 
-guint32                 gsk_spv_writer_push_new_code_block      (GskSpvWriter           *writer);
-void                    gsk_spv_writer_push_code_block          (GskSpvWriter           *writer,
-                                                                 GskSpvCodeBlock        *block);
-GskSpvCodeBlock *       gsk_spv_writer_pop_code_block           (GskSpvWriter           *writer);
-void                    gsk_spv_writer_commit_code_block        (GskSpvWriter           *writer);
-
-guint32                 gsk_spv_code_block_get_label            (GskSpvCodeBlock        *block);
+guint32                 gsk_spv_writer_get_label_id             (GskSpvWriter           *writer);
+guint32                 gsk_spv_writer_get_continue_id          (GskSpvWriter           *writer);
+guint32                 gsk_spv_writer_get_break_id             (GskSpvWriter           *writer);
+void                    gsk_spv_writer_start_code_block         (GskSpvWriter           *writer,
+                                                                 guint32                 label_id,
+                                                                 guint32                 continue_id,
+                                                                 guint32                 break_id);
 
 GskSpvAccessChain *     gsk_spv_access_chain_new                (GskSpvWriter           *writer,
                                                                  GskSlVariable          *variable);
diff --git a/gsk/spirv.js b/gsk/spirv.js
index c67451a..acef648 100644
--- a/gsk/spirv.js
+++ b/gsk/spirv.js
@@ -91,7 +91,8 @@ var SpecialTypes = {
   "OpPtrCastToGeneric": { "result_type": "IdResultPointerType" },
   "OpGenericCastToPtr": { "result_type": "IdResultPointerType" },
   "OpGenericCastToPtrExplicit": { "result_type": "IdResultPointerType" },
-  "OpFunctionParameter": { "result_type": "IdRef" }
+  "OpFunctionParameter": { "result_type": "IdRef" },
+  "OpLabel": { "result": "IdRef" }
 };
 
 var ExtraOperands = {
@@ -497,18 +498,17 @@ function fix_operand (ins, o)
     }
   if (!o.varname)
     throw new TypeError (o.name + " of type " + o.kind + " has no variable name");
+  let operand;
+  if (SpecialTypes[ins.opname] &&
+      SpecialTypes[ins.opname][o.varname])
+    o.kind = SpecialTypes[ins.opname][o.varname];
+  operand = Operands[o.kind];
+
   if (o.varname == "default")
     o.varname += "_";
   if (o.kind == "IdResult")
     ins.result = true;
 
-  let operand;
-  if (SpecialTypes[ins.opname] &&
-      SpecialTypes[ins.opname][o.varname])
-    operand = Operands[SpecialTypes[ins.opname][o.varname]];
-  else
-    operand = Operands[o.kind];
-
   o.ctype = operand.ctype;
   if (operand.append_one)
     o.append_one = operand.append_one;


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