From eb50d1d2a6357cec66822f8f6861f220923a946c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alejandro=20Pi=C3=B1eiro?= Date: Wed, 29 Aug 2018 16:24:12 +0200 Subject: [PATCH] nir/linker: use only the array element type for array of ssbo/ubo For this interfaces, the inner members are added only once as uniforms or resources, in opposite to other cases, like a uniform array of structs. For those guessing why a issue (16) from ARB_program_interface_query was used, instead of a quote of the core spec: The core spec is not really clear about how members of arrays of blocks should be enumerated. On GLSL this was also problematic, specially when we were trying to pass the 4.5 CTS tests. See commit "glsl: Fix program interface queries relating to interface blocks" (4c4d9e4f032d5753034361ee70aa88d16d3a04b4), as a reference. That one also needed to rely on issue (16) to justify the change, pointing that the core spec needs to be clarified. Reviewed-by: Timothy Arceri --- src/compiler/glsl/gl_nir_link_uniforms.c | 44 ++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/compiler/glsl/gl_nir_link_uniforms.c b/src/compiler/glsl/gl_nir_link_uniforms.c index 0f8911b5b81..bb126a40baa 100644 --- a/src/compiler/glsl/gl_nir_link_uniforms.c +++ b/src/compiler/glsl/gl_nir_link_uniforms.c @@ -498,11 +498,51 @@ gl_nir_link_uniforms(struct gl_context *ctx, state.current_var = var; + /* + * From ARB_program_interface spec, issue (16): + * + * "RESOLVED: We will follow the default rule for enumerating block + * members in the OpenGL API, which is: + * + * * If a variable is a member of an interface block without an + * instance name, it is enumerated using just the variable name. + * + * * If a variable is a member of an interface block with an + * instance name, it is enumerated as "BlockName.Member", where + * "BlockName" is the name of the interface block (not the + * instance name) and "Member" is the name of the variable. + * + * For example, in the following code: + * + * uniform Block1 { + * int member1; + * }; + * uniform Block2 { + * int member2; + * } instance2; + * uniform Block3 { + * int member3; + * } instance3[2]; // uses two separate buffer bindings + * + * the three uniforms (if active) are enumerated as "member1", + * "Block2.member2", and "Block3.member3"." + * + * Note that in the last example, with an array of ubo, only one + * uniform is generated. For that reason, while unrolling the + * uniforms of a ubo, or the variables of a ssbo, we need to treat + * arrays of instance as a single block. + */ + const struct glsl_type *type = var->type; + if (nir_variable_is_in_block(var) && + glsl_type_is_array(type)) { + type = glsl_without_array(type); + } + struct type_tree_entry *type_tree = - build_type_tree_for_type(var->type); + build_type_tree_for_type(type); state.current_type = type_tree; - int res = nir_link_uniform(ctx, prog, sh->Program, shader_type, var->type, + int res = nir_link_uniform(ctx, prog, sh->Program, shader_type, type, location, &state); free_type_tree(type_tree); -- 2.30.2