switch (from->base_type) {
case GLSL_TYPE_INT: return ir_unop_i2f;
case GLSL_TYPE_UINT: return ir_unop_u2f;
+ case GLSL_TYPE_DOUBLE: return ir_unop_d2f;
default: return (ir_expression_operation)0;
}
default: return (ir_expression_operation)0;
}
+ case GLSL_TYPE_DOUBLE:
+ if (!state->has_double())
+ return (ir_expression_operation)0;
+ switch (from->base_type) {
+ case GLSL_TYPE_INT: return ir_unop_i2d;
+ case GLSL_TYPE_UINT: return ir_unop_u2d;
+ case GLSL_TYPE_FLOAT: return ir_unop_f2d;
+ default: return (ir_expression_operation)0;
+ }
+
default: return (ir_expression_operation)0;
}
}
* type of both operands must be float.
*/
assert(type_a->is_matrix() || type_b->is_matrix());
- assert(type_a->base_type == GLSL_TYPE_FLOAT);
- assert(type_b->base_type == GLSL_TYPE_FLOAT);
+ assert(type_a->base_type == GLSL_TYPE_FLOAT ||
+ type_a->base_type == GLSL_TYPE_DOUBLE);
+ assert(type_b->base_type == GLSL_TYPE_FLOAT ||
+ type_b->base_type == GLSL_TYPE_DOUBLE);
/* "* The operator is add (+), subtract (-), or divide (/), and the
* operands are matrices with the same number of rows and the same
var = new(ctx) ir_variable(lvalue->type, "_post_incdec_tmp",
ir_var_temporary);
instructions->push_tail(var);
- var->data.mode = ir_var_auto;
instructions->push_tail(new(ctx) ir_assignment(new(ctx) ir_dereference_variable(var),
lvalue));
case GLSL_TYPE_UINT:
case GLSL_TYPE_INT:
case GLSL_TYPE_BOOL:
+ case GLSL_TYPE_DOUBLE:
return new(mem_ctx) ir_expression(operation, op0, op1);
case GLSL_TYPE_ARRAY: {
}
ir_constant *cond_val = op[0]->constant_expression_value();
- ir_constant *then_val = op[1]->constant_expression_value();
- ir_constant *else_val = op[2]->constant_expression_value();
if (then_instructions.is_empty()
&& else_instructions.is_empty()
- && (cond_val != NULL) && (then_val != NULL) && (else_val != NULL)) {
- result = (cond_val->value.b[0]) ? then_val : else_val;
+ && cond_val != NULL) {
+ result = cond_val->value.b[0] ? op[1] : op[2];
} else {
ir_variable *const tmp =
new(ctx) ir_variable(type, "conditional_tmp", ir_var_temporary);
result = new(ctx) ir_constant(bool(this->primary_expression.bool_constant));
break;
+ case ast_double_constant:
+ result = new(ctx) ir_constant(this->primary_expression.double_constant);
+ break;
+
case ast_sequence: {
/* It should not be possible to generate a sequence in the AST without
* any expressions in it.
"global variables");
}
- var->data.image.read_only |= qual->flags.q.read_only;
- var->data.image.write_only |= qual->flags.q.write_only;
- var->data.image.coherent |= qual->flags.q.coherent;
- var->data.image._volatile |= qual->flags.q._volatile;
- var->data.image.restrict_flag |= qual->flags.q.restrict_flag;
+ var->data.image_read_only |= qual->flags.q.read_only;
+ var->data.image_write_only |= qual->flags.q.write_only;
+ var->data.image_coherent |= qual->flags.q.coherent;
+ var->data.image_volatile |= qual->flags.q._volatile;
+ var->data.image_restrict |= qual->flags.q.restrict_flag;
var->data.read_only = true;
if (qual->flags.q.explicit_image_format) {
"base data type of the image");
}
- var->data.image.format = qual->image_format;
+ var->data.image_format = qual->image_format;
} else {
if (var->data.mode == ir_var_uniform && !qual->flags.q.write_only) {
_mesa_glsl_error(loc, state, "uniforms not qualified with "
"qualifier");
}
- var->data.image.format = GL_NONE;
+ var->data.image_format = GL_NONE;
}
}
}
/* If there is no qualifier that changes the mode of the variable, leave
* the setting alone.
*/
+ assert(var->data.mode != ir_var_temporary);
if (qual->flags.q.in && qual->flags.q.out)
var->data.mode = ir_var_function_inout;
else if (qual->flags.q.in)
_mesa_glsl_error(loc, state,
"varying variables may not be of type struct");
break;
+ case GLSL_TYPE_DOUBLE:
+ break;
default:
_mesa_glsl_error(loc, state, "illegal type for a varying variable");
break;
}
}
+static bool
+precision_qualifier_allowed(const glsl_type *type)
+{
+ /* Precision qualifiers apply to floating point, integer and sampler
+ * types.
+ *
+ * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says:
+ * "Any floating point or any integer declaration can have the type
+ * preceded by one of these precision qualifiers [...] Literal
+ * constants do not have precision qualifiers. Neither do Boolean
+ * variables.
+ *
+ * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30
+ * spec also says:
+ *
+ * "Precision qualifiers are added for code portability with OpenGL
+ * ES, not for functionality. They have the same syntax as in OpenGL
+ * ES."
+ *
+ * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says:
+ *
+ * "uniform lowp sampler2D sampler;
+ * highp vec2 coord;
+ * ...
+ * lowp vec4 col = texture2D (sampler, coord);
+ * // texture2D returns lowp"
+ *
+ * From this, we infer that GLSL 1.30 (and later) should allow precision
+ * qualifiers on sampler types just like float and integer types.
+ */
+ return type->is_float()
+ || type->is_integer()
+ || type->is_record()
+ || type->is_sampler();
+}
ir_rvalue *
ast_declarator_list::hir(exec_list *instructions,
handle_geometry_shader_input_decl(state, loc, var);
}
+ } else if (var->data.mode == ir_var_shader_out) {
+ const glsl_type *check_type = var->type->without_array();
+
+ /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec:
+ *
+ * It is a compile-time error to declare a vertex, tessellation
+ * evaluation, tessellation control, or geometry shader output
+ * that contains any of the following:
+ *
+ * * A Boolean type (bool, bvec2 ...)
+ * * An opaque type
+ */
+ if (check_type->is_boolean() || check_type->contains_opaque())
+ _mesa_glsl_error(&loc, state,
+ "%s shader output cannot have type %s",
+ _mesa_shader_stage_to_string(state->stage),
+ check_type->name);
+
+ /* From section 4.3.6 (Output variables) of the GLSL 4.40 spec:
+ *
+ * It is a compile-time error to declare a fragment shader output
+ * that contains any of the following:
+ *
+ * * A Boolean type (bool, bvec2 ...)
+ * * A double-precision scalar or vector (double, dvec2 ...)
+ * * An opaque type
+ * * Any matrix type
+ * * A structure
+ */
+ if (state->stage == MESA_SHADER_FRAGMENT) {
+ if (check_type->is_record() || check_type->is_matrix())
+ _mesa_glsl_error(&loc, state,
+ "fragment shader output "
+ "cannot have struct or array type");
+ switch (check_type->base_type) {
+ case GLSL_TYPE_UINT:
+ case GLSL_TYPE_INT:
+ case GLSL_TYPE_FLOAT:
+ break;
+ default:
+ _mesa_glsl_error(&loc, state,
+ "fragment shader output cannot have "
+ "type %s", check_type->name);
+ }
+ }
}
/* Integer fragment inputs must be qualified with 'flat'. In GLSL ES,
var_type);
}
+ /* Double fragment inputs must be qualified with 'flat'. */
+ if (var->type->contains_double() &&
+ var->data.interpolation != INTERP_QUALIFIER_FLAT &&
+ state->stage == MESA_SHADER_FRAGMENT &&
+ var->data.mode == ir_var_shader_in) {
+ _mesa_glsl_error(&loc, state, "if a fragment input is (or contains) "
+ "a double, then it must be qualified with 'flat'",
+ var_type);
+ }
/* Interpolation qualifiers cannot be applied to 'centroid' and
* 'centroid varying'.
}
- /* Precision qualifiers apply to floating point, integer and sampler
- * types.
- *
- * Section 4.5.2 (Precision Qualifiers) of the GLSL 1.30 spec says:
- * "Any floating point or any integer declaration can have the type
- * preceded by one of these precision qualifiers [...] Literal
- * constants do not have precision qualifiers. Neither do Boolean
- * variables.
- *
- * Section 4.5 (Precision and Precision Qualifiers) of the GLSL 1.30
- * spec also says:
- *
- * "Precision qualifiers are added for code portability with OpenGL
- * ES, not for functionality. They have the same syntax as in OpenGL
- * ES."
- *
- * Section 8 (Built-In Functions) of the GLSL ES 1.00 spec says:
- *
- * "uniform lowp sampler2D sampler;
- * highp vec2 coord;
- * ...
- * lowp vec4 col = texture2D (sampler, coord);
- * // texture2D returns lowp"
- *
- * From this, we infer that GLSL 1.30 (and later) should allow precision
- * qualifiers on sampler types just like float and integer types.
+ /* If a precision qualifier is allowed on a type, it is allowed on
+ * an array of that type.
*/
- if (this->type->qualifier.precision != ast_precision_none
- && !var->type->is_float()
- && !var->type->is_integer()
- && !var->type->is_record()
- && !var->type->is_sampler()
- && !(var->type->is_array()
- && (var->type->fields.array->is_float()
- || var->type->fields.array->is_integer()))) {
+ if (!(this->type->qualifier.precision == ast_precision_none
+ || precision_qualifier_allowed(var->type)
+ || (var->type->is_array()
+ && precision_qualifier_allowed(var->type->fields.array)))) {
_mesa_glsl_error(&loc, state,
"precision qualifiers apply only to floating point"
earlier->data.how_declared == ir_var_declared_in_block) {
_mesa_glsl_error(&loc, state,
"`%s' has already been redeclared using "
- "gl_PerVertex", var->name);
+ "gl_PerVertex", earlier->name);
}
earlier->data.how_declared = ir_var_declared_normally;
}
name);
}
+ /* Create an ir_function if one doesn't already exist. */
+ f = state->symbols->get_function(name);
+ if (f == NULL) {
+ f = new(ctx) ir_function(name);
+ if (!state->symbols->add_function(f)) {
+ /* This function name shadows a non-function use of the same name. */
+ YYLTYPE loc = this->get_location();
+
+ _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
+ "non-function", name);
+ return NULL;
+ }
+
+ emit_function(state, f);
+ }
+
+ /* From GLSL ES 3.0 spec, chapter 6.1 "Function Definitions", page 71:
+ *
+ * "A shader cannot redefine or overload built-in functions."
+ *
+ * While in GLSL ES 1.0 specification, chapter 8 "Built-in Functions":
+ *
+ * "User code can overload the built-in functions but cannot redefine
+ * them."
+ */
+ if (state->es_shader && state->language_version >= 300) {
+ /* Local shader has no exact candidates; check the built-ins. */
+ _mesa_glsl_initialize_builtin_functions();
+ if (_mesa_glsl_find_builtin_function_by_name(state, name)) {
+ YYLTYPE loc = this->get_location();
+ _mesa_glsl_error(& loc, state,
+ "A shader cannot redefine or overload built-in "
+ "function `%s' in GLSL ES 3.00", name);
+ return NULL;
+ }
+ }
+
/* Verify that this function's signature either doesn't match a previously
* seen signature for a function with the same name, or, if a match is found,
* that the previously seen signature does not have an associated definition.
*/
- f = state->symbols->get_function(name);
- if (f != NULL && (state->es_shader || f->has_user_signature())) {
+ if (state->es_shader || f->has_user_signature()) {
sig = f->exact_matching_signature(state, &hir_parameters);
if (sig != NULL) {
const char *badvar = sig->qualifiers_match(&hir_parameters);
}
}
}
- } else {
- f = new(ctx) ir_function(name);
- if (!state->symbols->add_function(f)) {
- /* This function name shadows a non-function use of the same name. */
- YYLTYPE loc = this->get_location();
-
- _mesa_glsl_error(&loc, state, "function name `%s' conflicts with "
- "non-function", name);
- return NULL;
- }
-
- emit_function(state, f);
}
/* Verify the return type of main() */
* loop.
*/
if (state->loop_nesting_ast != NULL &&
- mode == ast_continue) {
+ mode == ast_continue && !state->switch_state.is_switch_innermost) {
if (state->loop_nesting_ast->rest_expression) {
state->loop_nesting_ast->rest_expression->hir(instructions,
state);
}
if (state->switch_state.is_switch_innermost &&
+ mode == ast_continue) {
+ /* Set 'continue_inside' to true. */
+ ir_rvalue *const true_val = new (ctx) ir_constant(true);
+ ir_dereference_variable *deref_continue_inside_var =
+ new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+ instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
+ true_val));
+
+ /* Break out from the switch, continue for the loop will
+ * be called right after switch. */
+ ir_loop_jump *const jump =
+ new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+ instructions->push_tail(jump);
+
+ } else if (state->switch_state.is_switch_innermost &&
mode == ast_break) {
- /* Force break out of switch by setting is_break switch state.
- */
- ir_variable *const is_break_var = state->switch_state.is_break_var;
- ir_dereference_variable *const deref_is_break_var =
- new(ctx) ir_dereference_variable(is_break_var);
- ir_constant *const true_val = new(ctx) ir_constant(true);
- ir_assignment *const set_break_var =
- new(ctx) ir_assignment(deref_is_break_var, true_val);
-
- instructions->push_tail(set_break_var);
- }
- else {
+ /* Force break out of switch by inserting a break. */
+ ir_loop_jump *const jump =
+ new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+ instructions->push_tail(jump);
+ } else {
ir_loop_jump *const jump =
new(ctx) ir_loop_jump((mode == ast_break)
? ir_loop_jump::jump_break
instructions->push_tail(new(ctx) ir_assignment(deref_is_fallthru_var,
is_fallthru_val));
- /* Initalize is_break state to false.
+ /* Initialize continue_inside state to false.
*/
- ir_rvalue *const is_break_val = new (ctx) ir_constant(false);
- state->switch_state.is_break_var =
+ state->switch_state.continue_inside =
new(ctx) ir_variable(glsl_type::bool_type,
- "switch_is_break_tmp",
+ "continue_inside_tmp",
ir_var_temporary);
- instructions->push_tail(state->switch_state.is_break_var);
+ instructions->push_tail(state->switch_state.continue_inside);
- ir_dereference_variable *deref_is_break_var =
- new(ctx) ir_dereference_variable(state->switch_state.is_break_var);
- instructions->push_tail(new(ctx) ir_assignment(deref_is_break_var,
- is_break_val));
+ ir_rvalue *const false_val = new (ctx) ir_constant(false);
+ ir_dereference_variable *deref_continue_inside_var =
+ new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+ instructions->push_tail(new(ctx) ir_assignment(deref_continue_inside_var,
+ false_val));
state->switch_state.run_default =
new(ctx) ir_variable(glsl_type::bool_type,
ir_var_temporary);
instructions->push_tail(state->switch_state.run_default);
+ /* Loop around the switch is used for flow control. */
+ ir_loop * loop = new(ctx) ir_loop();
+ instructions->push_tail(loop);
+
/* Cache test expression.
*/
- test_to_hir(instructions, state);
+ test_to_hir(&loop->body_instructions, state);
/* Emit code for body of switch stmt.
*/
- body->hir(instructions, state);
+ body->hir(&loop->body_instructions, state);
+
+ /* Insert a break at the end to exit loop. */
+ ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_break);
+ loop->body_instructions.push_tail(jump);
+
+ /* If we are inside loop, check if continue got called inside switch. */
+ if (state->loop_nesting_ast != NULL) {
+ ir_dereference_variable *deref_continue_inside =
+ new(ctx) ir_dereference_variable(state->switch_state.continue_inside);
+ ir_if *irif = new(ctx) ir_if(deref_continue_inside);
+ ir_loop_jump *jump = new(ctx) ir_loop_jump(ir_loop_jump::jump_continue);
+
+ if (state->loop_nesting_ast != NULL) {
+ if (state->loop_nesting_ast->rest_expression) {
+ state->loop_nesting_ast->rest_expression->hir(&irif->then_instructions,
+ state);
+ }
+ if (state->loop_nesting_ast->mode ==
+ ast_iteration_statement::ast_do_while) {
+ state->loop_nesting_ast->condition_to_hir(&irif->then_instructions, state);
+ }
+ }
+ irif->then_instructions.push_tail(jump);
+ instructions->push_tail(irif);
+ }
hash_table_dtor(state->switch_state.labels_ht);
{
labels->hir(instructions, state);
- /* Conditionally set fallthru state based on break state. */
- ir_constant *const false_val = new(state) ir_constant(false);
- ir_dereference_variable *const deref_is_fallthru_var =
- new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
- ir_dereference_variable *const deref_is_break_var =
- new(state) ir_dereference_variable(state->switch_state.is_break_var);
- ir_assignment *const reset_fallthru_on_break =
- new(state) ir_assignment(deref_is_fallthru_var,
- false_val,
- deref_is_break_var);
- instructions->push_tail(reset_fallthru_on_break);
-
/* Guard case statements depending on fallthru state. */
ir_dereference_variable *const deref_fallthru_guard =
new(state) ir_dereference_variable(state->switch_state.is_fallthru_var);
*/
ir_variable *const junk =
new(state) ir_variable(type, "#default precision",
- ir_var_temporary);
+ ir_var_auto);
state->symbols->add_variable(junk);
}
YYLTYPE &loc,
glsl_struct_field **fields_ret,
bool is_interface,
- bool block_row_major,
+ enum glsl_matrix_layout matrix_layout,
bool allow_reserved_names,
ir_variable_mode var_mode)
{
"members");
}
+ if (qual->flags.q.constant) {
+ YYLTYPE loc = decl_list->get_location();
+ _mesa_glsl_error(&loc, state,
+ "const storage qualifier cannot be applied "
+ "to struct or interface block members");
+ }
+
field_type = process_array_type(&loc, decl_type,
decl->array_specifier, state);
fields[i].type = field_type;
"in uniform blocks or structures.");
}
- if (field_type->without_array()->is_matrix()) {
- fields[i].row_major = block_row_major;
+ /* Propogate row- / column-major information down the fields of the
+ * structure or interface block. Structures need this data because
+ * the structure may contain a structure that contains ... a matrix
+ * that need the proper layout.
+ */
+ if (field_type->without_array()->is_matrix()
+ || field_type->without_array()->is_record()) {
+ /* If no layout is specified for the field, inherit the layout
+ * from the block.
+ */
+ fields[i].matrix_layout = matrix_layout;
+
if (qual->flags.q.row_major)
- fields[i].row_major = true;
+ fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
else if (qual->flags.q.column_major)
- fields[i].row_major = false;
+ fields[i].matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
+
+ /* If we're processing an interface block, the matrix layout must
+ * be decided by this point.
+ */
+ assert(!is_interface
+ || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR
+ || fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_COLUMN_MAJOR);
}
i++;
loc,
&fields,
false,
- false,
+ GLSL_MATRIX_LAYOUT_INHERITED,
false /* allow_reserved_names */,
ir_var_auto);
{
YYLTYPE loc = this->get_location();
+ /* Interface blocks must be declared at global scope */
+ if (state->current_function != NULL) {
+ _mesa_glsl_error(&loc, state,
+ "Interface block `%s' must be declared "
+ "at global scope",
+ this->block_name);
+ }
+
/* The ast_interface_block has a list of ast_declarator_lists. We
* need to turn those into ir_variables with an association
* with this uniform block.
assert(!"interface block layout qualifier not found!");
}
+ enum glsl_matrix_layout matrix_layout = GLSL_MATRIX_LAYOUT_INHERITED;
+ if (this->layout.flags.q.row_major)
+ matrix_layout = GLSL_MATRIX_LAYOUT_ROW_MAJOR;
+ else if (this->layout.flags.q.column_major)
+ matrix_layout = GLSL_MATRIX_LAYOUT_COLUMN_MAJOR;
+
bool redeclaring_per_vertex = strcmp(this->block_name, "gl_PerVertex") == 0;
- bool block_row_major = this->layout.flags.q.row_major;
exec_list declared_variables;
glsl_struct_field *fields;
loc,
&fields,
true,
- block_row_major,
+ matrix_layout,
redeclaring_per_vertex,
var_mode);
state->struct_specifier_depth--;
- if (!redeclaring_per_vertex)
+ if (!redeclaring_per_vertex) {
validate_identifier(this->block_name, loc, state);
+ /* From section 4.3.9 ("Interface Blocks") of the GLSL 4.50 spec:
+ *
+ * "Block names have no other use within a shader beyond interface
+ * matching; it is a compile-time error to use a block name at global
+ * scope for anything other than as a block name."
+ */
+ ir_variable *var = state->symbols->get_variable(this->block_name);
+ if (var && !var->type->is_interface()) {
+ _mesa_glsl_error(&loc, state, "Block name `%s' is "
+ "already used in the scope.",
+ this->block_name);
+ }
+ }
+
const glsl_type *earlier_per_vertex = NULL;
if (redeclaring_per_vertex) {
/* Find the previous declaration of gl_PerVertex. If we're redeclaring
}
if (this->instance_name != NULL) {
_mesa_glsl_error(&loc, state,
- "gl_PerVertex input may not be redeclared with "
+ "gl_PerVertex output may not be redeclared with "
"an instance name");
}
break;
var_mode);
}
+ var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
+ ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
+
if (state->stage == MESA_SHADER_GEOMETRY && var_mode == ir_var_shader_in)
handle_geometry_shader_input_decl(state, loc, var);
var->data.sample = fields[i].sample;
var->init_interface_type(block_type);
+ if (fields[i].matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED) {
+ var->data.matrix_layout = matrix_layout == GLSL_MATRIX_LAYOUT_INHERITED
+ ? GLSL_MATRIX_LAYOUT_COLUMN_MAJOR : matrix_layout;
+ } else {
+ var->data.matrix_layout = fields[i].matrix_layout;
+ }
+
if (fields[i].stream != -1 &&
((unsigned)fields[i].stream) != this->layout.stream) {
_mesa_glsl_error(&loc, state,
var->data.stream = this->layout.stream;
+ /* Examine var name here since var may get deleted in the next call */
+ bool var_is_gl_id = is_gl_identifier(var->name);
+
if (redeclaring_per_vertex) {
ir_variable *earlier =
get_variable_being_redeclared(var, loc, state,
true /* allow_all_redeclarations */);
- if (!is_gl_identifier(var->name) || earlier == NULL) {
+ if (!var_is_gl_id || earlier == NULL) {
_mesa_glsl_error(&loc, state,
"redeclaration of gl_PerVertex can only "
"include built-in variables");
} else if (earlier->data.how_declared == ir_var_declared_normally) {
_mesa_glsl_error(&loc, state,
- "`%s' has already been redeclared", var->name);
+ "`%s' has already been redeclared",
+ earlier->name);
} else {
earlier->data.how_declared = ir_var_declared_in_block;
earlier->reinit_interface_type(block_type);
* declare it earlier).
*/
ir_variable *var = new(state->symbols)
- ir_variable(glsl_type::ivec3_type, "gl_WorkGroupSize", ir_var_auto);
+ ir_variable(glsl_type::uvec3_type, "gl_WorkGroupSize", ir_var_auto);
var->data.how_declared = ir_var_declared_implicitly;
var->data.read_only = true;
instructions->push_tail(var);
ir_constant_data data;
memset(&data, 0, sizeof(data));
for (int i = 0; i < 3; i++)
- data.i[i] = this->local_size[i];
- var->constant_value = new(var) ir_constant(glsl_type::ivec3_type, &data);
+ data.u[i] = this->local_size[i];
+ var->constant_value = new(var) ir_constant(glsl_type::uvec3_type, &data);
var->constant_initializer =
- new(var) ir_constant(glsl_type::ivec3_type, &data);
+ new(var) ir_constant(glsl_type::uvec3_type, &data);
var->data.has_initializer = true;
return NULL;