aco: handle GL_TEXTURE_RECTANGLE in tg4_integer_workarounds

Ported from LLVM side lower_gather4_integer().

Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Signed-off-by: Qiang Yu <yuq825@gmail.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26244>
This commit is contained in:
Qiang Yu 2023-11-17 10:46:33 +08:00 committed by Marge Bot
parent 695fc67baa
commit 1fabf535fa

View file

@ -9411,42 +9411,46 @@ visit_tex(isel_context* ctx, nir_tex_instr* instr)
Temp tg4_compare_cube_wa64 = Temp();
if (tg4_integer_workarounds) {
Temp tg4_lod = bld.copy(bld.def(v1), Operand::zero());
Temp size = bld.tmp(v2);
MIMG_instruction* tex = emit_mimg(bld, aco_opcode::image_get_resinfo, size, resource,
Operand(s4), std::vector<Temp>{tg4_lod});
tex->dim = dim;
tex->dmask = 0x3;
tex->da = da;
emit_split_vector(ctx, size, size.size());
Temp half_texel[2];
for (unsigned i = 0; i < 2; i++) {
half_texel[i] = emit_extract_vector(ctx, size, i, v1);
half_texel[i] = bld.vop1(aco_opcode::v_cvt_f32_i32, bld.def(v1), half_texel[i]);
half_texel[i] = bld.vop1(aco_opcode::v_rcp_iflag_f32, bld.def(v1), half_texel[i]);
half_texel[i] = bld.vop2(aco_opcode::v_mul_f32, bld.def(v1),
Operand::c32(0xbf000000 /*-0.5*/), half_texel[i]);
}
if (instr->sampler_dim == GLSL_SAMPLER_DIM_RECT) {
half_texel[0] = half_texel[1] = bld.copy(bld.def(v1), Operand::c32(0xbf000000 /*-0.5*/));
} else {
Temp tg4_lod = bld.copy(bld.def(v1), Operand::zero());
Temp size = bld.tmp(v2);
MIMG_instruction* tex = emit_mimg(bld, aco_opcode::image_get_resinfo, size, resource,
Operand(s4), std::vector<Temp>{tg4_lod});
tex->dim = dim;
tex->dmask = 0x3;
tex->da = da;
emit_split_vector(ctx, size, size.size());
if (instr->sampler_dim == GLSL_SAMPLER_DIM_2D && !instr->is_array) {
/* In vulkan, whether the sampler uses unnormalized
* coordinates or not is a dynamic property of the
* sampler. Hence, to figure out whether or not we
* need to divide by the texture size, we need to test
* the sampler at runtime. This tests the bit set by
* radv_init_sampler().
*/
unsigned bit_idx = ffs(S_008F30_FORCE_UNNORMALIZED(1)) - 1;
Temp dword0 = emit_extract_vector(ctx, sampler, 0, s1);
Temp not_needed =
bld.sopc(aco_opcode::s_bitcmp0_b32, bld.def(s1, scc), dword0, Operand::c32(bit_idx));
for (unsigned i = 0; i < 2; i++) {
half_texel[i] = emit_extract_vector(ctx, size, i, v1);
half_texel[i] = bld.vop1(aco_opcode::v_cvt_f32_i32, bld.def(v1), half_texel[i]);
half_texel[i] = bld.vop1(aco_opcode::v_rcp_iflag_f32, bld.def(v1), half_texel[i]);
half_texel[i] = bld.vop2(aco_opcode::v_mul_f32, bld.def(v1),
Operand::c32(0xbf000000 /*-0.5*/), half_texel[i]);
}
not_needed = bool_to_vector_condition(ctx, not_needed);
half_texel[0] = bld.vop2(aco_opcode::v_cndmask_b32, bld.def(v1),
Operand::c32(0xbf000000 /*-0.5*/), half_texel[0], not_needed);
half_texel[1] = bld.vop2(aco_opcode::v_cndmask_b32, bld.def(v1),
Operand::c32(0xbf000000 /*-0.5*/), half_texel[1], not_needed);
if (instr->sampler_dim == GLSL_SAMPLER_DIM_2D && !instr->is_array) {
/* In vulkan, whether the sampler uses unnormalized
* coordinates or not is a dynamic property of the
* sampler. Hence, to figure out whether or not we
* need to divide by the texture size, we need to test
* the sampler at runtime. This tests the bit set by
* radv_init_sampler().
*/
unsigned bit_idx = ffs(S_008F30_FORCE_UNNORMALIZED(1)) - 1;
Temp dword0 = emit_extract_vector(ctx, sampler, 0, s1);
Temp not_needed =
bld.sopc(aco_opcode::s_bitcmp0_b32, bld.def(s1, scc), dword0, Operand::c32(bit_idx));
not_needed = bool_to_vector_condition(ctx, not_needed);
half_texel[0] = bld.vop2(aco_opcode::v_cndmask_b32, bld.def(v1),
Operand::c32(0xbf000000 /*-0.5*/), half_texel[0], not_needed);
half_texel[1] = bld.vop2(aco_opcode::v_cndmask_b32, bld.def(v1),
Operand::c32(0xbf000000 /*-0.5*/), half_texel[1], not_needed);
}
}
Temp new_coords[2] = {bld.vop2(aco_opcode::v_add_f32, bld.def(v1), coords[0], half_texel[0]),