gskslprogram: Allow variables to have constant initializers

Technically, all intiializers should be allowed, but for now we're happy
we can do const ones.

Also store them properly in the SPIR-V output.
This commit is contained in:
Benjamin Otte
2017-09-26 18:08:05 +02:00
parent 850c6d1116
commit 7e4d163f11
3 changed files with 61 additions and 7 deletions

View File

@@ -132,7 +132,7 @@ gsk_sl_node_declaration_write_spv (const GskSlNode *node,
variable_id = gsk_spv_writer_get_id_for_variable (writer, declaration->variable);
if (declaration->initial)
if (declaration->initial && ! gsk_sl_variable_get_initial_value (declaration->variable))
{
gsk_spv_writer_add (writer,
GSK_SPV_WRITER_SECTION_CODE,

View File

@@ -20,6 +20,7 @@
#include "gskslprogramprivate.h"
#include "gskslexpressionprivate.h"
#include "gskslfunctionprivate.h"
#include "gskslnodeprivate.h"
#include "gskslpointertypeprivate.h"
@@ -27,6 +28,7 @@
#include "gskslscopeprivate.h"
#include "gsksltokenizerprivate.h"
#include "gsksltypeprivate.h"
#include "gskslvalueprivate.h"
#include "gskslvariableprivate.h"
#include "gskspvwriterprivate.h"
@@ -76,15 +78,55 @@ gsk_sl_program_parse_variable (GskSlProgram *program,
{
GskSlVariable *variable;
const GskSlToken *token;
GskSlValue *value = NULL;
GskSlPointerType *pointer_type;
token = gsk_sl_preprocessor_get (preproc);
if (gsk_sl_token_is (token, GSK_SL_TOKEN_EQUAL))
{
GskSlValue *unconverted;
GskSlExpression *initial;
gsk_sl_preprocessor_consume (preproc, program);
initial = gsk_sl_expression_parse_assignment (scope, preproc);
if (initial == NULL)
return FALSE;
if (!gsk_sl_type_can_convert (type, gsk_sl_expression_get_return_type (initial)))
{
gsk_sl_preprocessor_error (preproc, "Cannot convert from initializer type %s to variable type %s",
gsk_sl_type_get_name (gsk_sl_expression_get_return_type (initial)),
gsk_sl_type_get_name (type));
gsk_sl_expression_unref (initial);
return FALSE;
}
unconverted = gsk_sl_expression_get_constant (initial);
gsk_sl_expression_unref (initial);
if (unconverted)
{
value = gsk_sl_value_new_convert (unconverted, type);
gsk_sl_value_free (unconverted);
}
else
{
gsk_sl_preprocessor_error (preproc, "Initializer is not constant.");
return FALSE;
}
token = gsk_sl_preprocessor_get (preproc);
}
if (!gsk_sl_token_is (token, GSK_SL_TOKEN_SEMICOLON))
return FALSE;
{
gsk_sl_preprocessor_error (preproc, "No semicolon at end of variable declaration.");
return FALSE;
}
gsk_sl_preprocessor_consume (preproc, NULL);
pointer_type = gsk_sl_pointer_type_new (type, FALSE, decoration->values[GSK_SL_DECORATION_CALLER_ACCESS].value);
variable = gsk_sl_variable_new (pointer_type, g_strdup (name), NULL, decoration->values[GSK_SL_DECORATION_CONST].set);
variable = gsk_sl_variable_new (pointer_type, g_strdup (name), value, decoration->values[GSK_SL_DECORATION_CONST].set);
gsk_sl_pointer_type_unref (pointer_type);
program->variables = g_slist_append (program->variables, variable);
@@ -192,7 +234,14 @@ gsk_sl_program_print (GskSlProgram *program,
for (l = program->variables; l; l = l->next)
{
const GskSlValue *value;
gsk_sl_variable_print (l->data, string);
value = gsk_sl_variable_get_initial_value (l->data);
if (value)
{
g_string_append (string, " = ");
gsk_sl_value_print (value, string);
}
g_string_append (string, ";\n");
}

View File

@@ -124,16 +124,21 @@ guint32
gsk_sl_variable_write_spv (const GskSlVariable *variable,
GskSpvWriter *writer)
{
guint32 pointer_type_id, variable_id;
guint32 pointer_type_id, variable_id, value_id;
pointer_type_id = gsk_spv_writer_get_id_for_pointer_type (writer, variable->type);
variable_id = gsk_spv_writer_next_id (writer);
if (variable->initial_value)
value_id = gsk_spv_writer_get_id_for_value (writer, variable->initial_value);
else
value_id = 0;
gsk_spv_writer_add (writer,
GSK_SPV_WRITER_SECTION_CODE,
4, GSK_SPV_OP_VARIABLE,
(guint32[3]) { pointer_type_id,
variable->initial_value ? 5 : 4, GSK_SPV_OP_VARIABLE,
(guint32[4]) { pointer_type_id,
variable_id,
gsk_sl_pointer_type_get_storage_class (variable->type)});
gsk_sl_pointer_type_get_storage_class (variable->type),
value_id });
return variable_id;
}