Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright © 2011 Intel Corporation |
| 3 | * |
| 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 5 | * copy of this software and associated documentation files (the "Software"), |
| 6 | * to deal in the Software without restriction, including without limitation |
| 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 8 | * and/or sell copies of the Software, and to permit persons to whom the |
| 9 | * Software is furnished to do so, subject to the following conditions: |
| 10 | * |
| 11 | * The above copyright notice and this permission notice (including the next |
| 12 | * paragraph) shall be included in all copies or substantial portions of the |
| 13 | * Software. |
| 14 | * |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 21 | * IN THE SOFTWARE. |
| 22 | * |
| 23 | * Authors: |
| 24 | * Chris Wilson <chris@chris-wilson.co.uk> |
| 25 | * |
| 26 | */ |
| 27 | |
| 28 | #define _GNU_SOURCE |
| 29 | |
Thomas Wood | 804e11f | 2015-08-17 17:57:43 +0100 | [diff] [blame] | 30 | #include "igt.h" |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 31 | #include <stdlib.h> |
| 32 | #include <sys/ioctl.h> |
| 33 | #include <stdio.h> |
| 34 | #include <string.h> |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 35 | #include <fcntl.h> |
| 36 | #include <inttypes.h> |
Daniel Vetter | 254f19b | 2014-03-22 21:29:01 +0100 | [diff] [blame] | 37 | #include <errno.h> |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 38 | |
Daniel Vetter | 254f19b | 2014-03-22 21:29:01 +0100 | [diff] [blame] | 39 | #include <drm.h> |
| 40 | |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 41 | |
Thomas Wood | b2ac264 | 2014-11-28 11:02:44 +0000 | [diff] [blame] | 42 | IGT_TEST_DESCRIPTION("Test execbuf fence accounting."); |
| 43 | |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 44 | #define WIDTH 1024 |
| 45 | #define HEIGHT 1024 |
| 46 | #define OBJECT_SIZE (4*WIDTH*HEIGHT) |
| 47 | |
| 48 | #define BATCH_SIZE 4096 |
| 49 | |
Ville Syrjälä | e37eb35 | 2013-04-09 15:25:37 +0300 | [diff] [blame] | 50 | #define MAX_FENCES 32 |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 51 | |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 52 | /* |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 53 | * Testcase: execbuf fence accounting |
| 54 | * |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 55 | * We had a bug where we were falsely accounting upon reservation already |
| 56 | * fenced buffers as occupying a fence register even if they did not require |
| 57 | * one for the batch. |
| 58 | * |
| 59 | * We aim to exercise this by performing a sequence of fenced BLT |
| 60 | * with 2*num_avail_fence buffers, but alternating which half are fenced in |
| 61 | * each command. |
| 62 | */ |
| 63 | |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 64 | static drm_intel_bufmgr *bufmgr; |
| 65 | struct intel_batchbuffer *batch; |
| 66 | uint32_t devid; |
| 67 | |
| 68 | static void emit_dummy_load(void) |
| 69 | { |
| 70 | int i; |
| 71 | uint32_t tile_flags = 0; |
| 72 | uint32_t tiling_mode = I915_TILING_X; |
| 73 | unsigned long pitch; |
| 74 | drm_intel_bo *dummy_bo; |
| 75 | |
| 76 | dummy_bo = drm_intel_bo_alloc_tiled(bufmgr, "tiled dummy_bo", 2048, 2048, |
| 77 | 4, &tiling_mode, &pitch, 0); |
| 78 | |
| 79 | if (IS_965(devid)) { |
| 80 | pitch /= 4; |
| 81 | tile_flags = XY_SRC_COPY_BLT_SRC_TILED | |
| 82 | XY_SRC_COPY_BLT_DST_TILED; |
| 83 | } |
| 84 | |
| 85 | for (i = 0; i < 5; i++) { |
Chris Wilson | 10552b5 | 2014-08-30 11:44:51 +0100 | [diff] [blame] | 86 | BLIT_COPY_BATCH_START(tile_flags); |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 87 | OUT_BATCH((3 << 24) | /* 32 bits */ |
| 88 | (0xcc << 16) | /* copy ROP */ |
| 89 | pitch); |
| 90 | OUT_BATCH(0 << 16 | 1024); |
| 91 | OUT_BATCH((2048) << 16 | (2048)); |
| 92 | OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, 0); |
| 93 | OUT_BATCH(0 << 16 | 0); |
| 94 | OUT_BATCH(pitch); |
| 95 | OUT_RELOC_FENCED(dummy_bo, I915_GEM_DOMAIN_RENDER, 0, 0); |
| 96 | ADVANCE_BATCH(); |
| 97 | |
Chris Wilson | 10552b5 | 2014-08-30 11:44:51 +0100 | [diff] [blame] | 98 | if (batch->gen >= 6) { |
| 99 | BEGIN_BATCH(3, 0); |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 100 | OUT_BATCH(XY_SETUP_CLIP_BLT_CMD); |
| 101 | OUT_BATCH(0); |
| 102 | OUT_BATCH(0); |
| 103 | ADVANCE_BATCH(); |
| 104 | } |
| 105 | } |
| 106 | intel_batchbuffer_flush(batch); |
| 107 | |
| 108 | drm_intel_bo_unreference(dummy_bo); |
| 109 | } |
| 110 | |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 111 | static uint32_t |
| 112 | tiled_bo_create (int fd) |
| 113 | { |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 114 | uint32_t handle; |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 115 | |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 116 | handle = gem_create(fd, OBJECT_SIZE); |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 117 | |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 118 | gem_set_tiling(fd, handle, I915_TILING_X, WIDTH*4); |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 119 | |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 120 | return handle; |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | static uint32_t |
| 124 | batch_create (int fd) |
| 125 | { |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 126 | uint32_t buf[] = { MI_BATCH_BUFFER_END, 0 }; |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 127 | uint32_t batch_handle; |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 128 | |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 129 | batch_handle = gem_create(fd, BATCH_SIZE); |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 130 | |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 131 | gem_write(fd, batch_handle, 0, buf, sizeof(buf)); |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 132 | |
root | e287fe1 | 2012-01-10 22:34:52 +0100 | [diff] [blame] | 133 | return batch_handle; |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 134 | } |
| 135 | |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 136 | static void fill_reloc(struct drm_i915_gem_relocation_entry *reloc, uint32_t handle) |
| 137 | { |
| 138 | reloc->offset = 2 * sizeof(uint32_t); |
| 139 | reloc->target_handle = handle; |
| 140 | reloc->read_domains = I915_GEM_DOMAIN_RENDER; |
| 141 | reloc->write_domain = 0; |
| 142 | } |
| 143 | |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 144 | #define BUSY_LOAD (1 << 0) |
| 145 | #define INTERRUPTIBLE (1 << 1) |
| 146 | |
| 147 | static void run_test(int fd, int num_fences, int expected_errno, |
| 148 | unsigned flags) |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 149 | { |
| 150 | struct drm_i915_gem_execbuffer2 execbuf[2]; |
Ville Syrjälä | 2fe3f76 | 2013-04-11 20:43:40 +0300 | [diff] [blame] | 151 | struct drm_i915_gem_exec_object2 exec[2][2*MAX_FENCES+3]; |
| 152 | struct drm_i915_gem_relocation_entry reloc[2*MAX_FENCES+2]; |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 153 | |
Ville Syrjälä | 2fe3f76 | 2013-04-11 20:43:40 +0300 | [diff] [blame] | 154 | int i, n; |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 155 | int loop = 1000; |
| 156 | |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 157 | if (flags & BUSY_LOAD) { |
| 158 | bufmgr = drm_intel_bufmgr_gem_init(fd, 4096); |
| 159 | batch = intel_batchbuffer_alloc(bufmgr, devid); |
| 160 | |
| 161 | /* Takes forever otherwise. */ |
| 162 | loop = 50; |
| 163 | } |
| 164 | |
| 165 | if (flags & INTERRUPTIBLE) |
| 166 | igt_fork_signal_helper(); |
| 167 | |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 168 | memset(execbuf, 0, sizeof(execbuf)); |
| 169 | memset(exec, 0, sizeof(exec)); |
| 170 | memset(reloc, 0, sizeof(reloc)); |
| 171 | |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 172 | for (n = 0; n < 2*num_fences; n++) { |
| 173 | uint32_t handle = tiled_bo_create(fd); |
| 174 | exec[1][2*num_fences - n-1].handle = exec[0][n].handle = handle; |
| 175 | fill_reloc(&reloc[n], handle); |
| 176 | } |
| 177 | |
| 178 | for (i = 0; i < 2; i++) { |
| 179 | for (n = 0; n < num_fences; n++) |
| 180 | exec[i][n].flags = EXEC_OBJECT_NEEDS_FENCE; |
| 181 | |
| 182 | exec[i][2*num_fences].handle = batch_create(fd); |
| 183 | exec[i][2*num_fences].relocs_ptr = (uintptr_t)reloc; |
| 184 | exec[i][2*num_fences].relocation_count = 2*num_fences; |
| 185 | |
| 186 | execbuf[i].buffers_ptr = (uintptr_t)exec[i]; |
| 187 | execbuf[i].buffer_count = 2*num_fences+1; |
| 188 | execbuf[i].batch_len = 2*sizeof(uint32_t); |
| 189 | } |
| 190 | |
| 191 | do { |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 192 | if (flags & BUSY_LOAD) |
| 193 | emit_dummy_load(); |
| 194 | |
Chris Wilson | e3b68bb | 2016-01-23 09:44:19 +0000 | [diff] [blame] | 195 | igt_assert_eq(__gem_execbuf(fd, &execbuf[0]), -expected_errno); |
| 196 | igt_assert_eq(__gem_execbuf(fd, &execbuf[1]), -expected_errno); |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 197 | } while (--loop); |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 198 | |
| 199 | if (flags & INTERRUPTIBLE) |
| 200 | igt_stop_signal_helper(); |
Derek Morton | c69b135 | 2015-06-26 11:36:00 +0100 | [diff] [blame] | 201 | |
| 202 | /* Cleanup */ |
| 203 | for (n = 0; n < 2*num_fences; n++) |
| 204 | gem_close(fd, exec[0][n].handle); |
| 205 | |
| 206 | for (i = 0; i < 2; i++) |
| 207 | gem_close(fd, exec[i][2*num_fences].handle); |
| 208 | |
| 209 | if (flags & BUSY_LOAD) { |
| 210 | intel_batchbuffer_free(batch); |
| 211 | drm_intel_bufmgr_destroy(bufmgr); |
| 212 | } |
Ville Syrjälä | 2fe3f76 | 2013-04-11 20:43:40 +0300 | [diff] [blame] | 213 | } |
| 214 | |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 215 | int fd; |
| 216 | int num_fences; |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 217 | |
Daniel Vetter | 071e9ca | 2013-10-31 16:23:26 +0100 | [diff] [blame] | 218 | igt_main |
Ville Syrjälä | 2fe3f76 | 2013-04-11 20:43:40 +0300 | [diff] [blame] | 219 | { |
Daniel Vetter | 1caaf0a | 2013-08-12 12:17:35 +0200 | [diff] [blame] | 220 | igt_skip_on_simulation(); |
Damien Lespiau | 5fa15f7 | 2013-04-29 18:40:39 +0100 | [diff] [blame] | 221 | |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 222 | igt_fixture { |
Micah Fedke | c81d293 | 2015-07-22 21:54:02 +0000 | [diff] [blame] | 223 | fd = drm_open_driver(DRIVER_INTEL); |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 224 | num_fences = gem_available_fences(fd); |
| 225 | igt_assert(num_fences > 4); |
| 226 | devid = intel_get_drm_devid(fd); |
Ville Syrjälä | 2fe3f76 | 2013-04-11 20:43:40 +0300 | [diff] [blame] | 227 | |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 228 | igt_assert(num_fences <= MAX_FENCES); |
| 229 | } |
Ville Syrjälä | 2fe3f76 | 2013-04-11 20:43:40 +0300 | [diff] [blame] | 230 | |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 231 | igt_subtest("2-spare-fences") |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 232 | run_test(fd, num_fences - 2, 0, 0); |
| 233 | for (unsigned flags = 0; flags < 4; flags++) { |
| 234 | igt_subtest_f("no-spare-fences%s%s", |
| 235 | flags & BUSY_LOAD ? "-busy" : "", |
| 236 | flags & INTERRUPTIBLE ? "-interruptible" : "") |
| 237 | run_test(fd, num_fences, 0, flags); |
| 238 | } |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 239 | igt_subtest("too-many-fences") |
Daniel Vetter | 31139f6 | 2013-09-12 16:18:10 +0200 | [diff] [blame] | 240 | run_test(fd, num_fences + 1, intel_gen(devid) >= 4 ? 0 : EDEADLK, 0); |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 241 | |
Daniel Vetter | 7b36343 | 2013-09-12 14:38:13 +0200 | [diff] [blame] | 242 | igt_fixture |
| 243 | close(fd); |
Chris Wilson | 3ca054c | 2011-06-04 21:41:11 +0100 | [diff] [blame] | 244 | } |