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.
This commit is contained in:
Benjamin Otte
2017-10-07 16:34:04 +02:00
parent 918ff3d58e
commit 807b63fded
3 changed files with 115 additions and 43 deletions

View File

@@ -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_add (writer,
GSK_SPV_WRITER_SECTION_CODE,
2, GSK_SPV_OP_LABEL,
(guint32[1]) { label_id });
#endif
g_assert_not_reached ();
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_push_code_block (writer, after_block);
gsk_spv_writer_commit_code_block (writer);
}
static const GskSlStatementClass GSK_SL_STATEMENT_IF = {

View File

@@ -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)
{

View File

@@ -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