[gtk+/wip/otte/shader: 15/101] gskspv: Add GskSpvCodeBlock



commit cdab5b5900cccf895e53a7608e2f11dc261ea7a7
Author: Benjamin Otte <otte redhat com>
Date:   Sat Oct 7 16:34:04 2017 +0200

    gskspv: Add GskSpvCodeBlock
    
    This represents a block of code. For now it's only used for if
    statements (which are now enabled again), but in future commits
    writing of function blocks will use it, too.

 gsk/gskslstatement.c      |   81 +++++++++++++++++++++------------------------
 gsk/gskspvwriter.c        |   69 +++++++++++++++++++++++++++++++++++++-
 gsk/gskspvwriterprivate.h |   10 +++++
 3 files changed, 116 insertions(+), 44 deletions(-)
---
diff --git a/gsk/gskslstatement.c b/gsk/gskslstatement.c
index 128e35a..6ed888b 100644
--- a/gsk/gskslstatement.c
+++ b/gsk/gskslstatement.c
@@ -392,59 +392,54 @@ static void
 gsk_sl_statement_if_write_spv (const GskSlStatement *statement,
                                GskSpvWriter         *writer)
 {
-#if 0 
   GskSlStatementIf *if_stmt = (GskSlStatementIf *) statement;
-  guint32 label_id, if_id, else_id, condition_id;
+  guint32 if_id, else_id, condition_id;
+  GskSpvCodeBlock *if_block, *else_block, *after_block;
 
   condition_id = gsk_sl_expression_write_spv (if_stmt->condition, writer);
-  if_id = gsk_spv_writer_next_id (writer);
-  else_id = gsk_spv_writer_next_id (writer);
-  /* We compute the labels in this funny order to match what glslang does */
-  if (if_stmt->else_part)
-    label_id = gsk_spv_writer_next_id (writer);
-  else
-    label_id = else_id;
-  gsk_spv_writer_add (writer,
-                      GSK_SPV_WRITER_SECTION_CODE,
-                      3, GSK_SPV_OP_SELECTION_MERGE,
-                      (guint32[2]) { label_id,
-                                     0});
-  gsk_spv_writer_add (writer,
-                      GSK_SPV_WRITER_SECTION_CODE,
-                      4, GSK_SPV_OP_BRANCH_CONDITIONAL,
-                      (guint32[3]) { condition_id,
-                                     if_id,
-                                     else_id });
-
-  gsk_spv_writer_add (writer,
-                      GSK_SPV_WRITER_SECTION_CODE,
-                      2, GSK_SPV_OP_LABEL,
-                      (guint32[1]) { if_id });
+
+  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);
   gsk_sl_statement_write_spv (if_stmt->if_part, writer);
-  gsk_spv_writer_add (writer,
-                      GSK_SPV_WRITER_SECTION_CODE,
-                      2, GSK_SPV_OP_BRANCH,
-                      (guint32[1]) { label_id });
+  gsk_spv_writer_branch (writer,
+                         gsk_spv_code_block_get_label (after_block));
+  gsk_spv_writer_pop_code_block (writer);
 
   if (if_stmt->else_part)
     {
-      gsk_spv_writer_add (writer,
-                          GSK_SPV_WRITER_SECTION_CODE,
-                          2, GSK_SPV_OP_LABEL,
-                          (guint32[1]) { else_id });
+      else_id = gsk_spv_writer_push_new_code_block (writer);
       gsk_sl_statement_write_spv (if_stmt->else_part, writer);
-      gsk_spv_writer_add (writer,
-                          GSK_SPV_WRITER_SECTION_CODE,
-                          2, GSK_SPV_OP_BRANCH,
-                          (guint32[1]) { label_id });
+      gsk_spv_writer_branch (writer, 
+                             gsk_spv_code_block_get_label (after_block));
+      else_block = gsk_spv_writer_pop_code_block (writer);
+    }
+  else
+    {
+      else_id = gsk_spv_code_block_get_label (after_block);
+      else_block = NULL;
+    }
+
+  gsk_spv_writer_selection_merge (writer,
+                                  gsk_spv_code_block_get_label (after_block),
+                                  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);
+
+  if (else_block)
+    {
+      gsk_spv_writer_push_code_block (writer, else_block);
+      gsk_spv_writer_commit_code_block (writer);
     }
 
