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