Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 1 | /* |
| 2 | * Copyright © 2012 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 | /* Exercises the basic execbuffer using the handle LUT interface */ |
| 29 | |
| 30 | #include <stdlib.h> |
| 31 | #include <stdio.h> |
| 32 | #include <string.h> |
| 33 | #include <fcntl.h> |
| 34 | #include <inttypes.h> |
| 35 | #include <errno.h> |
| 36 | #include <sys/stat.h> |
| 37 | #include <sys/time.h> |
| 38 | #include "drm.h" |
| 39 | #include "ioctl_wrappers.h" |
| 40 | #include "igt_debugfs.h" |
| 41 | #include "drmtest.h" |
| 42 | |
| 43 | #define LOCAL_I915_EXEC_NO_RELOC (1<<11) |
| 44 | #define LOCAL_I915_EXEC_HANDLE_LUT (1<<12) |
| 45 | |
| 46 | #define SKIP_RELOC 0x1 |
| 47 | #define NO_RELOC 0x2 |
| 48 | #define CYCLE_BATCH 0x4 |
| 49 | #define FAULT 0x8 |
| 50 | #define LUT 0x10 |
| 51 | #define SEQUENTIAL_OFFSET 0x20 |
| 52 | #define REVERSE_OFFSET 0x40 |
| 53 | #define RANDOM_OFFSET 0x80 |
| 54 | |
| 55 | static uint32_t |
| 56 | hars_petruska_f54_1_random (void) |
| 57 | { |
| 58 | static uint32_t state = 0x12345678; |
| 59 | |
| 60 | #define rol(x,k) ((x << k) | (x >> (32-k))) |
| 61 | return state = (state ^ rol (state, 5) ^ rol (state, 24)) + 0x37798849; |
| 62 | #undef rol |
| 63 | } |
| 64 | |
| 65 | #define ELAPSED(a,b) (1e6*((b)->tv_sec - (a)->tv_sec) + ((b)->tv_usec - (a)->tv_usec)) |
| 66 | static int run(unsigned batch_size, |
| 67 | unsigned flags, |
| 68 | int num_objects, |
| 69 | int num_relocs, int reps) |
| 70 | { |
| 71 | uint32_t batch[2] = {MI_BATCH_BUFFER_END}; |
| 72 | uint32_t cycle[16]; |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 73 | int fd, n, count, c, size = 0; |
| 74 | struct drm_i915_gem_relocation_entry *reloc = NULL; |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 75 | struct drm_i915_gem_execbuffer2 execbuf; |
| 76 | struct drm_i915_gem_exec_object2 *objects; |
| 77 | struct timeval start, end; |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 78 | uint32_t reloc_handle = 0; |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 79 | struct drm_i915_gem_exec_object2 *gem_exec; |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 80 | struct drm_i915_gem_relocation_entry *mem_reloc = NULL; |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 81 | int *target; |
| 82 | |
| 83 | gem_exec = calloc(sizeof(*gem_exec), num_objects + 1); |
| 84 | mem_reloc = calloc(sizeof(*mem_reloc), num_relocs); |
| 85 | target = calloc(sizeof(*target), num_relocs); |
| 86 | |
Micah Fedke | c81d293 | 2015-07-22 21:54:02 +0000 | [diff] [blame] | 87 | fd = drm_open_driver(DRIVER_INTEL); |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 88 | |
| 89 | for (n = 0; n < num_objects; n++) |
| 90 | gem_exec[n].handle = gem_create(fd, 4096); |
| 91 | |
| 92 | for (n = 0; n < 16; n++) { |
| 93 | cycle[n] = gem_create(fd, batch_size); |
| 94 | gem_write(fd, cycle[n], 0, batch, sizeof(batch)); |
| 95 | } |
| 96 | gem_exec[num_objects].handle = cycle[c = 0]; |
| 97 | |
| 98 | for (n = 0; n < num_relocs; n++) { |
| 99 | mem_reloc[n].offset = 1024; |
| 100 | mem_reloc[n].read_domains = I915_GEM_DOMAIN_RENDER; |
| 101 | } |
| 102 | for (n = 0; n < num_relocs; n++) { |
| 103 | if (flags & SEQUENTIAL_OFFSET) |
| 104 | mem_reloc[n].offset = 8 + (8*n % (batch_size - 16)); |
| 105 | else if (flags & REVERSE_OFFSET) |
| 106 | mem_reloc[n].offset = batch_size - 8 - (8*n % (batch_size - 16)); |
| 107 | else if (flags & RANDOM_OFFSET) |
| 108 | mem_reloc[n].offset = 8 + |
| 109 | 8*hars_petruska_f54_1_random() % (batch_size - 16); |
| 110 | else |
| 111 | mem_reloc[n].offset = 1024; |
| 112 | mem_reloc[n].read_domains = I915_GEM_DOMAIN_RENDER; |
| 113 | } |
| 114 | |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 115 | if (num_relocs) { |
| 116 | size = ALIGN(sizeof(*mem_reloc)*num_relocs, 4096); |
| 117 | reloc_handle = gem_create(fd, size); |
Ville Syrjälä | b8a77dd | 2015-10-09 18:29:28 +0300 | [diff] [blame] | 118 | reloc = __gem_mmap__cpu(fd, reloc_handle, 0, size, PROT_READ | PROT_WRITE); |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 119 | memcpy(reloc, mem_reloc, sizeof(*mem_reloc)*num_relocs); |
| 120 | munmap(reloc, size); |
| 121 | |
| 122 | if (flags & FAULT) { |
| 123 | igt_disable_prefault(); |
Ville Syrjälä | b8a77dd | 2015-10-09 18:29:28 +0300 | [diff] [blame] | 124 | reloc = __gem_mmap__cpu(fd, reloc_handle, 0, size, PROT_READ | PROT_WRITE); |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 125 | } else |
| 126 | reloc = mem_reloc; |
| 127 | } |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 128 | |
| 129 | gem_exec[num_objects].relocation_count = num_relocs; |
| 130 | gem_exec[num_objects].relocs_ptr = (uintptr_t)reloc; |
| 131 | objects = gem_exec; |
| 132 | |
| 133 | memset(&execbuf, 0, sizeof(execbuf)); |
| 134 | execbuf.buffers_ptr = (uintptr_t)objects; |
| 135 | execbuf.buffer_count = num_objects + 1; |
| 136 | if (flags & LUT) |
| 137 | execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT; |
| 138 | if (flags & NO_RELOC) |
| 139 | execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC; |
| 140 | |
| 141 | for (n = 0; n < num_relocs; n++) { |
| 142 | target[n] = hars_petruska_f54_1_random() % num_objects; |
| 143 | if (flags & LUT) |
| 144 | reloc[n].target_handle = target[n]; |
| 145 | else |
| 146 | reloc[n].target_handle = objects[target[n]].handle; |
Chris Wilson | 7bd2ac6 | 2016-04-16 17:15:38 +0100 | [diff] [blame] | 147 | reloc[n].presumed_offset = -1; |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 148 | } |
| 149 | |
| 150 | gem_execbuf(fd, &execbuf); |
| 151 | |
| 152 | while (reps--) { |
| 153 | gettimeofday(&start, NULL); |
| 154 | for (count = 0; count < 1000; count++) { |
| 155 | if ((flags & SKIP_RELOC) == 0) { |
| 156 | for (n = 0; n < num_relocs; n++) |
Chris Wilson | 7bd2ac6 | 2016-04-16 17:15:38 +0100 | [diff] [blame] | 157 | reloc[n].presumed_offset = -1; |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 158 | if (flags & CYCLE_BATCH) { |
| 159 | c = (c + 1) % 16; |
| 160 | gem_exec[num_objects].handle = cycle[c]; |
| 161 | } |
| 162 | } |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 163 | if (flags & FAULT && reloc) { |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 164 | munmap(reloc, size); |
Ville Syrjälä | b8a77dd | 2015-10-09 18:29:28 +0300 | [diff] [blame] | 165 | reloc = __gem_mmap__cpu(fd, reloc_handle, 0, size, PROT_READ | PROT_WRITE); |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 166 | gem_exec[num_objects].relocs_ptr = (uintptr_t)reloc; |
| 167 | } |
| 168 | gem_execbuf(fd, &execbuf); |
| 169 | } |
| 170 | gettimeofday(&end, NULL); |
| 171 | printf("%.3f\n", ELAPSED(&start, &end)); |
| 172 | } |
| 173 | |
Chris Wilson | 5e68ad9 | 2015-08-21 22:26:42 +0100 | [diff] [blame] | 174 | if (flags & FAULT && reloc) { |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 175 | munmap(reloc, size); |
| 176 | igt_enable_prefault(); |
| 177 | } |
| 178 | |
| 179 | return 0; |
| 180 | } |
| 181 | |
| 182 | int main(int argc, char **argv) |
| 183 | { |
| 184 | unsigned num_objects = 1, num_relocs = 0, flags = 0; |
| 185 | unsigned size = 4096; |
| 186 | int reps = 13; |
| 187 | int c; |
| 188 | |
| 189 | while ((c = getopt (argc, argv, "b:r:s:e:l:m:o:")) != -1) { |
| 190 | switch (c) { |
| 191 | case 'l': |
| 192 | reps = atoi(optarg); |
| 193 | if (reps < 1) |
| 194 | reps = 1; |
| 195 | break; |
| 196 | |
| 197 | case 's': |
| 198 | size = atoi(optarg); |
| 199 | if (size < 4096) |
| 200 | size = 4096; |
| 201 | size = ALIGN(size, 4096); |
| 202 | break; |
| 203 | |
| 204 | case 'e': |
| 205 | if (strcmp(optarg, "busy") == 0) { |
| 206 | flags |= 0; |
| 207 | } else if (strcmp(optarg, "cyclic") == 0) { |
| 208 | flags |= CYCLE_BATCH; |
| 209 | } else if (strcmp(optarg, "fault") == 0) { |
| 210 | flags |= FAULT; |
| 211 | } else if (strcmp(optarg, "skip") == 0) { |
| 212 | flags |= SKIP_RELOC; |
| 213 | } else if (strcmp(optarg, "none") == 0) { |
| 214 | flags |= SKIP_RELOC | NO_RELOC; |
| 215 | } else { |
| 216 | abort(); |
| 217 | } |
| 218 | break; |
| 219 | |
| 220 | case 'm': |
| 221 | if (strcmp(optarg, "old") == 0) { |
| 222 | flags |= 0; |
| 223 | } else if (strcmp(optarg, "lut") == 0) { |
| 224 | flags |= LUT; |
| 225 | } else { |
| 226 | abort(); |
| 227 | } |
| 228 | break; |
| 229 | |
| 230 | case 'o': |
| 231 | if (strcmp(optarg, "constant") == 0) { |
| 232 | flags |= 0; |
| 233 | } else if (strcmp(optarg, "sequential") == 0) { |
| 234 | flags |= SEQUENTIAL_OFFSET; |
| 235 | } else if (strcmp(optarg, "reverse") == 0) { |
| 236 | flags |= REVERSE_OFFSET; |
| 237 | } else if (strcmp(optarg, "random") == 0) { |
| 238 | flags |= RANDOM_OFFSET; |
| 239 | } else { |
| 240 | abort(); |
| 241 | } |
| 242 | break; |
| 243 | |
| 244 | case 'b': |
| 245 | num_objects = atoi(optarg); |
| 246 | if (num_objects < 1) |
| 247 | num_objects = 1; |
| 248 | break; |
| 249 | |
| 250 | case 'r': |
| 251 | num_relocs = atoi(optarg); |
Chris Wilson | 38b3bd6 | 2015-08-11 12:57:38 +0100 | [diff] [blame] | 252 | break; |
| 253 | } |
| 254 | } |
| 255 | |
| 256 | return run(size, flags, num_objects, num_relocs, reps); |
| 257 | } |