[Mesa-dev] [PATCH] glsl/linker: remove ubo explicit binding handling at uniform_initializers
Alejandro Piñeiro
apinheiro at igalia.com
Thu Feb 8 07:34:20 UTC 2018
Ping.
FWIW, when I sent this patch, I also sent a test to the piglit ml, that
got reviewed and pushed:
https://cgit.freedesktop.org/piglit/commit/?id=88a9a99794f6108b656d4142cecd373b7995863c
To run it:
./bin/shader_runner
tests/spec/arb_arrays_of_arrays/execution/ubo/fs-const-explicit-binding.shader_test
-auto -fbo
right now, that test is crashing (at least on i965 driver, but it should
crash in most drivers).
On 24/01/18 15:30, Alejandro Piñeiro wrote:
> This is already handled at link_uniform_blocks, specifically at
> process_array_leaf.
>
> Additionally, this code was not handling correctly arrays of
> arrays. When creating the name of the block to set the binding, it
> only took into account the first level, so any attempt to set a
> explicit binding on a array of array ubo would trigger an assertion.
> ---
>
> I have just send a new test to the piglit list ("arb_arrays_of_arrays:
> add ubo test with explicit binding") that crashes without this
> patch. Without this patch it reachs the "unreachable("")" at the
> method set_block_binding that is being removed.
>
> It reaches that point because set_block_binding is called with a wrong
> block_name. When it is called with an array, it uses only the first
> layer, so for arrays of arrays, it creates a wrong name (block[0]
> instead of block[0][0] for example). See below, after the "Section
> 4.4.3" comment.
>
> Initially I was trying to solve this problem by fixing how the block
> name is created, until I realized that the binding at that point was
> already correct. Then I took a look to the code, and found that
> link_uniform_blocks were already handling setting the explicit
> binding, at process_block_array_leaf. Skimming it, seemed to handle
> all the corner cases. I also sent this patch to Intel CI and I didn't
> get any regression. And in any case, if there is any case not covered
> by the tests, I think that it would be better to handle explicit
> binding for ubos in just one place.
>
>
> src/compiler/glsl/link_uniform_initializers.cpp | 58 +------------------------
> 1 file changed, 2 insertions(+), 56 deletions(-)
>
> diff --git a/src/compiler/glsl/link_uniform_initializers.cpp b/src/compiler/glsl/link_uniform_initializers.cpp
> index 97796e721bf..35522f76467 100644
> --- a/src/compiler/glsl/link_uniform_initializers.cpp
> +++ b/src/compiler/glsl/link_uniform_initializers.cpp
> @@ -182,26 +182,6 @@ set_opaque_binding(void *mem_ctx, gl_shader_program *prog,
> }
> }
>
> -static void
> -set_block_binding(gl_shader_program *prog, const char *block_name,
> - unsigned mode, int binding)
> -{
> - unsigned num_blocks = mode == ir_var_uniform ?
> - prog->data->NumUniformBlocks :
> - prog->data->NumShaderStorageBlocks;
> - struct gl_uniform_block *blks = mode == ir_var_uniform ?
> - prog->data->UniformBlocks : prog->data->ShaderStorageBlocks;
> -
> - for (unsigned i = 0; i < num_blocks; i++) {
> - if (!strcmp(blks[i].Name, block_name)) {
> - blks[i].Binding = binding;
> - return;
> - }
> - }
> -
> - unreachable("Failed to initialize block binding");
> -}
> -
> void
> set_uniform_initializer(void *mem_ctx, gl_shader_program *prog,
> const char *name, const glsl_type *type,
> @@ -307,43 +287,9 @@ link_set_uniform_initializers(struct gl_shader_program *prog,
> linker::set_opaque_binding(mem_ctx, prog, var, var->type,
> var->name, &binding);
> } else if (var->is_in_buffer_block()) {
> - const glsl_type *const iface_type = var->get_interface_type();
> -
> - /* If the variable is an array and it is an interface instance,
> - * we need to set the binding for each array element. Just
> - * checking that the variable is an array is not sufficient.
> - * The variable could be an array element of a uniform block
> - * that lacks an instance name. For example:
> - *
> - * uniform U {
> - * float f[4];
> - * };
> - *
> - * In this case "f" would pass is_in_buffer_block (above) and
> - * type->is_array(), but it will fail is_interface_instance().
> + /* This case is handled by link_uniform_blocks (at
> + * process_block_array_leaf)
> */
> - if (var->is_interface_instance() && var->type->is_array()) {
> - for (unsigned i = 0; i < var->type->length; i++) {
> - const char *name =
> - ralloc_asprintf(mem_ctx, "%s[%u]", iface_type->name, i);
> -
> - /* Section 4.4.3 (Uniform Block Layout Qualifiers) of the
> - * GLSL 4.20 spec says:
> - *
> - * "If the binding identifier is used with a uniform
> - * block instanced as an array then the first element
> - * of the array takes the specified block binding and
> - * each subsequent element takes the next consecutive
> - * uniform block binding point."
> - */
> - linker::set_block_binding(prog, name, var->data.mode,
> - var->data.binding + i);
> - }
> - } else {
> - linker::set_block_binding(prog, iface_type->name,
> - var->data.mode,
> - var->data.binding);
> - }
> } else if (type->contains_atomic()) {
> /* we don't actually need to do anything. */
> } else {
More information about the mesa-dev
mailing list