summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2017-10-25 04:43:35 +0200
committerBenjamin Otte <otte@redhat.com>2017-10-30 02:58:03 +0100
commitcb857e7231e249791e408074853cbd315573c7e8 (patch)
treea2030cbe83cf7d91fea34cc817404840e525e5a9
parenta7dac28a3a669eea5394e511c27a8d661944173f (diff)
downloadgtk+-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.c91
-rw-r--r--gsk/gsksltype.c58
-rw-r--r--gsk/gsksltypeprivate.h5
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);