diff --git a/gsk/gskslexpression.c b/gsk/gskslexpression.c index d5a2421d9e..9dc35e925c 100644 --- a/gsk/gskslexpression.c +++ b/gsk/gskslexpression.c @@ -27,6 +27,7 @@ #include "gskslscopeprivate.h" #include "gsksltokenizerprivate.h" #include "gsksltypeprivate.h" +#include "gskslvalueprivate.h" #include "gskslvariableprivate.h" #include "gskspvwriterprivate.h" @@ -779,14 +780,7 @@ typedef struct _GskSlExpressionConstant GskSlExpressionConstant; struct _GskSlExpressionConstant { GskSlExpression parent; - GskSlScalarType type; - union { - gint32 i32; - guint32 u32; - float f; - double d; - gboolean b; - }; + GskSlValue *value; }; static void @@ -794,7 +788,7 @@ gsk_sl_expression_constant_free (GskSlExpression *expression) { GskSlExpressionConstant *constant = (GskSlExpressionConstant *) expression; - g_slice_free (GskSlExpressionConstant, constant); + gsk_sl_value_free (constant->value); } static void @@ -802,42 +796,8 @@ gsk_sl_expression_constant_print (const GskSlExpression *expression, GString *string) { const GskSlExpressionConstant *constant = (const GskSlExpressionConstant *) expression; - char buf[G_ASCII_DTOSTR_BUF_SIZE]; - switch (constant->type) - { - case GSK_SL_FLOAT: - g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, constant->f); - g_string_append (string, buf); - if (strchr (buf, '.') == NULL) - g_string_append (string, ".0"); - break; - - case GSK_SL_DOUBLE: - g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, constant->d); - g_string_append (string, buf); - if (strchr (buf, '.') == NULL) - g_string_append (string, ".0"); - g_string_append (string, "lf"); - break; - - case GSK_SL_INT: - g_string_append_printf (string, "%i", (gint) constant->i32); - break; - - case GSK_SL_UINT: - g_string_append_printf (string, "%uu", (guint) constant->u32); - break; - - case GSK_SL_BOOL: - g_string_append (string, constant->b ? "true" : "false"); - break; - - case GSK_SL_VOID: - default: - g_assert_not_reached (); - break; - } + gsk_sl_value_print (constant->value, string); } static GskSlType * @@ -845,7 +805,7 @@ gsk_sl_expression_constant_get_return_type (const GskSlExpression *expression) { const GskSlExpressionConstant *constant = (const GskSlExpressionConstant *) expression; - return gsk_sl_type_get_scalar (constant->type); + return gsk_sl_value_get_type (constant->value); } static gboolean @@ -859,72 +819,8 @@ gsk_sl_expression_constant_write_spv (const GskSlExpression *expression, GskSpvWriter *writer) { const GskSlExpressionConstant *constant = (const GskSlExpressionConstant *) expression; - guint32 type_id, result_id; - switch (constant->type) - { - case GSK_SL_FLOAT: - type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_FLOAT)); - result_id = gsk_spv_writer_next_id (writer); - gsk_spv_writer_add (writer, - GSK_SPV_WRITER_SECTION_DECLARE, - 4, GSK_SPV_OP_CONSTANT, - (guint32[3]) { type_id, - result_id, - *(guint32 *) &constant->f }); - break; - - case GSK_SL_DOUBLE: - type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_DOUBLE)); - result_id = gsk_spv_writer_next_id (writer); - gsk_spv_writer_add (writer, - GSK_SPV_WRITER_SECTION_DECLARE, - 5, GSK_SPV_OP_CONSTANT, - (guint32[4]) { type_id, - result_id, - *(guint32 *) &constant->d, - *(((guint32 *) &constant->d) + 1) }); - break; - - case GSK_SL_INT: - type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_INT)); - result_id = gsk_spv_writer_next_id (writer); - gsk_spv_writer_add (writer, - GSK_SPV_WRITER_SECTION_DECLARE, - 4, GSK_SPV_OP_CONSTANT, - (guint32[3]) { type_id, - result_id, - constant->i32 }); - break; - - case GSK_SL_UINT: - type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_UINT)); - result_id = gsk_spv_writer_next_id (writer); - gsk_spv_writer_add (writer, - GSK_SPV_WRITER_SECTION_DECLARE, - 4, GSK_SPV_OP_CONSTANT, - (guint32[3]) { type_id, - result_id, - constant->u32 }); - break; - - case GSK_SL_BOOL: - type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_BOOL)); - result_id = gsk_spv_writer_next_id (writer); - gsk_spv_writer_add (writer, - GSK_SPV_WRITER_SECTION_DECLARE, - 3, constant->b ? GSK_SPV_OP_CONSTANT_TRUE : GSK_SPV_OP_CONSTANT_FALSE, - (guint32[2]) { type_id, - result_id }); - break; - - case GSK_SL_VOID: - default: - g_assert_not_reached (); - break; - } - - return result_id; + return gsk_spv_writer_get_id_for_value (writer, constant->value); } static const GskSlExpressionClass GSK_SL_EXPRESSION_CONSTANT = { @@ -1043,36 +939,36 @@ gsk_sl_expression_parse_primary (GskSlScope *scope, case GSK_SL_TOKEN_INTCONSTANT: constant = gsk_sl_expression_new (GskSlExpressionConstant, &GSK_SL_EXPRESSION_CONSTANT); - constant->type = GSK_SL_INT; - constant->i32 = token->i32; + constant->value = gsk_sl_value_new (gsk_sl_type_get_scalar (GSK_SL_INT)); + *(gint32 *) gsk_sl_value_get_data (constant->value) = token->i32; gsk_sl_preprocessor_consume (stream, (GskSlExpression *) constant); return (GskSlExpression *) constant; case GSK_SL_TOKEN_UINTCONSTANT: constant = gsk_sl_expression_new (GskSlExpressionConstant, &GSK_SL_EXPRESSION_CONSTANT); - constant->type = GSK_SL_UINT; - constant->u32 = token->u32; + constant->value = gsk_sl_value_new (gsk_sl_type_get_scalar (GSK_SL_UINT)); + *(guint32 *) gsk_sl_value_get_data (constant->value) = token->u32; gsk_sl_preprocessor_consume (stream, (GskSlExpression *) constant); return (GskSlExpression *) constant; case GSK_SL_TOKEN_FLOATCONSTANT: constant = gsk_sl_expression_new (GskSlExpressionConstant, &GSK_SL_EXPRESSION_CONSTANT); - constant->type = GSK_SL_FLOAT; - constant->f = token->f; + constant->value = gsk_sl_value_new (gsk_sl_type_get_scalar (GSK_SL_FLOAT)); + *(float *) gsk_sl_value_get_data (constant->value) = token->f; gsk_sl_preprocessor_consume (stream, (GskSlExpression *) constant); return (GskSlExpression *) constant; case GSK_SL_TOKEN_BOOLCONSTANT: constant = gsk_sl_expression_new (GskSlExpressionConstant, &GSK_SL_EXPRESSION_CONSTANT); - constant->type = GSK_SL_BOOL; - constant->b = token->b; + constant->value = gsk_sl_value_new (gsk_sl_type_get_scalar (GSK_SL_BOOL)); + *(guint32 *) gsk_sl_value_get_data (constant->value) = token->b; gsk_sl_preprocessor_consume (stream, (GskSlExpression *) constant); return (GskSlExpression *) constant; case GSK_SL_TOKEN_DOUBLECONSTANT: constant = gsk_sl_expression_new (GskSlExpressionConstant, &GSK_SL_EXPRESSION_CONSTANT); - constant->type = GSK_SL_DOUBLE; - constant->d = token->d; + constant->value = gsk_sl_value_new (gsk_sl_type_get_scalar (GSK_SL_DOUBLE)); + *(double *) gsk_sl_value_get_data (constant->value) = token->f; gsk_sl_preprocessor_consume (stream, (GskSlExpression *) constant); return (GskSlExpression *) constant; diff --git a/gsk/gskslpointertype.c b/gsk/gskslpointertype.c index 42ca9f3490..8b8f1572a2 100644 --- a/gsk/gskslpointertype.c +++ b/gsk/gskslpointertype.c @@ -392,6 +392,12 @@ gsk_sl_pointer_type_get_storage_class (const GskSlPointerType *type) if (type->flags & GSK_SL_POINTER_TYPE_LOCAL) return GSK_SPV_STORAGE_CLASS_FUNCTION; + if (type->flags & GSK_SL_POINTER_TYPE_OUT) + return GSK_SPV_STORAGE_CLASS_OUTPUT; + + if (type->flags & GSK_SL_POINTER_TYPE_IN) + return GSK_SPV_STORAGE_CLASS_INPUT; + return GSK_SPV_STORAGE_CLASS_PRIVATE; } diff --git a/gsk/gsksltype.c b/gsk/gsksltype.c index 1ca6cf32a4..fe927db0c5 100644 --- a/gsk/gsksltype.c +++ b/gsk/gsksltype.c @@ -22,6 +22,7 @@ #include "gsksltokenizerprivate.h" #include "gskslpreprocessorprivate.h" +#include "gskslvalueprivate.h" #include "gskspvwriterprivate.h" #include @@ -44,10 +45,189 @@ struct _GskSlTypeClass { GskSlScalarType (* get_scalar_type) (const GskSlType *type); GskSlType * (* get_index_type) (const GskSlType *type); guint (* get_length) (const GskSlType *type); + gsize (* get_size) (const GskSlType *type); gboolean (* can_convert) (const GskSlType *target, const GskSlType *source); - guint32 (* write_spv) (const GskSlType *type, + guint32 (* write_spv) (GskSlType *type, GskSpvWriter *writer); + void (* print_value) (const GskSlType *type, + GString *string, + gconstpointer value); + guint32 (* write_value_spv) (GskSlType *type, + GskSpvWriter *writer, + gconstpointer value); +}; + +static void +print_void (GString *string, + gconstpointer value) +{ + g_assert_not_reached (); +} + +static guint32 +write_void_spv (GskSpvWriter *writer, + gconstpointer value) +{ + g_assert_not_reached (); +} + +static void +print_float (GString *string, + gconstpointer value) +{ + char buf[G_ASCII_DTOSTR_BUF_SIZE]; + const gfloat *f = value; + + g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, *f); + g_string_append (string, buf); + if (strchr (buf, '.') == NULL) + g_string_append (string, ".0"); +} + +static guint32 +write_float_spv (GskSpvWriter *writer, + gconstpointer value) +{ + guint32 type_id, result_id; + + type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_FLOAT)); + result_id = gsk_spv_writer_next_id (writer); + gsk_spv_writer_add (writer, + GSK_SPV_WRITER_SECTION_DECLARE, + 4, GSK_SPV_OP_CONSTANT, + (guint32[3]) { type_id, + result_id, + *(const guint32 *) value }); + + return result_id; +} + +static void +print_double (GString *string, + gconstpointer value) +{ + char buf[G_ASCII_DTOSTR_BUF_SIZE]; + const gdouble *d = value; + + g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, *d); + g_string_append (string, buf); + if (strchr (buf, '.') == NULL) + g_string_append (string, ".0"); + g_string_append (string, "lf"); +} + +static guint32 +write_double_spv (GskSpvWriter *writer, + gconstpointer value) +{ + guint32 type_id, result_id; + + type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_DOUBLE)); + result_id = gsk_spv_writer_next_id (writer); + gsk_spv_writer_add (writer, + GSK_SPV_WRITER_SECTION_DECLARE, + 5, GSK_SPV_OP_CONSTANT, + (guint32[4]) { type_id, + result_id, + *(const guint32 *) value, + *(((const guint32 *) value) + 1) }); + + return result_id; +} + +static void +print_int (GString *string, + gconstpointer value) +{ + const gint32 *i = value; + + g_string_append_printf (string, "%i", (gint) *i); +} + +static guint32 +write_int_spv (GskSpvWriter *writer, + gconstpointer value) +{ + guint32 type_id, result_id; + + type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_INT)); + result_id = gsk_spv_writer_next_id (writer); + gsk_spv_writer_add (writer, + GSK_SPV_WRITER_SECTION_DECLARE, + 4, GSK_SPV_OP_CONSTANT, + (guint32[3]) { type_id, + result_id, + *(const guint32 *) value }); + + return result_id; +} + +static void +print_uint (GString *string, + gconstpointer value) +{ + const guint32 *u = value; + + g_string_append_printf (string, "%uu", (guint) *u); +} + +static guint32 +write_uint_spv (GskSpvWriter *writer, + gconstpointer value) +{ + guint32 type_id, result_id; + + type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_UINT)); + result_id = gsk_spv_writer_next_id (writer); + gsk_spv_writer_add (writer, + GSK_SPV_WRITER_SECTION_DECLARE, + 4, GSK_SPV_OP_CONSTANT, + (guint32[3]) { type_id, + result_id, + *(const guint32 *) value }); + + return result_id; +} + +static void +print_bool (GString *string, + gconstpointer value) +{ + const guint32 *u = value; + + g_string_append_printf (string, *u ? "true" : "false"); +} + +static guint32 +write_bool_spv (GskSpvWriter *writer, + gconstpointer value) +{ + guint32 type_id, result_id; + + type_id = gsk_spv_writer_get_id_for_type (writer, gsk_sl_type_get_scalar (GSK_SL_BOOL)); + result_id = gsk_spv_writer_next_id (writer); + gsk_spv_writer_add (writer, + GSK_SPV_WRITER_SECTION_DECLARE, + 3, *(const guint32 *) value ? GSK_SPV_OP_CONSTANT_TRUE : GSK_SPV_OP_CONSTANT_FALSE, + (guint32[2]) { type_id, + result_id }); + + return result_id; +} + +struct { + const char *name; + gsize size; + void (* print_value) (GString *string, gconstpointer value); + guint32 (* write_value_spv) (GskSpvWriter *writer, gconstpointer value); +} scalar_infos[] = { + [GSK_SL_VOID] = { "void", 0, print_void, write_void_spv, }, + [GSK_SL_FLOAT] = { "float", 4, print_float, write_float_spv }, + [GSK_SL_DOUBLE] = { "double", 8, print_double, write_double_spv }, + [GSK_SL_INT] = { "int", 4, print_int, write_int_spv }, + [GSK_SL_UINT] = { "uint", 4, print_uint, write_uint_spv }, + [GSK_SL_BOOL] = { "bool", 4, print_bool, write_bool_spv } }; /* SCALAR */ @@ -71,24 +251,7 @@ gsk_sl_type_scalar_get_name (const GskSlType *type) { const GskSlTypeScalar *scalar = (const GskSlTypeScalar *) type; - switch (scalar->scalar) - { - case GSK_SL_VOID: - return "void"; - case GSK_SL_FLOAT: - return "float"; - case GSK_SL_DOUBLE: - return "double"; - case GSK_SL_INT: - return "int"; - case GSK_SL_UINT: - return "uint"; - case GSK_SL_BOOL: - return "bool"; - default: - g_assert_not_reached (); - break; - } + return scalar_infos[scalar->scalar].name; } static GskSlScalarType @@ -111,6 +274,14 @@ gsk_sl_type_scalar_get_length (const GskSlType *type) return 0; } +static gsize +gsk_sl_type_scalar_get_size (const GskSlType *type) +{ + const GskSlTypeScalar *scalar = (const GskSlTypeScalar *) type; + + return scalar_infos[scalar->scalar].size; +} + static gboolean gsk_sl_type_scalar_can_convert (const GskSlType *target, const GskSlType *source) @@ -125,8 +296,8 @@ gsk_sl_type_scalar_can_convert (const GskSlType *target, } static guint32 -gsk_sl_type_scalar_write_spv (const GskSlType *type, - GskSpvWriter *writer) +gsk_sl_type_scalar_write_spv (GskSlType *type, + GskSpvWriter *writer) { GskSlTypeScalar *scalar = (GskSlTypeScalar *) type; guint32 result; @@ -195,14 +366,37 @@ gsk_sl_type_scalar_write_spv (const GskSlType *type, return result; } +static void +gsk_sl_type_scalar_print_value (const GskSlType *type, + GString *string, + gconstpointer value) +{ + const GskSlTypeScalar *scalar = (const GskSlTypeScalar *) type; + + scalar_infos[scalar->scalar].print_value (string, value); +} + +static guint32 +gsk_sl_type_scalar_write_value_spv (GskSlType *type, + GskSpvWriter *writer, + gconstpointer value) +{ + GskSlTypeScalar *scalar = (GskSlTypeScalar *) type; + + return scalar_infos[scalar->scalar].write_value_spv (writer, value); +} + static const GskSlTypeClass GSK_SL_TYPE_SCALAR = { gsk_sl_type_scalar_free, gsk_sl_type_scalar_get_name, gsk_sl_type_scalar_get_scalar_type, gsk_sl_type_scalar_get_index_type, gsk_sl_type_scalar_get_length, + gsk_sl_type_scalar_get_size, gsk_sl_type_scalar_can_convert, - gsk_sl_type_scalar_write_spv + gsk_sl_type_scalar_write_spv, + gsk_sl_type_scalar_print_value, + gsk_sl_type_scalar_write_value_spv }; /* VECTOR */ @@ -255,6 +449,14 @@ gsk_sl_type_vector_get_length (const GskSlType *type) return vector->length; } +static gsize +gsk_sl_type_vector_get_size (const GskSlType *type) +{ + const GskSlTypeVector *vector = (const GskSlTypeVector *) type; + + return vector->length * scalar_infos[vector->scalar].size; +} + static gboolean gsk_sl_type_vector_can_convert (const GskSlType *target, const GskSlType *source) @@ -272,8 +474,8 @@ gsk_sl_type_vector_can_convert (const GskSlType *target, } static guint32 -gsk_sl_type_vector_write_spv (const GskSlType *type, - GskSpvWriter *writer) +gsk_sl_type_vector_write_spv (GskSlType *type, + GskSpvWriter *writer) { GskSlTypeVector *vector = (GskSlTypeVector *) type; guint32 result_id, scalar_id; @@ -290,14 +492,75 @@ gsk_sl_type_vector_write_spv (const GskSlType *type, return result_id; } +static void +gsk_sl_type_vector_print_value (const GskSlType *type, + GString *string, + gconstpointer value) +{ + const GskSlTypeVector *vector = (const GskSlTypeVector *) type; + guint i; + const guchar *data; + + data = value; + + g_string_append (string, vector->name); + g_string_append (string, "("); + for (i = 0; i < vector->length; i++) + { + if (i > 0) + g_string_append (string, ", "); + scalar_infos[vector->scalar].print_value (string, data); + data += scalar_infos[vector->scalar].size; + } + + g_string_append (string, ")"); +} + +static guint32 +gsk_sl_type_vector_write_value_spv (GskSlType *type, + GskSpvWriter *writer, + gconstpointer value) +{ + GskSlTypeVector *vector = (GskSlTypeVector *) type; + guint32 ids[vector->length + 2]; + GskSlType *scalar_type; + GskSlValue *v; + const guchar *data; + guint i; + + data = value; + scalar_type = gsk_sl_type_get_scalar (vector->scalar); + + ids[0] = gsk_spv_writer_get_id_for_type (writer, type); + for (i = 0; i < vector->length; i++) + { + v = gsk_sl_value_new_for_data (scalar_type, (gpointer) data, NULL, NULL); + ids[2 + i] = gsk_spv_writer_get_id_for_value (writer, v); + gsk_sl_value_free (v); + data += scalar_infos[vector->scalar].size; + } + ids[1] = gsk_spv_writer_next_id (writer); + + gsk_spv_writer_add (writer, + GSK_SPV_WRITER_SECTION_DECLARE, + 3 + vector->length, + GSK_SPV_OP_CONSTANT_COMPOSITE, + ids); + + return ids[1]; +} + static const GskSlTypeClass GSK_SL_TYPE_VECTOR = { gsk_sl_type_vector_free, gsk_sl_type_vector_get_name, gsk_sl_type_vector_get_scalar_type, gsk_sl_type_vector_get_index_type, gsk_sl_type_vector_get_length, + gsk_sl_type_vector_get_size, gsk_sl_type_vector_can_convert, - gsk_sl_type_vector_write_spv + gsk_sl_type_vector_write_spv, + gsk_sl_type_vector_print_value, + gsk_sl_type_vector_write_value_spv }; /* MATRIX */ @@ -351,6 +614,14 @@ gsk_sl_type_matrix_get_length (const GskSlType *type) return matrix->columns; } +static gsize +gsk_sl_type_matrix_get_size (const GskSlType *type) +{ + const GskSlTypeMatrix *matrix = (const GskSlTypeMatrix *) type; + + return matrix->columns * matrix->rows * scalar_infos[matrix->scalar].size; +} + static gboolean gsk_sl_type_matrix_can_convert (const GskSlType *target, const GskSlType *source) @@ -369,8 +640,8 @@ gsk_sl_type_matrix_can_convert (const GskSlType *target, } static guint32 -gsk_sl_type_matrix_write_spv (const GskSlType *type, - GskSpvWriter *writer) +gsk_sl_type_matrix_write_spv (GskSlType *type, + GskSpvWriter *writer) { GskSlTypeMatrix *matrix = (GskSlTypeMatrix *) type; guint32 result_id, vector_id; @@ -387,14 +658,75 @@ gsk_sl_type_matrix_write_spv (const GskSlType *type, return result_id; } +static void +gsk_sl_type_matrix_print_value (const GskSlType *type, + GString *string, + gconstpointer value) +{ + const GskSlTypeMatrix *matrix = (const GskSlTypeMatrix *) type; + guint i; + const guchar *data; + + data = value; + + g_string_append (string, matrix->name); + g_string_append (string, "("); + for (i = 0; i < matrix->rows * matrix->columns; i++) + { + if (i > 0) + g_string_append (string, ", "); + scalar_infos[matrix->scalar].print_value (string, data); + data += scalar_infos[matrix->scalar].size; + } + + g_string_append (string, ")"); +} + +static guint32 +gsk_sl_type_matrix_write_value_spv (GskSlType *type, + GskSpvWriter *writer, + gconstpointer value) +{ + GskSlTypeMatrix *matrix = (GskSlTypeMatrix *) type; + guint32 ids[matrix->rows + 2]; + GskSlType *vector_type; + GskSlValue *v; + const guchar *data; + guint i; + + data = value; + vector_type = gsk_sl_type_get_index_type (type); + + ids[0] = gsk_spv_writer_get_id_for_type (writer, type); + for (i = 0; i < matrix->columns; i++) + { + v = gsk_sl_value_new_for_data (vector_type, (gpointer) data, NULL, NULL); + ids[2 + i] = gsk_spv_writer_get_id_for_value (writer, v); + gsk_sl_value_free (v); + data += gsk_sl_type_get_size (vector_type); + } + ids[1] = gsk_spv_writer_next_id (writer); + + gsk_spv_writer_add (writer, + GSK_SPV_WRITER_SECTION_DECLARE, + 3 + matrix->columns, + GSK_SPV_OP_CONSTANT_COMPOSITE, + ids); + + return ids[1]; +} + static const GskSlTypeClass GSK_SL_TYPE_MATRIX = { gsk_sl_type_matrix_free, gsk_sl_type_matrix_get_name, gsk_sl_type_matrix_get_scalar_type, gsk_sl_type_matrix_get_index_type, gsk_sl_type_matrix_get_length, + gsk_sl_type_matrix_get_size, gsk_sl_type_matrix_can_convert, - gsk_sl_type_matrix_write_spv + gsk_sl_type_matrix_write_spv, + gsk_sl_type_matrix_print_value, + gsk_sl_type_matrix_write_value_spv }; GskSlType * @@ -711,12 +1043,18 @@ gsk_sl_type_get_index_type (const GskSlType *type) return type->class->get_index_type (type); } -GskSlScalarType +guint gsk_sl_type_get_length (const GskSlType *type) { return type->class->get_length (type); } +gsize +gsk_sl_type_get_size (const GskSlType *type) +{ + return type->class->get_size (type); +} + gboolean gsk_sl_scalar_type_can_convert (GskSlScalarType target, GskSlScalarType source) @@ -764,9 +1102,24 @@ gsk_sl_type_hash (gconstpointer type) } guint32 -gsk_sl_type_write_spv (const GskSlType *type, - GskSpvWriter *writer) +gsk_sl_type_write_spv (GskSlType *type, + GskSpvWriter *writer) { return type->class->write_spv (type, writer); } +void +gsk_sl_type_print_value (const GskSlType *type, + GString *string, + gconstpointer value) +{ + type->class->print_value (type, string, value); +} + +guint32 +gsk_sl_type_write_value_spv (GskSlType *type, + GskSpvWriter *writer, + gconstpointer value) +{ + return type->class->write_value_spv (type, writer, value); +} diff --git a/gsk/gsksltypeprivate.h b/gsk/gsksltypeprivate.h index bcf80e77eb..309133f64b 100644 --- a/gsk/gsksltypeprivate.h +++ b/gsk/gsksltypeprivate.h @@ -53,6 +53,7 @@ const char * gsk_sl_type_get_name (const GskSlType GskSlScalarType gsk_sl_type_get_scalar_type (const GskSlType *type); GskSlType * gsk_sl_type_get_index_type (const GskSlType *type); guint gsk_sl_type_get_length (const GskSlType *type); +gsize gsk_sl_type_get_size (const GskSlType *type); gboolean gsk_sl_scalar_type_can_convert (GskSlScalarType target, GskSlScalarType source); gboolean gsk_sl_type_can_convert (const GskSlType *target, @@ -62,9 +63,16 @@ gboolean gsk_sl_type_equal (gconstpointer gconstpointer b); guint gsk_sl_type_hash (gconstpointer type); -guint32 gsk_sl_type_write_spv (const GskSlType *type, +guint32 gsk_sl_type_write_spv (GskSlType *type, GskSpvWriter *writer); +void gsk_sl_type_print_value (const GskSlType *type, + GString *string, + gconstpointer value); +guint32 gsk_sl_type_write_value_spv (GskSlType *type, + GskSpvWriter *writer, + gconstpointer value); + G_END_DECLS #endif /* __GSK_SL_TYPE_PRIVATE_H__ */ diff --git a/gsk/gsksltypesprivate.h b/gsk/gsksltypesprivate.h index d99118a410..cd15ae16e2 100644 --- a/gsk/gsksltypesprivate.h +++ b/gsk/gsksltypesprivate.h @@ -29,6 +29,7 @@ typedef struct _GskSlPointerType GskSlPointerType; typedef struct _GskSlScope GskSlScope; typedef struct _GskSlToken GskSlToken; typedef struct _GskSlType GskSlType; +typedef struct _GskSlValue GskSlValue; typedef struct _GskSlVariable GskSlVariable; typedef struct _GskSpvWriter GskSpvWriter; diff --git a/gsk/gskslvalue.c b/gsk/gskslvalue.c new file mode 100644 index 0000000000..c70a438062 --- /dev/null +++ b/gsk/gskslvalue.c @@ -0,0 +1,138 @@ +/* GTK - The GIMP Toolkit + * + * Copyright © 2017 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#include "config.h" + +#include "gskslvalueprivate.h" + +#include "gsksltypeprivate.h" +#include "gskspvwriterprivate.h" + +struct _GskSlValue { + GskSlType *type; + + gpointer data; + GDestroyNotify free_func; + gpointer user_data; +}; + +GskSlValue * +gsk_sl_value_new (GskSlType *type) +{ + gpointer data; + + g_return_val_if_fail (gsk_sl_type_get_size (type) > 0, NULL); + + data = g_malloc0 (gsk_sl_type_get_size (type)); + + return gsk_sl_value_new_for_data (type, data, g_free, data); +} + +GskSlValue * +gsk_sl_value_new_for_data (GskSlType *type, + gpointer data, + GDestroyNotify free_func, + gpointer user_data) +{ + GskSlValue *value; + + g_return_val_if_fail (gsk_sl_type_get_size (type) > 0, NULL); + g_return_val_if_fail (data != NULL, NULL); + + value = g_slice_new0 (GskSlValue); + + value->type = gsk_sl_type_ref (type); + value->data = data; + value->free_func = free_func; + value->user_data = user_data; + + return value; +} + +GskSlValue * +gsk_sl_value_copy (const GskSlValue *source) +{ + gpointer data; + + data = g_memdup (source->data, gsk_sl_type_get_size (source->type)); + + return gsk_sl_value_new_for_data (source->type, data, g_free, data); +} + +void +gsk_sl_value_free (GskSlValue *value) +{ + if (value == NULL) + return; + + if (value->free_func) + value->free_func (value->user_data); + + gsk_sl_type_unref (value->type); + + g_slice_free (GskSlValue, value); +} + +void +gsk_sl_value_print (const GskSlValue *value, + GString *string) +{ + gsk_sl_type_print_value (value->type, string, value->data); +} + +GskSlType * +gsk_sl_value_get_type (const GskSlValue *value) +{ + return value->type; +} + +gpointer +gsk_sl_value_get_data (const GskSlValue *value) +{ + return value->data; +} + +gboolean +gsk_sl_value_equal (gconstpointer a_, + gconstpointer b_) +{ + const GskSlValue *a = a_; + const GskSlValue *b = b_; + + if (!gsk_sl_type_equal (a->type, b->type)) + return FALSE; + + /* XXX: This is wrong */ + return memcmp (a->data, b->data, gsk_sl_type_get_size (a->type)) == 0; +} + +guint +gsk_sl_value_hash (gconstpointer value_) +{ + const GskSlValue *value = value_; + + /* XXX: We definitely want to hash the data here ! */ + return gsk_sl_type_hash (value->type); +} + +guint32 +gsk_sl_value_write_spv (const GskSlValue *value, + GskSpvWriter *writer) +{ + return gsk_sl_type_write_value_spv (value->type, writer, value->data); +} diff --git a/gsk/gskslvalueprivate.h b/gsk/gskslvalueprivate.h new file mode 100644 index 0000000000..a4fe651665 --- /dev/null +++ b/gsk/gskslvalueprivate.h @@ -0,0 +1,49 @@ +/* GTK - The GIMP Toolkit + * + * Copyright © 2017 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see . + */ + +#ifndef __GSK_SL_VALUE_PRIVATE_H__ +#define __GSK_SL_VALUE_PRIVATE_H__ + +#include "gsk/gsksltypesprivate.h" + +G_BEGIN_DECLS + +GskSlValue * gsk_sl_value_new (GskSlType *type); +GskSlValue * gsk_sl_value_new_for_data (GskSlType *type, + gpointer data, + GDestroyNotify free_func, + gpointer user_data); +GskSlValue * gsk_sl_value_copy (const GskSlValue *source); +void gsk_sl_value_free (GskSlValue *value); + +void gsk_sl_value_print (const GskSlValue *value, + GString *string); + +GskSlType * gsk_sl_value_get_type (const GskSlValue *value); +gpointer gsk_sl_value_get_data (const GskSlValue *value); + +gboolean gsk_sl_value_equal (gconstpointer a, + gconstpointer b); +guint gsk_sl_value_hash (gconstpointer type); + +guint32 gsk_sl_value_write_spv (const GskSlValue *value, + GskSpvWriter *writer); + +G_END_DECLS + +#endif /* __GSK_SL_VALUE_PRIVATE_H__ */ diff --git a/gsk/gskspvwriter.c b/gsk/gskspvwriter.c index a514b156a6..b00ae63951 100644 --- a/gsk/gskspvwriter.c +++ b/gsk/gskspvwriter.c @@ -23,6 +23,7 @@ #include "gskslnodeprivate.h" #include "gskslpointertypeprivate.h" #include "gsksltypeprivate.h" +#include "gskslvalueprivate.h" #include "gskslvariableprivate.h" struct _GskSpvWriter @@ -35,6 +36,7 @@ struct _GskSpvWriter guint32 entry_point; GHashTable *types; GHashTable *pointer_types; + GHashTable *values; GHashTable *variables; }; @@ -56,6 +58,8 @@ gsk_spv_writer_new (void) (GDestroyNotify) gsk_sl_type_unref, NULL); writer->pointer_types = g_hash_table_new_full (gsk_sl_pointer_type_hash, gsk_sl_pointer_type_equal, (GDestroyNotify) gsk_sl_pointer_type_unref, NULL); + writer->values = g_hash_table_new_full (gsk_sl_value_hash, gsk_sl_value_equal, + (GDestroyNotify) gsk_sl_value_free, NULL); writer->variables = g_hash_table_new_full (g_direct_hash, g_direct_equal, (GDestroyNotify) gsk_sl_variable_unref, NULL); /* the ID 1 is reserved for the GLSL instruction set (for now) */ @@ -93,6 +97,7 @@ gsk_spv_writer_unref (GskSpvWriter *writer) g_hash_table_destroy (writer->pointer_types); g_hash_table_destroy (writer->types); + g_hash_table_destroy (writer->values); g_hash_table_destroy (writer->variables); g_slice_free (GskSpvWriter, writer); @@ -196,6 +201,21 @@ gsk_spv_writer_get_id_for_pointer_type (GskSpvWriter *writer, return result; } +guint32 +gsk_spv_writer_get_id_for_value (GskSpvWriter *writer, + GskSlValue *value) +{ + guint32 result; + + result = GPOINTER_TO_UINT (g_hash_table_lookup (writer->values, value)); + if (result != 0) + return result; + + result = gsk_sl_value_write_spv (value, writer); + g_hash_table_insert (writer->values, gsk_sl_value_copy (value), GUINT_TO_POINTER (result)); + return result; +} + guint32 gsk_spv_writer_get_id_for_variable (GskSpvWriter *writer, GskSlVariable *variable) diff --git a/gsk/gskspvwriterprivate.h b/gsk/gskspvwriterprivate.h index 8c699f3c4a..321c138515 100644 --- a/gsk/gskspvwriterprivate.h +++ b/gsk/gskspvwriterprivate.h @@ -182,6 +182,8 @@ guint32 gsk_spv_writer_get_id_for_type (GskSpvWriter GskSlType *type); guint32 gsk_spv_writer_get_id_for_pointer_type (GskSpvWriter *writer, GskSlPointerType *type); +guint32 gsk_spv_writer_get_id_for_value (GskSpvWriter *writer, + GskSlValue *value); guint32 gsk_spv_writer_get_id_for_variable (GskSpvWriter *writer, GskSlVariable *variable); diff --git a/gsk/meson.build b/gsk/meson.build index 2cc643196f..9e8ff5843f 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -43,6 +43,7 @@ gsk_private_sources = files([ 'gskslscope.c', 'gsksltokenizer.c', 'gsksltype.c', + 'gskslvalue.c', 'gskslvariable.c', 'gskspvwriter.c' ])