<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>