gallivm: Implement arrayed non-arrayed descriptor compatibility

Sampling with layer!=0 from a non arrayed descriptor should return 0 and
sampling without an explicit array layer from and arrayed descriptor
should sample the first layer.

Reviewed-by: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/36197>
This commit is contained in:
Konstantin Seurer
2025-07-12 11:13:40 +02:00
committed by Marge Bot
parent bc56ec7ce0
commit 45d48ecebf
6 changed files with 36 additions and 18 deletions
@@ -231,7 +231,7 @@ lp_bld_llvm_sampler_soa_emit_fetch_texel(const struct lp_build_sampler_soa *base
for (uint32_t i = 0; i < 4; i++) {
if (LLVMIsUndef(params->coords[i]))
args[num_args++] = LLVMGetUndef(coord_type);
args[num_args++] = LLVMConstNull(coord_type);
else
args[num_args++] = params->coords[i];
}
+21 -5
View File
@@ -4249,6 +4249,8 @@ visit_load_image(struct lp_build_nir_soa_context *bld,
{
LLVMValueRef coords[NIR_MAX_VEC_COMPONENTS] = { NULL };
get_src_vec(bld, 1, coords);
for (uint32_t i = nir_image_intrinsic_coord_components(instr); i < 4; i++)
coords[i] = bld->uint_bld.zero;
struct lp_img_params params = { 0 };
@@ -4282,8 +4284,12 @@ visit_store_image(struct lp_build_nir_soa_context *bld,
{
struct gallivm_state *gallivm = bld->base.gallivm;
LLVMBuilderRef builder = gallivm->builder;
LLVMValueRef coords[NIR_MAX_VEC_COMPONENTS] = { NULL };
get_src_vec(bld, 1, coords);
for (uint32_t i = nir_image_intrinsic_coord_components(instr); i < 4; i++)
coords[i] = bld->uint_bld.zero;
LLVMValueRef in_val[NIR_MAX_VEC_COMPONENTS] = { NULL };
get_src_vec(bld, 3, in_val);
struct lp_img_params params = { 0 };
@@ -4410,6 +4416,9 @@ lp_packed_img_op_from_intrinsic(nir_intrinsic_instr *instr)
flags |= LP_IMAGE_OP_64;
}
if (nir_intrinsic_image_array(instr))
flags |= LP_IMAGE_OP_HAS_LAYER;
return op + flags * LP_IMAGE_OP_COUNT;
}
@@ -4421,8 +4430,12 @@ visit_atomic_image(struct lp_build_nir_soa_context *bld,
struct gallivm_state *gallivm = bld->base.gallivm;
LLVMBuilderRef builder = gallivm->builder;
struct lp_img_params params = { 0 };
LLVMValueRef coords[NIR_MAX_VEC_COMPONENTS] = { NULL };
get_src_vec(bld, 1, coords);
for (uint32_t i = nir_image_intrinsic_coord_components(instr); i < 4; i++)
coords[i] = bld->uint_bld.zero;
LLVMValueRef in_val = get_src(bld, &instr->src[3], 0);
params.target = glsl_sampler_to_pipe(nir_intrinsic_image_dim(instr),
@@ -5290,6 +5303,9 @@ lp_build_nir_sample_key(gl_shader_stage stage, nir_tex_instr *instr)
sample_key |= LP_SAMPLER_OP_LODQ << LP_SAMPLER_OP_TYPE_SHIFT;
}
if (instr->is_array)
sample_key |= LP_SAMPLER_HAS_LAYER;
bool explicit_lod = false;
uint32_t lod_src = 0;
@@ -5369,7 +5385,7 @@ visit_tex(struct lp_build_nir_soa_context *bld, nir_tex_instr *instr)
nir_deref_instr *sampler_deref_instr = NULL;
LLVMValueRef texture_unit_offset = NULL;
LLVMValueRef texel[NIR_MAX_VEC_COMPONENTS];
LLVMValueRef coord_undef = LLVMGetUndef(bld->base.vec_type);
LLVMValueRef coord_zero = bld->base.zero;
unsigned coord_vals = instr->coord_components;
LLVMValueRef texture_resource = NULL;
@@ -5380,7 +5396,7 @@ visit_tex(struct lp_build_nir_soa_context *bld, nir_tex_instr *instr)
case nir_tex_src_coord: {
get_src_vec(bld, i, coords);
for (unsigned chan = coord_vals; chan < 5; chan++)
coords[chan] = coord_undef;
coords[chan] = coord_zero;
break;
}
case nir_tex_src_texture_deref:
@@ -5477,12 +5493,12 @@ visit_tex(struct lp_build_nir_soa_context *bld, nir_tex_instr *instr)
case nir_texop_txl:
case nir_texop_txd:
case nir_texop_lod:
for (unsigned chan = 0; chan < coord_vals; ++chan)
for (unsigned chan = 0; chan < 5; ++chan)
coords[chan] = cast_type(bld, coords[chan], nir_type_float, 32);
break;
case nir_texop_txf:
case nir_texop_txf_ms:
for (unsigned chan = 0; chan < instr->coord_components; ++chan)
for (unsigned chan = 0; chan < 5; ++chan)
coords[chan] = cast_type(bld, coords[chan], nir_type_int, 32);
break;
default:
@@ -5492,7 +5508,7 @@ visit_tex(struct lp_build_nir_soa_context *bld, nir_tex_instr *instr)
if (instr->is_array && instr->sampler_dim == GLSL_SAMPLER_DIM_1D) {
/* move layer coord for 1d arrays. */
coords[2] = coords[1];
coords[1] = coord_undef;
coords[1] = coord_zero;
}
uint32_t samp_base_index = 0, tex_base_index = 0;
@@ -100,7 +100,8 @@ enum lp_sampler_op_type {
#define LP_SAMPLER_FETCH_MS (1 << 10)
#define LP_SAMPLER_RESIDENCY (1 << 11)
#define LP_SAMPLER_MIN_LOD (1 << 12)
#define LP_SAMPLE_KEY_COUNT (1 << 13)
#define LP_SAMPLER_HAS_LAYER (1 << 13)
#define LP_SAMPLE_KEY_COUNT (1 << 14)
/* Parameters used to handle TEX instructions */
@@ -166,8 +167,9 @@ struct lp_sampler_size_query_params
#define LP_IMAGE_OP_MS 1
#define LP_IMAGE_OP_64 2
#define LP_IMAGE_OP_HAS_LAYER 4
#define LP_TOTAL_IMAGE_OP_COUNT (LP_IMAGE_OP_COUNT * 4)
#define LP_TOTAL_IMAGE_OP_COUNT (LP_IMAGE_OP_COUNT * 8)
struct lp_img_params
{
@@ -177,6 +179,7 @@ struct lp_img_params
unsigned img_op;
unsigned target;
unsigned packed_op;
bool instr_has_layer_coord;
LLVMAtomicRMWBinOp op;
LLVMValueRef exec_mask;
bool exec_mask_nz;
@@ -444,6 +447,7 @@ struct lp_build_sample_context
bool no_rho_approx;
bool fetch_ms;
bool residency;
bool instr_has_layer_coord;
/** regular scalar float type */
struct lp_type float_type;
@@ -2981,8 +2981,11 @@ lp_build_fetch_texel(struct lp_build_sample_context *bld,
lp_build_extract_image_sizes(bld, &bld->int_size_bld, int_coord_bld->type,
size, &width, &height, &depth);
/* Initialize undefined layer coords and handle layer for non arrayed textures
* to make the descriptors compatible.
*/
if (target == PIPE_TEXTURE_1D_ARRAY ||
target == PIPE_TEXTURE_2D_ARRAY) {
target == PIPE_TEXTURE_2D_ARRAY || bld->instr_has_layer_coord) {
if (out_of_bound_ret_zero) {
z = lp_build_layer_coord(bld, texture_unit, false, z, &out1);
out_of_bounds = lp_build_or(int_coord_bld, out_of_bounds, out1);
@@ -3378,6 +3381,7 @@ lp_build_sample_soa_code(struct gallivm_state *gallivm,
bld.fetch_ms = fetch_ms;
bld.residency = !!(sample_key & LP_SAMPLER_RESIDENCY);
bld.instr_has_layer_coord = !!(sample_key & LP_SAMPLER_HAS_LAYER);
if (op_is_gather)
bld.gather_comp = (sample_key & LP_SAMPLER_GATHER_COMP_MASK) >> LP_SAMPLER_GATHER_COMP_SHIFT;
bld.lodf_type = type;
@@ -4714,6 +4718,7 @@ lp_build_img_op_soa(const struct lp_static_texture_state *static_texture_state,
depth = LLVMBuildZExt(gallivm->builder, depth,
int_coord_bld.elem_type, "");
bool layer_coord = has_layer_coord(target);
layer_coord |= params->instr_has_layer_coord;
width = lp_build_scale_view_dim(gallivm, width, res_format_desc->block.width,
format_desc->block.width);
@@ -327,6 +327,8 @@ compile_image_function(struct llvmpipe_context *ctx, struct lp_static_texture_st
struct lp_img_params params = { 0 };
params.instr_has_layer_coord = flags & LP_IMAGE_OP_HAS_LAYER;
params.img_op = op % LP_IMAGE_OP_COUNT;
if (params.img_op >= LP_IMG_OP_COUNT - 1) {
params.op = params.img_op - (LP_IMG_OP_COUNT - 1);
@@ -17,12 +17,3 @@ test_raytracing_mismatch_global_rs_link,Fail
test_sampler_rounding,Fail
test_update_tile_mappings,Fail
test_view_min_lod,Fail
test_rwtex1d_array_reinterpretation_dxil,Fail
test_rwtex1d_array_reinterpretation_sm51,Fail
test_rwtex2d_array_reinterpretation_dxil,Fail
test_rwtex2d_array_reinterpretation_sm51,Fail
test_tex1d_array_reinterpretation_dxil,Fail
test_tex1d_array_reinterpretation_sm51,Fail
test_tex2d_array_reinterpretation_dxil,Fail
test_tex2d_array_reinterpretation_sm51,Fail