glsl: Track explicit location in AST to IR translation
This commit is contained in:
@@ -1627,6 +1627,53 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
|
||||
qual_string);
|
||||
}
|
||||
|
||||
if (qual->flags.q.explicit_location) {
|
||||
const bool global_scope = (state->current_function == NULL);
|
||||
bool fail = false;
|
||||
const char *string = "";
|
||||
|
||||
/* In the vertex shader only shader inputs can be given explicit
|
||||
* locations.
|
||||
*
|
||||
* In the fragment shader only shader outputs can be given explicit
|
||||
* locations.
|
||||
*/
|
||||
switch (state->target) {
|
||||
case vertex_shader:
|
||||
if (!global_scope || (var->mode != ir_var_in)) {
|
||||
fail = true;
|
||||
string = "input";
|
||||
}
|
||||
break;
|
||||
|
||||
case geometry_shader:
|
||||
_mesa_glsl_error(loc, state,
|
||||
"geometry shader variables cannot be given "
|
||||
"explicit locations\n");
|
||||
break;
|
||||
|
||||
case fragment_shader:
|
||||
if (!global_scope || (var->mode != ir_var_in)) {
|
||||
fail = true;
|
||||
string = "output";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
_mesa_glsl_error(loc, state,
|
||||
"only %s shader %s variables can be given an "
|
||||
"explicit location\n",
|
||||
_mesa_glsl_shader_target_name(state->target),
|
||||
string);
|
||||
} else {
|
||||
var->explicit_location = true;
|
||||
var->location = (state->target == vertex_shader)
|
||||
? (qual->location + VERT_ATTRIB_GENERIC0)
|
||||
: (qual->location + FRAG_RESULT_DATA0);
|
||||
}
|
||||
}
|
||||
|
||||
if (var->type->is_array() && state->language_version != 110) {
|
||||
var->array_lvalue = true;
|
||||
}
|
||||
|
@@ -1071,6 +1071,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
|
||||
this->ir_type = ir_type_variable;
|
||||
this->type = type;
|
||||
this->name = talloc_strdup(this, name);
|
||||
this->explicit_location = false;
|
||||
this->location = -1;
|
||||
this->warn_extension = NULL;
|
||||
this->constant_value = NULL;
|
||||
|
@@ -288,6 +288,15 @@ public:
|
||||
unsigned pixel_center_integer:1;
|
||||
/*@}*/
|
||||
|
||||
/**
|
||||
* Was the location explicitly set in the shader?
|
||||
*
|
||||
* If the location is explicitly set in the shader, it \b cannot be changed
|
||||
* by the linker or by the API (e.g., calls to \c glBindAttribLocation have
|
||||
* no effect).
|
||||
*/
|
||||
unsigned explicit_location:1;
|
||||
|
||||
/**
|
||||
* Storage location of the base of this variable
|
||||
*
|
||||
|
@@ -51,6 +51,9 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
|
||||
var->warn_extension = this->warn_extension;
|
||||
var->origin_upper_left = this->origin_upper_left;
|
||||
var->pixel_center_integer = this->pixel_center_integer;
|
||||
var->explicit_location = this->explicit_location;
|
||||
if (this->explicit_location)
|
||||
var->location = this->location;
|
||||
|
||||
if (this->constant_value)
|
||||
var->constant_value = this->constant_value->clone(mem_ctx, ht);
|
||||
|
Reference in New Issue
Block a user