From 30a2eff30220e303c1943b9895ab515a26a7cf73 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Thu, 5 Nov 2020 12:58:47 -0500 Subject: [PATCH] zink: split ubo loading for 64bit types into 2x32bit loads this loads 2x32 for each 64bit value and then zips it back into 64bit for storage Reviewed-by: Erik Faye-Lund Part-of: --- .../drivers/zink/nir_to_spirv/nir_to_spirv.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) 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 cce9b1b1d38..94e387cc81a 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 @@ -1591,11 +1591,15 @@ emit_load_ubo(struct ntv_context *ctx, nir_intrinsic_instr *intr) ASSERTED nir_const_value *const_block_index = nir_src_as_const_value(intr->src[0]); assert(const_block_index); // no dynamic indexing for now + unsigned bit_size = nir_dest_bit_size(intr->dest); SpvId uint_type = get_uvec_type(ctx, 32, 1); SpvId one = emit_uint_const(ctx, 32, 1); /* number of components being loaded */ unsigned num_components = nir_dest_num_components(intr->dest); + /* we need to grab 2x32 to fill the 64bit value */ + if (bit_size == 64) + num_components *= 2; SpvId constituents[num_components]; SpvId result; @@ -1653,8 +1657,24 @@ emit_load_ubo(struct ntv_context *ctx, nir_intrinsic_instr *intr) constituents[i] = spirv_builder_emit_load(&ctx->builder, uint_type, ptr); /* increment to the next vec4 member index for the next load */ vec_member_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_member_offset, one); + if (i == 3 && num_components > 4) { + vec_offset = emit_binop(ctx, SpvOpIAdd, uint_type, vec_offset, one); + vec_member_offset = emit_uint_const(ctx, 32, 0); + } } + /* if we're loading a 64bit value, we have to reassemble all the u32 values we've loaded into u64 values + * by creating uvec2 composites and bitcasting them to u64 values + */ + if (bit_size == 64) { + num_components /= 2; + type = get_uvec_type(ctx, 64, num_components); + SpvId u64_type = get_uvec_type(ctx, 64, 1); + for (unsigned i = 0; i < num_components; i++) { + constituents[i] = spirv_builder_emit_composite_construct(&ctx->builder, get_uvec_type(ctx, 32, 2), constituents + i * 2, 2); + constituents[i] = emit_bitcast(ctx, u64_type, constituents[i]); + } + } /* if loading more than 1 value, reassemble the results into the desired type, * otherwise just use the loaded result */