From: Dave Airlie Date: Fri, 10 Apr 2020 04:13:44 +0000 (+1000) Subject: gallivm/nir: handle non-uniform texture offsets X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=e168d148d76d780eda6f9aaa6c66608c4df3096c;p=mesa.git gallivm/nir: handle non-uniform texture offsets The way we construt vertex/geom shaders means these can diverge, so we have to just hammer it out manually, there are likely optimisation opportuniities in here Signed-off-by: Dave Airlie Reviewed-by: Roland Scheidegger Part-of: --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c index 8eb442998b8..0cabe848529 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c @@ -838,6 +838,16 @@ lp_build_fetch_rgba_soa(struct gallivm_state *gallivm, tmp_type = type; tmp_type.length = 4; + if (type.length == 1) { + LLVMValueRef fetch = lp_build_fetch_rgba_aos(gallivm, format_desc, tmp_type, + aligned, base_ptr, offset, + i, j, cache); + + for (k = 0; k < 4; k++) + rgba_out[k] = LLVMBuildExtractElement(gallivm->builder, fetch, lp_build_const_int32(gallivm, k), ""); + return; + } + /* * Note that vector transpose can be worse compared to insert/extract * for aos->soa conversion (for formats with 1 or 2 channels). However, diff --git a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c index 9c8b5221888..6444ae2237f 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_nir_soa.c @@ -1291,15 +1291,64 @@ static void emit_tex(struct lp_build_nir_context *bld_base, struct lp_sampler_params *params) { struct lp_build_nir_soa_context *bld = (struct lp_build_nir_soa_context *)bld_base; + struct gallivm_state *gallivm = bld_base->base.gallivm; params->type = bld_base->base.type; params->context_ptr = bld->context_ptr; params->thread_data_ptr = bld->thread_data_ptr; + if (params->texture_index_offset && bld_base->shader->info.stage != MESA_SHADER_FRAGMENT) { + /* this is horrible but this can be dynamic */ + LLVMValueRef coords[5]; + LLVMValueRef *orig_texel_ptr; + struct lp_build_context *uint_bld = &bld_base->uint_bld; + LLVMValueRef result[4] = { LLVMGetUndef(bld_base->base.vec_type), + LLVMGetUndef(bld_base->base.vec_type), + LLVMGetUndef(bld_base->base.vec_type), + LLVMGetUndef(bld_base->base.vec_type) }; + LLVMValueRef texel[4], orig_offset; + unsigned i; + orig_texel_ptr = params->texel; + + for (i = 0; i < 5; i++) { + coords[i] = params->coords[i]; + } + orig_offset = params->texture_index_offset; + + for (unsigned v = 0; v < uint_bld->type.length; v++) { + LLVMValueRef idx = lp_build_const_int32(gallivm, v); + LLVMValueRef new_coords[5]; + for (i = 0; i < 5; i++) { + new_coords[i] = LLVMBuildExtractElement(gallivm->builder, + coords[i], idx, ""); + } + params->coords = new_coords; + params->texture_index_offset = LLVMBuildExtractElement(gallivm->builder, + orig_offset, + idx, ""); + params->type = lp_elem_type(bld_base->base.type); + + params->texel = texel; + bld->sampler->emit_tex_sample(bld->sampler, + gallivm, + params); + + for (i = 0; i < 4; i++) { + result[i] = LLVMBuildInsertElement(gallivm->builder, result[i], texel[i], idx, ""); + } + } + for (i = 0; i < 4; i++) { + orig_texel_ptr[i] = result[i]; + } + return; + } + if (params->texture_index_offset) params->texture_index_offset = LLVMBuildExtractElement(bld_base->base.gallivm->builder, params->texture_index_offset, lp_build_const_int32(bld_base->base.gallivm, 0), ""); + + params->type = bld_base->base.type; bld->sampler->emit_tex_sample(bld->sampler, bld->bld_base.base.gallivm, params);