0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #include <drm/radeon_drm.h>
0026 #include "radeon_reg.h"
0027 #include "radeon.h"
0028
0029 #define RADEON_BENCHMARK_COPY_BLIT 1
0030 #define RADEON_BENCHMARK_COPY_DMA 0
0031
0032 #define RADEON_BENCHMARK_ITERATIONS 1024
0033 #define RADEON_BENCHMARK_COMMON_MODES_N 17
0034
0035 static int radeon_benchmark_do_move(struct radeon_device *rdev, unsigned size,
0036 uint64_t saddr, uint64_t daddr,
0037 int flag, int n,
0038 struct dma_resv *resv)
0039 {
0040 unsigned long start_jiffies;
0041 unsigned long end_jiffies;
0042 struct radeon_fence *fence = NULL;
0043 int i, r;
0044
0045 start_jiffies = jiffies;
0046 for (i = 0; i < n; i++) {
0047 switch (flag) {
0048 case RADEON_BENCHMARK_COPY_DMA:
0049 fence = radeon_copy_dma(rdev, saddr, daddr,
0050 size / RADEON_GPU_PAGE_SIZE,
0051 resv);
0052 break;
0053 case RADEON_BENCHMARK_COPY_BLIT:
0054 fence = radeon_copy_blit(rdev, saddr, daddr,
0055 size / RADEON_GPU_PAGE_SIZE,
0056 resv);
0057 break;
0058 default:
0059 DRM_ERROR("Unknown copy method\n");
0060 return -EINVAL;
0061 }
0062 if (IS_ERR(fence))
0063 return PTR_ERR(fence);
0064
0065 r = radeon_fence_wait(fence, false);
0066 radeon_fence_unref(&fence);
0067 if (r)
0068 return r;
0069 }
0070 end_jiffies = jiffies;
0071 return jiffies_to_msecs(end_jiffies - start_jiffies);
0072 }
0073
0074
0075 static void radeon_benchmark_log_results(int n, unsigned size,
0076 unsigned int time,
0077 unsigned sdomain, unsigned ddomain,
0078 char *kind)
0079 {
0080 unsigned int throughput = (n * (size >> 10)) / time;
0081 DRM_INFO("radeon: %s %u bo moves of %u kB from"
0082 " %d to %d in %u ms, throughput: %u Mb/s or %u MB/s\n",
0083 kind, n, size >> 10, sdomain, ddomain, time,
0084 throughput * 8, throughput);
0085 }
0086
0087 static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size,
0088 unsigned sdomain, unsigned ddomain)
0089 {
0090 struct radeon_bo *dobj = NULL;
0091 struct radeon_bo *sobj = NULL;
0092 uint64_t saddr, daddr;
0093 int r, n;
0094 int time;
0095
0096 n = RADEON_BENCHMARK_ITERATIONS;
0097 r = radeon_bo_create(rdev, size, PAGE_SIZE, true, sdomain, 0, NULL, NULL, &sobj);
0098 if (r) {
0099 goto out_cleanup;
0100 }
0101 r = radeon_bo_reserve(sobj, false);
0102 if (unlikely(r != 0))
0103 goto out_cleanup;
0104 r = radeon_bo_pin(sobj, sdomain, &saddr);
0105 radeon_bo_unreserve(sobj);
0106 if (r) {
0107 goto out_cleanup;
0108 }
0109 r = radeon_bo_create(rdev, size, PAGE_SIZE, true, ddomain, 0, NULL, NULL, &dobj);
0110 if (r) {
0111 goto out_cleanup;
0112 }
0113 r = radeon_bo_reserve(dobj, false);
0114 if (unlikely(r != 0))
0115 goto out_cleanup;
0116 r = radeon_bo_pin(dobj, ddomain, &daddr);
0117 radeon_bo_unreserve(dobj);
0118 if (r) {
0119 goto out_cleanup;
0120 }
0121
0122 if (rdev->asic->copy.dma) {
0123 time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
0124 RADEON_BENCHMARK_COPY_DMA, n,
0125 dobj->tbo.base.resv);
0126 if (time < 0)
0127 goto out_cleanup;
0128 if (time > 0)
0129 radeon_benchmark_log_results(n, size, time,
0130 sdomain, ddomain, "dma");
0131 }
0132
0133 if (rdev->asic->copy.blit) {
0134 time = radeon_benchmark_do_move(rdev, size, saddr, daddr,
0135 RADEON_BENCHMARK_COPY_BLIT, n,
0136 dobj->tbo.base.resv);
0137 if (time < 0)
0138 goto out_cleanup;
0139 if (time > 0)
0140 radeon_benchmark_log_results(n, size, time,
0141 sdomain, ddomain, "blit");
0142 }
0143
0144 out_cleanup:
0145 if (sobj) {
0146 r = radeon_bo_reserve(sobj, false);
0147 if (likely(r == 0)) {
0148 radeon_bo_unpin(sobj);
0149 radeon_bo_unreserve(sobj);
0150 }
0151 radeon_bo_unref(&sobj);
0152 }
0153 if (dobj) {
0154 r = radeon_bo_reserve(dobj, false);
0155 if (likely(r == 0)) {
0156 radeon_bo_unpin(dobj);
0157 radeon_bo_unreserve(dobj);
0158 }
0159 radeon_bo_unref(&dobj);
0160 }
0161
0162 if (r) {
0163 DRM_ERROR("Error while benchmarking BO move.\n");
0164 }
0165 }
0166
0167 void radeon_benchmark(struct radeon_device *rdev, int test_number)
0168 {
0169 int i;
0170 int common_modes[RADEON_BENCHMARK_COMMON_MODES_N] = {
0171 640 * 480 * 4,
0172 720 * 480 * 4,
0173 800 * 600 * 4,
0174 848 * 480 * 4,
0175 1024 * 768 * 4,
0176 1152 * 768 * 4,
0177 1280 * 720 * 4,
0178 1280 * 800 * 4,
0179 1280 * 854 * 4,
0180 1280 * 960 * 4,
0181 1280 * 1024 * 4,
0182 1440 * 900 * 4,
0183 1400 * 1050 * 4,
0184 1680 * 1050 * 4,
0185 1600 * 1200 * 4,
0186 1920 * 1080 * 4,
0187 1920 * 1200 * 4
0188 };
0189
0190 switch (test_number) {
0191 case 1:
0192
0193 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_GTT,
0194 RADEON_GEM_DOMAIN_VRAM);
0195 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM,
0196 RADEON_GEM_DOMAIN_GTT);
0197 break;
0198 case 2:
0199
0200 radeon_benchmark_move(rdev, 1024*1024, RADEON_GEM_DOMAIN_VRAM,
0201 RADEON_GEM_DOMAIN_VRAM);
0202 break;
0203 case 3:
0204
0205 for (i = 1; i <= 16384; i <<= 1)
0206 radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
0207 RADEON_GEM_DOMAIN_GTT,
0208 RADEON_GEM_DOMAIN_VRAM);
0209 break;
0210 case 4:
0211
0212 for (i = 1; i <= 16384; i <<= 1)
0213 radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
0214 RADEON_GEM_DOMAIN_VRAM,
0215 RADEON_GEM_DOMAIN_GTT);
0216 break;
0217 case 5:
0218
0219 for (i = 1; i <= 16384; i <<= 1)
0220 radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE,
0221 RADEON_GEM_DOMAIN_VRAM,
0222 RADEON_GEM_DOMAIN_VRAM);
0223 break;
0224 case 6:
0225
0226 for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++)
0227 radeon_benchmark_move(rdev, common_modes[i],
0228 RADEON_GEM_DOMAIN_GTT,
0229 RADEON_GEM_DOMAIN_VRAM);
0230 break;
0231 case 7:
0232
0233 for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++)
0234 radeon_benchmark_move(rdev, common_modes[i],
0235 RADEON_GEM_DOMAIN_VRAM,
0236 RADEON_GEM_DOMAIN_GTT);
0237 break;
0238 case 8:
0239
0240 for (i = 0; i < RADEON_BENCHMARK_COMMON_MODES_N; i++)
0241 radeon_benchmark_move(rdev, common_modes[i],
0242 RADEON_GEM_DOMAIN_VRAM,
0243 RADEON_GEM_DOMAIN_VRAM);
0244 break;
0245
0246 default:
0247 DRM_ERROR("Unknown benchmark\n");
0248 }
0249 }