nir/lower_tex: Add 1D lowering

From amd/common.

Signed-off-by: Alyssa Rosenzweig <alyssa@rosenzweig.io>
Reviewed-by: Faith Ekstrand <faith.ekstrand@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26377>
This commit is contained in:
Alyssa Rosenzweig 2023-11-27 09:40:50 -04:00 committed by Marge Bot
parent 5de5a0d475
commit e14633fa7d
2 changed files with 87 additions and 0 deletions

View file

@ -5694,6 +5694,15 @@ typedef struct nir_lower_tex_options {
*/
bool lower_rect;
/**
* If true, lower 1D textures to 2D. This requires the GL/VK driver to map 1D
* textures to 2D textures with height=1.
*
* lower_1d_shadow does this lowering for shadow textures only.
*/
bool lower_1d;
bool lower_1d_shadow;
/**
* If true, convert yuv to rgb.
*/

View file

@ -1,4 +1,5 @@
/*
* Copyright © 2023 Valve Corporation
* Copyright © 2015 Broadcom
*
* Permission is hereby granted, free of charge, to any person obtaining a
@ -246,6 +247,77 @@ lower_rect_tex_scale(nir_builder *b, nir_tex_instr *tex)
}
}
static void
lower_1d(nir_builder *b, nir_tex_instr *tex)
{
b->cursor = nir_before_instr(&tex->instr);
nir_def *coords = nir_steal_tex_src(tex, nir_tex_src_coord);
nir_def *offset = nir_steal_tex_src(tex, nir_tex_src_offset);
nir_def *ddx = nir_steal_tex_src(tex, nir_tex_src_ddx);
nir_def *ddy = nir_steal_tex_src(tex, nir_tex_src_ddy);
/* Add in 2D sources to become a 2D operation */
tex->sampler_dim = GLSL_SAMPLER_DIM_2D;
if (coords) {
/* We want to fetch texel 0 along the Y-axis. To do so, we sample at 0.5
* to get texel 0 with correct handling of wrap modes.
*/
nir_def *y = nir_imm_floatN_t(b, tex->op == nir_texop_txf ? 0.0 : 0.5,
coords->bit_size);
tex->coord_components++;
if (tex->is_array && tex->op != nir_texop_lod) {
assert(tex->coord_components == 3);
nir_def *x = nir_channel(b, coords, 0);
nir_def *idx = nir_channel(b, coords, 1);
coords = nir_vec3(b, x, y, idx);
} else {
assert(tex->coord_components == 2);
coords = nir_vec2(b, coords, y);
}
nir_tex_instr_add_src(tex, nir_tex_src_coord, coords);
}
if (offset) {
nir_tex_instr_add_src(tex, nir_tex_src_offset,
nir_pad_vector_imm_int(b, offset, 0, 2));
}
if (ddx || ddy) {
nir_tex_instr_add_src(tex, nir_tex_src_ddx,
nir_pad_vector_imm_int(b, ddx, 0, 2));
nir_tex_instr_add_src(tex, nir_tex_src_ddy,
nir_pad_vector_imm_int(b, ddy, 0, 2));
}
/* Handle destination component mismatch for txs. */
if (tex->op == nir_texop_txs) {
b->cursor = nir_after_instr(&tex->instr);
nir_def *dst;
if (tex->is_array) {
assert(tex->def.num_components == 2);
tex->def.num_components = 3;
/* For array, we take .xz to skip the newly added height */
dst = nir_channels(b, &tex->def, (1 << 0) | (1 << 2));
} else {
assert(tex->def.num_components == 1);
tex->def.num_components = 2;
dst = nir_channel(b, &tex->def, 0);
}
nir_def_rewrite_uses_after(&tex->def, dst, dst->parent_instr);
}
}
static void
lower_lod(nir_builder *b, nir_tex_instr *tex, nir_def *lod)
{
@ -1497,6 +1569,12 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
progress = true;
}
if (tex->sampler_dim == GLSL_SAMPLER_DIM_1D &&
(options->lower_1d || (tex->is_shadow && options->lower_1d_shadow))) {
lower_1d(b, tex);
progress = true;
}
unsigned texture_index = tex->texture_index;
uint32_t texture_mask = 1u << texture_index;
int tex_index = nir_tex_instr_src_index(tex, nir_tex_src_texture_deref);