tests/gem_dummy_reloc_loop: Add one subtest based on multi drm_fd to test CPU<->GPU...
authorZhao Yakui <yakui.zhao@intel.com>
Thu, 24 Apr 2014 02:15:45 +0000 (10:15 +0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Thu, 24 Apr 2014 09:32:07 +0000 (11:32 +0200)
The Broadwell GT3 machine has two independent BSD rings in kernel driver while
it is transparent to the user-space driver. In such case it needs to check
the CPU<->GPU sync for the second BSD ring.

V1->V2: Follow Daniel's comment to add one subtext instead of one individual
test case, which is used to test the CPU<->GPU sync under multi BSD rings.

V2->V3: Follow Imre's comment to remove the unnecessary initialization and
use igt_assert_f instead of igt_assert

Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
tests/gem_dummy_reloc_loop.c

index a61b59b..4e4dd49 100644 (file)
@@ -48,6 +48,13 @@ static drm_intel_bufmgr *bufmgr;
 struct intel_batchbuffer *batch;
 static drm_intel_bo *target_buffer;
 
+#define NUM_FD 50
+
+static int mfd[NUM_FD];
+static drm_intel_bufmgr *mbufmgr[NUM_FD];
+static struct intel_batchbuffer *mbatch[NUM_FD];
+static drm_intel_bo *mbuffer[NUM_FD];
+
 /*
  * Testcase: Basic check of ring<->cpu sync using a dummy reloc
  *
@@ -124,6 +131,50 @@ dummy_reloc_loop_random_ring(int num_rings)
        }
 }
 
+static void
+dummy_reloc_loop_random_ring_multi_fd(int num_rings)
+{
+       int i;
+       struct intel_batchbuffer *saved_batch;
+
+       saved_batch = batch;
+
+       srandom(0xdeadbeef);
+
+       for (i = 0; i < 0x100000; i++) {
+               int mindex;
+               int ring = random() % num_rings + 1;
+
+               mindex = random() % NUM_FD;
+               batch = mbatch[mindex];
+
+               if (ring == I915_EXEC_RENDER) {
+                       BEGIN_BATCH(4);
+                       OUT_BATCH(MI_COND_BATCH_BUFFER_END | MI_DO_COMPARE);
+                       OUT_BATCH(0xffffffff); /* compare dword */
+                       OUT_RELOC(mbuffer[mindex], I915_GEM_DOMAIN_RENDER,
+                                       I915_GEM_DOMAIN_RENDER, 0);
+                       OUT_BATCH(MI_NOOP);
+                       ADVANCE_BATCH();
+               } else {
+                       BEGIN_BATCH(4);
+                       OUT_BATCH(MI_FLUSH_DW | 1);
+                       OUT_BATCH(0); /* reserved */
+                       OUT_RELOC(mbuffer[mindex], I915_GEM_DOMAIN_RENDER,
+                                       I915_GEM_DOMAIN_RENDER, 0);
+                       OUT_BATCH(MI_NOOP | (1<<22) | (0xf));
+                       ADVANCE_BATCH();
+               }
+               intel_batchbuffer_flush_on_ring(batch, ring);
+
+               drm_intel_bo_map(target_buffer, 0);
+               // map to force waiting on rendering
+               drm_intel_bo_unmap(target_buffer);
+       }
+
+       batch = saved_batch;
+}
+
 int fd;
 int devid;
 int num_rings;
@@ -133,6 +184,7 @@ igt_main
        igt_skip_on_simulation();
 
        igt_fixture {
+               int i;
                fd = drm_open_any();
                devid = intel_get_drm_devid(fd);
                num_rings = gem_get_num_rings(fd);
@@ -148,6 +200,40 @@ igt_main
 
                target_buffer = drm_intel_bo_alloc(bufmgr, "target bo", 4096, 4096);
                igt_assert(target_buffer);
+
+               /* Create multi drm_fd and map one gem object to multi gem_contexts */
+               {
+                       unsigned int target_flink;
+                       char buffer_name[32];
+                       if (dri_bo_flink(target_buffer, &target_flink)) {
+                               printf("fail to get flink for target buffer\n");
+                               igt_assert_f(0, "fail to create global "
+                                            "gem_handle for target buffer\n");
+                       }
+                       for (i = 0; i < NUM_FD; i++) {
+                               sprintf(buffer_name, "Target buffer %d\n", i);
+                               mfd[i] = drm_open_any();
+                               mbufmgr[i] = drm_intel_bufmgr_gem_init(mfd[i], 4096);
+                               igt_assert_f(mbufmgr[i],
+                                            "fail to initialize buf manager "
+                                            "for drm_fd %d\n",
+                                            mfd[i]);
+                               drm_intel_bufmgr_gem_enable_reuse(mbufmgr[i]);
+                               mbatch[i] = intel_batchbuffer_alloc(mbufmgr[i], devid);
+                               igt_assert_f(mbatch[i],
+                                            "fail to create batchbuffer "
+                                            "for drm_fd %d\n",
+                                            mfd[i]);
+                               mbuffer[i] = intel_bo_gem_create_from_name(
+                                                               mbufmgr[i],
+                                                               buffer_name,
+                                                               target_flink);
+                               igt_assert_f(mbuffer[i],
+                                            "fail to create gem bo from global "
+                                            "gem_handle %d for drm_fd %d\n",
+                                            target_flink, mfd[i]);
+                       }
+               }
        }
 
        igt_subtest("render") {
@@ -190,8 +276,27 @@ igt_main
                        printf("dummy loop run on random rings completed\n");
                }
        }
-
+       igt_subtest("mixed_multi_fd") {
+               if (num_rings > 1) {
+                       sleep(2);
+                       printf("running dummy loop on random rings based on "
+                                       "multi drm_fd\n");
+                       dummy_reloc_loop_random_ring_multi_fd(num_rings);
+                       printf("dummy loop run on random rings based on "
+                                       "multi drm_fd completed\n");
+               }
+       }
        igt_fixture {
+               int i;
+               /* Free the buffer/batchbuffer/buffer mgr for multi-fd */
+               {
+                       for (i = 0; i < NUM_FD; i++) {
+                               dri_bo_unreference(mbuffer[i]);
+                               intel_batchbuffer_free(mbatch[i]);
+                               drm_intel_bufmgr_destroy(mbufmgr[i]);
+                               close(mfd[i]);
+                       }
+               }
                drm_intel_bo_unreference(target_buffer);
                intel_batchbuffer_free(batch);
                drm_intel_bufmgr_destroy(bufmgr);