mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-30 18:40:13 +01:00
nir/lower_tex: Add support for lowering texture swizzle
Reviewed-by: Connor Abbott <cwabbott0@gmail.com>
This commit is contained in:
parent
6921b17107
commit
8537b4ab76
2 changed files with 80 additions and 0 deletions
|
|
@ -2019,6 +2019,19 @@ typedef struct nir_lower_tex_options {
|
|||
unsigned saturate_s;
|
||||
unsigned saturate_t;
|
||||
unsigned saturate_r;
|
||||
|
||||
/* Bitmask of samplers that need swizzling.
|
||||
*
|
||||
* If (swizzle_result & (1 << sampler_index)), then the swizzle in
|
||||
* swizzles[sampler_index] is applied to the result of the texturing
|
||||
* operation.
|
||||
*/
|
||||
unsigned swizzle_result;
|
||||
|
||||
/* A swizzle for each sampler. Values 0-3 represent x, y, z, or w swizzles
|
||||
* while 4 and 5 represent 0 and 1 respectively.
|
||||
*/
|
||||
uint8_t swizzles[32][4];
|
||||
} nir_lower_tex_options;
|
||||
|
||||
bool nir_lower_tex(nir_shader *shader,
|
||||
|
|
|
|||
|
|
@ -215,6 +215,66 @@ saturate_src(nir_builder *b, nir_tex_instr *tex, unsigned sat_mask)
|
|||
}
|
||||
}
|
||||
|
||||
static nir_ssa_def *
|
||||
get_zero_or_one(nir_builder *b, nir_alu_type type, uint8_t swizzle_val)
|
||||
{
|
||||
nir_const_value v;
|
||||
|
||||
memset(&v, 0, sizeof(v));
|
||||
|
||||
if (swizzle_val == 4) {
|
||||
v.u[0] = v.u[1] = v.u[2] = v.u[3] = 0;
|
||||
} else {
|
||||
assert(swizzle_val == 5);
|
||||
if (type == nir_type_float)
|
||||
v.f[0] = v.f[1] = v.f[2] = v.f[3] = 1.0;
|
||||
else
|
||||
v.u[0] = v.u[1] = v.u[2] = v.u[3] = 1;
|
||||
}
|
||||
|
||||
return nir_build_imm(b, 4, v);
|
||||
}
|
||||
|
||||
static void
|
||||
swizzle_result(nir_builder *b, nir_tex_instr *tex, const uint8_t swizzle[4])
|
||||
{
|
||||
assert(tex->dest.is_ssa);
|
||||
|
||||
b->cursor = nir_after_instr(&tex->instr);
|
||||
|
||||
nir_ssa_def *swizzled;
|
||||
if (tex->op == nir_texop_tg4) {
|
||||
if (swizzle[tex->component] < 4) {
|
||||
/* This one's easy */
|
||||
tex->component = swizzle[tex->component];
|
||||
return;
|
||||
} else {
|
||||
swizzled = get_zero_or_one(b, tex->dest_type, swizzle[tex->component]);
|
||||
}
|
||||
} else {
|
||||
assert(nir_tex_instr_dest_size(tex) == 4);
|
||||
if (swizzle[0] < 4 && swizzle[1] < 4 &&
|
||||
swizzle[2] < 4 && swizzle[3] < 4) {
|
||||
unsigned swiz[4] = { swizzle[0], swizzle[1], swizzle[2], swizzle[3] };
|
||||
/* We have no 0's or 1's, just emit a swizzling MOV */
|
||||
swizzled = nir_swizzle(b, &tex->dest.ssa, swiz, 4, false);
|
||||
} else {
|
||||
nir_ssa_def *srcs[4];
|
||||
for (unsigned i = 0; i < 4; i++) {
|
||||
if (swizzle[i] < 4) {
|
||||
srcs[i] = nir_channel(b, &tex->dest.ssa, swizzle[i]);
|
||||
} else {
|
||||
srcs[i] = get_zero_or_one(b, tex->dest_type, swizzle[i]);
|
||||
}
|
||||
}
|
||||
swizzled = nir_vec(b, srcs, 4);
|
||||
}
|
||||
}
|
||||
|
||||
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, nir_src_for_ssa(swizzled),
|
||||
swizzled->parent_instr);
|
||||
}
|
||||
|
||||
static bool
|
||||
nir_lower_tex_block(nir_block *block, void *void_state)
|
||||
{
|
||||
|
|
@ -256,6 +316,13 @@ nir_lower_tex_block(nir_block *block, void *void_state)
|
|||
saturate_src(b, tex, sat_mask);
|
||||
state->progress = true;
|
||||
}
|
||||
|
||||
if (((1 << tex->sampler_index) & state->options->swizzle_result) &&
|
||||
!nir_tex_instr_is_query(tex) &&
|
||||
!(tex->is_shadow && tex->is_new_style_shadow)) {
|
||||
swizzle_result(b, tex, state->options->swizzles[tex->sampler_index]);
|
||||
state->progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue