[Mesa-dev] [RFC PATCH] nir: add support for tg4 with multiple offsets
Karol Herbst
kherbst at redhat.com
Tue Feb 27 12:54:09 UTC 2018
Just want quick feedback on this. Nouveau can make use of it, which would
eliminate the need of having 4 seperate tg4 instructions.
The current code runs into the assert when PIPE_CAP_TEXTURE_GATHER_OFFSETS is
enabled.
Signed-off-by: Karol Herbst <kherbst at redhat.com>
---
src/compiler/glsl/glsl_to_nir.cpp | 25 ++++++++++++++++------
src/compiler/nir/nir.h | 9 +++++++-
src/compiler/nir/nir_print.c | 9 ++++++++
.../drivers/nouveau/codegen/nv50_ir_from_nir.cpp | 15 ++++++++++---
4 files changed, 47 insertions(+), 11 deletions(-)
diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp
index 7a9d15015e..a4a7526aa5 100644
--- a/src/compiler/glsl/glsl_to_nir.cpp
+++ b/src/compiler/glsl/glsl_to_nir.cpp
@@ -2038,7 +2038,9 @@ nir_visitor::visit(ir_texture *ir)
num_srcs++;
if (ir->shadow_comparator != NULL)
num_srcs++;
- if (ir->offset != NULL)
+ if (ir->offset != NULL && ir->offset->type->is_array())
+ num_srcs += ir->offset->type->array_size();
+ else if (ir->offset != NULL)
num_srcs++;
nir_tex_instr *instr = nir_tex_instr_create(this->shader, num_srcs);
@@ -2093,12 +2095,21 @@ nir_visitor::visit(ir_texture *ir)
if (ir->offset != NULL) {
/* we don't support multiple offsets yet */
- assert(ir->offset->type->is_vector() || ir->offset->type->is_scalar());
-
- instr->src[src_number].src =
- nir_src_for_ssa(evaluate_rvalue(ir->offset));
- instr->src[src_number].src_type = nir_tex_src_offset;
- src_number++;
+ if (ir->offset->type->is_vector() || ir->offset->type->is_scalar()) {
+ instr->src[src_number].src =
+ nir_src_for_ssa(evaluate_rvalue(ir->offset));
+ instr->src[src_number].src_type = nir_tex_src_offset;
+ src_number++;
+ } else if (ir->offset->type->is_array()) {
+ for (int i = 0; i < ir->offset->type->array_size(); i++) {
+ instr->src[src_number].src =
+ nir_src_for_ssa(evaluate_rvalue(ir->offset->as_constant()->get_array_element(i)->as_rvalue()));
+ instr->src[src_number].src_type = (nir_tex_src_type)(nir_tex_src_offset + i);
+ src_number++;
+ }
+ } else {
+ assert(false);
+ }
}
switch (ir->op) {
diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
index 2acd9511f5..bc83573b90 100644
--- a/src/compiler/nir/nir.h
+++ b/src/compiler/nir/nir.h
@@ -1162,6 +1162,9 @@ typedef enum {
nir_tex_src_projector,
nir_tex_src_comparator, /* shadow comparator */
nir_tex_src_offset,
+ nir_tex_src_offset1,
+ nir_tex_src_offset2,
+ nir_tex_src_offset3,
nir_tex_src_bias,
nir_tex_src_lod,
nir_tex_src_ms_index, /* MSAA sample index */
@@ -1364,6 +1367,9 @@ nir_tex_instr_src_type(const nir_tex_instr *instr, unsigned src)
return nir_type_float;
case nir_tex_src_offset:
+ case nir_tex_src_offset1:
+ case nir_tex_src_offset2:
+ case nir_tex_src_offset3:
case nir_tex_src_ms_index:
case nir_tex_src_texture_offset:
case nir_tex_src_sampler_offset:
@@ -1395,7 +1401,8 @@ nir_tex_instr_src_size(const nir_tex_instr *instr, unsigned src)
/* Usual APIs don't allow cube + offset, but we allow it, with 2 coords for
* the offset, since a cube maps to a single face.
*/
- if (instr->src[src].src_type == nir_tex_src_offset) {
+ if (instr->src[src].src_type >= nir_tex_src_offset &&
+ instr->src[src].src_type <= nir_tex_src_offset3) {
if (instr->sampler_dim == GLSL_SAMPLER_DIM_CUBE)
return 2;
else if (instr->is_array)
diff --git a/src/compiler/nir/nir_print.c b/src/compiler/nir/nir_print.c
index fcc8025346..e4736e38a7 100644
--- a/src/compiler/nir/nir_print.c
+++ b/src/compiler/nir/nir_print.c
@@ -744,6 +744,15 @@ print_tex_instr(nir_tex_instr *instr, print_state *state)
case nir_tex_src_offset:
fprintf(fp, "(offset)");
break;
+ case nir_tex_src_offset1:
+ fprintf(fp, "(offset1)");
+ break;
+ case nir_tex_src_offset2:
+ fprintf(fp, "(offset2)");
+ break;
+ case nir_tex_src_offset3:
+ fprintf(fp, "(offset3)");
+ break;
case nir_tex_src_bias:
fprintf(fp, "(bias)");
break;
diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
index d877a73054..bc762c2610 100644
--- a/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
+++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_from_nir.cpp
@@ -2697,7 +2697,10 @@ Converter::visit(nir_tex_instr *insn)
int ddyIdx = nir_tex_instr_src_index(insn, nir_tex_src_ddy);
int msIdx = nir_tex_instr_src_index(insn, nir_tex_src_ms_index);
int lodIdx = nir_tex_instr_src_index(insn, nir_tex_src_lod);
- int offsetIdx = nir_tex_instr_src_index(insn, nir_tex_src_offset);
+ int offsetIdx0 = nir_tex_instr_src_index(insn, nir_tex_src_offset);
+ int offsetIdx1 = nir_tex_instr_src_index(insn, nir_tex_src_offset1);
+ int offsetIdx2 = nir_tex_instr_src_index(insn, nir_tex_src_offset2);
+ int offsetIdx3 = nir_tex_instr_src_index(insn, nir_tex_src_offset3);
int projIdx = nir_tex_instr_src_index(insn, nir_tex_src_projector);
int sampOffIdx = nir_tex_instr_src_index(insn, nir_tex_src_sampler_offset);
int texOffIdx = nir_tex_instr_src_index(insn, nir_tex_src_texture_offset);
@@ -2730,8 +2733,14 @@ Converter::visit(nir_tex_instr *insn)
srcs.push_back(getSrc(&insn->src[lodIdx].src, 0));
if (msIdx != -1)
srcs.push_back(getSrc(&insn->src[msIdx].src, 0));
- if (offsetIdx != -1)
- offsets.push_back(&insn->src[offsetIdx].src);
+ if (offsetIdx0 != -1)
+ offsets.push_back(&insn->src[offsetIdx0].src);
+ if (offsetIdx1 != -1)
+ offsets.push_back(&insn->src[offsetIdx1].src);
+ if (offsetIdx2 != -1)
+ offsets.push_back(&insn->src[offsetIdx2].src);
+ if (offsetIdx3 != -1)
+ offsets.push_back(&insn->src[offsetIdx3].src);
if (compIdx != -1)
srcs.push_back(applyProjection(getSrc(&insn->src[compIdx].src, 0), proj));
if (texOffIdx != -1) {
--
2.14.3
More information about the mesa-dev
mailing list