diff options
author | Ilia Mirkin <[email protected]> | 2016-07-06 19:35:16 -0400 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2016-08-12 20:21:08 -0400 |
commit | 1baae00089c7bf5f31424c1287aa24f8ce5981a3 (patch) | |
tree | afb8142df612bce0cd69e7bf4c159c38edda36ca /src/compiler/glsl/linker.cpp | |
parent | 0294dd00ccdab2c20d5df786ba780d7e091c2ab4 (diff) |
glsl: look for frag data bindings with [0] tacked onto the end for arrays
The GL spec is very unclear on this point. Apparently this is discussed
without resolution in the closed Khronos bugtracker at
https://cvs.khronos.org/bugzilla/show_bug.cgi?id=7829 . The
recommendation is to allow dropping the [0] for looking up the bindings.
The approach taken in this patch is to instead tack on [0]'s for each
arrayness level of the output's type, and doing the lookup again. That
way, for
out vec4 foo[2][2][2]
we will end up looking for bindings for foo, foo[0], foo[0][0], and
foo[0][0][0], in that order of preference.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=96765
Signed-off-by: Ilia Mirkin <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/compiler/glsl/linker.cpp')
-rw-r--r-- | src/compiler/glsl/linker.cpp | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index 7a3d35f9253..51d7643fa40 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -2530,6 +2530,7 @@ find_available_slots(unsigned used_mask, unsigned needed_count) /** * Assign locations for either VS inputs or FS outputs * + * \param mem_ctx Temporary ralloc context used for linking * \param prog Shader program whose variables need locations assigned * \param constants Driver specific constant values for the program. * \param target_index Selector for the program target to receive location @@ -2541,7 +2542,8 @@ find_available_slots(unsigned used_mask, unsigned needed_count) * error is emitted to the shader link log and false is returned. */ bool -assign_attribute_or_color_locations(gl_shader_program *prog, +assign_attribute_or_color_locations(void *mem_ctx, + gl_shader_program *prog, struct gl_constants *constants, unsigned target_index) { @@ -2644,16 +2646,31 @@ assign_attribute_or_color_locations(gl_shader_program *prog, } else if (target_index == MESA_SHADER_FRAGMENT) { unsigned binding; unsigned index; + const char *name = var->name; + const glsl_type *type = var->type; + + while (type) { + /* Check if there's a binding for the variable name */ + if (prog->FragDataBindings->get(binding, name)) { + assert(binding >= FRAG_RESULT_DATA0); + var->data.location = binding; + var->data.is_unmatched_generic_inout = 0; + + if (prog->FragDataIndexBindings->get(index, name)) { + var->data.index = index; + } + break; + } - if (prog->FragDataBindings->get(binding, var->name)) { - assert(binding >= FRAG_RESULT_DATA0); - var->data.location = binding; - var->data.is_unmatched_generic_inout = 0; + /* If not, but it's an array type, look for name[0] */ + if (type->is_array()) { + name = ralloc_asprintf(mem_ctx, "%s[0]", name); + type = type->fields.array; + continue; + } - if (prog->FragDataIndexBindings->get(index, var->name)) { - var->data.index = index; - } - } + break; + } } /* From GL4.5 core spec, section 15.2 (Shader Execution): @@ -4505,12 +4522,12 @@ link_varyings_and_uniforms(unsigned first, unsigned last, prev = i; } - if (!assign_attribute_or_color_locations(prog, &ctx->Const, + if (!assign_attribute_or_color_locations(mem_ctx, prog, &ctx->Const, MESA_SHADER_VERTEX)) { return false; } - if (!assign_attribute_or_color_locations(prog, &ctx->Const, + if (!assign_attribute_or_color_locations(mem_ctx, prog, &ctx->Const, MESA_SHADER_FRAGMENT)) { return false; } |