<div dir="ltr">tests also look good for me so:<div>Reviewed-by Rodrigo Vivi <<a href="mailto:rodrigo.vivi@gmail.com">rodrigo.vivi@gmail.com</a>><br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">
On Wed, May 21, 2014 at 5:17 AM,  <span dir="ltr"><<a href="mailto:ville.syrjala@linux.intel.com" target="_blank">ville.syrjala@linux.intel.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="">From: Ville Syrjälä <<a href="mailto:ville.syrjala@linux.intel.com">ville.syrjala@linux.intel.com</a>><br>
<br>
kms_mmio_vs_cs_flip has two subtests:<br>
- setplane_vs_cs_flip tests the interaction between<br>
  fullscreen sprites and CS flips<br>
- setcrtc_vs_cs_flip tests the interaction between<br>
  primary plane panning and CS flips<br>
<br>
</div>v2: Skip sprite test when there are no sprites<br>
    Reduce busy_bo to 64MB (now works on my gen2)<br>
    Handle pipe vs. port incompatibility<br>
<div class=""><br>
Signed-off-by: Ville Syrjälä <<a href="mailto:ville.syrjala@linux.intel.com">ville.syrjala@linux.intel.com</a>><br>
---<br>
 tests/Makefile.sources      |   1 +<br>
</div> tests/kms_mmio_vs_cs_flip.c | 537 ++++++++++++++++++++++++++++++++++++++++++++<br>
 2 files changed, 538 insertions(+)<br>
<div class=""> create mode 100644 tests/kms_mmio_vs_cs_flip.c<br>
<br>
diff --git a/tests/Makefile.sources b/tests/Makefile.sources<br>
</div>index 383a209..1f7931d 100644<br>
--- a/tests/Makefile.sources<br>
+++ b/tests/Makefile.sources<br>
@@ -64,6 +64,7 @@ TESTS_progs_M = \<br>
        kms_fence_pin_leak \<br>
<div class="">        kms_flip \<br>
        kms_flip_tiling \<br>
+       kms_mmio_vs_cs_flip \<br>
        kms_pipe_crc_basic \<br>
        kms_plane \<br>
        kms_render \<br>
