The code didn't deal with explicit function indexes properly.
It also handed out the indexes at link time, when we really
need them in the lowering pass to create the correct if ladder.
So this patch moves assigning the non-explicit indexes earlier,
fixes the lowering pass and the lookups to get the correct values.
This fixes a few of:
GL45-CTS.explicit_uniform_location.subroutine-index-*
Signed-off-by: Dave Airlie <airlied@redhat.com>
extern "C" {
+static void
+assign_subroutine_indexes(struct gl_shader *sh,
+ struct _mesa_glsl_parse_state *state)
+{
+ int j, k;
+ int index = 0;
+
+ for (j = 0; j < state->num_subroutines; j++) {
+ while (state->subroutines[j]->subroutine_index == -1) {
+ for (k = 0; k < state->num_subroutines; k++) {
+ if (state->subroutines[k]->subroutine_index == index)
+ break;
+ else if (k == state->num_subroutines - 1) {
+ state->subroutines[j]->subroutine_index = index;
+ }
+ }
+ index++;
+ }
+ }
+}
+
void
_mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *shader,
bool dump_ast, bool dump_hir)
struct gl_shader_compiler_options *options =
&ctx->Const.ShaderCompilerOptions[shader->Stage];
+ assign_subroutine_indexes(shader, state);
lower_subroutine(shader->ir, state);
/* Do some optimization at compile time to reduce shader IR size
* and reduce later work if the same shader is linked multiple times
if (sh == NULL)
continue;
+ sh->MaxSubroutineFunctionIndex = 0;
foreach_in_list(ir_instruction, node, sh->ir) {
ir_function *fn = node->as_function();
if (!fn)
if (!fn->num_subroutine_types)
continue;
+ /* these should have been calculated earlier. */
+ assert(fn->subroutine_index != -1);
if (sh->NumSubroutineFunctions + 1 > MAX_SUBROUTINES) {
linker_error(prog, "Too many subroutine functions declared.\n");
return;
sh->SubroutineFunctions[sh->NumSubroutineFunctions].index =
fn->subroutine_index;
+ if (fn->subroutine_index > (int)sh->MaxSubroutineFunctionIndex)
+ sh->MaxSubroutineFunctionIndex = fn->subroutine_index;
+
for (int j = 0; j < fn->num_subroutine_types; j++)
sh->SubroutineFunctions[sh->NumSubroutineFunctions].types[j] = fn->subroutine_types[j];
sh->NumSubroutineFunctions++;
}
-
- /* Assign index for subroutines without an explicit index*/
- int index = 0;
- for (unsigned j = 0; j < sh->NumSubroutineFunctions; j++) {
- while (sh->SubroutineFunctions[j].index == -1) {
- for (unsigned k = 0; k < sh->NumSubroutineFunctions; k++) {
- if (sh->SubroutineFunctions[k].index == index)
- break;
- else if (k == sh->NumSubroutineFunctions - 1)
- sh->SubroutineFunctions[j].index = index;
- }
- index++;
- }
- }
}
}
for (int s = this->state->num_subroutines - 1; s >= 0; s--) {
ir_rvalue *var;
- ir_constant *lc = new(mem_ctx)ir_constant(s);
ir_function *fn = this->state->subroutines[s];
+ ir_constant *lc = new(mem_ctx)ir_constant(fn->subroutine_index);
+
bool is_compat = false;
for (int i = 0; i < fn->num_subroutine_types; i++) {
* and storage for them.
*/
GLuint NumSubroutineFunctions;
+ GLuint MaxSubroutineFunctionIndex;
struct gl_subroutine_function *SubroutineFunctions;
};
}
int uni_count = uni->array_elements ? uni->array_elements : 1;
- int j, k;
+ int j, k, f;
for (j = i; j < i + uni_count; j++) {
- struct gl_subroutine_function *subfn;
- if (indices[j] >= sh->NumSubroutineFunctions) {
+ struct gl_subroutine_function *subfn = NULL;
+ if (indices[j] > sh->MaxSubroutineFunctionIndex) {
_mesa_error(ctx, GL_INVALID_VALUE, "%s", api_name);
return;
}
- subfn = &sh->SubroutineFunctions[indices[j]];
+ for (f = 0; f < sh->NumSubroutineFunctions; f++) {
+ if (sh->SubroutineFunctions[f].index == indices[j])
+ subfn = &sh->SubroutineFunctions[f];
+ }
+
+ if (!subfn) {
+ continue;
+ }
+
for (k = 0; k < subfn->num_compat_types; k++) {
if (subfn->types[k] == uni->type)
break;