summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl
diff options
context:
space:
mode:
authorIlia Mirkin <[email protected]>2016-07-06 19:35:16 -0400
committerIlia Mirkin <[email protected]>2016-08-12 20:21:08 -0400
commit1baae00089c7bf5f31424c1287aa24f8ce5981a3 (patch)
treeafb8142df612bce0cd69e7bf4c159c38edda36ca /src/compiler/glsl
parent0294dd00ccdab2c20d5df786ba780d7e091c2ab4 (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')
-rw-r--r--src/compiler/glsl/linker.cpp39
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;
}