diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index abd1495be9d..76515498c5e 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -4913,6 +4913,12 @@ typedef struct nir_lower_tex_options { */ bool lower_txs_lod; + /** + * If true, lower nir_texop_txs for cube arrays to a nir_texop_txs with a + * 2D array type followed by a nir_idiv by 6. + */ + bool lower_txs_cube_array; + /** * If true, apply a .bagr swizzle on tg4 results to handle Broadcom's * mixed-up tg4 locations. diff --git a/src/compiler/nir/nir_lower_tex.c b/src/compiler/nir/nir_lower_tex.c index cf8275c5786..6a47851478f 100644 --- a/src/compiler/nir/nir_lower_tex.c +++ b/src/compiler/nir/nir_lower_tex.c @@ -1155,6 +1155,25 @@ nir_lower_txs_lod(nir_builder *b, nir_tex_instr *tex) return true; } +static void +nir_lower_txs_cube_array(nir_builder *b, nir_tex_instr *tex) +{ + assert(tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE && tex->is_array); + tex->sampler_dim = GLSL_SAMPLER_DIM_2D; + + b->cursor = nir_after_instr(&tex->instr); + + assert(tex->dest.is_ssa); + assert(tex->dest.ssa.num_components == 3); + nir_ssa_def *size = &tex->dest.ssa; + size = nir_vec3(b, nir_channel(b, size, 0), + nir_channel(b, size, 1), + nir_idiv(b, nir_channel(b, size, 2), + nir_imm_int(b, 6))); + + nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, size, size->parent_instr); +} + static bool nir_lower_tex_block(nir_block *block, nir_builder *b, const nir_lower_tex_options *options, @@ -1346,6 +1365,13 @@ nir_lower_tex_block(nir_block *block, nir_builder *b, continue; } + if (options->lower_txs_cube_array && tex->op == nir_texop_txs && + tex->sampler_dim == GLSL_SAMPLER_DIM_CUBE && tex->is_array) { + nir_lower_txs_cube_array(b, tex); + progress = true; + continue; + } + /* has to happen after all the other lowerings as the original tg4 gets * replaced by 4 tg4 instructions. */