summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/Makefile.sources1
-rw-r--r--src/compiler/glsl/gl_nir_lower_samplers.c128
-rw-r--r--src/compiler/nir/meson.build1
-rw-r--r--src/compiler/nir/nir.h2
-rw-r--r--src/compiler/nir/nir_lower_samplers.c154
5 files changed, 159 insertions, 127 deletions
diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources
index edf1b936ac1..ac6c0670444 100644
--- a/src/compiler/Makefile.sources
+++ b/src/compiler/Makefile.sources
@@ -272,6 +272,7 @@ NIR_FILES = \
nir/nir_lower_phis_to_scalar.c \
nir/nir_lower_regs_to_ssa.c \
nir/nir_lower_returns.c \
+ nir/nir_lower_samplers.c \
nir/nir_lower_scratch.c \
nir/nir_lower_subgroups.c \
nir/nir_lower_system_values.c \
diff --git a/src/compiler/glsl/gl_nir_lower_samplers.c b/src/compiler/glsl/gl_nir_lower_samplers.c
index 85535c074dc..08817316b9c 100644
--- a/src/compiler/glsl/gl_nir_lower_samplers.c
+++ b/src/compiler/glsl/gl_nir_lower_samplers.c
@@ -24,142 +24,16 @@
*/
#include "compiler/nir/nir.h"
-#include "compiler/nir/nir_builder.h"
#include "gl_nir.h"
-#include "ir_uniform.h"
-
-#include "main/compiler.h"
-#include "main/mtypes.h"
-
-static void
-lower_tex_src_to_offset(nir_builder *b,
- nir_tex_instr *instr, unsigned src_idx)
-{
- nir_ssa_def *index = NULL;
- unsigned base_index = 0;
- unsigned array_elements = 1;
- nir_tex_src *src = &instr->src[src_idx];
- bool is_sampler = src->src_type == nir_tex_src_sampler_deref;
-
- /* We compute first the offsets */
- nir_deref_instr *deref = nir_instr_as_deref(src->src.ssa->parent_instr);
- while (deref->deref_type != nir_deref_type_var) {
- assert(deref->parent.is_ssa);
- nir_deref_instr *parent =
- nir_instr_as_deref(deref->parent.ssa->parent_instr);
-
- assert(deref->deref_type == nir_deref_type_array);
-
- if (nir_src_is_const(deref->arr.index) && index == NULL) {
- /* We're still building a direct index */
- base_index += nir_src_as_uint(deref->arr.index) * array_elements;
- } else {
- if (index == NULL) {
- /* We used to be direct but not anymore */
- index = nir_imm_int(b, base_index);
- base_index = 0;
- }
-
- index = nir_iadd(b, index,
- nir_imul(b, nir_imm_int(b, array_elements),
- nir_ssa_for_src(b, deref->arr.index, 1)));
- }
-
- array_elements *= glsl_get_length(parent->type);
-
- deref = parent;
- }
-
- if (index)
- index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
-
- /* We hit the deref_var. This is the end of the line */
- assert(deref->deref_type == nir_deref_type_var);
-
- base_index += deref->var->data.binding;
-
- /* We have the offsets, we apply them, rewriting the source or removing
- * instr if needed
- */
- if (index) {
- nir_instr_rewrite_src(&instr->instr, &src->src,
- nir_src_for_ssa(index));
-
- src->src_type = is_sampler ?
- nir_tex_src_sampler_offset :
- nir_tex_src_texture_offset;
-
- instr->texture_array_size = array_elements;
- } else {
- nir_tex_instr_remove_src(instr, src_idx);
- }
-
- if (is_sampler) {
- instr->sampler_index = base_index;
- } else {
- instr->texture_index = base_index;
- instr->texture_array_size = array_elements;
- }
-}
-
-static bool
-lower_sampler(nir_builder *b, nir_tex_instr *instr)
-{
- int texture_idx =
- nir_tex_instr_src_index(instr, nir_tex_src_texture_deref);
-
- if (texture_idx >= 0) {
- b->cursor = nir_before_instr(&instr->instr);
-
- lower_tex_src_to_offset(b, instr, texture_idx);
- }
-
- int sampler_idx =
- nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref);
-
- if (sampler_idx >= 0) {
- lower_tex_src_to_offset(b, instr, sampler_idx);
- }
-
- if (texture_idx < 0 && sampler_idx < 0)
- return false;
-
- return true;
-}
-
-static bool
-lower_impl(nir_function_impl *impl)
-{
- nir_builder b;
- nir_builder_init(&b, impl);
- bool progress = false;
-
- nir_foreach_block(block, impl) {
- nir_foreach_instr(instr, block) {
- if (instr->type == nir_instr_type_tex)
- progress |= lower_sampler(&b, nir_instr_as_tex(instr));
- }
- }
-
- return progress;
-}
bool
gl_nir_lower_samplers(nir_shader *shader,
const struct gl_shader_program *shader_program)
{
- bool progress = false;
-
/* First, use gl_nir_lower_samplers_as_derefs to set var->data.binding
* based on the uniforms, and split structures to simplify derefs.
*/
gl_nir_lower_samplers_as_deref(shader, shader_program);
- /* Next, lower derefs to offsets. */
- nir_foreach_function(function, shader) {
- if (function->impl)
- progress |= lower_impl(function->impl);
- }
-
- return progress;
+ return nir_lower_samplers(shader);
}
diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build
index 04e4f729902..1da26ef561c 100644
--- a/src/compiler/nir/meson.build
+++ b/src/compiler/nir/meson.build
@@ -152,6 +152,7 @@ files_libnir = files(
'nir_lower_point_size.c',
'nir_lower_regs_to_ssa.c',
'nir_lower_returns.c',
+ 'nir_lower_samplers.c',
'nir_lower_scratch.c',
'nir_lower_subgroups.c',
'nir_lower_system_values.c',
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index bad1d6af212..ab1aab774a0 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -3938,6 +3938,8 @@ bool nir_lower_phis_to_regs_block(nir_block *block);
bool nir_lower_ssa_defs_to_regs_block(nir_block *block);
bool nir_rematerialize_derefs_in_use_blocks_impl(nir_function_impl *impl);
+bool nir_lower_samplers(nir_shader *shader);
+
/* This is here for unit tests. */
bool nir_opt_comparison_pre_impl(nir_function_impl *impl);
diff --git a/src/compiler/nir/nir_lower_samplers.c b/src/compiler/nir/nir_lower_samplers.c
new file mode 100644
index 00000000000..5a440f7117c
--- /dev/null
+++ b/src/compiler/nir/nir_lower_samplers.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2005-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2008 VMware, Inc. All Rights Reserved.
+ * Copyright © 2014 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.
+ */
+
+#include "nir/nir.h"
+#include "nir_builder.h"
+
+static void
+lower_tex_src_to_offset(nir_builder *b,
+ nir_tex_instr *instr, unsigned src_idx)
+{
+ nir_ssa_def *index = NULL;
+ unsigned base_index = 0;
+ unsigned array_elements = 1;
+ nir_tex_src *src = &instr->src[src_idx];
+ bool is_sampler = src->src_type == nir_tex_src_sampler_deref;
+
+ /* We compute first the offsets */
+ nir_deref_instr *deref = nir_instr_as_deref(src->src.ssa->parent_instr);
+ while (deref->deref_type != nir_deref_type_var) {
+ assert(deref->parent.is_ssa);
+ nir_deref_instr *parent =
+ nir_instr_as_deref(deref->parent.ssa->parent_instr);
+
+ assert(deref->deref_type == nir_deref_type_array);
+
+ if (nir_src_is_const(deref->arr.index) && index == NULL) {
+ /* We're still building a direct index */
+ base_index += nir_src_as_uint(deref->arr.index) * array_elements;
+ } else {
+ if (index == NULL) {
+ /* We used to be direct but not anymore */
+ index = nir_imm_int(b, base_index);
+ base_index = 0;
+ }
+
+ index = nir_iadd(b, index,
+ nir_imul(b, nir_imm_int(b, array_elements),
+ nir_ssa_for_src(b, deref->arr.index, 1)));
+ }
+
+ array_elements *= glsl_get_length(parent->type);
+
+ deref = parent;
+ }
+
+ if (index)
+ index = nir_umin(b, index, nir_imm_int(b, array_elements - 1));
+
+ /* We hit the deref_var. This is the end of the line */
+ assert(deref->deref_type == nir_deref_type_var);
+
+ base_index += deref->var->data.binding;
+
+ /* We have the offsets, we apply them, rewriting the source or removing
+ * instr if needed
+ */
+ if (index) {
+ nir_instr_rewrite_src(&instr->instr, &src->src,
+ nir_src_for_ssa(index));
+
+ src->src_type = is_sampler ?
+ nir_tex_src_sampler_offset :
+ nir_tex_src_texture_offset;
+
+ instr->texture_array_size = array_elements;
+ } else {
+ nir_tex_instr_remove_src(instr, src_idx);
+ }
+
+ if (is_sampler) {
+ instr->sampler_index = base_index;
+ } else {
+ instr->texture_index = base_index;
+ instr->texture_array_size = array_elements;
+ }
+}
+
+static bool
+lower_sampler(nir_builder *b, nir_tex_instr *instr)
+{
+ int texture_idx =
+ nir_tex_instr_src_index(instr, nir_tex_src_texture_deref);
+
+ if (texture_idx >= 0) {
+ b->cursor = nir_before_instr(&instr->instr);
+
+ lower_tex_src_to_offset(b, instr, texture_idx);
+ }
+
+ int sampler_idx =
+ nir_tex_instr_src_index(instr, nir_tex_src_sampler_deref);
+
+ if (sampler_idx >= 0) {
+ lower_tex_src_to_offset(b, instr, sampler_idx);
+ }
+
+ if (texture_idx < 0 && sampler_idx < 0)
+ return false;
+
+ return true;
+}
+
+static bool
+lower_impl(nir_function_impl *impl)
+{
+ nir_builder b;
+ nir_builder_init(&b, impl);
+ bool progress = false;
+
+ nir_foreach_block(block, impl) {
+ nir_foreach_instr(instr, block) {
+ if (instr->type == nir_instr_type_tex)
+ progress |= lower_sampler(&b, nir_instr_as_tex(instr));
+ }
+ }
+
+ return progress;
+}
+
+bool
+nir_lower_samplers(nir_shader *shader)
+{
+ bool progress = false;
+
+ /* Next, lower derefs to offsets. */
+ nir_foreach_function(function, shader) {
+ if (function->impl)
+ progress |= lower_impl(function->impl);
+ }
+
+ return progress;
+}