From 94ed482c19916ddede91c3c2ea3a538039ddb489 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Tue, 29 Mar 2016 14:15:14 -0700 Subject: [PATCH] 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 Reviewed-by: Timothy Arceri --- src/compiler/glsl/linker.cpp | 18 +++++++++++++----- src/mesa/main/shader_query.cpp | 11 +++-------- 2 files changed, 16 insertions(+), 13 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, diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 190f6387987..4650a5c9ef1 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -780,10 +780,6 @@ program_resource_location(struct gl_shader_program *shProg, struct gl_program_resource *res, const char *name, unsigned array_index) { - /* VERT_ATTRIB_GENERIC0 and FRAG_RESULT_DATA0 are decremented as these - * offsets are used internally to differentiate between built-in attributes - * and user-defined attributes. - */ switch (res->Type) { case GL_PROGRAM_INPUT: { const gl_shader_variable *var = RESOURCE_VAR(res); @@ -796,9 +792,8 @@ program_resource_location(struct gl_shader_program *shProg, && array_index >= var->type->length) { return -1; } - return (var->location + - (array_index * var->type->without_array()->matrix_columns) - - VERT_ATTRIB_GENERIC0); + return var->location + + (array_index * var->type->without_array()->matrix_columns); } case GL_PROGRAM_OUTPUT: if (RESOURCE_VAR(res)->location == -1) @@ -809,7 +804,7 @@ program_resource_location(struct gl_shader_program *shProg, && array_index >= RESOURCE_VAR(res)->type->length) { return -1; } - return RESOURCE_VAR(res)->location + array_index - FRAG_RESULT_DATA0; + return RESOURCE_VAR(res)->location + array_index; case GL_UNIFORM: /* If the uniform is built-in, fail. */ if (RESOURCE_UNI(res)->builtin) -- 2.30.2