nvc0/ir: check that the image format doesn't mismatch
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Mon, 25 Apr 2016 21:13:00 +0000 (23:13 +0200)
committerSamuel Pitoiset <samuel.pitoiset@gmail.com>
Tue, 26 Apr 2016 17:47:49 +0000 (19:47 +0200)
This re-uses NVE4_SU_INFO_CALL which is not used anymore because we
don't use our lib for format conversions. While we are at it, add a
todo for image buffers because there are some robustness-related
issues to fix.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp
src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
src/gallium/drivers/nouveau/nvc0/nvc0_tex.c

index ce678983841ef66e5d634526111e38f0615a1e2d..1376a1a0f09c78d0844beae5dabd434c02694b91 100644 (file)
@@ -2545,6 +2545,7 @@ Converter::handleSTORE()
          mkTex(OP_SUSTP, getImageTarget(code, r), code->images[r].slot,
                0, dummy, src);
       st->tex.mask = tgsi.getDst(0).getMask();
+      st->tex.format = getImageFormat(code, r);
       st->cache = tgsi.getCacheMode();
       if (tgsi.getDst(0).isIndirect(0))
          st->setIndirectR(fetchSrc(tgsi.getDst(0).getIndirect(0), 0, NULL));
@@ -2662,6 +2663,7 @@ Converter::handleATOM(Value *dst0[4], DataType ty, uint16_t subOp)
                                   code->images[r].slot, 0, defv, srcv);
       tex->subOp = subOp;
       tex->tex.mask = 1;
+      tex->tex.format = getImageFormat(code, r);
       tex->setType(ty);
       if (tgsi.getSrc(0).isIndirect(0))
          tex->setIndirectR(fetchSrc(tgsi.getSrc(0).getIndirect(0), 0, NULL));
index 5326561ea04babdfa03a75802f75b43f7274b50a..3bce9624ab6d98d7e6875f460fcfcc32d5a96b6e 100644 (file)
@@ -1476,7 +1476,7 @@ NVC0LoweringPass::loadMsInfo32(Value *ptr, uint32_t off)
 #define NVE4_SU_INFO_HEIGHT 0x24
 #define NVE4_SU_INFO_DEPTH  0x28
 #define NVE4_SU_INFO_TARGET 0x2c
-#define NVE4_SU_INFO_CALL   0x30
+#define NVE4_SU_INFO_BSIZE  0x30
 #define NVE4_SU_INFO_RAW_X  0x34
 #define NVE4_SU_INFO_MS_X   0x38
 #define NVE4_SU_INFO_MS_Y   0x3c
@@ -1792,7 +1792,26 @@ NVC0LoweringPass::processSurfaceCoordsNVE4(TexInstruction *su)
       bld.mkCmp(OP_SET, CC_EQ, TYPE_U32, bld.getSSA(1, FILE_PREDICATE),
                 TYPE_U32, bld.mkImm(0),
                 loadSuInfo32(ind, base + NVE4_SU_INFO_ADDR));
+
+   if (su->tex.format) {
+      const TexInstruction::ImgFormatDesc *format = su->tex.format;
+      int blockwidth = format->bits[0] + format->bits[1] +
+                       format->bits[2] + format->bits[3];
+
+      if (blockwidth >= 8) {
+         // make sure that the format doesn't mismatch
+         bld.mkCmp(OP_SET_OR, CC_NE, TYPE_U32, pred1->getDef(0),
+                   TYPE_U32, bld.loadImm(NULL, blockwidth / 8),
+                   loadSuInfo32(ind, base + NVE4_SU_INFO_BSIZE),
+                   pred1->getDef(0));
+      }
+   }
    su->setPredicate(CC_NOT_P, pred1->getDef(0));
+
+   // TODO: initialize def values to 0 when the surface operation is not
+   // performed (not needed for stores). Also, fix the "address bounds test"
+   // subtests from arb_shader_image_load_store-invalid for buffers, because it
+   // seems like that the predicate is not correctly set by suclamp.
 }
 
 static DataType
index 08c920810efffdb7084fb458c25e1fca603b0066..f5bf2cab656529ab6390604292f3ad606c8884c5 100644 (file)
@@ -836,7 +836,9 @@ nve4_set_surface_info(struct nouveau_pushbuf *push,
    }
    log2cpp = (0xf000 & nve4_su_format_aux_map[view->format]) >> 12;
 
-   info[12] = nve4_suldp_lib_offset[view->format] + screen->lib_code->start;
+   /* Stick the blockwidth (ie. number of bytes per pixel) to check if the
+    * format doesn't mismatch. */
+   info[12] = util_format_get_blocksize(view->format);
 
    /* limit in bytes for raw access */
    info[13] = (0x06 << 22) | ((width << log2cpp) - 1);