mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-04 20:00:11 +01:00
nir/lower-tex: add srgb->linear lowering
Signed-off-by: Rob Clark <robclark@freedesktop.org> Reviewed-by: Eric Anholt <eric@anholt.net> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
This commit is contained in:
parent
eb00a0fc58
commit
eddfc97709
2 changed files with 53 additions and 0 deletions
|
|
@ -2301,6 +2301,13 @@ typedef struct nir_lower_tex_options {
|
|||
* while 4 and 5 represent 0 and 1 respectively.
|
||||
*/
|
||||
uint8_t swizzles[32][4];
|
||||
|
||||
/**
|
||||
* Bitmap of textures that need srgb to linear conversion. If
|
||||
* (lower_srgb & (1 << texture_index)) then the rgb (xyz) components
|
||||
* of the texture are lowered to linear.
|
||||
*/
|
||||
unsigned lower_srgb;
|
||||
} nir_lower_tex_options;
|
||||
|
||||
bool nir_lower_tex(nir_shader *shader,
|
||||
|
|
|
|||
|
|
@ -275,6 +275,45 @@ swizzle_result(nir_builder *b, nir_tex_instr *tex, const uint8_t swizzle[4])
|
|||
swizzled->parent_instr);
|
||||
}
|
||||
|
||||
static void
|
||||
linearize_srgb_result(nir_builder *b, nir_tex_instr *tex)
|
||||
{
|
||||
assert(tex->dest.is_ssa);
|
||||
assert(nir_tex_instr_dest_size(tex) == 4);
|
||||
assert(nir_alu_type_get_base_type(tex->dest_type) == nir_type_float);
|
||||
|
||||
b->cursor = nir_after_instr(&tex->instr);
|
||||
|
||||
static const unsigned swiz[4] = {0, 1, 2, 0};
|
||||
nir_ssa_def *comp = nir_swizzle(b, &tex->dest.ssa, swiz, 3, true);
|
||||
|
||||
/* Formula is:
|
||||
* (comp <= 0.04045) ?
|
||||
* (comp / 12.92) :
|
||||
* pow((comp + 0.055) / 1.055, 2.4)
|
||||
*/
|
||||
nir_ssa_def *low = nir_fmul(b, comp, nir_imm_float(b, 1.0 / 12.92));
|
||||
nir_ssa_def *high = nir_fpow(b,
|
||||
nir_fmul(b,
|
||||
nir_fadd(b,
|
||||
comp,
|
||||
nir_imm_float(b, 0.055)),
|
||||
nir_imm_float(b, 1.0 / 1.055)),
|
||||
nir_imm_float(b, 2.4));
|
||||
nir_ssa_def *cond = nir_fge(b, nir_imm_float(b, 0.04045), comp);
|
||||
nir_ssa_def *rgb = nir_bcsel(b, cond, low, high);
|
||||
|
||||
/* alpha is untouched: */
|
||||
nir_ssa_def *result = nir_vec4(b,
|
||||
nir_channel(b, rgb, 0),
|
||||
nir_channel(b, rgb, 1),
|
||||
nir_channel(b, rgb, 2),
|
||||
nir_channel(b, &tex->dest.ssa, 3));
|
||||
|
||||
nir_ssa_def_rewrite_uses_after(&tex->dest.ssa, nir_src_for_ssa(result),
|
||||
result->parent_instr);
|
||||
}
|
||||
|
||||
static bool
|
||||
nir_lower_tex_block(nir_block *block, void *void_state)
|
||||
{
|
||||
|
|
@ -323,6 +362,13 @@ nir_lower_tex_block(nir_block *block, void *void_state)
|
|||
swizzle_result(b, tex, options->swizzles[tex->texture_index]);
|
||||
state->progress = true;
|
||||
}
|
||||
|
||||
/* should be after swizzle so we know which channels are rgb: */
|
||||
if (((1 << tex->texture_index) & options->lower_srgb) &&
|
||||
!nir_tex_instr_is_query(tex) && !tex->is_shadow) {
|
||||
linearize_srgb_result(b, tex);
|
||||
state->progress = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue