summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/linker.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-03-29 14:15:14 -0700
committerKenneth Graunke <[email protected]>2016-04-01 22:05:20 -0700
commit94ed482c19916ddede91c3c2ea3a538039ddb489 (patch)
treef5ae21f660c357d74b33ce701a88d5c502ec77a7 /src/compiler/glsl/linker.cpp
parentc123294dfe2e52443f2eff2723ef922f22972ef5 (diff)
glsl: Fix prorgram interface query locations biasing for SSO.
With SSO, the GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT interfaces refer to the first and last shader stage linked into a program. This may not be the vertex and fragment shader stages. So, subtracting VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 is bogus. We need to subtract VERT_ATTRIB_GENERIC0 for VS inputs, FRAG_RESULT_DATA0 for FS outputs, and VARYING_SLOT_VAR0 for other cases. Note that built-in variables get a location of -1. Fixes 4 dEQP-GLES31.functional.program_interface_query tests: - program_input.location.separable_fragment.var_explicit_location - program_input.location.separable_fragment.var_array_explicit_location - program_output.location.separable_vertex.var_array_explicit_location - program_output.location.separable_vertex.var_array_explicit_location Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/compiler/glsl/linker.cpp')
-rw-r--r--src/compiler/glsl/linker.cpp18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp
index 71dbddd8763..736852e7809 100644
--- a/src/compiler/glsl/linker.cpp
+++ b/src/compiler/glsl/linker.cpp
@@ -3498,7 +3498,8 @@ build_stageref(struct gl_shader_program *shProg, const char *name,
*/
static gl_shader_variable *
create_shader_variable(struct gl_shader_program *shProg,
- const ir_variable *in, bool use_implicit_location)
+ const ir_variable *in, bool use_implicit_location,
+ int location_bias)
{
gl_shader_variable *out = ralloc(shProg, struct gl_shader_variable);
if (!out)
@@ -3536,7 +3537,7 @@ create_shader_variable(struct gl_shader_program *shProg,
!(in->data.explicit_location || use_implicit_location)) {
out->location = -1;
} else {
- out->location = in->data.location;
+ out->location = in->data.location - location_bias;
}
out->type = in->type;
@@ -3559,15 +3560,21 @@ add_interface_variables(struct gl_shader_program *shProg,
if (!var || var->data.how_declared == ir_var_hidden)
continue;
+ int loc_bias;
+
switch (var->data.mode) {
case ir_var_system_value:
case ir_var_shader_in:
if (programInterface != GL_PROGRAM_INPUT)
continue;
+ loc_bias = (stage == MESA_SHADER_VERTEX) ? int(VERT_ATTRIB_GENERIC0)
+ : int(VARYING_SLOT_VAR0);
break;
case ir_var_shader_out:
if (programInterface != GL_PROGRAM_OUTPUT)
continue;
+ loc_bias = (stage == MESA_SHADER_FRAGMENT) ? int(FRAG_RESULT_DATA0)
+ : int(VARYING_SLOT_VAR0);
break;
default:
continue;
@@ -3590,7 +3597,7 @@ add_interface_variables(struct gl_shader_program *shProg,
(stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_out);
gl_shader_variable *sha_v =
- create_shader_variable(shProg, var, vs_input_or_fs_output);
+ create_shader_variable(shProg, var, vs_input_or_fs_output, loc_bias);
if (!sha_v)
return false;
@@ -3625,7 +3632,7 @@ add_packed_varyings(struct gl_shader_program *shProg, int stage, GLenum type)
if (type == iface) {
gl_shader_variable *sha_v =
- create_shader_variable(shProg, var, false);
+ create_shader_variable(shProg, var, false, VARYING_SLOT_VAR0);
if (!sha_v)
return false;
if (!add_program_resource(shProg, iface, sha_v,
@@ -3650,7 +3657,8 @@ add_fragdata_arrays(struct gl_shader_program *shProg)
ir_variable *var = node->as_variable();
if (var) {
assert(var->data.mode == ir_var_shader_out);
- gl_shader_variable *sha_v = create_shader_variable(shProg, var, true);
+ gl_shader_variable *sha_v =
+ create_shader_variable(shProg, var, true, FRAG_RESULT_DATA0);
if (!sha_v)
return false;
if (!add_program_resource(shProg, GL_PROGRAM_OUTPUT, sha_v,