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:
@@ -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 = {
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user