1 /* $OpenBSD: radeon_benchmark.c,v 1.5 2015/07/11 04:00:46 jsg Exp $ */ 2 /* 3 * Copyright 2009 Jerome Glisse. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 21 * OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: Jerome Glisse 24 */ 25 #include <dev/pci/drm/drmP.h> 26 #include <dev/pci/drm/radeon_drm.h> 27 #include "radeon_reg.h" 28 #include "radeon.h" 29 30 #define RADEON_BENCHMARK_COPY_BLIT 1 31 #define RADEON_BENCHMARK_COPY_DMA 0 32 33 #define RADEON_BENCHMARK_ITERATIONS 1024 34 #define RADEON_BENCHMARK_COMMON_MODES_N 17 35 36 static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size, 37 uint64_t saddr, uint64_t daddr, 38 int flag, int n) 39 { 40 unsigned long start_jiffies; 41 unsigned long end_jiffies; 42 struct radeon_fence *fence = NULL; 43 int i, r; 44 45 start_jiffies = jiffies; 46 for (i = 0; i < n; i++) { 47 switch (flag) { 48 case RADEON_BENCHMARK_COPY_DMA: 49 r = radeon_copy_dma(rdev, saddr, daddr, 50 size / RADEON_GPU_PAGE_SIZE, 51 &fence); 52 break; 53 case RADEON_BENCHMARK_COPY_BLIT: 54 r = radeon_copy_blit(rdev, saddr, daddr, 55 size / RADEON_GPU_PAGE_SIZE, 56 &fence); 57 break; 58 default: 59 DRM_ERROR("Unknown copy method\n"); 60 r = -EINVAL; 61 } 62 if (r) 63 goto exit_do_move; 64 r = radeon_fence_wait(fence, false); 65 if (r) 66 goto exit_do_move; 67 radeon_fence_unref(&fence); 68 } 69 end_jiffies = jiffies; 70 r = jiffies_to_msecs(end_jiffies - start_jiffies); 71 72 exit_do_move: 73 if (fence) 74 radeon_fence_unref(&fence); 75 return r; 76 } 77 78 79 static void radeon_benchmark_log_results(int n, unsigned size, 80 unsigned int time, 81 unsigned sdomain, unsigned ddomain, 82 char *kind) 83 { 84 #ifdef DRMDEBUG 85 unsigned int throughput = (n * (size >> 10)) / time; 86 #endif 87 DRM_INFO("radeon: %s %u bo moves of %u kB from" 88 " %d to %d in %u ms, throughput: %u Mb/s or %u MB/s\n", 89 kind, n, size >> 10, sdomain, ddomain, time, 90 throughput * 8, throughput); 91 } 92 93 static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, 94 unsigned sdomain, unsigned ddomain) 95 { 96 struct radeon_bo *dobj = NULL; 97 struct radeon_bo *sobj = NULL; 98 uint64_t saddr, daddr; 99 int r, n; 100 int time; 101 102 n = RADEON_BENCHMARK_ITERATIONS; 103 r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, NULL, &sobj); 104 if (r) { 105 goto out_cleanup; 106 } 107 r = radeon_bo_reserve(sobj, false); 108 if (unlikely(r != 0)) 109 goto out_cleanup; 110 r = radeon_bo_pin(sobj, sdomain, &saddr); 111 radeon_bo_unreserve(sobj); 112 if (r) { 113 goto out_cleanup; 114 } 115 r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, NULL, &dobj); 116 if (r) { 117 goto out_cleanup; 118 } 119 r = radeon_bo_reserve(dobj, false); 120 if (unlikely(r != 0)) 121 goto out_cleanup; 122 r = radeon_bo_pin(dobj, ddomain, &daddr); 123 radeon_bo_unreserve(dobj); 124 if (r) { 125 goto out_cleanup; 126 } 127 128 /* r100 doesn't have dma engine so skip the test */ 129 /* also, VRAM-to-VRAM test doesn't make much sense for DMA */ 130 /* skip it as well if domains are the same */ 131 if ((rdev->asic->copy.dma) && (sdomain != ddomain)) { 132 time = radeon_benchmark_do_move(rdev, size, saddr, daddr, 133 RADEON_BENCHMARK_COPY_DMA, n); 134 if (time < 0) 135 goto out_cleanup; 136 if (time > 0) 137 radeon_benchmark_log_results(n, size, time, 138 sdomain, ddomain, "dma"); 139 } 140 141 if (rdev->asic->copy.blit) { 142 time = radeon_benchmark_do_move(rdev, size, saddr, daddr, 143 RADEON_BENCHMARK_COPY_BLIT, n); 144 if (time < 0) 145 goto out_cleanup; 146 if (time > 0) 147 radeon_benchmark_log_results(n, size, time, 148 sdomain, ddomain, "blit"); 149 } 150 151 out_cleanup: 152 if (sobj) { 153 r = radeon_bo_reserve(sobj, false); 154 if (likely(r == 0)) { 155 radeon_bo_unpin(sobj); 156 radeon_bo_unreserve(sobj); 157 } 158 radeon_bo_unref(&sobj); 159 } 160 if (dobj) { 161 r = radeon_bo_reserve(dobj, false); 162 if (likely(r == 0)) { 163 radeon_bo_unpin(dobj); 164 radeon_bo_unreserve(dobj); 165 } 166 radeon_bo_unref(&dobj); 167 } 168 169 if (r) { 170 DRM_ERROR("Error while benchmarking BO move.\n"); 171 } 172 } 173 174 void radeon_benchmark(struct radeon_device *rdev, int test_number) 175 { 176 int i; 177 int common_modes[RADEON_BENCHMARK_COMMON_MODES_N] = { 178 640 * 480 * 4, 179 720 * 480 * 4, 180 800 * 600 * 4, 181 848 * 480 * 4, 182 1024 * 768 * 4, 183 1152 * 768 * 4, 184 1280 * 720 * 4, 185 1280 * 800 * 4, 186 1280 * 854 * 4, 187 1280 * 960 * 4, 188 1280 * 1024 * 4, 189 1440 * 900 * 4, 190 1400 * 1050 * 4, 191 1680 * 1050 * 4, 192 1600 * 1200 * 4, 193 1920 * 1080 * 4, 194 1920 * 1200 * 4 195 }; 196 197 switch (test_number) { 198 case 1: 199 /* simple test, VRAM to GTT and GTT to VRAM */ 200 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_GTT, 201 RADEON_GEM_DOMAIN_VRAM); 202 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, 203 RADEON_GEM_DOMAIN_GTT); 204 break; 205 case 2: 206 /* simple test, VRAM to VRAM */ 207 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM, 208 RADEON_GEM_DOMAIN_VRAM); 209 break; 210 case 3: 211 /* GTT to VRAM, buffer size sweep, powers of 2 */ 212 for (i = 1; i <= 16384; i <<= 1) 213 radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 214 RADEON_GEM_DOMAIN_GTT, 215 RADEON_GEM_DOMAIN_VRAM); 216 break; 217 case 4: 218 /* VRAM to GTT, buffer size sweep, powers of 2 */ 219 for (i = 1; i <= 16384; i <<= 1) 220 radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 221 RADEON_GEM_DOMAIN_VRAM, 222 RADEON_GEM_DOMAIN_GTT); 223 break; 224 case 5: 225 /* VRAM to VRAM, buffer size sweep, powers of 2 */ 226 for (i = 1; i <= 16384; i <<= 1) 227 radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, 228 RADEON_GEM_DOMAIN_VRAM, 229 RADEON_GEM_DOMAIN_VRAM); 230 break; 231 case 6: 232 /* GTT to VRAM, buffer size sweep, common modes */ 233 for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 234 radeon_benchmark_move(rdev, common_modes[i], 235 RADEON_GEM_DOMAIN_GTT, 236 RADEON_GEM_DOMAIN_VRAM); 237 break; 238 case 7: 239 /* VRAM to GTT, buffer size sweep, common modes */ 240 for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 241 radeon_benchmark_move(rdev, common_modes[i], 242 RADEON_GEM_DOMAIN_VRAM, 243 RADEON_GEM_DOMAIN_GTT); 244 break; 245 case 8: 246 /* VRAM to VRAM, buffer size sweep, common modes */ 247 for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++) 248 radeon_benchmark_move(rdev, common_modes[i], 249 RADEON_GEM_DOMAIN_VRAM, 250 RADEON_GEM_DOMAIN_VRAM); 251 break; 252 253 default: 254 DRM_ERROR("Unknown benchmark\n"); 255 } 256 } 257