nir/lower_tex: Add support for lowering coordinate offsets
On i965, we can't support coordinate offsets for texelFetch or rectangle textures. Previously, we were doing this with a GLSL pass but we need to do it in NIR if we want those workarounds for SPIR-V. Signed-off-by: Jason Ekstrand <jason@jlekstrand.net> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org> Cc: "12.0" <mesa-dev@lists.freedesktop.org>
This commit is contained in:
@@ -2408,6 +2408,16 @@ typedef struct nir_lower_tex_options {
|
|||||||
*/
|
*/
|
||||||
unsigned lower_txp;
|
unsigned lower_txp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, lower away nir_tex_src_offset for all texelfetch instructions.
|
||||||
|
*/
|
||||||
|
bool lower_txf_offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If true, lower away nir_tex_src_offset for all rect textures.
|
||||||
|
*/
|
||||||
|
bool lower_rect_offset;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true, lower rect textures to 2D, using txs to fetch the
|
* If true, lower rect textures to 2D, using txs to fetch the
|
||||||
* texture dimensions and dividing the texture coords by the
|
* texture dimensions and dividing the texture coords by the
|
||||||
|
@@ -128,6 +128,54 @@ project_src(nir_builder *b, nir_tex_instr *tex)
|
|||||||
tex_instr_remove_src(tex, proj_index);
|
tex_instr_remove_src(tex, proj_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
lower_offset(nir_builder *b, nir_tex_instr *tex)
|
||||||
|
{
|
||||||
|
int offset_index = tex_instr_find_src(tex, nir_tex_src_offset);
|
||||||
|
if (offset_index < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
int coord_index = tex_instr_find_src(tex, nir_tex_src_coord);
|
||||||
|
assert(coord_index >= 0);
|
||||||
|
|
||||||
|
assert(tex->src[offset_index].src.is_ssa);
|
||||||
|
assert(tex->src[coord_index].src.is_ssa);
|
||||||
|
nir_ssa_def *offset = tex->src[offset_index].src.ssa;
|
||||||
|
nir_ssa_def *coord = tex->src[coord_index].src.ssa;
|
||||||
|
|
||||||
|
b->cursor = nir_before_instr(&tex->instr);
|
||||||
|
|
||||||
|
nir_ssa_def *offset_coord;
|
||||||
|
if (nir_tex_instr_src_type(tex, coord_index) == nir_type_float) {
|
||||||
|
assert(tex->sampler_dim == GLSL_SAMPLER_DIM_RECT);
|
||||||
|
offset_coord = nir_fadd(b, coord, nir_i2f(b, offset));
|
||||||
|
} else {
|
||||||
|
offset_coord = nir_iadd(b, coord, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tex->is_array) {
|
||||||
|
/* The offset is not applied to the array index */
|
||||||
|
if (tex->coord_components == 2) {
|
||||||
|
offset_coord = nir_vec2(b, nir_channel(b, offset_coord, 0),
|
||||||
|
nir_channel(b, coord, 1));
|
||||||
|
} else if (tex->coord_components == 3) {
|
||||||
|
offset_coord = nir_vec3(b, nir_channel(b, offset_coord, 0),
|
||||||
|
nir_channel(b, offset_coord, 1),
|
||||||
|
nir_channel(b, coord, 2));
|
||||||
|
} else {
|
||||||
|
unreachable("Invalid number of components");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nir_instr_rewrite_src(&tex->instr, &tex->src[coord_index].src,
|
||||||
|
nir_src_for_ssa(offset_coord));
|
||||||
|
|
||||||
|
tex_instr_remove_src(tex, offset_index);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static nir_ssa_def *
|
static nir_ssa_def *
|
||||||
get_texture_size(nir_builder *b, nir_tex_instr *tex)
|
get_texture_size(nir_builder *b, nir_tex_instr *tex)
|
||||||
{
|
{
|
||||||
@@ -458,6 +506,12 @@ nir_lower_tex_block(nir_block *block, nir_builder *b,
|
|||||||
progress = true;
|
progress = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((tex->op == nir_texop_txf && options->lower_txf_offset) ||
|
||||||
|
(tex->sampler_dim == GLSL_SAMPLER_DIM_RECT &&
|
||||||
|
options->lower_rect_offset)) {
|
||||||
|
progress = lower_offset(b, tex) || progress;
|
||||||
|
}
|
||||||
|
|
||||||
if ((tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) && options->lower_rect) {
|
if ((tex->sampler_dim == GLSL_SAMPLER_DIM_RECT) && options->lower_rect) {
|
||||||
lower_rect(b, tex);
|
lower_rect(b, tex);
|
||||||
progress = true;
|
progress = true;
|
||||||
|
Reference in New Issue
Block a user