nvc0/ir: fix indirect access for images
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Sun, 22 May 2016 20:39:31 +0000 (22:39 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Sun, 22 May 2016 21:06:16 +0000 (23:06 +0200)
When the array doesn't start at 0 we need to account for su->tex.r.
While we are at it, make sure to avoid out of bounds access by masking
the index.

This fixes GL45-CTS.shading_language_420pack.binding_image_array.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reported-by: Dave Airlie <airlied@redhat.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp

index 9b4bf8230fa23bcfc71653f9f5bc8157cfd4382b..869040ca562e322ec416b578ede09d2b87e89b68 100644 (file)
@@ -1677,10 +1677,13 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
    adjustCoordinatesMS(su);
 
    if (su->tex.rIndirectSrc >= 0) {
-      // FIXME: out of bounds
-      assert(su->tex.r == 0);
-      ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
-                       su->getIndirectR(), bld.mkImm(6));
+      ind = su->getIndirectR();
+      if (su->tex.r > 0) {
+         ind = bld.mkOp2v(OP_ADD, TYPE_U32, bld.getSSA(), ind,
+                          bld.loadImm(NULL, su->tex.r));
+      }
+      ind = bld.mkOp2v(OP_AND, TYPE_U32, bld.getSSA(), ind, bld.mkImm(7));
+      ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(), ind, bld.mkImm(6));
    }
 
    // calculate clamped coordinates
@@ -2026,10 +2029,13 @@ NVC0LoweringPass::processSurfaceCoordsNVC0(TexInstruction *su)
    Value *ind = NULL;
 
    if (su->tex.rIndirectSrc >= 0) {
-      // FIXME: out of bounds
-      assert(su->tex.r == 0);
-      ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(),
-                       su->getIndirectR(), bld.mkImm(6));
+      ind = su->getIndirectR();
+      if (su->tex.r > 0) {
+         ind = bld.mkOp2v(OP_ADD, TYPE_U32, bld.getSSA(), ind,
+                          bld.loadImm(NULL, su->tex.r));
+      }
+      ind = bld.mkOp2v(OP_AND, TYPE_U32, bld.getSSA(), ind, bld.mkImm(7));
+      ind = bld.mkOp2v(OP_SHL, TYPE_U32, bld.getSSA(), ind, bld.mkImm(6));
    }
 
    // get surface coordinates