diff --git a/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c b/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c index 0e873d1f3fc..04ebe67df22 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_jit_types.c @@ -89,16 +89,32 @@ lp_llvm_buffer_member(struct gallivm_state *gallivm, const char *member_name) { LLVMBuilderRef builder = gallivm->builder; - LLVMValueRef indices[3]; - - indices[0] = lp_build_const_int32(gallivm, 0); - LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, buffers_offset, lp_build_const_int32(gallivm, buffers_limit), ""); - indices[1] = LLVMBuildSelect(gallivm->builder, cond, buffers_offset, lp_build_const_int32(gallivm, 0), ""); - indices[2] = lp_build_const_int32(gallivm, member_index); LLVMTypeRef buffer_type = lp_build_create_jit_buffer_type(gallivm); - LLVMTypeRef buffers_type = LLVMArrayType(buffer_type, buffers_limit); - LLVMValueRef ptr = LLVMBuildGEP2(builder, buffers_type, buffers_ptr, indices, ARRAY_SIZE(indices), ""); + + LLVMValueRef ptr; + if (LLVMGetTypeKind(LLVMTypeOf(buffers_offset)) == LLVMArrayTypeKind) { + LLVMValueRef desc_ptr = lp_llvm_descriptor_base(gallivm, buffers_ptr, buffers_offset, buffers_limit); + + LLVMTypeRef buffer_ptr_type = LLVMPointerType(buffer_type, 0); + desc_ptr = LLVMBuildIntToPtr(builder, desc_ptr, buffer_ptr_type, ""); + + LLVMValueRef indices[2] = { + lp_build_const_int32(gallivm, 0), + lp_build_const_int32(gallivm, member_index), + }; + ptr = LLVMBuildGEP2(builder, buffer_type, desc_ptr, indices, ARRAY_SIZE(indices), ""); + } else { + LLVMValueRef indices[3]; + + indices[0] = lp_build_const_int32(gallivm, 0); + LLVMValueRef cond = LLVMBuildICmp(gallivm->builder, LLVMIntULT, buffers_offset, lp_build_const_int32(gallivm, buffers_limit), ""); + indices[1] = LLVMBuildSelect(gallivm->builder, cond, buffers_offset, lp_build_const_int32(gallivm, 0), ""); + indices[2] = lp_build_const_int32(gallivm, member_index); + + LLVMTypeRef buffers_type = LLVMArrayType(buffer_type, buffers_limit); + ptr = LLVMBuildGEP2(builder, buffers_type, buffers_ptr, indices, ARRAY_SIZE(indices), ""); + } LLVMTypeRef res_type = LLVMStructGetTypeAtIndex(buffer_type, member_index); LLVMValueRef res = LLVMBuildLoad2(builder, res_type, ptr, ""); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir.c b/src/gallium/auxiliary/gallivm/lp_bld_nir.c index dded75c84e4..5292798fdd2 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir.c @@ -1523,7 +1523,10 @@ visit_load_ubo(struct lp_build_nir_context *bld_base, LLVMValueRef offset = get_src(bld_base, instr->src[1]); bool offset_is_uniform = nir_src_is_always_uniform(instr->src[1]); - idx = LLVMBuildExtractElement(builder, idx, lp_build_const_int32(gallivm, 0), ""); + + if (nir_src_num_components(instr->src[0]) == 1) + idx = LLVMBuildExtractElement(builder, idx, lp_build_const_int32(gallivm, 0), ""); + bld_base->load_ubo(bld_base, nir_dest_num_components(instr->dest), nir_dest_bit_size(instr->dest), offset_is_uniform, idx, offset, result); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 355d02337ad..7d11b1d98e1 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -1185,6 +1185,23 @@ lp_offset_in_range(struct lp_build_nir_context *bld_base, return LLVMBuildAnd(gallivm->builder, fetch_in_bounds, fetch_non_negative, ""); } +static LLVMValueRef +build_resource_to_scalar(struct lp_build_nir_context *bld_base, LLVMValueRef resource) +{ + struct gallivm_state *gallivm = bld_base->base.gallivm; + + LLVMValueRef invocation = first_active_invocation(bld_base); + + LLVMValueRef set = LLVMBuildExtractValue(gallivm->builder, resource, 0, ""); + set = LLVMBuildExtractElement(gallivm->builder, set, invocation, ""); + + LLVMValueRef binding = LLVMBuildExtractValue(gallivm->builder, resource, 1, ""); + binding = LLVMBuildExtractElement(gallivm->builder, binding, invocation, ""); + + LLVMValueRef components[2] = { set, binding }; + return lp_nir_array_build_gather_values(gallivm->builder, components, 2); +} + static void emit_load_ubo(struct lp_build_nir_context *bld_base, unsigned nc, unsigned bit_size, @@ -1193,6 +1210,9 @@ static void emit_load_ubo(struct lp_build_nir_context *bld_base, LLVMValueRef offset, LLVMValueRef result[NIR_MAX_VEC_COMPONENTS]) { + if (LLVMGetTypeKind(LLVMTypeOf(index)) == LLVMArrayTypeKind) + index = build_resource_to_scalar(bld_base, index); + struct lp_build_nir_soa_context *bld = (struct lp_build_nir_soa_context *)bld_base; struct gallivm_state *gallivm = bld_base->base.gallivm; LLVMBuilderRef builder = gallivm->builder;