gem_ringfill: Make this actually test that all the batches executed.
authorEric Anholt <eric@anholt.net>
Mon, 20 Feb 2012 18:04:02 +0000 (10:04 -0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 22 Feb 2012 09:45:53 +0000 (10:45 +0100)
I was looking into some strange behavior in Mesa that looks like
batches maybe being skipped, but this test didn't catch it.

tests/gem_ringfill.c

index 5050e57..685a010 100644 (file)
@@ -31,6 +31,7 @@
  * catching failure to manage the ring properly near full.
  */
 
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 static drm_intel_bufmgr *bufmgr;
 struct intel_batchbuffer *batch;
 static const int width = 512, height = 512;
-static const int size = 1024 * 1024;
 
 int main(int argc, char **argv)
 {
        int fd;
        int i;
        drm_intel_bo *src_bo, *dst_bo;
+       uint32_t *map;
+       int fails = 0;
+       int pitch = width * 4;
+       int size = pitch * height;
+       int blits;
 
        fd = drm_open_any();
 
@@ -67,6 +72,20 @@ int main(int argc, char **argv)
        src_bo = drm_intel_bo_alloc(bufmgr, "src bo", size, 4096);
        dst_bo = drm_intel_bo_alloc(bufmgr, "src bo", size, 4096);
 
+       /* Fill the src with indexes of the pixels */
+       drm_intel_bo_map(src_bo, true);
+       map = src_bo->virtual;
+       for (i = 0; i < width * height; i++)
+               map[i] = i;
+       drm_intel_bo_unmap(src_bo);
+
+       /* Fill the dst with garbage. */
+       drm_intel_bo_map(dst_bo, true);
+       map = dst_bo->virtual;
+       for (i = 0; i < width * height; i++)
+               map[i] = 0xd0d0d0d0;
+       drm_intel_bo_unmap(dst_bo);
+
        /* The ring we've been using is 128k, and each rendering op
         * will use at least 8 dwords:
         *
@@ -82,15 +101,53 @@ int main(int argc, char **argv)
         * So iterate just a little more than that -- if we don't fill the ring
         * doing this, we aren't likely to with this test.
         */
-       for (i = 0; i < 128 * 1024 / (8 * 4) * 1.25; i++) {
-               intel_copy_bo(batch, dst_bo, src_bo, width, height);
+       blits = width * height;
+       for (i = 0; i < blits; i++) {
+               int x = i % width;
+               int y = i / width;
+
+               assert(y < height);
+
+               BEGIN_BATCH(8);
+               OUT_BATCH(XY_SRC_COPY_BLT_CMD |
+                         XY_SRC_COPY_BLT_WRITE_ALPHA |
+                         XY_SRC_COPY_BLT_WRITE_RGB);
+               OUT_BATCH((3 << 24) | /* 32 bits */
+                         (0xcc << 16) | /* copy ROP */
+                         pitch);
+               OUT_BATCH((y << 16) | x); /* dst x1,y1 */
+               OUT_BATCH(((y + 1) << 16) | (x + 1)); /* dst x2,y2 */
+               OUT_RELOC(dst_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);
+               OUT_BATCH((y << 16) | x); /* src x1,y1 */
+               OUT_BATCH(pitch);
+               OUT_RELOC(src_bo, I915_GEM_DOMAIN_RENDER, 0, 0);
+               ADVANCE_BATCH();
+
                intel_batchbuffer_flush(batch);
        }
 
+       /* verify */
+       drm_intel_bo_map(dst_bo, false);
+       map = dst_bo->virtual;
+       for (i = 0; i < blits; i++) {
+               int x = i % width;
+               int y = i / width;
+
+               if (map[i] != i) {
+
+                       printf("Copy #%d at %d,%d failed: read 0x%08x\n",
+                              i, x, y, map[i]);
+
+                       if (fails++ > 9)
+                               exit(1);
+               }
+       }
+       drm_intel_bo_unmap(dst_bo);
+
        intel_batchbuffer_free(batch);
        drm_intel_bufmgr_destroy(bufmgr);
 
        close(fd);
 
-       return 0;
+       return fails != 0;
 }