[Mesa-dev] [PATCH 2/4] st/glsl_to_tgsi: fix textureGatherOffset with indirectly loaded offsets

Nicolai Hähnle nhaehnle at gmail.com
Wed Oct 12 17:50:28 UTC 2016


From: Nicolai Hähnle <nicolai.haehnle at amd.com>

Cc: mesa-stable at lists.freedesktop.org
---
 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 33c1f87..be0aa2e 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -553,20 +553,21 @@ public:
                           unsigned *base,
                           unsigned *index,
                           st_src_reg *reladdr);
   void calc_deref_offsets(ir_dereference *head,
                           ir_dereference *tail,
                           unsigned *array_elements,
                           unsigned *base,
                           unsigned *index,
                           st_src_reg *indirect,
                           unsigned *location);
+   st_src_reg canonicalize_gather_offset(st_src_reg offset);
 
    bool try_emit_mad(ir_expression *ir,
               int mul_operand);
    bool try_emit_mad_for_and_not(ir_expression *ir,
               int mul_operand);
 
    void emit_swz(ir_expression *ir);
 
    bool process_move_condition(ir_rvalue *ir);
 
@@ -3963,20 +3964,34 @@ glsl_to_tgsi_visitor::get_deref_offsets(ir_dereference *ir,
       *base = *index;
       *array_size = 1;
    }
 
    if (location != 0xffffffff) {
       *base += this->shader_program->UniformStorage[location].opaque[shader].index;
       *index += this->shader_program->UniformStorage[location].opaque[shader].index;
    }
 }
 
+st_src_reg
+glsl_to_tgsi_visitor::canonicalize_gather_offset(st_src_reg offset)
+{
+   if (offset.reladdr || offset.reladdr2) {
+      st_src_reg tmp = get_temp(glsl_type::ivec2_type);
+      st_dst_reg tmp_dst = st_dst_reg(tmp);
+      tmp_dst.writemask = WRITEMASK_XY;
+      emit_asm(NULL, TGSI_OPCODE_MOV, tmp_dst, offset);
+      return tmp;
+   }
+
+   return offset;
+}
+
 void
 glsl_to_tgsi_visitor::visit(ir_texture *ir)
 {
    st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy;
    st_src_reg offset[MAX_GLSL_TEXTURE_OFFSET], sample_index, component;
    st_src_reg levels_src, reladdr;
    st_dst_reg result_dst, coord_dst, cube_sc_dst;
    glsl_to_tgsi_instruction *inst = NULL;
    unsigned opcode = TGSI_OPCODE_NOP;
    const glsl_type *sampler_type = ir->sampler->type;
@@ -4088,23 +4103,24 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
       component = this->result;
       if (ir->offset) {
          ir->offset->accept(this);
          if (ir->offset->type->base_type == GLSL_TYPE_ARRAY) {
             const glsl_type *elt_type = ir->offset->type->fields.array;
             for (i = 0; i < ir->offset->type->length; i++) {
                offset[i] = this->result;
                offset[i].index += i * type_size(elt_type);
                offset[i].type = elt_type->base_type;
                offset[i].swizzle = swizzle_for_size(elt_type->vector_elements);
+               offset[i] = canonicalize_gather_offset(offset[i]);
             }
          } else {
-            offset[0] = this->result;
+            offset[0] = canonicalize_gather_offset(this->result);
          }
       }
       break;
    case ir_lod:
       opcode = TGSI_OPCODE_LODQ;
       break;
    case ir_texture_samples:
       opcode = TGSI_OPCODE_TXQS;
       break;
    case ir_samples_identical:
-- 
2.7.4



More information about the mesa-dev mailing list