{
unsigned count = 0;
- foreach_list (n, parameters) {
- ast_node *const ast = exec_node_data(ast_node, n, link);
+ foreach_list_typed(ast_node, ast, link, parameters) {
ir_rvalue *result = ast->hir(instructions, state);
ir_constant *const constant = result->constant_expression_value();
ralloc_asprintf_append(&str, "%s(", name);
const char *comma = "";
- foreach_list(node, parameters) {
- const ir_variable *const param = (ir_variable *) node;
-
+ foreach_in_list(const ir_variable, param, parameters) {
ralloc_asprintf_append(&str, "%s%s", comma, param->type->name);
comma = ", ";
}
return str;
}
+static bool
+verify_image_parameter(YYLTYPE *loc, _mesa_glsl_parse_state *state,
+ const ir_variable *formal, const ir_variable *actual)
+{
+ /**
+ * From the ARB_shader_image_load_store specification:
+ *
+ * "The values of image variables qualified with coherent,
+ * volatile, restrict, readonly, or writeonly may not be passed
+ * to functions whose formal parameters lack such
+ * qualifiers. [...] It is legal to have additional qualifiers
+ * on a formal parameter, but not to have fewer."
+ */
+ if (actual->data.image_coherent && !formal->data.image_coherent) {
+ _mesa_glsl_error(loc, state,
+ "function call parameter `%s' drops "
+ "`coherent' qualifier", formal->name);
+ return false;
+ }
+
+ if (actual->data.image_volatile && !formal->data.image_volatile) {
+ _mesa_glsl_error(loc, state,
+ "function call parameter `%s' drops "
+ "`volatile' qualifier", formal->name);
+ return false;
+ }
+
+ if (actual->data.image_restrict && !formal->data.image_restrict) {
+ _mesa_glsl_error(loc, state,
+ "function call parameter `%s' drops "
+ "`restrict' qualifier", formal->name);
+ return false;
+ }
+
+ if (actual->data.image_read_only && !formal->data.image_read_only) {
+ _mesa_glsl_error(loc, state,
+ "function call parameter `%s' drops "
+ "`readonly' qualifier", formal->name);
+ return false;
+ }
+
+ if (actual->data.image_write_only && !formal->data.image_write_only) {
+ _mesa_glsl_error(loc, state,
+ "function call parameter `%s' drops "
+ "`writeonly' qualifier", formal->name);
+ return false;
+ }
+
+ return true;
+}
+
/**
* Verify that 'out' and 'inout' actual parameters are lvalues. Also, verify
* that 'const_in' formal parameters (an extension in our IR) correspond to
exec_node *actual_ir_node = actual_ir_parameters.head;
exec_node *actual_ast_node = actual_ast_parameters.head;
- foreach_list(formal_node, &sig->parameters) {
+ foreach_in_list(const ir_variable, formal, &sig->parameters) {
/* The lists must be the same length. */
assert(!actual_ir_node->is_tail_sentinel());
assert(!actual_ast_node->is_tail_sentinel());
- const ir_variable *const formal = (ir_variable *) formal_node;
const ir_rvalue *const actual = (ir_rvalue *) actual_ir_node;
const ast_expression *const actual_ast =
exec_node_data(ast_expression, actual_ast_node, link);
return false;
}
+ /* Verify that shader_in parameters are shader inputs */
+ if (formal->data.must_be_shader_input) {
+ ir_variable *var = actual->variable_referenced();
+ if (var && var->data.mode != ir_var_shader_in) {
+ _mesa_glsl_error(&loc, state,
+ "parameter `%s` must be a shader input",
+ formal->name);
+ return false;
+ }
+
+ if (actual->ir_type == ir_type_swizzle) {
+ _mesa_glsl_error(&loc, state,
+ "parameter `%s` must not be swizzled",
+ formal->name);
+ return false;
+ }
+ }
+
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
if (formal->data.mode == ir_var_function_out
|| formal->data.mode == ir_var_function_inout) {
}
}
+ if (formal->type->is_image() &&
+ actual->variable_referenced()) {
+ if (!verify_image_parameter(&loc, state, formal,
+ actual->variable_referenced()))
+ return false;
+ }
+
actual_ir_node = actual_ir_node->next;
actual_ast_node = actual_ast_node->next;
}
* call takes place. Since we haven't emitted the call yet, we'll place
* the post-call conversions in a temporary exec_list, and emit them later.
*/
- exec_list_iterator actual_iter = actual_parameters->iterator();
- exec_list_iterator formal_iter = sig->parameters.iterator();
-
- while (actual_iter.has_next()) {
- ir_rvalue *actual = (ir_rvalue *) actual_iter.get();
- ir_variable *formal = (ir_variable *) formal_iter.get();
-
- assert(actual != NULL);
- assert(formal != NULL);
+ foreach_two_lists(formal_node, &sig->parameters,
+ actual_node, actual_parameters) {
+ ir_rvalue *actual = (ir_rvalue *) actual_node;
+ ir_variable *formal = (ir_variable *) formal_node;
if (formal->type->is_numeric() || formal->type->is_boolean()) {
switch (formal->data.mode) {
break;
}
}
-
- actual_iter.next();
- formal_iter.next();
}
/* If the function call is a constant expression, don't generate any
ir_dereference_variable *deref = NULL;
if (!sig->return_type->is_void()) {
/* Create a new temporary to hold the return value. */
+ char *const name = ir_variable::temporaries_allocate_names
+ ? ralloc_asprintf(ctx, "%s_retval", sig->function_name())
+ : NULL;
+
ir_variable *var;
- var = new(ctx) ir_variable(sig->return_type,
- ralloc_asprintf(ctx, "%s_retval",
- sig->function_name()),
- ir_var_temporary);
+ var = new(ctx) ir_variable(sig->return_type, name, ir_var_temporary);
instructions->push_tail(var);
+ ralloc_free(name);
+
deref = new(ctx) ir_dereference_variable(var);
}
ir_call *call = new(ctx) ir_call(sig, deref, actual_parameters);
goto done; /* no match */
if (f != NULL) {
+ /* In desktop GL, the presence of a user-defined signature hides any
+ * built-in signatures, so we must ignore them. In contrast, in ES2
+ * user-defined signatures add new overloads, so we must consider them.
+ */
+ bool allow_builtins = state->es_shader || !f->has_user_signature();
+
/* Look for a match in the local shader. If exact, we're done. */
bool is_exact = false;
sig = local_sig = f->matching_signature(state, actual_parameters,
- &is_exact);
+ allow_builtins, &is_exact);
if (is_exact)
goto done;
- if (!state->es_shader && f->has_user_signature()) {
- /* In desktop GL, the presence of a user-defined signature hides any
- * built-in signatures, so we must ignore them. In contrast, in ES2
- * user-defined signatures add new overloads, so we must proceed.
- */
+ if (!allow_builtins)
goto done;
- }
}
/* Local shader has no exact candidates; check the built-ins. */
if (f == NULL)
return;
- foreach_list (node, &f->signatures) {
- ir_function_signature *sig = (ir_function_signature *) node;
-
+ foreach_in_list(ir_function_signature, sig, &f->signatures) {
if (sig->is_builtin() && !sig->is_builtin_available(state))
continue;
exec_list *actual_parameters,
_mesa_glsl_parse_state *state)
{
- char *str = prototype_string(NULL, name, actual_parameters);
- _mesa_glsl_error(loc, state,
- "no matching function for call to `%s'; candidates are:",
- str);
- ralloc_free(str);
+ gl_shader *sh = _mesa_glsl_get_builtin_function_shader();
- print_function_prototypes(state, loc, state->symbols->get_function(name));
+ if (state->symbols->get_function(name) == NULL
+ && (!state->uses_builtin_functions
+ || sh->symbols->get_function(name) == NULL)) {
+ _mesa_glsl_error(loc, state, "no function with name '%s'", name);
+ } else {
+ char *str = prototype_string(NULL, name, actual_parameters);
+ _mesa_glsl_error(loc, state,
+ "no matching function for call to `%s'; candidates are:",
+ str);
+ ralloc_free(str);
+
+ print_function_prototypes(state, loc, state->symbols->get_function(name));
- if (state->uses_builtin_functions) {
- gl_shader *sh = _mesa_glsl_get_builtin_function_shader();
- print_function_prototypes(state, loc, sh->symbols->get_function(name));
+ if (state->uses_builtin_functions) {
+ print_function_prototypes(state, loc, sh->symbols->get_function(name));
+ }
}
}
bool all_parameters_are_constant = true;
/* Type cast each parameter and, if possible, fold constants. */
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *ir = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
ir_rvalue *result = ir;
/* Apply implicit conversions (not the scalar constructor rules!). See
glsl_type::get_instance(GLSL_TYPE_FLOAT,
ir->type->vector_elements,
ir->type->matrix_columns);
- if (result->type->can_implicitly_convert_to(desired_type)) {
+ if (result->type->can_implicitly_convert_to(desired_type, state)) {
/* Even though convert_component() implements the constructor
* conversion rules (not the implicit conversion rules), its safe
* to use it here because we already checked that the implicit
instructions->push_tail(var);
int i = 0;
- foreach_list(node, &actual_parameters) {
- ir_rvalue *rhs = (ir_rvalue *) node;
- ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
- new(ctx) ir_constant(i));
- ir_instruction *assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
+ foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
+ ir_instruction *assignment = NULL;
+
+ if (var->type->is_matrix()) {
+ ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
+ new(ctx) ir_constant(i));
+ assignment = new(ctx) ir_assignment(lhs, rhs, NULL);
+ } else {
+ /* use writemask rather than index for vector */
+ assert(var->type->is_vector());
+ assert(i < 4);
+ ir_dereference *lhs = new(ctx) ir_dereference_variable(var);
+ assignment = new(ctx) ir_assignment(lhs, rhs, NULL, (unsigned)(1 << i));
+ }
+
instructions->push_tail(assignment);
i++;
bool all_parameters_are_constant = true;
/* Type cast each parameter and, if possible, fold constants. */
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *ir = (ir_rvalue *) n;
+ foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
ir_rvalue *result = ir;
/* Apply implicit conversions (not the scalar constructor rules!). See
glsl_type::get_instance(GLSL_TYPE_FLOAT,
ir->type->vector_elements,
ir->type->matrix_columns);
- if (result->type->can_implicitly_convert_to(desired_type)) {
+ if (result->type->can_implicitly_convert_to(desired_type, state)) {
/* Even though convert_component() implements the constructor
* conversion rules (not the implicit conversion rules), its safe
* to use it here because we already checked that the implicit
instructions->push_tail(var);
int i = 0;
- foreach_list(node, &actual_parameters) {
- ir_rvalue *rhs = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, rhs, &actual_parameters) {
ir_rvalue *lhs = new(ctx) ir_dereference_array(var,
new(ctx) ir_constant(i));
constant_record_constructor(const glsl_type *constructor_type,
exec_list *parameters, void *mem_ctx)
{
- foreach_list(node, parameters) {
- ir_constant *constant = ((ir_instruction *) node)->as_constant();
+ foreach_in_list(ir_instruction, node, parameters) {
+ ir_constant *constant = node->as_constant();
if (constant == NULL)
return NULL;
node->replace_with(constant);
memset(&data, 0, sizeof(data));
- foreach_list(node, parameters) {
- ir_rvalue *param = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, param, parameters) {
unsigned rhs_components = param->type->components();
/* Do not try to assign more components to the vector than it has!
}
base_component = 0;
- foreach_list(node, parameters) {
- ir_rvalue *param = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, param, parameters) {
unsigned rhs_components = param->type->components();
/* Do not try to assign more components to the vector than it has!
unsigned col_idx = 0;
unsigned row_idx = 0;
- foreach_list (node, parameters) {
- ir_rvalue *const rhs = (ir_rvalue *) node;
+ foreach_in_list(ir_rvalue, rhs, parameters) {
const unsigned components_remaining_this_column = rows - row_idx;
unsigned rhs_components = rhs->type->components();
unsigned rhs_base = 0;
unsigned nonmatrix_parameters = 0;
exec_list actual_parameters;
- foreach_list (n, &this->expressions) {
- ast_node *ast = exec_node_data(ast_node, n, link);
- ir_rvalue *result = ast->hir(instructions, state)->as_rvalue();
+ foreach_list_typed(ast_node, ast, link, &this->expressions) {
+ ir_rvalue *result = ast->hir(instructions, state);
/* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
*
* need to break them up into a series of column vectors.
*/
if (constructor_type->base_type != GLSL_TYPE_FLOAT) {
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *matrix = (ir_rvalue *) n;
-
+ foreach_in_list_safe(ir_rvalue, matrix, &actual_parameters) {
if (!matrix->type->is_matrix())
continue;
bool all_parameters_are_constant = true;
/* Type cast each parameter and, if possible, fold constants.*/
- foreach_list_safe(n, &actual_parameters) {
- ir_rvalue *ir = (ir_rvalue *) n;
-
+ foreach_in_list_safe(ir_rvalue, ir, &actual_parameters) {
const glsl_type *desired_type =
glsl_type::get_instance(constructor_type->base_type,
ir->type->vector_elements,
{
void *ctx = state;
YYLTYPE loc = this->get_location();
- const char *name;
if (!this->constructor_type) {
_mesa_glsl_error(&loc, state, "type of C-style initializer unknown");
return ir_rvalue::error_value(ctx);
}
- const glsl_type *const constructor_type =
- this->constructor_type->glsl_type(&name, state);
+ const glsl_type *const constructor_type = this->constructor_type;
if (!state->ARB_shading_language_420pack_enable) {
_mesa_glsl_error(&loc, state, "C-style initialization requires the "
return ir_rvalue::error_value(ctx);
}
- if (this->constructor_type->is_array) {
+ if (constructor_type->is_array()) {
return process_array_constructor(instructions, constructor_type, &loc,
&this->expressions, state);
}
- if (this->constructor_type->structure) {
+ if (constructor_type->is_record()) {
return process_record_constructor(instructions, constructor_type, &loc,
&this->expressions, state);
}