gsksl: Add support for parsing blocks
This commit is contained in:
@@ -76,15 +76,6 @@ gsk_sl_pointer_type_unref (GskSlPointerType *type)
|
||||
g_slice_free (GskSlPointerType, type);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_pointer_type_print (const GskSlPointerType *type,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
if (gsk_sl_qualifier_print (&type->qualifier, printer))
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_name (type->type));
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_pointer_type_get_type (const GskSlPointerType *type)
|
||||
{
|
||||
|
||||
@@ -32,9 +32,6 @@ GskSlPointerType * gsk_sl_pointer_type_new (GskSlTy
|
||||
GskSlPointerType * gsk_sl_pointer_type_ref (GskSlPointerType *type);
|
||||
void gsk_sl_pointer_type_unref (GskSlPointerType *type);
|
||||
|
||||
void gsk_sl_pointer_type_print (const GskSlPointerType *type,
|
||||
GskSlPrinter *printer);
|
||||
|
||||
GskSlType * gsk_sl_pointer_type_get_type (const GskSlPointerType *type);
|
||||
const GskSlQualifier * gsk_sl_pointer_type_get_qualifier (const GskSlPointerType *type);
|
||||
|
||||
|
||||
330
gsk/gsksltype.c
330
gsk/gsksltype.c
@@ -1210,6 +1210,201 @@ static const GskSlTypeClass GSK_SL_TYPE_STRUCT = {
|
||||
gsk_sl_type_struct_write_value_spv
|
||||
};
|
||||
|
||||
/* BLOCK */
|
||||
|
||||
typedef struct _GskSlTypeBlock GskSlTypeBlock;
|
||||
|
||||
struct _GskSlTypeBlock {
|
||||
GskSlType parent;
|
||||
|
||||
char *name;
|
||||
gsize size;
|
||||
|
||||
GskSlTypeMember *members;
|
||||
guint n_members;
|
||||
};
|
||||
|
||||
static void
|
||||
gsk_sl_type_block_free (GskSlType *type)
|
||||
{
|
||||
GskSlTypeBlock *block = (GskSlTypeBlock *) type;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < block->n_members; i++)
|
||||
{
|
||||
gsk_sl_type_unref (block->members[i].type);
|
||||
g_free (block->members[i].name);
|
||||
}
|
||||
|
||||
g_free (block->members);
|
||||
g_free (block->name);
|
||||
|
||||
g_slice_free (GskSlTypeBlock, block);
|
||||
}
|
||||
|
||||
static const char *
|
||||
gsk_sl_type_block_get_name (const GskSlType *type)
|
||||
{
|
||||
GskSlTypeBlock *block = (GskSlTypeBlock *) type;
|
||||
|
||||
return block->name;
|
||||
}
|
||||
|
||||
static GskSlScalarType
|
||||
gsk_sl_type_block_get_scalar_type (const GskSlType *type)
|
||||
{
|
||||
return GSK_SL_VOID;
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_type_block_get_index_type (const GskSlType *type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_sl_type_block_get_index_stride (const GskSlType *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_type_block_get_length (const GskSlType *type)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static gsize
|
||||
gsk_sl_type_block_get_size (const GskSlType *type)
|
||||
{
|
||||
const GskSlTypeBlock *block = (const GskSlTypeBlock *) type;
|
||||
|
||||
return block->size;
|
||||
}
|
||||
|
||||
static guint
|
||||
gsk_sl_type_block_get_n_members (const GskSlType *type)
|
||||
{
|
||||
const GskSlTypeBlock *block = (const GskSlTypeBlock *) type;
|
||||
|
||||
return block->n_members;
|
||||
}
|
||||
|
||||
static const GskSlTypeMember *
|
||||
gsk_sl_type_block_get_member (const GskSlType *type,
|
||||
guint n)
|
||||
{
|
||||
const GskSlTypeBlock *block = (const GskSlTypeBlock *) type;
|
||||
|
||||
return &block->members[n];
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gsk_sl_type_block_can_convert (const GskSlType *target,
|
||||
const GskSlType *source)
|
||||
{
|
||||
return gsk_sl_type_equal (target, source);
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_type_block_write_spv (GskSlType *type,
|
||||
GskSpvWriter *writer)
|
||||
{
|
||||
GskSlTypeBlock *block = (GskSlTypeBlock *) type;
|
||||
guint32 ids[block->n_members + 1];
|
||||
guint i;
|
||||
|
||||
ids[0] = gsk_spv_writer_next_id (writer);
|
||||
|
||||
for (i = 0; i < block->n_members; i++)
|
||||
{
|
||||
ids[i + 1] = gsk_spv_writer_get_id_for_type (writer, block->members[i].type);
|
||||
}
|
||||
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_DEBUG,
|
||||
3, GSK_SPV_OP_DECORATE,
|
||||
(guint32[2]) { ids[0],
|
||||
GSK_SPV_DECORATION_BLOCK });
|
||||
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_DECLARE,
|
||||
2 + block->n_members, GSK_SPV_OP_TYPE_STRUCT,
|
||||
ids);
|
||||
|
||||
return ids[0];
|
||||
}
|
||||
|
||||
static void
|
||||
gsk_sl_type_block_print_value (const GskSlType *type,
|
||||
GskSlPrinter *printer,
|
||||
gconstpointer value)
|
||||
{
|
||||
const GskSlTypeBlock *block = (const GskSlTypeBlock *) type;
|
||||
guint i;
|
||||
|
||||
gsk_sl_printer_append (printer, block->name);
|
||||
gsk_sl_printer_append (printer, "(");
|
||||
|
||||
for (i = 0; i < block->n_members; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
gsk_sl_printer_append (printer, ", ");
|
||||
gsk_sl_type_print_value (block->members[i].type,
|
||||
printer,
|
||||
(guchar *) value + block->members[i].offset);
|
||||
}
|
||||
|
||||
gsk_sl_printer_append (printer, ")");
|
||||
}
|
||||
|
||||
static guint32
|
||||
gsk_sl_type_block_write_value_spv (GskSlType *type,
|
||||
GskSpvWriter *writer,
|
||||
gconstpointer value)
|
||||
{
|
||||
GskSlTypeBlock *block = (GskSlTypeBlock *) type;
|
||||
guint32 ids[block->n_members + 2];
|
||||
GskSlValue *v;
|
||||
guint i;
|
||||
|
||||
ids[0] = gsk_spv_writer_get_id_for_type (writer, type);
|
||||
for (i = 0; i < block->n_members; i++)
|
||||
{
|
||||
v = gsk_sl_value_new_for_data (block->members[i].type,
|
||||
(guchar *) value + block->members[i].offset,
|
||||
NULL, NULL);
|
||||
ids[2 + i] = gsk_spv_writer_get_id_for_value (writer, v);
|
||||
gsk_sl_value_free (v);
|
||||
}
|
||||
|
||||
ids[1] = gsk_spv_writer_next_id (writer);
|
||||
|
||||
gsk_spv_writer_add (writer,
|
||||
GSK_SPV_WRITER_SECTION_DECLARE,
|
||||
3 + block->n_members,
|
||||
GSK_SPV_OP_CONSTANT_COMPOSITE,
|
||||
ids);
|
||||
|
||||
return ids[1];
|
||||
}
|
||||
|
||||
static const GskSlTypeClass GSK_SL_TYPE_BLOCK = {
|
||||
gsk_sl_type_block_free,
|
||||
gsk_sl_type_block_get_name,
|
||||
gsk_sl_type_block_get_scalar_type,
|
||||
gsk_sl_type_block_get_index_type,
|
||||
gsk_sl_type_block_get_index_stride,
|
||||
gsk_sl_type_block_get_length,
|
||||
gsk_sl_type_block_get_size,
|
||||
gsk_sl_type_block_get_n_members,
|
||||
gsk_sl_type_block_get_member,
|
||||
gsk_sl_type_block_can_convert,
|
||||
gsk_sl_type_block_write_spv,
|
||||
gsk_sl_type_block_print_value,
|
||||
gsk_sl_type_block_write_value_spv
|
||||
};
|
||||
|
||||
/* API */
|
||||
|
||||
static GskSlType *
|
||||
@@ -1311,6 +1506,85 @@ out:
|
||||
return type;
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_type_parse_block (GskSlScope *scope,
|
||||
GskSlPreprocessor *preproc)
|
||||
{
|
||||
GskSlType *type;
|
||||
const GskSlToken *token;
|
||||
GskSlTypeBuilder *builder;
|
||||
|
||||
if (!gsk_sl_scope_is_global (scope))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Blocks are only allowed in global scope.");
|
||||
return gsk_sl_type_ref (gsk_sl_type_get_scalar (GSK_SL_FLOAT));
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
builder = gsk_sl_type_builder_new_block (token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected block name.");
|
||||
return gsk_sl_type_ref (gsk_sl_type_get_scalar (GSK_SL_FLOAT));
|
||||
}
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_LEFT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected opening \"{\" after block declaration.");
|
||||
goto out;
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
for (token = gsk_sl_preprocessor_get (preproc);
|
||||
!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE) && !gsk_sl_token_is (token, GSK_SL_TOKEN_EOF);
|
||||
token = gsk_sl_preprocessor_get (preproc))
|
||||
{
|
||||
type = gsk_sl_type_new_parse (scope, preproc);
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_IDENTIFIER))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected identifier for type name.");
|
||||
break;
|
||||
}
|
||||
if (gsk_sl_type_builder_has_member (builder, token->str))
|
||||
gsk_sl_preprocessor_error (preproc, DECLARATION, "struct already has a member named \"%s\".", token->str);
|
||||
else
|
||||
gsk_sl_type_builder_add_member (builder, type, token->str);
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
token = gsk_sl_preprocessor_get (preproc);
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_COMMA))
|
||||
break;
|
||||
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
gsk_sl_type_unref (type);
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected semicolon after block member declaration.");
|
||||
else
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
}
|
||||
|
||||
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_RIGHT_BRACE))
|
||||
{
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected closing \"}\" after block declaration.");
|
||||
gsk_sl_preprocessor_sync (preproc, GSK_SL_TOKEN_RIGHT_BRACE);
|
||||
}
|
||||
gsk_sl_preprocessor_consume (preproc, NULL);
|
||||
|
||||
out:
|
||||
return gsk_sl_type_builder_free (builder);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_type_get_builtin (GskSlBuiltinType builtin)
|
||||
{
|
||||
@@ -1545,8 +1819,9 @@ gsk_sl_type_new_parse (GskSlScope *scope,
|
||||
type = gsk_sl_type_ref (type);
|
||||
break;
|
||||
}
|
||||
|
||||
return gsk_sl_type_parse_block (scope, preproc);
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
gsk_sl_preprocessor_error (preproc, SYNTAX, "Expected type specifier");
|
||||
return gsk_sl_type_ref (gsk_sl_type_get_scalar (GSK_SL_FLOAT));
|
||||
@@ -1736,6 +2011,12 @@ gsk_sl_type_is_struct (const GskSlType *type)
|
||||
return type->class == &GSK_SL_TYPE_STRUCT;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_sl_type_is_block (const GskSlType *type)
|
||||
{
|
||||
return type->class == &GSK_SL_TYPE_BLOCK;
|
||||
}
|
||||
|
||||
GskSlScalarType
|
||||
gsk_sl_type_get_scalar_type (const GskSlType *type)
|
||||
{
|
||||
@@ -1923,6 +2204,7 @@ struct _GskSlTypeBuilder {
|
||||
char *name;
|
||||
gsize size;
|
||||
GArray *members;
|
||||
guint is_block :1;
|
||||
};
|
||||
|
||||
GskSlTypeBuilder *
|
||||
@@ -1938,6 +2220,22 @@ gsk_sl_type_builder_new_struct (const char *name)
|
||||
return builder;
|
||||
}
|
||||
|
||||
GskSlTypeBuilder *
|
||||
gsk_sl_type_builder_new_block (const char *name)
|
||||
{
|
||||
GskSlTypeBuilder *builder;
|
||||
|
||||
g_assert (name != NULL);
|
||||
|
||||
builder = g_slice_new0 (GskSlTypeBuilder);
|
||||
|
||||
builder->name = g_strdup (name);
|
||||
builder->members = g_array_new (FALSE, FALSE, sizeof (GskSlTypeMember));
|
||||
builder->is_block = TRUE;
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
static char *
|
||||
gsk_sl_type_builder_generate_name (GskSlTypeBuilder *builder)
|
||||
{
|
||||
@@ -1966,8 +2264,8 @@ gsk_sl_type_builder_generate_name (GskSlTypeBuilder *builder)
|
||||
return g_string_free (string, FALSE);
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_type_builder_free (GskSlTypeBuilder *builder)
|
||||
static GskSlType *
|
||||
gsk_sl_type_builder_free_to_struct (GskSlTypeBuilder *builder)
|
||||
{
|
||||
GskSlTypeStruct *result;
|
||||
|
||||
@@ -1986,6 +2284,32 @@ gsk_sl_type_builder_free (GskSlTypeBuilder *builder)
|
||||
return &result->parent;
|
||||
}
|
||||
|
||||
static GskSlType *
|
||||
gsk_sl_type_builder_free_to_block (GskSlTypeBuilder *builder)
|
||||
{
|
||||
GskSlTypeBlock *result;
|
||||
|
||||
result = gsk_sl_type_new (GskSlTypeBlock, &GSK_SL_TYPE_BLOCK);
|
||||
|
||||
result->name = builder->name;
|
||||
result->size = builder->size;
|
||||
result->n_members = builder->members->len;
|
||||
result->members = (GskSlTypeMember *) g_array_free (builder->members, FALSE);
|
||||
|
||||
g_slice_free (GskSlTypeBuilder, builder);
|
||||
|
||||
return &result->parent;
|
||||
}
|
||||
|
||||
GskSlType *
|
||||
gsk_sl_type_builder_free (GskSlTypeBuilder *builder)
|
||||
{
|
||||
if (builder->is_block)
|
||||
return gsk_sl_type_builder_free_to_block (builder);
|
||||
else
|
||||
return gsk_sl_type_builder_free_to_struct (builder);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder,
|
||||
GskSlType *type,
|
||||
|
||||
@@ -46,6 +46,7 @@ gboolean gsk_sl_type_is_scalar (const GskSlType
|
||||
gboolean gsk_sl_type_is_vector (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_matrix (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_struct (const GskSlType *type);
|
||||
gboolean gsk_sl_type_is_block (const GskSlType *type);
|
||||
|
||||
const char * gsk_sl_type_get_name (const GskSlType *type);
|
||||
GskSlScalarType gsk_sl_type_get_scalar_type (const GskSlType *type);
|
||||
@@ -89,6 +90,7 @@ void gsk_sl_scalar_type_convert_value (GskSlScalarType
|
||||
gconstpointer source_value);
|
||||
|
||||
GskSlTypeBuilder * gsk_sl_type_builder_new_struct (const char *name);
|
||||
GskSlTypeBuilder * gsk_sl_type_builder_new_block (const char *name);
|
||||
GskSlType * gsk_sl_type_builder_free (GskSlTypeBuilder *builder);
|
||||
void gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder,
|
||||
GskSlType *type,
|
||||
|
||||
@@ -85,7 +85,31 @@ void
|
||||
gsk_sl_variable_print (const GskSlVariable *variable,
|
||||
GskSlPrinter *printer)
|
||||
{
|
||||
gsk_sl_pointer_type_print (variable->type, printer);
|
||||
GskSlType *type;
|
||||
|
||||
if (gsk_sl_qualifier_print (gsk_sl_pointer_type_get_qualifier (variable->type), printer))
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
type = gsk_sl_pointer_type_get_type (variable->type);
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_name (type));
|
||||
if (gsk_sl_type_is_block (type))
|
||||
{
|
||||
guint i, n;
|
||||
|
||||
gsk_sl_printer_append (printer, " {");
|
||||
gsk_sl_printer_push_indentation (printer);
|
||||
n = gsk_sl_type_get_n_members (type);
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
gsk_sl_printer_newline (printer);
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_name (gsk_sl_type_get_member_type (type, i)));
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
gsk_sl_printer_append (printer, gsk_sl_type_get_member_name (type, i));
|
||||
gsk_sl_printer_append (printer, ";");
|
||||
}
|
||||
gsk_sl_printer_pop_indentation (printer);
|
||||
gsk_sl_printer_newline (printer);
|
||||
gsk_sl_printer_append (printer, "}");
|
||||
}
|
||||
if (variable->name)
|
||||
{
|
||||
gsk_sl_printer_append (printer, " ");
|
||||
|
||||
@@ -95,6 +95,11 @@ typedef enum {
|
||||
GSK_SPV_OP_ARRAY_LENGTH = 68,
|
||||
GSK_SPV_OP_GENERIC_PTR_MEM_SEMANTICS = 69,
|
||||
GSK_SPV_OP_IN_BOUNDS_PTR_ACCESS_CHAIN = 70,
|
||||
GSK_SPV_OP_DECORATE = 71,
|
||||
GSK_SPV_OP_MEMBER_DECORATE = 72,
|
||||
GSK_SPV_OP_DECORATION_GROUP = 73,
|
||||
GSK_SPV_OP_GROUP_DECORATE = 74,
|
||||
GSK_SPV_OP_GROUP_MEMBER_DECORATE = 75,
|
||||
GSK_SPV_OP_VECTOR_EXTRACT_DYNAMIC = 77,
|
||||
GSK_SPV_OP_VECTOR_INSERT_DYNAMIC = 78,
|
||||
GSK_SPV_OP_VECTOR_SHUFFLE = 79,
|
||||
@@ -161,7 +166,8 @@ typedef enum {
|
||||
GSK_SPV_OP_LIFETIME_STOP = 257,
|
||||
GSK_SPV_OP_SIZE_OF = 321,
|
||||
GSK_SPV_OP_TYPE_PIPE_STORAGE = 322,
|
||||
GSK_SPV_OP_TYPE_NAMED_BARRIER = 327
|
||||
GSK_SPV_OP_TYPE_NAMED_BARRIER = 327,
|
||||
GSK_SPV_OP_DECORATE_ID = 332
|
||||
} GskSpvOpcode;
|
||||
|
||||
typedef enum {
|
||||
@@ -211,6 +217,29 @@ typedef enum {
|
||||
GSK_SPV_STORAGE_CLASS_STORAGE_BUFFER = 12
|
||||
} GskSpvStorageClass;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_DECORATION_RELAXED_PRECISION = 0,
|
||||
GSK_SPV_DECORATION_SPEC_ID = 1,
|
||||
GSK_SPV_DECORATION_BLOCK = 2,
|
||||
GSK_SPV_DECORATION_BUFFER_BLOCK = 3,
|
||||
GSK_SPV_DECORATION_ROW_MAJOR = 4,
|
||||
GSK_SPV_DECORATION_COLUMN_MAJOR = 5,
|
||||
GSK_SPV_DECORATION_ARRAY_STRIDE = 6,
|
||||
GSK_SPV_DECORATION_MATRIX_STRIDE = 7,
|
||||
GSK_SPV_DECORATION_GLSL_SHARED = 8,
|
||||
GSK_SPV_DECORATION_GLSL_PACKED = 9,
|
||||
GSK_SPV_DECORATION_C_PACKED = 10,
|
||||
GSK_SPV_DECORATION_BUILTIN = 11,
|
||||
GSK_SPV_DECORATION_NO_PERSPECTIVE = 13,
|
||||
GSK_SPV_DECORATION_FLAT = 14,
|
||||
GSK_SPV_DECORATION_PATCH = 15,
|
||||
GSK_SPV_DECORATION_CENTROID = 16,
|
||||
GSK_SPV_DECORATION_SAMPLE = 17,
|
||||
GSK_SPV_DECORATION_INVARIANT = 18,
|
||||
GSK_SPV_DECORATION_RESTRICT = 19,
|
||||
GSK_SPV_DECORATION_ALIASED = 20
|
||||
} GskSpvDecoration;
|
||||
|
||||
typedef enum {
|
||||
GSK_SPV_WRITER_SECTION_HEADER,
|
||||
GSK_SPV_WRITER_SECTION_DEBUG,
|
||||
|
||||
Reference in New Issue
Block a user