Module: Mesa Branch: master Commit: 22be7b96747d4d54b2bdc401766e8243e60f382c URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=22be7b96747d4d54b2bdc401766e8243e60f382c
Author: Mike Blumenkrantz <[email protected]> Date: Wed Jul 29 20:33:50 2020 -0400 zink: handle arrays of ubos with the nir pass removing all dynamic indexing, all that's needed here is generating extra binding points for each array member, as everything else is already handled Reviewed-by: Erik Faye-Lund <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8314> --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 39 ++++++++++++++-------- src/gallium/drivers/zink/zink_compiler.c | 33 ++++++++++++------ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c index e003ce2c992..6108bda4ea8 100644 --- a/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c +++ b/src/gallium/drivers/zink/nir_to_spirv/nir_to_spirv.c @@ -618,10 +618,11 @@ emit_sampler(struct ntv_context *ctx, struct nir_variable *var) static void emit_ubo(struct ntv_context *ctx, struct nir_variable *var) { + bool is_ubo_array = glsl_type_is_array(var->type) && glsl_type_is_interface(glsl_without_array(var->type)); /* variables accessed inside a uniform block will get merged into a big * memory blob and accessed by offset */ - if (var->data.location) + if (var->data.location && !is_ubo_array) return; uint32_t size = glsl_count_attribute_slots(var->interface_type, false); @@ -643,24 +644,36 @@ emit_ubo(struct ntv_context *ctx, struct nir_variable *var) SpvDecorationBlock); spirv_builder_emit_member_offset(&ctx->builder, struct_type, 0, 0); - SpvId pointer_type = spirv_builder_type_pointer(&ctx->builder, SpvStorageClassUniform, struct_type); - SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type, - SpvStorageClassUniform); - if (var->name) - spirv_builder_emit_name(&ctx->builder, var_id, var->name); + /* if this is a ubo array, create a binding point for each array member: + * + "For uniform blocks declared as arrays, each individual array element + corresponds to a separate buffer object backing one instance of the block." + - ARB_gpu_shader5 - assert(ctx->num_ubos < ARRAY_SIZE(ctx->ubos)); - ctx->ubos[ctx->num_ubos++] = var_id; + (also it's just easier) + */ + for (unsigned i = 0; i < (is_ubo_array ? glsl_get_aoa_size(var->type) : 1); i++) { + SpvId var_id = spirv_builder_emit_var(&ctx->builder, pointer_type, + SpvStorageClassUniform); + if (var->name) { + char struct_name[100]; + snprintf(struct_name, sizeof(struct_name), "%s[%u]", var->name, i); + spirv_builder_emit_name(&ctx->builder, var_id, var->name); + } - spirv_builder_emit_descriptor_set(&ctx->builder, var_id, 0); - int binding = zink_binding(ctx->stage, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - var->data.binding); - spirv_builder_emit_binding(&ctx->builder, var_id, binding); + assert(ctx->num_ubos < ARRAY_SIZE(ctx->ubos)); + ctx->ubos[ctx->num_ubos++] = var_id; + + spirv_builder_emit_descriptor_set(&ctx->builder, var_id, 0); + int binding = zink_binding(ctx->stage, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + var->data.binding + i); + spirv_builder_emit_binding(&ctx->builder, var_id, binding); + } } static void diff --git a/src/gallium/drivers/zink/zink_compiler.c b/src/gallium/drivers/zink/zink_compiler.c index 13413e89176..d070f607fa1 100644 --- a/src/gallium/drivers/zink/zink_compiler.c +++ b/src/gallium/drivers/zink/zink_compiler.c @@ -476,18 +476,29 @@ zink_shader_create(struct zink_screen *screen, struct nir_shader *nir, nir_var_mem_ssbo)) { if (var->data.mode == nir_var_mem_ubo) { /* ignore variables being accessed if they aren't the base of the UBO */ - if (var->data.location) + bool ubo_array = glsl_type_is_array(var->type) && glsl_type_is_interface(glsl_without_array(var->type)); + if (var->data.location && !ubo_array) continue; - var->data.binding = cur_ubo++; - - int binding = zink_binding(nir->info.stage, - VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - var->data.binding); - ret->bindings[ret->num_bindings].index = ubo_index++; - ret->bindings[ret->num_bindings].binding = binding; - ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; - ret->bindings[ret->num_bindings].size = 1; - ret->num_bindings++; + var->data.binding = cur_ubo; + /* if this is a ubo array, create a binding point for each array member: + * + "For uniform blocks declared as arrays, each individual array element + corresponds to a separate buffer object backing one instance of the block." + - ARB_gpu_shader5 + + (also it's just easier) + */ + for (unsigned i = 0; i < (ubo_array ? glsl_get_aoa_size(var->type) : 1); i++) { + + int binding = zink_binding(nir->info.stage, + VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, + cur_ubo++); + ret->bindings[ret->num_bindings].index = ubo_index++; + ret->bindings[ret->num_bindings].binding = binding; + ret->bindings[ret->num_bindings].type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; + ret->bindings[ret->num_bindings].size = 1; + ret->num_bindings++; + } } else { assert(var->data.mode == nir_var_uniform); const struct glsl_type *type = glsl_without_array(var->type); _______________________________________________ mesa-commit mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/mesa-commit
