Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: Add stress test for mapping / zero mapping. #2216

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 184 additions & 2 deletions tests/d3d12_sparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#define VKD3D_DBG_CHANNEL VKD3D_DBG_CHANNEL_API
#include "d3d12_crosstest.h"

#define TILE_SIZE 65536

static uint32_t compute_tile_count(uint32_t resource_size, uint32_t mip, uint32_t tile_size)
{
uint32_t mip_size = max(resource_size >> mip, 1u);
Expand Down Expand Up @@ -323,6 +325,188 @@ static void set_region_size(D3D12_TILE_REGION_SIZE *region, uint32_t num_tiles,
region->Depth = d;
}

void test_update_tile_mappings_remap_stress(void)
{
D3D12_FEATURE_DATA_D3D12_OPTIONS options;
D3D12_ROOT_SIGNATURE_DESC rs_desc;
D3D12_ROOT_PARAMETER rs_params[2];
D3D12_RESOURCE_DESC resource_desc;
D3D12_HEAP_PROPERTIES heap_props;
ID3D12Resource *output_resource;
struct test_context_desc desc;
struct test_context context;
struct resource_readback rb;
D3D12_HEAP_DESC heap_desc;
ID3D12Resource *resource;
unsigned int i, j, iter;
ID3D12Heap *heap = NULL;
HRESULT hr;

#include "shaders/sparse/headers/update_tile_mappings.h"

memset(&desc, 0, sizeof(desc));
desc.no_render_target = true;
desc.no_pipeline = true;
desc.no_root_signature = true;
if (!init_test_context(&context, &desc))
return;

hr = ID3D12Device_CheckFeatureSupport(context.device, D3D12_FEATURE_D3D12_OPTIONS, &options, sizeof(options));
ok(hr == S_OK, "Failed to check feature support, hr %#x.\n", hr);

if (!options.TiledResourcesTier)
{
skip("Tiled resources not supported by device.\n");
destroy_test_context(&context);
return;
}

memset(&heap_props, 0, sizeof(heap_props));
heap_props.Type = D3D12_HEAP_TYPE_DEFAULT;

heap_desc.Properties = heap_props;
heap_desc.Alignment = 0;
heap_desc.SizeInBytes = 64 * TILE_SIZE;
heap_desc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;

resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
resource_desc.Alignment = 0;
resource_desc.Width = 64 * TILE_SIZE;
resource_desc.Height = 1;
resource_desc.DepthOrArraySize = 1;
resource_desc.MipLevels = 1;
resource_desc.Format = DXGI_FORMAT_UNKNOWN;
resource_desc.SampleDesc.Count = 1;
resource_desc.SampleDesc.Quality = 0;
resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
resource_desc.Flags = 0;

hr = ID3D12Device_CreateReservedResource(context.device, &resource_desc,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, NULL, &IID_ID3D12Resource, (void **)&resource);
ok(hr == S_OK, "Failed to create reserved buffer, hr %#x.\n", hr);

output_resource = create_default_buffer(context.device, 64 * sizeof(uint32_t),
D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);

memset(rs_params, 0, sizeof(rs_params));
memset(&rs_desc, 0, sizeof(rs_desc));
rs_desc.NumParameters = ARRAY_SIZE(rs_params);
rs_desc.pParameters = rs_params;
rs_params[0].ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV;
rs_params[1].ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV;
create_root_signature(context.device, &rs_desc, &context.root_signature);

context.pipeline_state = create_compute_pipeline_state(
context.device, context.root_signature, update_tile_mappings_dxbc);

for (iter = 0; iter < 100; iter++)
{
D3D12_TILE_REGION_SIZE resource_tile_region_size;
D3D12_TILED_RESOURCE_COORDINATE resource_coord;
D3D12_TILE_RANGE_FLAGS heap_range_flags;
ID3D12Resource *placed_resource;
ID3D12Resource *upload;
UINT heap_tile_offset;
uint32_t *upload_data;
UINT heap_tile_count;
ID3D12Heap *new_heap;

const struct mappings
{
UINT resource_tile;
UINT heap_tile;
UINT count;
D3D12_TILE_RANGE_FLAGS flags;
} mappings[] = {
{ 0, 0, 64, D3D12_TILE_RANGE_FLAG_NULL },
{ 4 + (iter & 31), 8 + (iter & 1), 3, D3D12_TILE_RANGE_FLAG_NONE },
{ 1 + (iter & 14), 2 + (iter & 4), 40, D3D12_TILE_RANGE_FLAG_NONE },
{ 13 + (iter & 9), 0, 9, D3D12_TILE_RANGE_FLAG_NULL },
{ 13 + (iter & 7), 19 + (iter & 4), 8, D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE },
{ 30 + (iter & 5), 0, 7, D3D12_TILE_RANGE_FLAG_NULL },
{ 1 + (iter & 3), 0, 7, D3D12_TILE_RANGE_FLAG_NULL },
};

hr = ID3D12Device_CreateHeap(context.device, &heap_desc, &IID_ID3D12Heap, (void **)&new_heap);
ok(hr == S_OK, "Failed to create heap, hr %#x.\n", hr);

hr = ID3D12Device_CreatePlacedResource(context.device, new_heap, 0, &resource_desc,
D3D12_RESOURCE_STATE_COMMON, NULL, &IID_ID3D12Resource, (void **)&placed_resource);
ok(SUCCEEDED(hr), "Failed to create resource, hr #%x.\n", hr);

/* Destroy the old heap while it has mappings to the heap, then rebind those pages. Should not explode. */
if (heap)
ID3D12Heap_Release(heap);
heap = new_heap;

upload_data = malloc(resource_desc.Width);
for (i = 0; i < resource_desc.Width / 4; i++)
upload_data[i] = i + 1;
upload = create_upload_buffer(context.device, resource_desc.Width, upload_data);
ID3D12GraphicsCommandList_CopyResource(context.list, placed_resource, upload);
ID3D12GraphicsCommandList_Close(context.list);
exec_command_list(context.queue, context.list);
ID3D12GraphicsCommandList_Reset(context.list, context.allocator, NULL);
free(upload_data);

for (i = 0; i < ARRAY_SIZE(mappings); i++)
{
memset(&resource_coord, 0, sizeof(resource_coord));
memset(&resource_tile_region_size, 0, sizeof(resource_tile_region_size));
resource_coord.X = mappings[i].resource_tile;
resource_tile_region_size.NumTiles = mappings[i].count;
resource_tile_region_size.UseBox = FALSE;
heap_range_flags = mappings[i].flags;
heap_tile_offset = mappings[i].heap_tile;
heap_tile_count = mappings[i].count;

ID3D12CommandQueue_UpdateTileMappings(context.queue, resource,
1, &resource_coord, &resource_tile_region_size, heap, 1,
&heap_range_flags, &heap_tile_offset, &heap_tile_count, D3D12_TILE_MAPPING_FLAG_NONE);
}

#define OFFSET_INTO_PAGE 50000

ID3D12GraphicsCommandList_SetComputeRootSignature(context.list, context.root_signature);
ID3D12GraphicsCommandList_SetPipelineState(context.list, context.pipeline_state);
ID3D12GraphicsCommandList_SetComputeRootShaderResourceView(context.list, 0,
ID3D12Resource_GetGPUVirtualAddress(resource) + OFFSET_INTO_PAGE);
ID3D12GraphicsCommandList_SetComputeRootUnorderedAccessView(context.list, 1,
ID3D12Resource_GetGPUVirtualAddress(output_resource));
ID3D12GraphicsCommandList_Dispatch(context.list, 1, 1, 1);
transition_resource_state(context.list, output_resource, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
D3D12_RESOURCE_STATE_COPY_SOURCE);
get_buffer_readback_with_command_list(output_resource, DXGI_FORMAT_R32_UINT, &rb, context.queue, context.list);
reset_command_list(context.list, context.allocator);
for (i = 0; i < 64; i++)
{
uint32_t expected = 0;
for (j = 0; j < ARRAY_SIZE(mappings); j++)
{
if (i >= mappings[j].resource_tile && i < mappings[j].resource_tile + mappings[j].count)
{
if (mappings[j].flags == D3D12_TILE_RANGE_FLAG_NULL)
expected = 0;
else if (mappings[j].flags == D3D12_TILE_RANGE_FLAG_REUSE_SINGLE_TILE)
expected = mappings[j].heap_tile * TILE_SIZE / 4 + OFFSET_INTO_PAGE / 4 + 1;
else
expected = (mappings[j].heap_tile + (i - mappings[j].resource_tile)) * TILE_SIZE / 4 + OFFSET_INTO_PAGE / 4 + 1;
}
}
ok(expected == get_readback_uint(&rb, i, 0, 0),
"Iter %u: value %u: Expected %u, got %u.\n", iter, i, expected, get_readback_uint(&rb, i, 0, 0));
}
release_resource_readback(&rb);
ID3D12Resource_Release(placed_resource);
ID3D12Resource_Release(upload);
}

ID3D12Resource_Release(resource);
ID3D12Resource_Release(output_resource);
ID3D12Heap_Release(heap);
destroy_test_context(&context);
}

void test_update_tile_mappings(void)
{
D3D12_TILED_RESOURCE_COORDINATE region_offsets[8];
Expand Down Expand Up @@ -1008,7 +1192,6 @@ void test_update_tile_mappings(void)

void test_copy_tiles(void)
{
#define TILE_SIZE 65536
ID3D12Resource *tiled_resource, *dst_buffer, *src_buffer;
D3D12_TILED_RESOURCE_COORDINATE region_offset;
D3D12_FEATURE_DATA_D3D12_OPTIONS options;
Expand Down Expand Up @@ -1859,7 +2042,6 @@ static void test_texture_feedback_instructions(bool use_dxil)
ID3D12Resource_Release(residency_rt);
ID3D12RootSignature_Release(root_signature);
destroy_test_context(&context);
#undef TILE_SIZE
}

void test_texture_feedback_instructions_sm51(void)
Expand Down
1 change: 1 addition & 0 deletions tests/d3d12_tests.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ decl_test(test_stencil_export_dxil);
decl_test(test_raytracing);
decl_test(test_get_resource_tiling);
decl_test(test_update_tile_mappings);
decl_test(test_update_tile_mappings_remap_stress);
decl_test(test_sampler_border_color);
decl_test(test_copy_tiles);
decl_test(test_buffer_feedback_instructions_sm51);
Expand Down