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 <erik.faye-lund@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8314>
This commit is contained in:
parent
dbba989907
commit
22be7b9674
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
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
|
||||
|
||||
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++;
|
||||
(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);
|
||||
|
|
Loading…
Reference in New Issue