nir: Usher nir_normalize_cubemap_coords into 2022
I stumbled upon this old NIR pass (still in use by intel and broadcom) and noticed how most of the code was NIR boilerplate that we have helpers for. Rewrite the pass to use all the helpers. v2: Fix cube map arrays. Signed-off-by: Alyssa Rosenzweig <alyssa@collabora.com> Reviewed-by: Jason Ekstrand <jason.ekstrand@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18754>
This commit is contained in:
committed by
Marge Bot
parent
fc5c671e87
commit
2c7be4d421
@@ -25,92 +25,53 @@
|
||||
*/
|
||||
|
||||
#include "nir.h"
|
||||
#include "nir_builder.h"
|
||||
#include "nir_builtin_builder.h"
|
||||
|
||||
/**
|
||||
* This file implements a NIR lowering pass to perform the normalization of
|
||||
* the cubemap coordinates to have the largest magnitude component be -1.0
|
||||
* or 1.0. This is based on the old GLSL IR based pass by Eric.
|
||||
/*
|
||||
* Lower cubemap coordinate to have normalized coordinates where the largest
|
||||
* magnitude component is -1.0 or 1.0.
|
||||
*/
|
||||
|
||||
static bool
|
||||
normalize_cubemap_coords_block(nir_block *block, nir_builder *b)
|
||||
normalize_cubemap_coords(nir_builder *b, nir_instr *instr, void *data)
|
||||
{
|
||||
bool progress = false;
|
||||
if (instr->type != nir_instr_type_tex)
|
||||
return false;
|
||||
|
||||
nir_foreach_instr(instr, block) {
|
||||
if (instr->type != nir_instr_type_tex)
|
||||
continue;
|
||||
nir_tex_instr *tex = nir_instr_as_tex(instr);
|
||||
if (tex->sampler_dim != GLSL_SAMPLER_DIM_CUBE)
|
||||
return false;
|
||||
|
||||
nir_tex_instr *tex = nir_instr_as_tex(instr);
|
||||
if (tex->sampler_dim != GLSL_SAMPLER_DIM_CUBE)
|
||||
continue;
|
||||
b->cursor = nir_before_instr(instr);
|
||||
|
||||
b->cursor = nir_before_instr(&tex->instr);
|
||||
int idx = nir_tex_instr_src_index(tex, nir_tex_src_coord);
|
||||
if (idx < 0)
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < tex->num_srcs; i++) {
|
||||
if (tex->src[i].src_type != nir_tex_src_coord)
|
||||
continue;
|
||||
nir_ssa_def *orig_coord =
|
||||
nir_ssa_for_src(b, tex->src[idx].src, nir_tex_instr_src_size(tex, idx));
|
||||
assert(orig_coord->num_components >= 3);
|
||||
|
||||
nir_ssa_def *orig_coord =
|
||||
nir_ssa_for_src(b, tex->src[i].src, nir_tex_instr_src_size(tex, i));
|
||||
assert(orig_coord->num_components >= 3);
|
||||
nir_ssa_def *orig_xyz = nir_trim_vector(b, orig_coord, 3);
|
||||
nir_ssa_def *norm = nir_fmax_abs_vec_comp(b, orig_xyz);
|
||||
nir_ssa_def *normalized = nir_fmul(b, orig_coord, nir_frcp(b, norm));
|
||||
|
||||
nir_ssa_def *abs = nir_fabs(b, orig_coord);
|
||||
nir_ssa_def *norm = nir_fmax(b, nir_channel(b, abs, 0),
|
||||
nir_fmax(b, nir_channel(b, abs, 1),
|
||||
nir_channel(b, abs, 2)));
|
||||
|
||||
nir_ssa_def *normalized = nir_fmul(b, orig_coord, nir_frcp(b, norm));
|
||||
|
||||
/* Array indices don't have to be normalized, so make a new vector
|
||||
* with the coordinate's array index untouched.
|
||||
*/
|
||||
if (tex->coord_components == 4) {
|
||||
normalized = nir_vec4(b,
|
||||
nir_channel(b, normalized, 0),
|
||||
nir_channel(b, normalized, 1),
|
||||
nir_channel(b, normalized, 2),
|
||||
nir_channel(b, orig_coord, 3));
|
||||
}
|
||||
|
||||
nir_instr_rewrite_src(&tex->instr,
|
||||
&tex->src[i].src,
|
||||
nir_src_for_ssa(normalized));
|
||||
|
||||
progress = true;
|
||||
}
|
||||
/* Array indices don't have to be normalized, so make a new vector
|
||||
* with the coordinate's array index untouched.
|
||||
*/
|
||||
if (tex->coord_components == 4) {
|
||||
normalized = nir_vector_insert_imm(b, normalized,
|
||||
nir_channel(b, orig_coord, 3), 3);
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
static bool
|
||||
normalize_cubemap_coords_impl(nir_function_impl *impl)
|
||||
{
|
||||
nir_builder b;
|
||||
nir_builder_init(&b, impl);
|
||||
bool progress = false;
|
||||
|
||||
nir_foreach_block(block, impl) {
|
||||
progress |= normalize_cubemap_coords_block(block, &b);
|
||||
}
|
||||
|
||||
nir_metadata_preserve(impl, nir_metadata_block_index |
|
||||
nir_metadata_dominance);
|
||||
|
||||
return progress;
|
||||
nir_instr_rewrite_src_ssa(instr, &tex->src[idx].src, normalized);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nir_normalize_cubemap_coords(nir_shader *shader)
|
||||
{
|
||||
bool progress = false;
|
||||
|
||||
nir_foreach_function(function, shader) {
|
||||
if (function->impl)
|
||||
progress = normalize_cubemap_coords_impl(function->impl) || progress;
|
||||
}
|
||||
|
||||
return progress;
|
||||
return nir_shader_instructions_pass(shader, normalize_cubemap_coords,
|
||||
nir_metadata_block_index |
|
||||
nir_metadata_dominance,
|
||||
NULL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user