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);
|
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) {
|
if (var->type->is_array() && state->language_version != 110) {
|
||||||
var->array_lvalue = true;
|
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->ir_type = ir_type_variable;
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->name = talloc_strdup(this, name);
|
this->name = talloc_strdup(this, name);
|
||||||
|
this->explicit_location = false;
|
||||||
this->location = -1;
|
this->location = -1;
|
||||||
this->warn_extension = NULL;
|
this->warn_extension = NULL;
|
||||||
this->constant_value = NULL;
|
this->constant_value = NULL;
|
||||||
|
@@ -288,6 +288,15 @@ public:
|
|||||||
unsigned pixel_center_integer:1;
|
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
|
* 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->warn_extension = this->warn_extension;
|
||||||
var->origin_upper_left = this->origin_upper_left;
|
var->origin_upper_left = this->origin_upper_left;
|
||||||
var->pixel_center_integer = this->pixel_center_integer;
|
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)
|
if (this->constant_value)
|
||||||
var->constant_value = this->constant_value->clone(mem_ctx, ht);
|
var->constant_value = this->constant_value->clone(mem_ctx, ht);
|
||||||
|
Reference in New Issue
Block a user