diff options
author | Benjamin Otte <otte@redhat.com> | 2017-10-25 04:43:35 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2017-10-30 02:58:03 +0100 |
commit | cb857e7231e249791e408074853cbd315573c7e8 (patch) | |
tree | a2030cbe83cf7d91fea34cc817404840e525e5a9 | |
parent | a7dac28a3a669eea5394e511c27a8d661944173f (diff) | |
download | gtk+-cb857e7231e249791e408074853cbd315573c7e8.tar.gz |
gsksl: Add support for native blocks
and implement gl_PerVertex's gl_Position and gl_PointSize with it.
-rw-r--r-- | gsk/gskslnativevariable.c | 91 | ||||
-rw-r--r-- | gsk/gsksltype.c | 58 | ||||
-rw-r--r-- | gsk/gsksltypeprivate.h | 5 |
3 files changed, 130 insertions, 24 deletions
diff --git a/gsk/gskslnativevariable.c b/gsk/gskslnativevariable.c index d26e89463a..4c99101222 100644 --- a/gsk/gskslnativevariable.c +++ b/gsk/gskslnativevariable.c @@ -26,34 +26,115 @@ #include "gsksltypeprivate.h" #include "gskslvariableprivate.h" +typedef struct _NativeVariable NativeVariable; +struct _NativeVariable { + const char *name; + GskSlType *type; + GskSpvBuiltIn builtin; +}; + +static void +gsk_sl_native_variable_add_block (GskSlScope *scope, + const char *block_name, + const char *block_instance_name, + GskSlStorage storage, + const NativeVariable *variables, + gsize n_variables) +{ + GskSlQualifier qualifier; + GskSlVariable *variable; + GskSlTypeBuilder *builder; + GskSlType *type; + gsize i; + + gsk_sl_qualifier_init (&qualifier); + qualifier.storage = storage; + + builder = gsk_sl_type_builder_new_block (block_name); + for (i = 0; i < n_variables; i++) + { + gsk_sl_type_builder_add_builtin_member (builder, + variables[i].type, + variables[i].name, + variables[i].builtin); + } + type = gsk_sl_type_builder_free (builder); + + variable = gsk_sl_variable_new (block_instance_name, + type, + &qualifier, + NULL); + if (block_instance_name) + { + gsk_sl_scope_add_variable (scope, variable); + } + else + { + for (i = 0; i < n_variables; i++) + { + GskSlVariable *sub; + + sub = gsk_sl_variable_new_block_member (variable, i); + gsk_sl_scope_add_variable (scope, sub); + gsk_sl_variable_unref (sub); + } + } + gsk_sl_variable_unref (variable); +} + static void gsk_sl_native_variable_add (GskSlScope *scope, const char *name, - GskSlScalarType scalar, + GskSlStorage storage, + GskSlType *type, GskSpvBuiltIn builtin) { GskSlQualifier qualifier; GskSlVariable *variable; gsk_sl_qualifier_init (&qualifier); - qualifier.storage = GSK_SL_STORAGE_GLOBAL_IN; + qualifier.storage = storage; variable = gsk_sl_variable_new_builtin (name, - gsk_sl_type_get_scalar (scalar), + type, &qualifier, builtin); gsk_sl_scope_add_variable (scope, variable); gsk_sl_variable_unref (variable); } +static void +gsk_sl_native_variable_add_simple (GskSlScope *scope, + const char *name, + GskSlScalarType scalar, + GskSpvBuiltIn builtin) +{ + gsk_sl_native_variable_add (scope, name, GSK_SL_STORAGE_GLOBAL_IN, gsk_sl_type_get_scalar (scalar), builtin); +} + void gsk_sl_native_variables_add (GskSlScope *scope, GskSlEnvironment *environment) { if (gsk_sl_environment_get_stage (environment) == GSK_SL_SHADER_VERTEX) { - gsk_sl_native_variable_add (scope, "gl_VertexIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_VERTEX_INDEX); - gsk_sl_native_variable_add (scope, "gl_InstanceIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_INSTANCE_INDEX); + gsk_sl_native_variable_add_simple (scope, "gl_VertexIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_VERTEX_INDEX); + gsk_sl_native_variable_add_simple (scope, "gl_InstanceIndex", GSK_SL_INT, GSK_SPV_BUILT_IN_INSTANCE_INDEX); + if (gsk_sl_environment_get_version (environment) >= 150) + { + gsk_sl_native_variable_add_block (scope, + "gl_PerVertex", NULL, + GSK_SL_STORAGE_GLOBAL_OUT, + (NativeVariable[2]) { + { "gl_Position", gsk_sl_type_get_vector (GSK_SL_FLOAT, 4), GSK_SPV_BUILT_IN_POSITION }, + { "gl_PointSize", gsk_sl_type_get_scalar (GSK_SL_FLOAT), GSK_SPV_BUILT_IN_POINT_SIZE } + }, 2); + } + else + { + gsk_sl_native_variable_add (scope, "gl_Position", GSK_SL_STORAGE_GLOBAL_OUT, gsk_sl_type_get_vector (GSK_SL_FLOAT, 4), GSK_SPV_BUILT_IN_POSITION); + gsk_sl_native_variable_add (scope, "gl_PointSize", GSK_SL_STORAGE_GLOBAL_OUT, gsk_sl_type_get_scalar (GSK_SL_FLOAT), GSK_SPV_BUILT_IN_POINT_SIZE); + } } } diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c index 45d9a97835..34382a40cc 100644 --- a/gsk/gsksltype.c +++ b/gsk/gsksltype.c @@ -40,6 +40,7 @@ typedef struct _GskSlTypeClass GskSlTypeClass; struct _GskSlTypeMember { GskSlType *type; char *name; + GskSpvBuiltIn builtin; gsize offset; }; @@ -1606,27 +1607,30 @@ gsk_sl_type_struct_has_name (const GskSlTypeStruct *struc) } static void -gsk_sl_type_write_member_decoration (GskSpvWriter *writer, - guint32 type_id, - gsize index, - GskSlType *member_type, - const char *member_name, - gsize member_offset) +gsk_sl_type_write_member_decoration (GskSpvWriter *writer, + guint32 type_id, + gsize index, + const GskSlTypeMember *member) { - gsk_spv_writer_member_name (writer, type_id, index, member_name); + gsk_spv_writer_member_name (writer, type_id, index, member->name); - gsk_spv_writer_member_decorate (writer, type_id, index, - GSK_SPV_DECORATION_OFFSET, - (guint32[1]) { member_offset }, 1); + if (member->builtin != -1) + gsk_spv_writer_member_decorate (writer, type_id, index, + GSK_SPV_DECORATION_BUILT_IN, + (guint32[1]) { member->builtin }, 1); + else + gsk_spv_writer_member_decorate (writer, type_id, index, + GSK_SPV_DECORATION_OFFSET, + (guint32[1]) { member->offset }, 1); - if (gsk_sl_type_is_matrix (member_type)) + if (gsk_sl_type_is_matrix (member->type)) { gsk_spv_writer_member_decorate (writer, type_id, index, GSK_SPV_DECORATION_COL_MAJOR, NULL, 0); gsk_spv_writer_member_decorate (writer, type_id, index, GSK_SPV_DECORATION_MATRIX_STRIDE, - (guint32[1]) { gsk_sl_type_get_size (gsk_sl_type_get_index_type (member_type)) }, 1); + (guint32[1]) { gsk_sl_type_get_size (gsk_sl_type_get_index_type (member->type)) }, 1); } } @@ -1656,8 +1660,7 @@ gsk_sl_type_struct_write_spv (GskSlType *type, for (i = 0; i < struc->n_members; i++) { - gsk_sl_type_write_member_decoration (writer, result_id, i, struc->members[i].type, - struc->members[i].name, struc->members[i].offset); + gsk_sl_type_write_member_decoration (writer, result_id, i, &struc->members[i]); } return result_id; @@ -1885,8 +1888,7 @@ gsk_sl_type_block_write_spv (GskSlType *type, for (i = 0; i < block->n_members; i++) { - gsk_sl_type_write_member_decoration (writer, result_id, i, block->members[i].type, - block->members[i].name, block->members[i].offset); + gsk_sl_type_write_member_decoration (writer, result_id, i, &block->members[i]); } return result_id; @@ -2432,6 +2434,14 @@ gsk_sl_type_new_parse (GskSlScope *scope, break; case GSK_SL_TOKEN_STRUCT: return gsk_sl_type_parse_struct (scope, preproc); + case GSK_SL_TOKEN_IDENTIFIER: + type = gsk_sl_scope_lookup_type (scope, token->str); + if (type) + { + type = gsk_sl_type_ref (type); + break; + } + /* 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)); @@ -3044,18 +3054,28 @@ gsk_sl_type_builder_free (GskSlTypeBuilder *builder) } void -gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder, - GskSlType *type, - const char *name) +gsk_sl_type_builder_add_builtin_member (GskSlTypeBuilder *builder, + GskSlType *type, + const char *name, + GskSpvBuiltIn builtin) { g_array_append_vals (builder->members, &(GskSlTypeMember) { gsk_sl_type_ref (type), g_strdup (name), + builtin, builder->size }, 1); builder->size += gsk_sl_type_get_size (type); } +void +gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder, + GskSlType *type, + const char *name) +{ + gsk_sl_type_builder_add_builtin_member (builder, type, name, -1); +} + gboolean gsk_sl_type_builder_has_member (GskSlTypeBuilder *builder, const char *name) diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h index ee3f0d7577..151dcb8e64 100644 --- a/gsk/gsksltypeprivate.h +++ b/gsk/gsksltypeprivate.h @@ -22,6 +22,7 @@ #include <glib.h> #include "gsksltypesprivate.h" +#include "gskspvenumsprivate.h" G_BEGIN_DECLS @@ -115,6 +116,10 @@ GskSlType * gsk_sl_type_builder_free (GskSlTypeBuilde void gsk_sl_type_builder_add_member (GskSlTypeBuilder *builder, GskSlType *type, const char *name); +void gsk_sl_type_builder_add_builtin_member (GskSlTypeBuilder *builder, + GskSlType *type, + const char *name, + GskSpvBuiltIn builtin); gboolean gsk_sl_type_builder_has_member (GskSlTypeBuilder *builder, const char *name); |