From f1d1371e512e32d03f7f54d873020e589ee67d47 Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Fri, 22 Apr 2022 14:47:38 -0400 Subject: [PATCH] gallivm/draw: fix oob ubo reads the first case in gallivm did no checking, so this was always going to be broken, so instead just copy the now-correct ssbo logic cc: mesa-stable Reviewed-by: Dave Airlie Part-of: --- src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c | 38 ++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 1ab7595..44358b6 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -1048,6 +1048,7 @@ static void emit_load_ubo(struct lp_build_nir_context *bld_base, struct lp_build_context *uint_bld = &bld_base->uint_bld; struct lp_build_context *bld_broad = get_int_bld(bld_base, true, bit_size); LLVMValueRef consts_ptr = lp_build_array_get(gallivm, bld->consts_ptr, index); + LLVMValueRef num_consts = lp_build_array_get(gallivm, bld->const_sizes_ptr, index); unsigned size_shift = bit_size_to_shift_size(bit_size); if (size_shift) offset = lp_build_shr(uint_bld, offset, lp_build_const_int_vec(gallivm, uint_bld->type, size_shift)); @@ -1057,16 +1058,43 @@ static void emit_load_ubo(struct lp_build_nir_context *bld_base, if (offset_is_uniform && invocation_0_must_be_active(bld_base)) { offset = LLVMBuildExtractElement(builder, offset, lp_build_const_int32(gallivm, 0), ""); - + struct lp_build_context *load_bld = get_int_bld(bld_base, true, bit_size); + switch (bit_size) { + case 8: + num_consts = LLVMBuildShl(gallivm->builder, num_consts, lp_build_const_int32(gallivm, 2), ""); + break; + case 16: + num_consts = LLVMBuildShl(gallivm->builder, num_consts, lp_build_const_int32(gallivm, 1), ""); + break; + case 64: + num_consts = LLVMBuildLShr(gallivm->builder, num_consts, lp_build_const_int32(gallivm, 1), ""); + break; + default: break; + } for (unsigned c = 0; c < nc; c++) { - LLVMValueRef this_offset = LLVMBuildAdd(builder, offset, lp_build_const_int32(gallivm, c), ""); + LLVMValueRef chan_offset = LLVMBuildAdd(builder, offset, lp_build_const_int32(gallivm, c), ""); - LLVMValueRef scalar = lp_build_pointer_get(builder, consts_ptr, this_offset); - result[c] = lp_build_broadcast_scalar(bld_broad, scalar); + LLVMValueRef scalar; + /* If loading outside the UBO, we need to skip the load and read 0 instead. */ + LLVMValueRef zero = lp_build_zero_bits(gallivm, bit_size); + LLVMValueRef res_store = lp_build_alloca(gallivm, LLVMTypeOf(zero), ""); + LLVMBuildStore(builder, zero, res_store); + + LLVMValueRef fetch_extent = LLVMBuildAdd(builder, chan_offset, lp_build_const_int32(gallivm, 1), ""); + LLVMValueRef fetch_cond = LLVMBuildICmp(gallivm->builder, LLVMIntUGE, num_consts, fetch_extent, ""); + LLVMValueRef fetch_cond2 = LLVMBuildICmp(gallivm->builder, LLVMIntSGE, chan_offset, lp_build_const_int32(gallivm, 0), ""); + LLVMValueRef fetch_cond_final = LLVMBuildAnd(gallivm->builder, fetch_cond, fetch_cond2, ""); + struct lp_build_if_state ifthen; + lp_build_if(&ifthen, gallivm, fetch_cond_final); + LLVMBuildStore(builder, lp_build_pointer_get(builder, consts_ptr, chan_offset), res_store); + lp_build_endif(&ifthen); + + scalar = LLVMBuildLoad(builder, res_store, ""); + + result[c] = lp_build_broadcast_scalar(load_bld, scalar); } } else { LLVMValueRef overflow_mask; - LLVMValueRef num_consts = lp_build_array_get(gallivm, bld->const_sizes_ptr, index); num_consts = lp_build_broadcast_scalar(uint_bld, num_consts); if (bit_size == 64) -- 2.7.4