-  gsk_spv_writer_add (writer,
-                      GSK_SPV_WRITER_SECTION_CODE,
-                      2, GSK_SPV_OP_LABEL,
-                      (guint32[1]) { label_id });
-#endif
-  g_assert_not_reached ();
+  gsk_spv_writer_push_code_block (writer, after_block);
+  gsk_spv_writer_commit_code_block (writer);
 }
 
 static const GskSlStatementClass GSK_SL_STATEMENT_IF = {
diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c
index d68cabd..6249bf2 100644
--- a/gsk/gskspvwriter.c
+++ b/gsk/gskspvwriter.c
@@ -25,12 +25,20 @@
 #include "gskslvalueprivate.h"
 #include "gskslvariableprivate.h"
 
+struct _GskSpvCodeBlock
+{
+  GArray *code;
+
+  guint32 label;
+};
+
 struct _GskSpvWriter
 {
   int ref_count;
 
   guint32 last_id;
   GArray *code[GSK_SPV_WRITER_N_SECTIONS];
+  GSList *blocks;
 
   guint32 entry_point;
   GHashTable *types;
@@ -50,7 +58,7 @@ gsk_spv_writer_new (void)
 
   for (i = 0; i < GSK_SPV_WRITER_N_SECTIONS; i++)
     {
-      writer->code[i] = g_array_new (FALSE, FALSE, sizeof (guint32));
+      writer->code[i] = g_array_new (FALSE, TRUE, sizeof (guint32));
     }
 
   writer->types = g_hash_table_new_full (gsk_sl_type_hash, gsk_sl_type_equal,
@@ -293,9 +301,68 @@ GArray *
 gsk_spv_writer_get_bytes (GskSpvWriter        *writer,
                           GskSpvWriterSection  section)
 {
+  if (section == GSK_SPV_WRITER_SECTION_CODE && writer->blocks)
+    return ((GskSpvCodeBlock *) writer->blocks->data)->code;
   return writer->code[section];
 }
 
+guint32
+gsk_spv_writer_push_new_code_block (GskSpvWriter *writer)
+{
+  GskSpvCodeBlock *block;
+
+  block = g_slice_new0 (GskSpvCodeBlock);
+  block->code = g_array_new (FALSE, TRUE, sizeof (guint32));
+
+  gsk_spv_writer_push_code_block (writer, block);
+
+  block->label = gsk_spv_writer_label (writer);
+
+  return block->label;
+}
+
+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)
+{
+  GskSpvCodeBlock *result;
+
+  result = writer->blocks->data;
+  g_assert (result);
+
+  writer->blocks = g_slist_remove (writer->blocks, result);
+
+  return result;
+}
+
+void
+gsk_spv_writer_commit_code_block (GskSpvWriter *writer)
+{
+  GskSpvCodeBlock *block;
+  GArray *commit_target;
+
+  block = gsk_spv_writer_pop_code_block (writer);
+
+  commit_target = gsk_spv_writer_get_bytes (writer, GSK_SPV_WRITER_SECTION_CODE);
+  g_array_append_vals (commit_target, block->code->data, block->code->len);
+
+  g_array_free (block->code, TRUE);
+
+  g_slice_free (GskSpvCodeBlock, block);
+}
+
+guint32
+gsk_spv_code_block_get_label (GskSpvCodeBlock *block)
+{
+  return block->label;
+}
+
 static void
 copy_4_bytes (gpointer dest, gpointer src)
 {
diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h
index 6be694b..29e430a 100644
--- a/gsk/gskspvwriterprivate.h
+++ b/gsk/gskspvwriterprivate.h
@@ -31,6 +31,8 @@ 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,
@@ -73,6 +75,14 @@ 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);
+
 #include "gskspvwritergeneratedprivate.h"
 
 G_END_DECLS


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