glsl: move array validation into its own function
V2: return true when var->type is unsized but max access is within valid range Reviewed-by: Mark Janes <mark.a.janes@intel.com>
This commit is contained in:
+50
-39
@@ -681,6 +681,45 @@ validate_geometry_shader_emissions(struct gl_context *ctx,
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
validate_intrastage_arrays(struct gl_shader_program *prog,
|
||||
ir_variable *const var,
|
||||
ir_variable *const existing)
|
||||
{
|
||||
/* Consider the types to be "the same" if both types are arrays
|
||||
* of the same type and one of the arrays is implicitly sized.
|
||||
* In addition, set the type of the linked variable to the
|
||||
* explicitly sized array.
|
||||
*/
|
||||
if (var->type->is_array() && existing->type->is_array() &&
|
||||
(var->type->fields.array == existing->type->fields.array) &&
|
||||
((var->type->length == 0)|| (existing->type->length == 0))) {
|
||||
if (var->type->length != 0) {
|
||||
if (var->type->length <= existing->data.max_array_access) {
|
||||
linker_error(prog, "%s `%s' declared as type "
|
||||
"`%s' but outermost dimension has an index"
|
||||
" of `%i'\n",
|
||||
mode_string(var),
|
||||
var->name, var->type->name,
|
||||
existing->data.max_array_access);
|
||||
}
|
||||
existing->type = var->type;
|
||||
return true;
|
||||
} else if (existing->type->length != 0) {
|
||||
if(existing->type->length <= var->data.max_array_access) {
|
||||
linker_error(prog, "%s `%s' declared as type "
|
||||
"`%s' but outermost dimension has an index"
|
||||
" of `%i'\n",
|
||||
mode_string(var),
|
||||
var->name, existing->type->name,
|
||||
var->data.max_array_access);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Perform validation of global variables used across multiple shaders
|
||||
@@ -720,50 +759,22 @@ cross_validate_globals(struct gl_shader_program *prog,
|
||||
*/
|
||||
ir_variable *const existing = variables.get_variable(var->name);
|
||||
if (existing != NULL) {
|
||||
/* Check if types match. Interface blocks have some special
|
||||
* rules so we handle those elsewhere.
|
||||
*/
|
||||
if (var->type != existing->type) {
|
||||
/* Consider the types to be "the same" if both types are arrays
|
||||
* of the same type and one of the arrays is implicitly sized.
|
||||
* In addition, set the type of the linked variable to the
|
||||
* explicitly sized array.
|
||||
*/
|
||||
if (var->type->is_array()
|
||||
&& existing->type->is_array()
|
||||
&& (var->type->fields.array == existing->type->fields.array)
|
||||
&& ((var->type->length == 0)
|
||||
|| (existing->type->length == 0))) {
|
||||
if (var->type->length != 0) {
|
||||
if (var->type->length <= existing->data.max_array_access) {
|
||||
linker_error(prog, "%s `%s' declared as type "
|
||||
"`%s' but outermost dimension has an index"
|
||||
" of `%i'\n",
|
||||
mode_string(var),
|
||||
var->name, var->type->name,
|
||||
existing->data.max_array_access);
|
||||
return;
|
||||
}
|
||||
existing->type = var->type;
|
||||
} else if (existing->type->length != 0
|
||||
&& existing->type->length <=
|
||||
var->data.max_array_access) {
|
||||
if (!validate_intrastage_arrays(prog, var, existing)) {
|
||||
if (var->type->is_record() && existing->type->is_record()
|
||||
&& existing->type->record_compare(var->type)) {
|
||||
existing->type = var->type;
|
||||
} else {
|
||||
linker_error(prog, "%s `%s' declared as type "
|
||||
"`%s' but outermost dimension has an index"
|
||||
" of `%i'\n",
|
||||
"`%s' and type `%s'\n",
|
||||
mode_string(var),
|
||||
var->name, existing->type->name,
|
||||
var->data.max_array_access);
|
||||
var->name, var->type->name,
|
||||
existing->type->name);
|
||||
return;
|
||||
}
|
||||
} else if (var->type->is_record()
|
||||
&& existing->type->is_record()
|
||||
&& existing->type->record_compare(var->type)) {
|
||||
existing->type = var->type;
|
||||
} else {
|
||||
linker_error(prog, "%s `%s' declared as type "
|
||||
"`%s' and type `%s'\n",
|
||||
mode_string(var),
|
||||
var->name, var->type->name,
|
||||
existing->type->name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,11 @@ link_uniform_blocks(void *mem_ctx,
|
||||
unsigned num_shaders,
|
||||
struct gl_uniform_block **blocks_ret);
|
||||
|
||||
bool
|
||||
validate_intrastage_arrays(struct gl_shader_program *prog,
|
||||
ir_variable *const var,
|
||||
ir_variable *const existing);
|
||||
|
||||
void
|
||||
validate_intrastage_interface_blocks(struct gl_shader_program *prog,
|
||||
const gl_shader **shader_list,
|
||||
|
||||
Reference in New Issue
Block a user