v3d: Add support for non-constant texture offsets.
authorEric Anholt <eric@anholt.net>
Thu, 27 Dec 2018 07:35:22 +0000 (23:35 -0800)
committerEric Anholt <eric@anholt.net>
Sun, 30 Dec 2018 16:05:11 +0000 (08:05 -0800)
Fixes
dEQP-GLES31.functional.texture.gather.offset_dynamic.min_required_offset.2d.rgba8.size_pot.clamp_to_edge_repeat
and others.

src/broadcom/compiler/v3d40_tex.c

index c12d14c6fe6aedf33fa9dd4034c8503fb8b94bfb..c41cd33505a68e5d9be6efd13ee148d9e8912048 100644 (file)
@@ -132,14 +132,30 @@ v3d40_vir_emit_tex(struct v3d_compile *c, nir_tex_instr *instr)
                         break;
 
                 case nir_tex_src_offset: {
-                        nir_const_value *offset =
-                                nir_src_as_const_value(instr->src[i].src);
-
-                        p2_unpacked.offset_s = offset->i32[0];
-                        if (instr->coord_components >= 2)
-                                p2_unpacked.offset_t = offset->i32[1];
-                        if (instr->coord_components >= 3)
-                                p2_unpacked.offset_r = offset->i32[2];
+                        if (nir_src_is_const(instr->src[i].src)) {
+                                nir_const_value *offset =
+                                        nir_src_as_const_value(instr->src[i].src);
+
+                                p2_unpacked.offset_s = offset->i32[0];
+                                if (instr->coord_components >= 2)
+                                        p2_unpacked.offset_t = offset->i32[1];
+                                if (instr->coord_components >= 3)
+                                        p2_unpacked.offset_r = offset->i32[2];
+                        } else {
+                                struct qreg mask = vir_uniform_ui(c, 0xf);
+                                struct qreg x, y, offset;
+
+                                x = vir_AND(c, ntq_get_src(c, instr->src[i].src,
+                                                           0), mask);
+                                y = vir_AND(c, ntq_get_src(c, instr->src[i].src,
+                                                           1), mask);
+                                offset = vir_OR(c, x,
+                                                vir_SHL(c, y,
+                                                        vir_uniform_ui(c, 4)));
+
+                                vir_TMU_WRITE(c, V3D_QPU_WADDR_TMUOFF,
+                                              offset, &tmu_writes);
+                        }
                         break;
                 }