diff --git a/tests/kms_mmio_vs_cs_flip.c b/tests/kms_mmio_vs_cs_flip.c<br>
new file mode 100644<br>
</div>index 0000000..a724721<br>
--- /dev/null<br>
+++ b/tests/kms_mmio_vs_cs_flip.c<br>
@@ -0,0 +1,537 @@<br>
<div><div class="h5">+/*<br>
+ * Copyright © 2014 Intel Corporation<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
+ * IN THE SOFTWARE.<br>
+ */<br>
+<br>
+#include <errno.h><br>
+#include <stdbool.h><br>
+#include <stdio.h><br>
+#include <string.h><br>
+#include <time.h><br>
+<br>
+#include "drmtest.h"<br>
+#include "igt_debugfs.h"<br>
+#include "igt_kms.h"<br>
+#include "intel_chipset.h"<br>
+#include "ioctl_wrappers.h"<br>
+<br>
+typedef struct {<br>
+       int drm_fd;<br>
+       igt_display_t display;<br>
+       igt_pipe_crc_t *pipe_crc;<br>
+       drm_intel_bufmgr *bufmgr;<br>
+       drm_intel_bo *busy_bo;<br>
+       uint32_t devid;<br>
+       bool flip_done;<br>
+} data_t;<br>
+<br>
+static void exec_nop(data_t *data, uint32_t handle, unsigned int ring)<br>
+{<br>
+       struct intel_batchbuffer *batch;<br>
+       drm_intel_bo *bo;<br>
+<br>
+       batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);<br>
+       igt_assert(batch);<br>
+<br>
+       bo = gem_handle_to_libdrm_bo(data->bufmgr, data->drm_fd, "", handle);<br>
+       igt_assert(bo);<br>
+<br>
+       /* add relocs to make sure the kernel will think we write to dst */<br>
+       BEGIN_BATCH(4);<br>
+       OUT_BATCH(MI_BATCH_BUFFER_END);<br>
+       OUT_BATCH(MI_NOOP);<br>
+       OUT_RELOC(bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);<br>
+       OUT_BATCH(MI_NOOP);<br>
+       ADVANCE_BATCH();<br>
+<br>
+       intel_batchbuffer_flush_on_ring(batch, ring);<br>
+       intel_batchbuffer_free(batch);<br>
+<br>
</div></div>+       drm_intel_bo_unreference(bo);<br>
<div><div class="h5">+}<br>
+<br>
+static void exec_blt(data_t *data)<br>
+{<br>
+       struct intel_batchbuffer *batch;<br>
+       int w, h, pitch, i;<br>
+<br>
+       batch = intel_batchbuffer_alloc(data->bufmgr, data->devid);<br>
+       igt_assert(batch);<br>
+<br>
+       w = 8192;<br>
+       h = data->busy_bo->size / (8192 * 4);<br>
+       pitch = w * 4;<br>
+<br>
+       for (i = 0; i < 40; i++) {<br>
+               BLIT_COPY_BATCH_START(data->devid, 0);<br>
+               OUT_BATCH((3 << 24) | /* 32 bits */<br>
+                         (0xcc << 16) | /* copy ROP */<br>
+                         pitch);<br>
+               OUT_BATCH(0 << 16 | 0);<br>
+               OUT_BATCH(h << 16 | w);<br>
+               OUT_RELOC(data->busy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0);<br>
+               BLIT_RELOC_UDW(data->devid);<br>
+               OUT_BATCH(0 << 16 | 0);<br>
+               OUT_BATCH(pitch);<br>
+               OUT_RELOC(data->busy_bo, I915_GEM_DOMAIN_RENDER, 0, 0);<br>
+               BLIT_RELOC_UDW(data->devid);<br>
+               ADVANCE_BATCH();<br>
+       }<br>
+<br>
+       intel_batchbuffer_flush(batch);<br>
+       intel_batchbuffer_free(batch);<br>
+}<br>
+<br>
+static void page_flip_handler(int fd, unsigned int frame, unsigned int sec,<br>
+                             unsigned int usec, void *_data)<br>
+{<br>
+       data_t *data = _data;<br>
+<br>
+       data->flip_done = true;<br>
+}<br>
+<br>
+static void wait_for_flip(data_t *data, uint32_t flip_handle)<br>
+{<br>
+       struct timeval timeout = {<br>
+               .tv_sec = 3,<br>
+               .tv_usec = 0,<br>
+       };<br>
+       drmEventContext evctx = {<br>
+               .version = DRM_EVENT_CONTEXT_VERSION,<br>
+               .page_flip_handler = page_flip_handler,<br>
+       };<br>
+       fd_set fds;<br>
+<br>
+       FD_ZERO(&fds);<br>
+       FD_SET(data->drm_fd, &fds);<br>
+<br>
+       while (!data->flip_done) {<br>
+               int ret = select(data->drm_fd + 1, &fds, NULL, NULL, &timeout);<br>
+<br>
+               if (ret < 0 && errno == EINTR)<br>
+                       continue;<br>
+<br>
+               igt_assert(ret >= 0);<br>
+<br>
+               do_or_die(drmHandleEvent(data->drm_fd, &evctx));<br>
+       }<br>
+<br>
+       /*<br>
+        * The flip completion may have been signalled prematurely, so<br>
+        * also submit another nop batch and wait for it to make sure<br>
+        * the ring has really been drained.<br>
+        */<br>
+       if (IS_GEN7(data->devid) || IS_GEN8(data->devid))<br>
+               exec_nop(data, flip_handle, I915_EXEC_BLT);<br>
+       else<br>
+               exec_nop(data, flip_handle, I915_EXEC_RENDER);<br>
+       gem_sync(data->drm_fd, flip_handle);<br>
+}<br>
+<br>
+static void make_gpu_busy(data_t *data, uint32_t flip_handle)<br>
+{<br>
+       /*<br>
+        * Make sure flip_handle has been used on the blt ring.<br>
+        * This should make the flip use the same ring on gen7+.<br>
+        */<br>
+       if (IS_GEN7(data->devid) || IS_GEN8(data->devid))<br>
+               exec_nop(data, flip_handle, I915_EXEC_BLT);<br>
+<br>
+       /*<br>
+        * Add a pile commands to the ring.  The flip will be<br>
+        * stuck behing these commands and hence gets delayed<br>
+        * significantly.<br>
+        */<br>
+       exec_blt(data);<br>
+<br>
+       /*<br>
+        * Make sure the render ring will block until the blt ring is clear.<br>
+        * This is in case the flip will execute on the render ring and the<br>
+        * blits were on the blt ring (this will be the case on gen6 at least).<br>
+        *<br>
+        * We can't add an explicit dependency between flip_handle and the<br>
+        * blits since that would cause the driver to block until the blits<br>
+        * have completed before it will perform a subsequent mmio flip,<br>
+        * and so the test would fail to exercise the mmio vs. CS flip race.<br>
+        */<br>
+       if (HAS_BLT_RING(data->devid))<br>
+               exec_nop(data, data->busy_bo->handle, I915_EXEC_RENDER);<br>
+}<br>
+<br>
+/*<br>
+ * 1. set primary plane to full red<br>
+ * 2. grab a reference crc<br>
+ * 3. set primary plane to full blue<br>
+ * 4. queue lots of GPU activity to delay the subsequent page flip<br>
+ * 5. queue a page flip to the same blue fb<br>
+ * 6. toggle a fullscreen sprite (green) on and back off again<br>
+ * 7. set primary plane to red fb<br>
+ * 8. wait for GPU to finish<br>
+ * 9. compare current crc with reference crc<br>
+ *<br>
+ * We expect the primary plane to display full red at the end.<br>
+ * If the sprite operations have interfered with the page flip,<br>
+ * the driver may have mistakenly completed the flip before<br>
+ * it was executed by the CS, and hence the subsequent mmio<br>
+ * flips may have overtaken it. So once we've finished everything<br>
+ * the CS flip may have been the last thing to occur, which means<br>
+ * the primary plane may be full blue instead of the red it's<br>
+ * supposed to be.<br>
+ */<br>
+static void<br>
+test_plane(data_t *data, igt_output_t *output, enum pipe pipe, enum igt_plane plane)<br>
+{<br>
+       struct igt_fb red_fb, green_fb, blue_fb;<br>
+       drmModeModeInfo *mode;<br>
+       igt_plane_t *primary, *sprite;<br>
+       igt_crc_t ref_crc, crc;<br>
+       int ret;<br>
+<br>
</div></div>+       igt_output_set_pipe(output, pipe);<br>
+       igt_display_commit(&data->display);<br>
+<br>
+       if (!output->valid) {<br>
<div class="">+               igt_output_set_pipe(output, PIPE_ANY);<br>
+               igt_display_commit(&data->display);<br>
</div>+               return;<br>
+       }<br>
<div class="">+<br>
+       primary = igt_output_get_plane(output, 0);<br>
+       sprite = igt_output_get_plane(output, plane);<br>
+<br>
</div><div><div class="h5">+       mode = igt_output_get_mode(output);<br>
+       igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,<br>
+                           DRM_FORMAT_XRGB8888,<br>
+                           false, /* tiled */<br>
+                           1.0, 0.0, 0.0,<br>
+                           &red_fb);<br>
+       igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,<br>
+                           DRM_FORMAT_XRGB8888,<br>
+                           false, /* tiled */<br>
+                           0.0, 1.0, 0.0,<br>
+                           &green_fb);<br>
+       igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay,<br>
+                           DRM_FORMAT_XRGB8888,<br>
+                           false, /* tiled */<br>
+                           0.0, 0.0, 1.0,<br>
+                           &blue_fb);<br>
+<br>
+       /*<br>
+        * Make sure these buffers are suited for display use<br>
+        * because most of the modeset operations must be fast<br>
+        * later on.<br>
+        */<br>
+       igt_plane_set_fb(primary, &blue_fb);<br>
+       igt_display_commit(&data->display);<br>
+       igt_plane_set_fb(sprite, &green_fb);<br>
+       igt_display_commit(&data->display);<br>
+       igt_plane_set_fb(sprite, NULL);<br>
+       igt_display_commit(&data->display);<br>
+<br>
</div></div><div class="">+       if (data->pipe_crc)<br>
+               igt_pipe_crc_free(data->pipe_crc);<br>
+       data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);<br>
+<br>
</div><div><div class="h5">+       /* set red fb and grab reference crc */<br>
+       igt_plane_set_fb(primary, &red_fb);<br>
+       igt_display_commit(&data->display);<br>
+       igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc);<br>
+<br>
+       ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id,<br>
+                            blue_fb.fb_id, 0, 0, &output->id, 1,<br>
+                            mode);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       make_gpu_busy(data, blue_fb.gem_handle);<br>
+<br>
+       data->flip_done = false;<br>
+       ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id,<br>
+                             blue_fb.fb_id, DRM_MODE_PAGE_FLIP_EVENT, data);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       /*<br>
+        * Toggle a fullscreen sprite on and back off. This will result<br>
+        * in the primary plane getting disabled and re-enbled, and that<br>
+        * leads to mmio flips. The driver may then mistake the flip done<br>
+        * interrupts from the mmio flips as the flip done interrupts for<br>
+        * the CS flip, and hence subsequent mmio flips won't wait for the<br>
+        * CS flips like they should.<br>
+        */<br>
+       ret = drmModeSetPlane(data->drm_fd,<br>
+                             sprite->drm_plane->plane_id,<br>
+                             output->config.crtc->crtc_id,<br>
+                             green_fb.fb_id, 0,<br>
+                             0, 0, mode->hdisplay, mode->vdisplay,<br>
+                             0, 0, mode->hdisplay << 16, mode->vdisplay << 16);<br>
+       igt_assert(ret == 0);<br>
+       ret = drmModeSetPlane(data->drm_fd,<br>
+                             sprite->drm_plane->plane_id,<br>
+                             output->config.crtc->crtc_id,<br>
+                             0, 0,<br>
+                             0, 0, 0, 0,<br>
+                             0, 0, 0, 0);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       /*<br>
+        * Set primary plane to red fb. This should wait for the CS flip<br>
+        * to complete. But if the kernel mistook the flip done interrupt<br>
+        * from the mmio flip as the flip done from the CS flip, this will<br>
+        * not wait for anything. And hence the the CS flip will actually<br>
+        * occur after this mmio flip.<br>
+        */<br>
+       ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id,<br>
+                            red_fb.fb_id, 0, 0, &output->id, 1,<br>
+                            mode);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       /* Make sure the flip has been executed */<br>
+       wait_for_flip(data, blue_fb.gem_handle);<br>
+<br>
+       /* Grab crc and compare with the extected result */<br>
+       igt_pipe_crc_collect_crc(data->pipe_crc, &crc);<br>
+<br>
+       igt_plane_set_fb(primary, NULL);<br>
+       igt_display_commit(&data->display);<br>
+<br>
+       igt_remove_fb(data->drm_fd, &red_fb);<br>
+       igt_remove_fb(data->drm_fd, &green_fb);<br>
+       igt_remove_fb(data->drm_fd, &blue_fb);<br>
+<br>
+       igt_pipe_crc_free(data->pipe_crc);<br>
+       data->pipe_crc = NULL;<br>
+<br>
+       igt_output_set_pipe(output, PIPE_ANY);<br>
+       igt_display_commit(&data->display);<br>
+<br>
+       igt_assert(igt_crc_equal(&ref_crc, &crc));<br>
+}<br>
+<br>
+/*<br>
+ * 1. set primary plane to full red<br>
+ * 2. grab a reference crc<br>
+ * 3. set primary plane to full green<br>
+ * 4. wait for vblank<br>
+ * 5. pan primary plane a bit (to cause a mmio flip w/o vblank wait)<br>
+ * 6. queue lots of GPU activity to delay the subsequent page flip<br>
+ * 6. queue a page flip to a blue fb<br>
+ * 7. set primary plane to red fb<br>
+ * 8. wait for GPU to finish<br>
+ * 9. compare current crc with reference crc<br>
+ *<br>
+ * We expect the primary plane to display full red at the end.<br>
+ * If the previously schedule primary plane pan operation has interfered<br>
+ * with the following page flip, the driver may have mistakenly completed<br>
+ * the flip before it was executed by the CS, and hence the subsequent mmio<br>
+ * flips may have overtaken it. So once we've finished everything<br>
+ * the CS flip may have been the last thing to occur, which means<br>
+ * the primary plane may be full blue instead of the red it's<br>
+ * supposed to be.<br>
+ */<br>
+static void<br>
+test_crtc(data_t *data, igt_output_t *output, enum pipe pipe)<br>
+{<br>
+       struct igt_fb red_fb, green_fb, blue_fb;<br>
+       drmModeModeInfo *mode;<br>
+       igt_plane_t *primary;<br>
+       igt_crc_t ref_crc, crc;<br>
+       int ret;<br>
+<br>
</div></div>+       igt_output_set_pipe(output, pipe);<br>
+       igt_display_commit(&data->display);<br>
+<br>
+       if (!output->valid) {<br>
<div class="">+               igt_output_set_pipe(output, PIPE_ANY);<br>
+               igt_display_commit(&data->display);<br>
</div>+               return;<br>
+       }<br>
<div><div class="h5">+<br>
+       primary = igt_output_get_plane(output, 0);<br>
+<br>
+       mode = igt_output_get_mode(output);<br>
+       igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1,<br>
+                           DRM_FORMAT_XRGB8888,<br>
+                           false, /* tiled */<br>
+                           1.0, 0.0, 0.0,<br>
+                           &red_fb);<br>
+       igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1,<br>
+                           DRM_FORMAT_XRGB8888,<br>
+                           false, /* tiled */<br>
+                           0.0, 0.0, 1.0,<br>
+                           &blue_fb);<br>
+       igt_create_color_fb(data->drm_fd, mode->hdisplay, mode->vdisplay+1,<br>
+                           DRM_FORMAT_XRGB8888,<br>
+                           false, /* tiled */<br>
+                           0.0, 1.0, 0.0,<br>
+                           &green_fb);<br>
+<br>
+       /*<br>
+        * Make sure these buffers are suited for display use<br>
+        * because most of the modeset operations must be fast<br>
+        * later on.<br>
+        */<br>
+       igt_plane_set_fb(primary, &green_fb);<br>
+       igt_display_commit(&data->display);<br>
+       igt_plane_set_fb(primary, &blue_fb);<br>
+       igt_display_commit(&data->display);<br>
+<br>
</div></div><div class="">+       if (data->pipe_crc)<br>
+               igt_pipe_crc_free(data->pipe_crc);<br>
+       data->pipe_crc = igt_pipe_crc_new(pipe, INTEL_PIPE_CRC_SOURCE_AUTO);<br>
+<br>
</div><div><div class="h5">+       /* set red fb and grab reference crc */<br>
+       igt_plane_set_fb(primary, &red_fb);<br>
+       igt_display_commit(&data->display);<br>
+       igt_pipe_crc_collect_crc(data->pipe_crc, &ref_crc);<br>
+<br>
+       /*<br>
+        * Further down we need to issue an mmio flip w/o the kernel<br>
+        * waiting for vblank. The easiest way is to just pan within<br>
+        * the same FB. So pan away a bit here, and later we undo this<br>
+        * with another pan which will result in the desired mmio flip.<br>
+        */<br>
+       ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id,<br>
+                            green_fb.fb_id, 0, 1, &output->id, 1,<br>
+                            mode);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       /*<br>
+        * Make it more likely that the CS flip has been submitted into the<br>
+        * ring by the time the mmio flip from the drmModeSetCrtc() below<br>
+        * completes. The driver will then mistake the flip done interrupt<br>
+        * from the mmio flip as the flip done interrupt from the CS flip.<br>
+        */<br>
+       igt_wait_for_vblank(data->drm_fd, pipe);<br>
+<br>
+       /* now issue the mmio flip w/o vblank waits in the kernel, ie. pan a bit */<br>
+       ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id,<br>
+                            green_fb.fb_id, 0, 0, &output->id, 1,<br>
+                            mode);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       make_gpu_busy(data, blue_fb.gem_handle);<br>
+<br>
+       /*<br>
+        * Submit the CS flip. The commands must be emitted into the ring<br>
+        * before the mmio flip from the panning operation completes.<br>
+        */<br>
+       data->flip_done = false;<br>
+       ret = drmModePageFlip(data->drm_fd, output->config.crtc->crtc_id,<br>
+                             blue_fb.fb_id, DRM_MODE_PAGE_FLIP_EVENT, data);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       /*<br>
+        * Set primary plane to red fb. This should wait for the CS flip<br>
+        * to complete. But if the kernel mistook the flip done interrupt<br>
+        * from the mmio flip as the flip done from the CS flip, this will<br>
+        * not wait for anything. And hence the the CS flip will actually<br>
+        * occur after this mmio flip.<br>
+        */<br>
+       ret = drmModeSetCrtc(data->drm_fd, output->config.crtc->crtc_id,<br>
+                            red_fb.fb_id, 0, 0, &output->id, 1,<br>
+                            mode);<br>
+       igt_assert(ret == 0);<br>
+<br>
+       /* Make sure the flip has been executed */<br>
+       wait_for_flip(data, blue_fb.gem_handle);<br>
+<br>
+       /* Grab crc and compare with the extected result */<br>
+       igt_pipe_crc_collect_crc(data->pipe_crc, &crc);<br>
+<br>
+       igt_plane_set_fb(primary, NULL);<br>
+       igt_display_commit(&data->display);<br>
+<br>
+       igt_remove_fb(data->drm_fd, &red_fb);<br>
+       igt_remove_fb(data->drm_fd, &green_fb);<br>
+       igt_remove_fb(data->drm_fd, &blue_fb);<br>
+<br>
+       igt_pipe_crc_free(data->pipe_crc);<br>
+       data->pipe_crc = NULL;<br>
+<br>
+       igt_output_set_pipe(output, PIPE_ANY);<br>
+       igt_display_commit(&data->display);<br>
+<br>
+       igt_assert(igt_crc_equal(&ref_crc, &crc));<br>
+}<br>
+<br>
+static void<br>
+run_plane_test_for_pipe(data_t *data, enum pipe pipe)<br>
+{<br>
+       igt_output_t *output;<br>
+       enum igt_plane plane = 1; /* testing with one sprite is enough */<br>
+<br>
</div></div>+       igt_require(data->display.pipes[pipe].n_planes > 2);<br>
<div><div class="h5">+<br>
+       for_each_connected_output(&data->display, output)<br>
+               test_plane(data, output, pipe, plane);<br>
+}<br>
+<br>
+static void<br>
+run_crtc_test_for_pipe(data_t *data, enum pipe pipe)<br>
+{<br>
+       igt_output_t *output;<br>
+<br>
+       for_each_connected_output(&data->display, output)<br>
+               test_crtc(data, output, pipe);<br>
+}<br>
+<br>
+static data_t data;<br>
+<br>
+igt_main<br>
+{<br>
+       int pipe;<br>
+<br>
+       igt_skip_on_simulation();<br>
+<br>
+       igt_fixture {<br>
+               data.drm_fd = drm_open_any();<br>
+<br>
+               igt_set_vt_graphics_mode();<br>
+<br>
+               data.devid = intel_get_drm_devid(data.drm_fd);<br>
+<br>
+               igt_require_pipe_crc();<br>
+               igt_display_init(&data.display, data.drm_fd);<br>
+<br>
+               data.bufmgr = drm_intel_bufmgr_gem_init(data.drm_fd, 4096);<br>
+               igt_assert(data.bufmgr);<br>
+               drm_intel_bufmgr_gem_enable_reuse(data.bufmgr);<br>
+<br>
+               data.busy_bo = drm_intel_bo_alloc(data.bufmgr, "bo",<br>
</div></div>+                                                 64*1024*1024, 4096);<br>
<div class="">+               gem_set_tiling(data.drm_fd, data.busy_bo->handle, 0, 4096);<br>
+       }<br>
+<br>
+       igt_subtest_f("setplane_vs_cs_flip") {<br>
+               for (pipe = 0; pipe < data.display.n_pipes; pipe++)<br>
+                       run_plane_test_for_pipe(&data, pipe);<br>
+       }<br>
+<br>
+       igt_subtest_f("setcrtc_vs_cs_flip") {<br>
+               for (pipe = 0; pipe < data.display.n_pipes; pipe++)<br>
+                       run_crtc_test_for_pipe(&data, pipe);<br>
+       }<br>
+<br>
+       igt_fixture {<br>
</div>+               drm_intel_bo_unreference(data.busy_bo);<br>
<div class="">+               drm_intel_bufmgr_destroy(data.bufmgr);<br>
+               igt_display_fini(&data.display);<br>
+       }<br>
+}<br>
--<br>
</div>1.8.5.5<br>
<div class="HOEnZb"><div class="h5"><br>
_______________________________________________<br>
Intel-gfx mailing list<br>
<a href="mailto:Intel-gfx@lists.freedesktop.org">Intel-gfx@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/intel-gfx" target="_blank">http://lists.freedesktop.org/mailman/listinfo/intel-gfx</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Rodrigo Vivi</div><div>Blog: <a href="http://blog.vivi.eng.br" target="_blank">http://blog.vivi.eng.br</a></div><div> </div>
</div>