radeonsi: add a new blit microbenchmark

Reviewed-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/28917>
This commit is contained in:
Marek Olšák
2024-03-24 15:59:31 -04:00
committed by Marge Bot
parent 0c545e2fca
commit c5641387f3
4 changed files with 717 additions and 2 deletions

View File

@@ -82,8 +82,9 @@ files_libradeonsi = files(
'si_state_shaders.cpp',
'si_state_streamout.c',
'si_state_viewport.c',
'si_test_image_copy_region.c',
'si_test_blit_perf.c',
'si_test_dma_perf.c',
'si_test_image_copy_region.c',
'si_texture.c',
'si_utrace.c',
'si_utrace.h',

View File

@@ -127,6 +127,7 @@ static const struct debug_named_value test_options[] = {
{"testvmfaultshader", DBG(TEST_VMFAULT_SHADER), "Invoke a shader VM fault test and exit."},
{"testdmaperf", DBG(TEST_DMA_PERF), "Test DMA performance"},
{"testmemperf", DBG(TEST_MEM_PERF), "Test map + memcpy perf using the winsys."},
{"blitperf", DBG(TEST_BLIT_PERF), "Test gfx and compute clear/copy/blit/resolve performance"},
DEBUG_NAMED_VALUE_END /* must be last */
};
@@ -1498,6 +1499,9 @@ static struct pipe_screen *radeonsi_screen_create_impl(struct radeon_winsys *ws,
if (test_flags & DBG(TEST_MEM_PERF))
si_test_mem_perf(sscreen);
if (test_flags & DBG(TEST_BLIT_PERF))
si_test_blit_perf(sscreen);
if (test_flags & (DBG(TEST_VMFAULT_CP) | DBG(TEST_VMFAULT_SHADER)))
si_test_vmfault(sscreen, test_flags);

View File

@@ -254,6 +254,7 @@ enum
DBG_TEST_VMFAULT_SHADER,
DBG_TEST_DMA_PERF,
DBG_TEST_MEM_PERF,
DBG_TEST_BLIT_PERF,
};
#define DBG_ALL_SHADERS (((1 << (DBG_CS + 1)) - 1))
@@ -1716,9 +1717,11 @@ void si_test_blit(struct si_screen *sscreen, unsigned test_flags);
/* si_test_dma_perf.c */
void si_test_dma_perf(struct si_screen *sscreen);
void si_test_mem_perf(struct si_screen *sscreen);
/* si_test_blit_perf.c */
void si_test_blit_perf(struct si_screen *sscreen);
/* si_uvd.c */
struct pipe_video_codec *si_uvd_create_decoder(struct pipe_context *context,
const struct pipe_video_codec *templ);

View File

@@ -0,0 +1,707 @@
/*
* Copyright 2024 Advanced Micro Devices, Inc.
*
* SPDX-License-Identifier: MIT
*/
/* This file implements performance tests for graphics and compute blits and clears. */
#include "si_pipe.h"
#include "util/rand_xor.h"
#include "util/u_surface.h"
#define RANDOM_DATA_SIZE (611953 * 8) /* prime number * 8 */
/* For MSAA, level_or_sample_index == 0 means set all samples, while level_or_sample_index > 0
* means set the sample equal to level_or_sample_index - 1.
*/
static void set_random_pixels(struct pipe_context *ctx, struct pipe_resource *tex,
unsigned level_or_sample_index, uint64_t *random_data)
{
struct pipe_transfer *t;
uint8_t *map = pipe_texture_map_3d(ctx, tex, level_or_sample_index, PIPE_MAP_WRITE, 0, 0, 0,
tex->width0, tex->height0, tex->depth0, &t);
assert(map);
/* It's static because we want following calls of this function to continue from
* the previous offset.
*/
static unsigned random_data_offset = 0;
for (unsigned z = 0; z < tex->depth0; z++) {
for (unsigned y = 0; y < tex->height0; y++) {
uint64_t *ptr = (uint64_t *)(map + t->layer_stride * z + t->stride * y);
unsigned size = t->stride;
assert(size % 8 == 0);
while (size) {
unsigned copy_size =
random_data_offset + size <= RANDOM_DATA_SIZE ? size :
RANDOM_DATA_SIZE - random_data_offset;
memcpy(ptr, (uint8_t*)random_data + random_data_offset, copy_size);
size -= copy_size;
ptr += copy_size / 8;
random_data_offset += copy_size;
if (random_data_offset >= RANDOM_DATA_SIZE) {
assert(random_data_offset == RANDOM_DATA_SIZE);
random_data_offset = 0;
}
}
}
}
pipe_texture_unmap(ctx, t);
}
static void set_gradient_pixels(struct pipe_context *ctx, struct pipe_resource *tex)
{
struct pipe_transfer *t;
uint8_t *map = pipe_texture_map_3d(ctx, tex, 0, PIPE_MAP_WRITE, 0, 0, 0,
tex->width0, tex->height0, tex->depth0, &t);
assert(map);
/* Generate just 1 line of pixels. */
unsigned pix_size = util_format_get_blocksize(tex->format);
unsigned line_size = tex->width0 * pix_size;
uint8_t *line = (uint8_t*)malloc(line_size);
if (util_format_is_pure_integer(tex->format)) {
for (unsigned x = 0; x < tex->width0; x++) {
union pipe_color_union color;
color.ui[0] = color.ui[1] = color.ui[2] = color.ui[3] = x;
util_pack_color_union(tex->format, (union util_color *)(line + x * pix_size), &color);
}
} else if (util_format_is_float(tex->format)) {
for (unsigned x = 0; x < tex->width0; x++) {
union pipe_color_union color;
color.f[0] = color.f[1] = color.f[2] = color.f[3] = (float)x / (tex->width0 - 1);
util_pack_color_union(tex->format, (union util_color *)(line + x * pix_size), &color);
}
} else {
for (unsigned x = 0; x < tex->width0; x++)
util_pack_color_ub(x, x, x, x, tex->format, (union util_color *)(line + x * pix_size));
}
/* Copy the generated line to all lines. */
for (unsigned z = 0; z < tex->depth0; z++) {
for (unsigned y = 0; y < tex->height0; y++)
memcpy(map + t->layer_stride * z + t->stride * y, line, line_size);
}
free(line);
pipe_texture_unmap(ctx, t);
}
static enum pipe_format formats[] = {
PIPE_FORMAT_R8_UNORM,
PIPE_FORMAT_R8_UINT,
PIPE_FORMAT_R16_UINT,
PIPE_FORMAT_R16_FLOAT,
PIPE_FORMAT_R8G8B8A8_UNORM,
PIPE_FORMAT_R32_UINT,
PIPE_FORMAT_R32_FLOAT,
PIPE_FORMAT_R32G32_UINT,
PIPE_FORMAT_R32G32_FLOAT,
PIPE_FORMAT_R16G16B16A16_FLOAT,
PIPE_FORMAT_R32G32B32A32_UINT,
PIPE_FORMAT_R32G32B32A32_FLOAT,
};
enum {
TEST_FB_CLEAR,
TEST_CLEAR,
TEST_COPY,
TEST_BLIT,
TEST_RESOLVE,
NUM_TESTS,
};
static const char *test_strings[] = {
[TEST_FB_CLEAR] = "fbclear",
[TEST_CLEAR] = "cleartex",
[TEST_COPY] = "copy",
[TEST_BLIT] = "blit",
[TEST_RESOLVE] = "resolve",
};
enum {
LAYOUT_T2T, /* tiled to tiled or clear tiled */
LAYOUT_L2T, /* linear to tiled */
LAYOUT_T2L, /* tiled to linear */
LAYOUT_L2L, /* linear to linear or clear linear */
NUM_LAYOUTS,
};
static const char *layout_strings[] = {
[LAYOUT_T2T] = "T2T",
[LAYOUT_L2T] = "L2T",
[LAYOUT_T2L] = "T2L",
[LAYOUT_L2L] = "L2L",
};
enum {
BOX_FULL,
BOX_FULL_YFLIP,
BOX_PARTIAL,
BOX_PARTIAL_UNALIGNED,
BOX_PARTIAL_UNALIGNED_YFLIP,
NUM_BOXES,
};
static const char *box_strings[] = {
[BOX_FULL] = "full",
[BOX_FULL_YFLIP] = "yflip",
[BOX_PARTIAL] = "partial",
[BOX_PARTIAL_UNALIGNED] = "unaligned",
[BOX_PARTIAL_UNALIGNED_YFLIP] = "yflip/unali",
};
enum {
FILL_BLACK,
FILL_SOLID,
FILL_GRADIENT,
FILL_RANDOM,
FILL_RANDOM_FRAGMENTED2,
FILL_RANDOM_FRAGMENTED4,
FILL_RANDOM_FRAGMENTED8,
NUM_FILLS,
};
static const char *fill_strings[] = {
[FILL_BLACK] = "black",
[FILL_SOLID] = "solid",
[FILL_GRADIENT] = "gradient",
[FILL_RANDOM] = "random",
[FILL_RANDOM_FRAGMENTED2] = "fragmented2",
[FILL_RANDOM_FRAGMENTED4] = "fragmented4",
[FILL_RANDOM_FRAGMENTED8] = "fragmented8",
};
enum {
METHOD_DEFAULT,
METHOD_GFX,
METHOD_COMPUTE,
METHOD_SPECIAL,
NUM_METHODS,
};
static const union pipe_color_union black_color_float = {.f = {0, 0, 0, 0}};
static const union pipe_color_union solid_color_float = {.f = {0.2, 0.3, 0.4, 0.5}};
static const union pipe_color_union black_color_uint = {.ui = {0, 0, 0, 0}};
static const union pipe_color_union solid_color_uint = {.ui = {23, 45, 89, 107}};
void si_test_blit_perf(struct si_screen *sscreen)
{
struct pipe_screen *screen = &sscreen->b;
struct pipe_context *ctx = screen->context_create(screen, NULL, 0);
struct si_context *sctx = (struct si_context *)ctx;
uint64_t seed_xorshift128plus[2];
uint64_t random_data[RANDOM_DATA_SIZE / 8];
/* Set the seed for random pixel data */
s_rand_xorshift128plus(seed_xorshift128plus, false);
/* Pre-generate random data for initializing textures. */
for (unsigned i = 0; i < ARRAY_SIZE(random_data); i++)
random_data[i] = rand_xorshift128plus(seed_xorshift128plus);
sscreen->ws->cs_set_pstate(&sctx->gfx_cs, RADEON_CTX_PSTATE_PEAK);
printf("Op , Special ,Dim, Format ,MS,Layout, Fill , Box ,"
" small , small , small , small , LARGE , LARGE , LARGE , LARGE\n");
printf("--------,----------,---,-------------------,--,------,------------,-------------,"
" Default , Gfx , Compute , Special , Default , Gfx , Compute , Special\n");
for (unsigned test_flavor = 0; test_flavor < NUM_TESTS; test_flavor++) {
for (unsigned dim = 1; dim <= 3; dim++) {
for (unsigned format_index = 0; format_index < ARRAY_SIZE(formats); format_index++) {
for (unsigned samples = 1; samples <= 8; samples *= 2) {
for (unsigned layout = 0; layout < NUM_LAYOUTS; layout++) {
/* Reject invalid combinations. */
if (samples >= 2 && (dim != 2 || layout != LAYOUT_T2T))
continue;
if (dim == 1 && layout != LAYOUT_L2L)
continue;
if (test_flavor != TEST_COPY &&
(layout == LAYOUT_L2T || layout == LAYOUT_T2L))
continue;
if (test_flavor != TEST_COPY && dim != 1 &&
layout != LAYOUT_T2T)
continue;
if (test_flavor == TEST_RESOLVE && samples == 1)
continue;
if (test_flavor == TEST_RESOLVE &&
util_format_is_pure_integer(formats[format_index]))
continue;
/* Create textures. */
struct pipe_resource *src[2] = {0}, *dst[2] = {0};
const struct pipe_resource templ = {
.array_size = 1,
.format = formats[format_index],
.target = PIPE_TEXTURE_1D + dim - 1,
.usage = PIPE_USAGE_DEFAULT,
};
unsigned bpe = util_format_get_blocksize(templ.format);
unsigned pix_size = bpe * samples;
/* TODOs:
* CS:
* - optimize for gfx10.3
* - move the compute blit to amd/common
*/
for (unsigned size_factor = 0; size_factor <= 1; size_factor++) {
unsigned mb_size = (size_factor ? 256 : 8) * 1024 * 1024;
unsigned width = 1, height = 1, depth = 1;
/* Determine the size. The footprint must be exactly "mb_size" for 2D and 3D. */
if (dim == 1) {
width = size_factor ? 16384 : 2048;
} else if (dim == 2) {
width = height = util_next_power_of_two(sqrt(mb_size / pix_size));
for (unsigned i = 0; width * height * pix_size != mb_size; i++) {
if (i % 2 == 1)
width /= 2;
else
height /= 2;
}
} else if (dim == 3) {
width = height = depth = util_next_power_of_two(pow(mb_size / pix_size, 0.333333));
for (unsigned i = 0; width * height * depth * pix_size != mb_size; i++) {
if (i % 3 == 2)
width /= 2;
else if (i % 3 == 1)
height /= 2;
else
depth /= 2;
}
}
struct pipe_resource src_templ = templ;
src_templ.width0 = MIN2(width, 16384);
src_templ.height0 = MIN2(height, 16384);
src_templ.depth0 = MIN2(depth, 16384);
src_templ.nr_samples = src_templ.nr_storage_samples = samples;
src_templ.bind = layout == LAYOUT_L2L ||
layout == LAYOUT_L2T ? PIPE_BIND_LINEAR : 0;
if (test_flavor != TEST_FB_CLEAR && test_flavor != TEST_CLEAR)
src[size_factor] = screen->resource_create(screen, &src_templ);
struct pipe_resource dst_templ = src_templ;
dst_templ.bind = layout == LAYOUT_L2L ||
layout == LAYOUT_T2L ? PIPE_BIND_LINEAR : 0;
if (test_flavor == TEST_RESOLVE)
dst_templ.nr_samples = dst_templ.nr_storage_samples = 1;
dst[size_factor] = screen->resource_create(screen, &dst_templ);
}
for (unsigned fill_flavor = 0; fill_flavor < NUM_FILLS; fill_flavor++) {
const union pipe_color_union *clear_color =
util_format_is_pure_integer(templ.format) ?
(fill_flavor == FILL_BLACK ? &black_color_uint : &solid_color_uint) :
(fill_flavor == FILL_BLACK ? &black_color_float : &solid_color_float);
/* Reject invalid combinations. */
if ((test_flavor == TEST_FB_CLEAR || test_flavor == TEST_CLEAR) &&
fill_flavor != FILL_SOLID && fill_flavor != FILL_BLACK)
continue;
if ((samples == 1 && fill_flavor >= FILL_RANDOM_FRAGMENTED2) ||
(samples == 2 && fill_flavor >= FILL_RANDOM_FRAGMENTED4) ||
(samples == 4 && fill_flavor >= FILL_RANDOM_FRAGMENTED8))
continue;
/* Fill the source texture. */
if (test_flavor != TEST_FB_CLEAR && test_flavor != TEST_CLEAR) {
for (unsigned size_factor = 0; size_factor <= 1; size_factor++) {
switch (fill_flavor) {
case FILL_BLACK:
case FILL_SOLID: {
union util_color packed_color;
util_pack_color(clear_color->f, templ.format, &packed_color);
struct pipe_box box = {0};
box.width = src[size_factor]->width0;
box.height = src[size_factor]->height0;
box.depth = src[size_factor]->depth0;
ctx->clear_texture(ctx, src[size_factor], 0, &box, &packed_color);
break;
}
case FILL_GRADIENT:
set_gradient_pixels(ctx, src[size_factor]);
break;
case FILL_RANDOM:
set_random_pixels(ctx, src[size_factor], 0, random_data);
break;
case FILL_RANDOM_FRAGMENTED2:
assert(samples >= 2);
/* Make all samples equal. */
set_random_pixels(ctx, src[size_factor], 0, random_data);
/* Make sample 0 different. */
set_random_pixels(ctx, src[size_factor], 1, random_data);
break;
case FILL_RANDOM_FRAGMENTED4:
assert(samples >= 4);
/* Make all samples equal. */
set_random_pixels(ctx, src[size_factor], 0, random_data);
/* Make samples 0..2 different. */
for (unsigned i = 0; i <= 2; i++)
set_random_pixels(ctx, src[size_factor], i + 1, random_data);
break;
case FILL_RANDOM_FRAGMENTED8:
assert(samples == 8);
/* Make all samples equal. */
set_random_pixels(ctx, src[size_factor], 0, random_data);
/* Make samples 0..6 different. */
for (unsigned i = 0; i <= 6; i++)
set_random_pixels(ctx, src[size_factor], i + 1, random_data);
break;
}
}
}
for (unsigned box_flavor = 0; box_flavor < NUM_BOXES; box_flavor++) {
bool yflip = box_flavor == BOX_FULL_YFLIP ||
box_flavor == BOX_PARTIAL_UNALIGNED_YFLIP;
/* Reject invalid combinations. */
if (test_flavor == TEST_FB_CLEAR && box_flavor != BOX_FULL)
continue;
if ((test_flavor == TEST_CLEAR || test_flavor == TEST_COPY) && yflip)
continue;
const char *special_op =
test_flavor == TEST_FB_CLEAR ? "cleartex" :
test_flavor == TEST_CLEAR && box_flavor == BOX_FULL ? "fastclear" :
test_flavor == TEST_BLIT && !yflip ? "copy" :
test_flavor == TEST_RESOLVE ? "cbresolve" : "n/a";
printf("%-8s, %-9s, %uD, %-18s, %u, %-5s, %-11s, %-11s",
test_strings[test_flavor], special_op, dim,
util_format_short_name(formats[format_index]), samples,
layout_strings[layout], fill_strings[fill_flavor],
box_strings[box_flavor]);
for (unsigned size_factor = 0; size_factor <= 1; size_factor++) {
/* Determine the box. */
struct pipe_box src_box = {0}, dst_box = {0};
dst_box.width = dst[size_factor]->width0;
dst_box.height = dst[size_factor]->height0;
dst_box.depth = dst[size_factor]->depth0;
src_box = dst_box;
switch (box_flavor) {
case BOX_FULL:
break;
case BOX_FULL_YFLIP:
src_box.y = src_box.height;
src_box.height = -src_box.height;
break;
case BOX_PARTIAL:
if (dim == 1) {
dst_box.x = 256;
dst_box.width -= 256;
} else if (dim == 2) {
dst_box.x = 16;
dst_box.y = 16;
dst_box.width -= 16;
dst_box.height -= 16;
} else {
dst_box.x = 8;
dst_box.y = 8;
dst_box.z = 8;
dst_box.width -= 8;
dst_box.height -= 8;
dst_box.depth -= 8;
}
src_box = dst_box;
break;
case BOX_PARTIAL_UNALIGNED:
case BOX_PARTIAL_UNALIGNED_YFLIP: {
const unsigned off = 13;
dst_box.x = off;
dst_box.width -= off;
if (dim >= 2) {
dst_box.y = off;
dst_box.height -= off;
if (dim == 3) {
dst_box.z = off;
dst_box.depth -= off;
}
}
src_box = dst_box;
if (box_flavor == BOX_PARTIAL_UNALIGNED_YFLIP) {
src_box.y += src_box.height;
src_box.height = -src_box.height;
}
break;
}
}
assert(dst_box.x >= 0);
assert(dst_box.y >= 0);
assert(dst_box.z >= 0);
assert(dst_box.width > 0);
assert(dst_box.height > 0);
assert(dst_box.depth > 0);
assert(dst_box.x + dst_box.width <= dst[size_factor]->width0);
assert(dst_box.y + dst_box.height <= dst[size_factor]->height0);
assert(dst_box.z + dst_box.depth <= dst[size_factor]->depth0);
if (src[size_factor]) {
assert(src_box.width);
assert(src_box.height);
assert(src_box.depth > 0);
if (src_box.width > 0) {
assert(src_box.x >= 0);
assert(src_box.x + src_box.width <= src[size_factor]->width0);
} else {
assert(src_box.x + src_box.width >= 0);
assert(src_box.x - 1 < src[size_factor]->width0);
}
if (src_box.height > 0) {
assert(src_box.y >= 0);
assert(src_box.y + src_box.height <= src[size_factor]->height0);
} else {
assert(src_box.y + src_box.height >= 0);
assert(src_box.y - 1 < src[size_factor]->height0);
}
assert(src_box.z >= 0);
assert(src_box.z + src_box.depth <= src[size_factor]->depth0);
}
for (unsigned method = 0; method < NUM_METHODS; method++) {
struct pipe_surface *dst_surf = NULL;
/* Create pipe_surface for clears. */
if (test_flavor == TEST_FB_CLEAR || test_flavor == TEST_CLEAR) {
struct pipe_surface surf_templ;
u_surface_default_template(&surf_templ, dst[size_factor]);
surf_templ.u.tex.last_layer = dst[size_factor]->depth0 - 1;
dst_surf = ctx->create_surface(ctx, dst[size_factor], &surf_templ);
/* Bind the colorbuffer for FB clears. */
if (box_flavor == BOX_FULL) {
struct pipe_framebuffer_state fb = {0};
fb.width = dst[size_factor]->width0;
fb.height = dst[size_factor]->height0;
fb.layers = dst[size_factor]->depth0;
fb.samples = dst[size_factor]->nr_samples;
fb.nr_cbufs = 1;
fb.cbufs[0] = dst_surf;
ctx->set_framebuffer_state(ctx, &fb);
si_emit_cache_flush_direct(sctx);
}
}
struct pipe_query *q = ctx->create_query(ctx, PIPE_QUERY_TIME_ELAPSED, 0);
unsigned num_warmup_repeats = 1, num_repeats = 4;
bool success = true;
/* Run tests. */
for (unsigned i = 0; i < num_warmup_repeats + num_repeats; i++) {
/* The first few just warm up caches and the hw. */
if (i == num_warmup_repeats)
ctx->begin_query(ctx, q);
switch (test_flavor) {
case TEST_FB_CLEAR:
case TEST_CLEAR:
switch (method) {
case METHOD_DEFAULT:
if (test_flavor == TEST_FB_CLEAR) {
ctx->clear(ctx, PIPE_CLEAR_COLOR, NULL, clear_color, 0, 0);
sctx->flags |= SI_CONTEXT_FLUSH_AND_INV_CB | SI_CONTEXT_INV_L2;
} else {
ctx->clear_render_target(ctx, dst_surf, clear_color,
dst_box.x, dst_box.y,
dst_box.width, dst_box.height,
false);
}
break;
case METHOD_GFX:
si_gfx_clear_render_target(ctx, dst_surf, clear_color,
dst_box.x, dst_box.y,
dst_box.width, dst_box.height,
false);
break;
case METHOD_COMPUTE:
success &=
si_compute_clear_image(sctx, dst_surf->texture,
dst_surf->format, 0, &dst_box,
clear_color, false, false);
break;
case METHOD_SPECIAL:
if (test_flavor == TEST_CLEAR) {
success &=
si_compute_fast_clear_image(sctx, dst_surf->texture,
dst_surf->format, 0,
&dst_box, clear_color,
false, false);
} else {
ctx->clear_render_target(ctx, dst_surf, clear_color,
dst_box.x, dst_box.y,
dst_box.width, dst_box.height,
false);
}
break;
}
break;
case TEST_COPY:
switch (method) {
case METHOD_DEFAULT:
si_resource_copy_region(ctx, dst[size_factor], 0, dst_box.x,
dst_box.y, dst_box.z, src[size_factor],
0, &src_box);
break;
case METHOD_GFX:
si_gfx_copy_image(sctx, dst[size_factor], 0, dst_box.x,
dst_box.y, dst_box.z, src[size_factor],
0, &src_box);
break;
case METHOD_COMPUTE:
success &= si_compute_copy_image(sctx, dst[size_factor], 0,
src[size_factor], 0,
dst_box.x, dst_box.y,
dst_box.z, &src_box, false);
break;
case METHOD_SPECIAL:
success = false;
break;
}
break;
case TEST_BLIT:
case TEST_RESOLVE: {
struct pipe_blit_info info;
memset(&info, 0, sizeof(info));
info.dst.resource = dst[size_factor];
info.dst.level = 0;
info.dst.box = dst_box;
info.dst.format = templ.format;
info.src.resource = src[size_factor];
info.src.level = 0;
info.src.box = src_box;
info.src.format = templ.format;
info.mask = PIPE_MASK_RGBA;
switch (method) {
case METHOD_DEFAULT:
ctx->blit(ctx, &info);
break;
case METHOD_GFX:
si_gfx_blit(ctx, &info);
break;
case METHOD_COMPUTE:
success &= si_compute_blit(sctx, &info, NULL, 0, 0,
SI_OP_SYNC_BEFORE_AFTER);
break;
case METHOD_SPECIAL:
if (test_flavor == TEST_BLIT && !yflip) {
si_resource_copy_region(ctx, dst[size_factor], 0, dst_box.x,
dst_box.y, dst_box.z, src[size_factor],
0, &src_box);
} else if (test_flavor == TEST_RESOLVE) {
success &= si_msaa_resolve_blit_via_CB(ctx, &info, false);
} else {
success = false;
}
break;
}
break;
}
}
}
/* Wait for idle after all tests. */
sctx->flags |= SI_CONTEXT_FLUSH_AND_INV_CB |
SI_CONTEXT_CS_PARTIAL_FLUSH |
SI_CONTEXT_INV_L2 | SI_CONTEXT_INV_SCACHE |
SI_CONTEXT_INV_VCACHE;
si_emit_cache_flush_direct(sctx);
ctx->end_query(ctx, q);
pipe_surface_reference(&dst_surf, NULL);
/* Unbind the colorbuffer. */
if ((test_flavor == TEST_FB_CLEAR || test_flavor == TEST_CLEAR) &&
box_flavor == BOX_FULL) {
struct pipe_framebuffer_state fb = {0};
fb.width = 64;
fb.height = 64;
fb.layers = 1;
fb.samples = 1;
ctx->set_framebuffer_state(ctx, &fb);
}
/* Get results. */
if (success) {
union pipe_query_result result;
ctx->get_query_result(ctx, q, true, &result);
ctx->destroy_query(ctx, q);
double sec = (double)result.u64 / (1000 * 1000 * 1000);
uint64_t pixels_per_surf = num_repeats * dst_box.width *
dst_box.height * dst_box.depth;
uint64_t bytes;
if (test_flavor == TEST_FB_CLEAR || test_flavor == TEST_CLEAR)
bytes = pixels_per_surf * pix_size;
else if (test_flavor == TEST_RESOLVE)
bytes = pixels_per_surf * (pix_size + bpe);
else
bytes = pixels_per_surf * pix_size * 2;
double bytes_per_sec = bytes / sec;
printf(" , %9.2f", bytes_per_sec / (1024 * 1024 * 1024));
} else {
printf(" , n/a ");
}
}
}
printf("\n");
}
}
for (unsigned size_factor = 0; size_factor <= 1; size_factor++) {
pipe_resource_reference(&dst[size_factor], NULL);
pipe_resource_reference(&src[size_factor], NULL);
}
}
}
}
}
}
ctx->destroy(ctx);
exit(0);
}