--- src/mesa/drivers/dri/i965/Makefile.sources | 1 + src/mesa/drivers/dri/i965/brw_nir.h | 2 + .../drivers/dri/i965/brw_nir_cubemap_normalize.c | 111 +++++++++++++++++++++ 3 files changed, 114 insertions(+) create mode 100644 src/mesa/drivers/dri/i965/brw_nir_cubemap_normalize.c
diff --git a/src/mesa/drivers/dri/i965/Makefile.sources b/src/mesa/drivers/dri/i965/Makefile.sources index 498d5a7..8e723b0 100644 --- a/src/mesa/drivers/dri/i965/Makefile.sources +++ b/src/mesa/drivers/dri/i965/Makefile.sources @@ -78,6 +78,7 @@ i965_FILES = \ brw_multisample_state.h \ brw_nir.h \ brw_nir_analyze_boolean_resolves.c \ + brw_nir_cubemap_normalize.c \ brw_object_purgeable.c \ brw_packed_float.c \ brw_performance_monitor.c \ diff --git a/src/mesa/drivers/dri/i965/brw_nir.h b/src/mesa/drivers/dri/i965/brw_nir.h index 27782a3..5885a07 100644 --- a/src/mesa/drivers/dri/i965/brw_nir.h +++ b/src/mesa/drivers/dri/i965/brw_nir.h @@ -73,6 +73,8 @@ enum { void brw_nir_analyze_boolean_resolves(nir_shader *nir); +void brw_nir_cubemap_normalize(nir_shader *nir); + #ifdef __cplusplus } #endif diff --git a/src/mesa/drivers/dri/i965/brw_nir_cubemap_normalize.c b/src/mesa/drivers/dri/i965/brw_nir_cubemap_normalize.c new file mode 100644 index 0000000..6464f41 --- /dev/null +++ b/src/mesa/drivers/dri/i965/brw_nir_cubemap_normalize.c @@ -0,0 +1,111 @@ +/* + * Copyright © 2015 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Jason Ekstrand <ja...@jlekstrand.net> + */ + +#include "brw_nir.h" +#include "glsl/nir/nir_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. + */ + +static nir_ssa_def * +channel(nir_builder *b, nir_ssa_def *def, int c) +{ + return nir_swizzle(b, def, (unsigned[4]){c, c, c, c}, 1, false); +} + +static bool +cubemap_normalize_block(nir_block *block, void *void_state) +{ + nir_builder *b = void_state; + + nir_foreach_instr(block, instr) { + 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) + continue; + + nir_builder_insert_before_instr(b, &tex->instr); + + 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[i].src, nir_tex_instr_src_size(tex, i)); + assert(orig_coord->num_components >= 3); + + nir_ssa_def *abs0 = nir_fabs(b, channel(b, orig_coord, 0)); + nir_ssa_def *abs1 = nir_fabs(b, channel(b, orig_coord, 1)); + nir_ssa_def *abs2 = nir_fabs(b, channel(b, orig_coord, 2)); + + nir_ssa_def *norm1 = nir_fmax(b, abs0, nir_fmax(b, abs1, abs2)); + + nir_ssa_def *normalized = nir_fmul(b, orig_coord, nir_frcp(b, norm1)); + + /* 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, + channel(b, normalized, 0), + channel(b, normalized, 1), + channel(b, normalized, 2), + channel(b, orig_coord, 3)); + } + + nir_instr_rewrite_src(&tex->instr, + &tex->src[i].src, + nir_src_for_ssa(normalized)); + } + } + + return true; +} + +static void +cubemap_normalize_impl(nir_function_impl *impl) +{ + nir_builder b; + nir_builder_init(&b, impl); + + nir_foreach_block(impl, cubemap_normalize_block, &b); + + nir_metadata_preserve(impl, nir_metadata_block_index | + nir_metadata_dominance); +} + +void +brw_nir_cubemap_normalize(nir_shader *shader) +{ + nir_foreach_overload(shader, overload) + if (overload->impl) + cubemap_normalize_impl(overload->impl); +} -- 2.3.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev