From: Conor McCarthy cmccarthy@codeweavers.com
Based on vkd3d-proton patches by Philip Rebohle and Hans-Kristian Arntzen. --- tests/d3d12.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 2f1c905f2..9f00d74fb 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -36438,6 +36438,280 @@ static void test_vs_ps_relative_addressing(void) destroy_test_context(&context); }
+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); + return (mip_size + tile_size - 1) / tile_size; +} + +static void test_get_resource_tiling(void) +{ + D3D12_SUBRESOURCE_TILING tilings_alt[17]; + D3D12_PACKED_MIP_INFO packed_mip_info; + D3D12_SUBRESOURCE_TILING tilings[17]; + UINT num_resource_tiles, num_tilings; + D3D12_RESOURCE_DESC resource_desc; + struct test_context_desc desc; + struct test_context context; + D3D12_TILE_SHAPE tile_shape; + ID3D12Resource *resource; + unsigned int i, j; + bool no_tier_3; + HRESULT hr; + + static const struct + { + D3D12_RESOURCE_DIMENSION dim; + DXGI_FORMAT format; + UINT width; + UINT height; + UINT depth_or_array_layers; + UINT mip_levels; + UINT expected_tile_count; + UINT expected_tiling_count; + UINT expected_standard_mips; + UINT tile_shape_w; + UINT tile_shape_h; + UINT tile_shape_d; + D3D12_TILED_RESOURCES_TIER min_tier; + bool todo_radv; + } + tests[] = + { + /* Test buffers */ + { D3D12_RESOURCE_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 1024, 1, 1, 1, 1, 1, 0, 65536, 1, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 16*65536, 1, 1, 1, 16, 1, 0, 65536, 1, 1, D3D12_TILED_RESOURCES_TIER_1 }, + /* Test small resource behavior */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 1, 1, 1, 1, 1, 1, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 2, 2, 1, 2, 1, 2, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 4, 4, 1, 3, 1, 3, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 8, 8, 1, 4, 1, 4, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 16, 16, 1, 5, 1, 5, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 32, 32, 1, 6, 1, 6, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 64, 64, 1, 7, 1, 7, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 128, 128, 1, 8, 1, 8, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 256, 256, 1, 9, 2, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + /* Test various image formats */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8_UNORM, 512, 512, 1, 1, 8, 1, 1, 256, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 512, 512, 1, 1, 16, 1, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R16G16B16A16_UNORM, 512, 512, 1, 1, 32, 1, 1, 128, 64, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R32G32B32A32_FLOAT, 512, 512, 1, 1, 64, 1, 1, 64, 64, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_D16_UNORM, 512, 512, 1, 1, 8, 1, 1, 256, 128, 1, D3D12_TILED_RESOURCES_TIER_1, true }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_D32_FLOAT, 512, 512, 1, 1, 16, 1, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1, true }, + /* Test rectangular textures */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 1024, 256, 1, 1, 16, 1, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 256, 1024, 1, 1, 16, 1, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 192, 128, 1, 1, 2, 1, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_2 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 128, 192, 1, 1, 2, 1, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_2 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 320, 192, 1, 1, 6, 1, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_2 }, + /* Test array layers and packed mip levels */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 128, 128, 16, 1, 16, 16, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 128, 128, 1, 8, 1, 8, 1, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 512, 512, 1, 10, 21, 10, 3, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 512, 512, 4, 3, 84, 12, 3, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8G8B8A8_UNORM, 64, 64, 1, 1, 0, 1, 0, 128, 128, 1, D3D12_TILED_RESOURCES_TIER_1 }, + /* Test 3D textures */ + { D3D12_RESOURCE_DIMENSION_TEXTURE3D, DXGI_FORMAT_R8_UNORM, 64, 64, 64, 1, 4, 1, 1, 64, 32, 32, D3D12_TILED_RESOURCES_TIER_3 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE3D, DXGI_FORMAT_R8G8_UNORM, 64, 64, 64, 1, 8, 1, 1, 32, 32, 32, D3D12_TILED_RESOURCES_TIER_3 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE3D, DXGI_FORMAT_R8G8B8A8_UNORM, 64, 64, 64, 1, 16, 1, 1, 32, 32, 16, D3D12_TILED_RESOURCES_TIER_3 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE3D, DXGI_FORMAT_R32G32B32A32_FLOAT, 64, 64, 64, 3, 73, 3, 3, 16, 16, 16, D3D12_TILED_RESOURCES_TIER_3 }, + /* Basic BC configurations. */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 512, 512, 1, 1, 2, 1, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC2_UNORM, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC3_UNORM, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC4_UNORM, 512, 512, 1, 1, 2, 1, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC5_UNORM, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC6H_UF16, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC6H_SF16, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + /* Basic mipmapping with obvious tiling layouts. */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 512, 256, 1, 10, 2, 10, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 1024, 512, 1, 10, 6, 10, 2, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 2048, 1024, 1, 10, 22, 10, 3, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 256, 256, 1, 9, 2, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 512, 512, 1, 9, 6, 9, 2, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 1024, 1024, 1, 9, 22, 9, 3, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + /* Wide shapes. On AMD, we keep observing standard mips even when the smallest dimension dips below the tile size. + * This is not the case on NV however. */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 1024, 256, 1, 10, 3, 10, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 2048, 256, 1, 10, 6, 10, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 4096, 256, 1, 10, 11, 10, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 512, 256, 1, 9, 3, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 1024, 256, 1, 9, 6, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 2048, 256, 1, 9, 11, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + /* Tall shapes. Similar to wide tests. */ + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 512, 512, 1, 10, 3, 10, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 512, 1024, 1, 10, 6, 10, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC1_UNORM, 512, 2048, 1, 10, 11, 10, 1, 512, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 256, 512, 1, 9, 3, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 256, 1024, 1, 9, 6, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_BC7_UNORM, 256, 2048, 1, 9, 11, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 }, + }; + + memset(&desc, 0, sizeof(desc)); + desc.rt_width = 640; + desc.rt_height = 480; + desc.rt_format = DXGI_FORMAT_R8G8B8A8_UNORM; + if (!init_test_context(&context, &desc)) + return; + + /* Test behaviour with various parameter combinations */ + resource_desc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + resource_desc.Alignment = 0; + resource_desc.Width = 512; + resource_desc.Height = 512; + resource_desc.DepthOrArraySize = 1; + resource_desc.MipLevels = 10; + resource_desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + resource_desc.SampleDesc.Count = 1; + resource_desc.SampleDesc.Quality = 0; + resource_desc.Layout = D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; + resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + hr = ID3D12Device_CreateReservedResource(context.device, &resource_desc, + D3D12_RESOURCE_STATE_GENERIC_READ, NULL, &IID_ID3D12Resource, (void **)&resource); + ok(hr == S_OK, "Failed to create reserved resource, hr %#x.\n", hr); + + /* This is nonsense, but it doesn't crash or generate errors. */ + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, NULL, 0, NULL); + + /* If num_tilings is NULL, tilings_alt is ignored. */ + memset(tilings, 0, sizeof(tilings)); + memset(tilings_alt, 0, sizeof(tilings_alt)); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, NULL, 0, tilings_alt); + ok(memcmp(tilings, tilings_alt, sizeof(tilings_alt)) == 0, "Mismatch.\n"); + + num_tilings = 0; + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &num_tilings, 0, NULL); + ok(num_tilings == 0, "Unexpected tiling count %u.\n", num_tilings); + + num_tilings = ARRAY_SIZE(tilings); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &num_tilings, 10, tilings); + todo ok(num_tilings == 0, "Unexpected tiling count %u.\n", num_tilings); + + num_tilings = ARRAY_SIZE(tilings); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &num_tilings, 2, tilings); + todo ok(num_tilings == 8, "Unexpected tiling count %u.\n", num_tilings); + todo ok(tilings[0].StartTileIndexInOverallResource == 20, "Unexpected start tile index %u.\n", tilings[0].StartTileIndexInOverallResource); + + num_tilings = 1; + memset(&tilings, 0xaa, sizeof(tilings)); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &num_tilings, 2, tilings); + ok(num_tilings == 1, "Unexpected tiling count %u.\n", num_tilings); + todo ok(tilings[0].StartTileIndexInOverallResource == 20, "Unexpected start tile index %u.\n", tilings[0].StartTileIndexInOverallResource); + ok(tilings[1].StartTileIndexInOverallResource == 0xaaaaaaaa, "Tiling array got modified.\n"); + + ID3D12Resource_Release(resource); + + /* Tiled tier is not included in feature support yet so as not to break future bisections. */ + no_tier_3 = is_amd_windows_device(context.device) || is_radv_device(context.device); + + /* Test actual tiling properties */ + for (i = 0; i < ARRAY_SIZE(tests); i++, vkd3d_test_pop_context()) + { + unsigned int tile_index = 0; + vkd3d_test_push_context("test %u", i); + + if (no_tier_3 && tests[i].min_tier > D3D12_TILED_RESOURCES_TIER_2) + { + skip("Tiled resources tier %u not supported.\n", tests[i].min_tier); + continue; + } + + memset(&packed_mip_info, 0xaa, sizeof(packed_mip_info)); + memset(&tile_shape, 0xaa, sizeof(tile_shape)); + memset(&tilings, 0xaa, sizeof(tilings)); + + num_resource_tiles = 0xdeadbeef; + num_tilings = ARRAY_SIZE(tilings); + + resource_desc.Dimension = tests[i].dim; + resource_desc.Alignment = 0; + resource_desc.Width = tests[i].width; + resource_desc.Height = tests[i].height; + resource_desc.DepthOrArraySize = tests[i].depth_or_array_layers; + resource_desc.MipLevels = tests[i].mip_levels; + resource_desc.Format = tests[i].format; + resource_desc.SampleDesc.Count = 1; + resource_desc.SampleDesc.Quality = 0; + resource_desc.Layout = D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; + resource_desc.Flags = D3D12_RESOURCE_FLAG_NONE; + + if (tests[i].dim == D3D12_RESOURCE_DIMENSION_BUFFER) + resource_desc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + + hr = ID3D12Device_CreateReservedResource(context.device, &resource_desc, + D3D12_RESOURCE_STATE_GENERIC_READ, NULL, &IID_ID3D12Resource, (void **)&resource); + todo_if(is_radv_device(context.device) && tests[i].todo_radv) + ok(hr == S_OK, "Failed to create reserved resource, hr %#x.\n", hr); + + if (hr != S_OK) + continue; + + ID3D12Device_GetResourceTiling(context.device, resource, &num_resource_tiles, &packed_mip_info, &tile_shape, &num_tilings, 0, tilings); + + todo ok(num_resource_tiles != 0xdeadbeef && num_resource_tiles >= tests[i].expected_tile_count, + "Unexpected resource tile count %u.\n", num_resource_tiles); + todo ok(num_tilings == tests[i].expected_tiling_count, "Unexpected subresource tiling count %u.\n", num_tilings); + + todo ok(packed_mip_info.NumStandardMips != 0xaa && packed_mip_info.NumStandardMips >= tests[i].expected_standard_mips, + "Unexpected standard mip count %u.\n", packed_mip_info.NumStandardMips); + todo ok(packed_mip_info.NumPackedMips == (tests[i].dim == D3D12_RESOURCE_DIMENSION_BUFFER + ? 0 : tests[i].mip_levels - packed_mip_info.NumStandardMips), + "Unexpected packed mip count %u.\n", packed_mip_info.NumPackedMips); + todo ok(packed_mip_info.NumPackedMips != 0xaa + && (packed_mip_info.NumTilesForPackedMips == 0) == (packed_mip_info.NumPackedMips == 0), + "Unexpected packed tile count %u.\n", packed_mip_info.NumTilesForPackedMips); + + /* Docs say that tile shape should be cleared to zero if there is no standard mip, but drivers don't seem to care about this. */ + todo ok(tile_shape.WidthInTexels == tests[i].tile_shape_w, "Unexpected tile width %u.\n", tile_shape.WidthInTexels); + todo ok(tile_shape.HeightInTexels == tests[i].tile_shape_h, "Unexpected tile height %u.\n", tile_shape.HeightInTexels); + todo ok(tile_shape.DepthInTexels == tests[i].tile_shape_d, "Unexpected tile depth %u.\n", tile_shape.DepthInTexels); + + for (j = 0; j < tests[i].expected_tiling_count; j++) + { + uint32_t mip = j % tests[i].mip_levels; + + if (mip < packed_mip_info.NumStandardMips || !packed_mip_info.NumPackedMips) + { + uint32_t expected_w = compute_tile_count(tests[i].width, mip, tests[i].tile_shape_w); + uint32_t expected_h = compute_tile_count(tests[i].height, mip, tests[i].tile_shape_h); + uint32_t expected_d = 1; + + if (tests[i].dim == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + expected_d = compute_tile_count(tests[i].depth_or_array_layers, mip, tests[i].tile_shape_d); + + todo ok(tilings[j].WidthInTiles == expected_w, "Unexpected width %u for subresource %u.\n", tilings[j].WidthInTiles, j); + todo ok(tilings[j].HeightInTiles == expected_h, "Unexpected width %u for subresource %u.\n", tilings[j].HeightInTiles, j); + todo ok(tilings[j].DepthInTiles == expected_d, "Unexpected width %u for subresource %u.\n", tilings[j].DepthInTiles, j); + + todo ok(tilings[j].StartTileIndexInOverallResource == tile_index, "Unexpected start tile index %u for subresource %u.\n", + tilings[j].StartTileIndexInOverallResource, j); + + tile_index += tilings[j].WidthInTiles * tilings[j].HeightInTiles * tilings[j].DepthInTiles; + } + else + { + todo ok(!tilings[j].WidthInTiles && !tilings[j].HeightInTiles && !tilings[j].DepthInTiles, + "Unexpected tile count (%u,%u,%u) for packed subresource %u.\n", + tilings[j].WidthInTiles, tilings[j].HeightInTiles, tilings[j].DepthInTiles, j); + todo ok(tilings[j].StartTileIndexInOverallResource == 0xffffffff, "Unexpected start tile index %u for packed subresource %u.\n", + tilings[j].StartTileIndexInOverallResource, j); + } + } + + todo ok(num_resource_tiles == tile_index + packed_mip_info.NumTilesForPackedMips, + "Unexpected resource tile count %u.\n", num_resource_tiles); + todo ok(packed_mip_info.StartTileIndexInOverallResource == (packed_mip_info.NumPackedMips ? tile_index : 0), + "Unexpected mip tail start tile index %u.\n", packed_mip_info.StartTileIndexInOverallResource); + + ID3D12Resource_Release(resource); + } + + destroy_test_context(&context); +} + START_TEST(d3d12) { parse_args(argc, argv); @@ -36617,4 +36891,5 @@ START_TEST(d3d12) run_test(test_clock_calibration); run_test(test_readback_map_stability); run_test(test_vs_ps_relative_addressing); + run_test(test_get_resource_tiling); }
From: Conor McCarthy cmccarthy@codeweavers.com
--- libs/vkd3d/device.c | 16 +++++- libs/vkd3d/resource.c | 102 +++++++++++++++++++++++++++++++++++-- libs/vkd3d/vkd3d_private.h | 24 +++++++++ tests/d3d12.c | 38 ++++++++------ 4 files changed, 159 insertions(+), 21 deletions(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index b9a8943cc..e98d8ad53 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -3891,12 +3891,24 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling, D3D12_SUBRESOURCE_TILING *sub_resource_tilings) { - FIXME("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " + const struct d3d12_resource *resource_impl = impl_from_ID3D12Resource(resource); + struct d3d12_device *device = impl_from_ID3D12Device(iface); + + TRACE("iface %p, resource %p, total_tile_count %p, packed_mip_info %p, " "standard_title_shape %p, sub_resource_tiling_count %p, " - "first_sub_resource_tiling %u, sub_resource_tilings %p stub!\n", + "first_sub_resource_tiling %u, sub_resource_tilings %p.\n", iface, resource, total_tile_count, packed_mip_info, standard_tile_shape, sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); + + if (d3d12_resource_is_texture(resource_impl)) + { + FIXME("Not implemented for textures.\n"); + return; + } + + d3d12_resource_get_tiling(device, resource_impl, total_tile_count, packed_mip_info, standard_tile_shape, + sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); }
static LUID * STDMETHODCALLTYPE d3d12_device_GetAdapterLuid(ID3D12Device *iface, LUID *luid) diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 4c07d3265..c6110f5e3 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -971,6 +971,11 @@ HRESULT vkd3d_get_image_allocation_info(struct d3d12_device *device, return hr; }
+static void d3d12_resource_tile_info_cleanup(struct d3d12_resource *resource) +{ + vkd3d_free(resource->tiles.subresources); +} + static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12_device *device) { const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; @@ -986,6 +991,8 @@ static void d3d12_resource_destroy(struct d3d12_resource *resource, struct d3d12 else VK_CALL(vkDestroyImage(device->vk_device, resource->u.vk_image, NULL));
+ d3d12_resource_tile_info_cleanup(resource); + if (resource->heap) d3d12_heap_resource_destroyed(resource->heap); } @@ -1057,9 +1064,94 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource, box->back = d3d12_resource_desc_get_depth(&resource->desc, level); }
-static void d3d12_resource_init_tiles(struct d3d12_resource *resource) +void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, + UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, + UINT *subresource_tiling_count, UINT first_subresource_tiling, + D3D12_SUBRESOURCE_TILING *subresource_tilings) { - resource->tiles.subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc); + unsigned int i, subresource, subresource_count, count; + const struct vkd3d_subresource_tile_info *tile_info; + const VkExtent3D *tile_extent; + + tile_extent = &resource->tiles.tile_extent; + + if (packed_mip_info) + { + packed_mip_info->NumStandardMips = resource->tiles.standard_mip_count; + packed_mip_info->NumPackedMips = 0; + packed_mip_info->NumTilesForPackedMips = 0; + packed_mip_info->StartTileIndexInOverallResource = 0; + } + + if (standard_tile_shape) + { + /* D3D12 docs say tile shape is cleared to zero if there is no standard mip, but drivers don't to do this. */ + standard_tile_shape->WidthInTexels = tile_extent->width; + standard_tile_shape->HeightInTexels = tile_extent->height; + standard_tile_shape->DepthInTexels = tile_extent->depth; + } + + if (total_tile_count) + *total_tile_count = resource->tiles.total_count; + + if (!subresource_tiling_count) + return; + + subresource_count = resource->tiles.subresource_count; + + count = subresource_count - min(first_subresource_tiling, subresource_count); + count = min(count, *subresource_tiling_count); + + for (i = 0; i < count; ++i) + { + subresource = i + first_subresource_tiling; + tile_info = &resource->tiles.subresources[subresource]; + subresource_tilings[i].StartTileIndexInOverallResource = tile_info->offset; + subresource_tilings[i].WidthInTiles = tile_info->extent.width; + subresource_tilings[i].HeightInTiles = tile_info->extent.height; + subresource_tilings[i].DepthInTiles = tile_info->extent.depth; + } + *subresource_tiling_count = i; +} + +static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device) +{ + struct vkd3d_subresource_tile_info *tile_info; + unsigned int subresource_count; + + subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc); + + if (!d3d12_resource_is_buffer(resource)) + return true; + + if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources)))) + { + ERR("Failed to allocate subresource info array.\n"); + return false; + } + + if (d3d12_resource_is_buffer(resource)) + { + tile_info = &resource->tiles.subresources[0]; + tile_info->offset = 0; + tile_info->extent.width = align(resource->desc.Width, D3D12_TILE_SIZE) / D3D12_TILE_SIZE; + tile_info->extent.height = 1; + tile_info->extent.depth = 1; + tile_info->count = tile_info->extent.width; + + resource->tiles.tile_extent.width = D3D12_TILE_SIZE; + resource->tiles.tile_extent.height = 1; + resource->tiles.tile_extent.depth = 1; + resource->tiles.total_count = tile_info->extent.width; + resource->tiles.subresource_count = 1; + resource->tiles.standard_mip_count = 1; + } + else + { + vkd3d_unreachable(); + } + + return true; }
/* ID3D12Resource */ @@ -2013,7 +2105,11 @@ HRESULT d3d12_reserved_resource_create(struct d3d12_device *device, desc, initial_state, optimized_clear_value, &object))) return hr;
- d3d12_resource_init_tiles(object); + if (!d3d12_resource_init_tiles(object, device)) + { + d3d12_resource_Release(&object->ID3D12Resource_iface); + return E_OUTOFMEMORY; + }
TRACE("Created reserved resource %p.\n", object);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index c5259420a..644cc9065 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -673,11 +673,31 @@ struct d3d12_heap *unsafe_impl_from_ID3D12Heap(ID3D12Heap *iface); #define VKD3D_RESOURCE_DEDICATED_HEAP 0x00000008 #define VKD3D_RESOURCE_LINEAR_TILING 0x00000010
+struct vkd3d_tiled_region_extent +{ + unsigned int width; + unsigned int height; + unsigned int depth; +}; + +struct vkd3d_subresource_tile_info +{ + unsigned int offset; + unsigned int count; + struct vkd3d_tiled_region_extent extent; +}; + struct d3d12_resource_tile_info { + VkExtent3D tile_extent; + unsigned int total_count; + unsigned int standard_mip_count; unsigned int subresource_count; + struct vkd3d_subresource_tile_info *subresources; };
+#define D3D12_TILE_SIZE 0x10000u + /* ID3D12Resource */ struct d3d12_resource { @@ -728,6 +748,10 @@ static inline bool d3d12_resource_is_texture(const struct d3d12_resource *resour
bool d3d12_resource_is_cpu_accessible(const struct d3d12_resource *resource); HRESULT d3d12_resource_validate_desc(const D3D12_RESOURCE_DESC *desc, struct d3d12_device *device); +void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, + UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, + UINT *sub_resource_tiling_count, UINT first_sub_resource_tiling, + D3D12_SUBRESOURCE_TILING *sub_resource_tilings);
HRESULT d3d12_committed_resource_create(struct d3d12_device *device, const D3D12_HEAP_PROPERTIES *heap_properties, D3D12_HEAP_FLAGS heap_flags, diff --git a/tests/d3d12.c b/tests/d3d12.c index 9f00d74fb..2801ec45a 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -36619,6 +36619,12 @@ static void test_get_resource_tiling(void) continue; }
+ if (tests[i].dim != D3D12_RESOURCE_DIMENSION_BUFFER) + { + skip("Tiled textures not supported.\n"); + continue; + } + memset(&packed_mip_info, 0xaa, sizeof(packed_mip_info)); memset(&tile_shape, 0xaa, sizeof(tile_shape)); memset(&tilings, 0xaa, sizeof(tilings)); @@ -36651,23 +36657,23 @@ static void test_get_resource_tiling(void)
ID3D12Device_GetResourceTiling(context.device, resource, &num_resource_tiles, &packed_mip_info, &tile_shape, &num_tilings, 0, tilings);
- todo ok(num_resource_tiles != 0xdeadbeef && num_resource_tiles >= tests[i].expected_tile_count, + ok(num_resource_tiles != 0xdeadbeef && num_resource_tiles >= tests[i].expected_tile_count, "Unexpected resource tile count %u.\n", num_resource_tiles); - todo ok(num_tilings == tests[i].expected_tiling_count, "Unexpected subresource tiling count %u.\n", num_tilings); + ok(num_tilings == tests[i].expected_tiling_count, "Unexpected subresource tiling count %u.\n", num_tilings);
- todo ok(packed_mip_info.NumStandardMips != 0xaa && packed_mip_info.NumStandardMips >= tests[i].expected_standard_mips, + ok(packed_mip_info.NumStandardMips != 0xaa && packed_mip_info.NumStandardMips >= tests[i].expected_standard_mips, "Unexpected standard mip count %u.\n", packed_mip_info.NumStandardMips); - todo ok(packed_mip_info.NumPackedMips == (tests[i].dim == D3D12_RESOURCE_DIMENSION_BUFFER + ok(packed_mip_info.NumPackedMips == (tests[i].dim == D3D12_RESOURCE_DIMENSION_BUFFER ? 0 : tests[i].mip_levels - packed_mip_info.NumStandardMips), "Unexpected packed mip count %u.\n", packed_mip_info.NumPackedMips); - todo ok(packed_mip_info.NumPackedMips != 0xaa + ok(packed_mip_info.NumPackedMips != 0xaa && (packed_mip_info.NumTilesForPackedMips == 0) == (packed_mip_info.NumPackedMips == 0), "Unexpected packed tile count %u.\n", packed_mip_info.NumTilesForPackedMips);
/* Docs say that tile shape should be cleared to zero if there is no standard mip, but drivers don't seem to care about this. */ - todo ok(tile_shape.WidthInTexels == tests[i].tile_shape_w, "Unexpected tile width %u.\n", tile_shape.WidthInTexels); - todo ok(tile_shape.HeightInTexels == tests[i].tile_shape_h, "Unexpected tile height %u.\n", tile_shape.HeightInTexels); - todo ok(tile_shape.DepthInTexels == tests[i].tile_shape_d, "Unexpected tile depth %u.\n", tile_shape.DepthInTexels); + ok(tile_shape.WidthInTexels == tests[i].tile_shape_w, "Unexpected tile width %u.\n", tile_shape.WidthInTexels); + ok(tile_shape.HeightInTexels == tests[i].tile_shape_h, "Unexpected tile height %u.\n", tile_shape.HeightInTexels); + ok(tile_shape.DepthInTexels == tests[i].tile_shape_d, "Unexpected tile depth %u.\n", tile_shape.DepthInTexels);
for (j = 0; j < tests[i].expected_tiling_count; j++) { @@ -36682,28 +36688,28 @@ static void test_get_resource_tiling(void) if (tests[i].dim == D3D12_RESOURCE_DIMENSION_TEXTURE3D) expected_d = compute_tile_count(tests[i].depth_or_array_layers, mip, tests[i].tile_shape_d);
- todo ok(tilings[j].WidthInTiles == expected_w, "Unexpected width %u for subresource %u.\n", tilings[j].WidthInTiles, j); - todo ok(tilings[j].HeightInTiles == expected_h, "Unexpected width %u for subresource %u.\n", tilings[j].HeightInTiles, j); - todo ok(tilings[j].DepthInTiles == expected_d, "Unexpected width %u for subresource %u.\n", tilings[j].DepthInTiles, j); + ok(tilings[j].WidthInTiles == expected_w, "Unexpected width %u for subresource %u.\n", tilings[j].WidthInTiles, j); + ok(tilings[j].HeightInTiles == expected_h, "Unexpected width %u for subresource %u.\n", tilings[j].HeightInTiles, j); + ok(tilings[j].DepthInTiles == expected_d, "Unexpected width %u for subresource %u.\n", tilings[j].DepthInTiles, j);
- todo ok(tilings[j].StartTileIndexInOverallResource == tile_index, "Unexpected start tile index %u for subresource %u.\n", + ok(tilings[j].StartTileIndexInOverallResource == tile_index, "Unexpected start tile index %u for subresource %u.\n", tilings[j].StartTileIndexInOverallResource, j);
tile_index += tilings[j].WidthInTiles * tilings[j].HeightInTiles * tilings[j].DepthInTiles; } else { - todo ok(!tilings[j].WidthInTiles && !tilings[j].HeightInTiles && !tilings[j].DepthInTiles, + ok(!tilings[j].WidthInTiles && !tilings[j].HeightInTiles && !tilings[j].DepthInTiles, "Unexpected tile count (%u,%u,%u) for packed subresource %u.\n", tilings[j].WidthInTiles, tilings[j].HeightInTiles, tilings[j].DepthInTiles, j); - todo ok(tilings[j].StartTileIndexInOverallResource == 0xffffffff, "Unexpected start tile index %u for packed subresource %u.\n", + ok(tilings[j].StartTileIndexInOverallResource == 0xffffffff, "Unexpected start tile index %u for packed subresource %u.\n", tilings[j].StartTileIndexInOverallResource, j); } }
- todo ok(num_resource_tiles == tile_index + packed_mip_info.NumTilesForPackedMips, + ok(num_resource_tiles == tile_index + packed_mip_info.NumTilesForPackedMips, "Unexpected resource tile count %u.\n", num_resource_tiles); - todo ok(packed_mip_info.StartTileIndexInOverallResource == (packed_mip_info.NumPackedMips ? tile_index : 0), + ok(packed_mip_info.StartTileIndexInOverallResource == (packed_mip_info.NumPackedMips ? tile_index : 0), "Unexpected mip tail start tile index %u.\n", packed_mip_info.StartTileIndexInOverallResource);
ID3D12Resource_Release(resource);
From: Conor McCarthy cmccarthy@codeweavers.com
--- include/vkd3d_d3d12.idl | 1 + libs/vkd3d/device.c | 6 --- libs/vkd3d/resource.c | 90 ++++++++++++++++++++++++++++++++++---- libs/vkd3d/vkd3d_private.h | 1 + tests/d3d12.c | 14 ++---- 5 files changed, 87 insertions(+), 25 deletions(-)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 06287f5a8..495a04678 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -75,6 +75,7 @@ const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512; const UINT D3D12_UAV_COUNTER_PLACEMENT_ALIGNMENT = 4096; const UINT D3D12_VS_INPUT_REGISTER_COUNT = 32; const UINT D3D12_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE = 16; +const UINT D3D12_PACKED_TILE = 0xffffffff;
cpp_quote("#endif")
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index e98d8ad53..d461256be 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -3901,12 +3901,6 @@ static void STDMETHODCALLTYPE d3d12_device_GetResourceTiling(ID3D12Device *iface sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings);
- if (d3d12_resource_is_texture(resource_impl)) - { - FIXME("Not implemented for textures.\n"); - return; - } - d3d12_resource_get_tiling(device, resource_impl, total_tile_count, packed_mip_info, standard_tile_shape, sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings); } diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index c6110f5e3..3810feb7b 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1064,12 +1064,26 @@ static void d3d12_resource_get_level_box(const struct d3d12_resource *resource, box->back = d3d12_resource_desc_get_depth(&resource->desc, level); }
+static void compute_image_subresource_size_in_tiles(const VkExtent3D *tile_extent, + const struct D3D12_RESOURCE_DESC *desc, unsigned int miplevel_idx, + struct vkd3d_tiled_region_extent *size) +{ + unsigned int width, height, depth; + + width = d3d12_resource_desc_get_width(desc, miplevel_idx); + height = d3d12_resource_desc_get_height(desc, miplevel_idx); + depth = d3d12_resource_desc_get_depth(desc, miplevel_idx); + size->width = (width + tile_extent->width - 1) / tile_extent->width; + size->height = (height + tile_extent->height - 1) / tile_extent->height; + size->depth = (depth + tile_extent->depth - 1) / tile_extent->depth; +} + void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_resource *resource, UINT *total_tile_count, D3D12_PACKED_MIP_INFO *packed_mip_info, D3D12_TILE_SHAPE *standard_tile_shape, UINT *subresource_tiling_count, UINT first_subresource_tiling, D3D12_SUBRESOURCE_TILING *subresource_tilings) { - unsigned int i, subresource, subresource_count, count; + unsigned int i, subresource, subresource_count, miplevel_idx, count; const struct vkd3d_subresource_tile_info *tile_info; const VkExtent3D *tile_extent;
@@ -1078,9 +1092,10 @@ void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_r if (packed_mip_info) { packed_mip_info->NumStandardMips = resource->tiles.standard_mip_count; - packed_mip_info->NumPackedMips = 0; - packed_mip_info->NumTilesForPackedMips = 0; - packed_mip_info->StartTileIndexInOverallResource = 0; + packed_mip_info->NumPackedMips = resource->desc.MipLevels - packed_mip_info->NumStandardMips; + packed_mip_info->NumTilesForPackedMips = !!resource->tiles.packed_mip_tile_count; /* non-zero dummy value */ + packed_mip_info->StartTileIndexInOverallResource = packed_mip_info->NumPackedMips + ? resource->tiles.subresources[resource->tiles.standard_mip_count].offset : 0; }
if (standard_tile_shape) @@ -1105,6 +1120,14 @@ void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_r for (i = 0; i < count; ++i) { subresource = i + first_subresource_tiling; + miplevel_idx = subresource % resource->desc.MipLevels; + if (miplevel_idx >= resource->tiles.standard_mip_count) + { + memset(&subresource_tilings[i], 0, sizeof(subresource_tilings[i])); + subresource_tilings[i].StartTileIndexInOverallResource = D3D12_PACKED_TILE; + continue; + } + tile_info = &resource->tiles.subresources[subresource]; subresource_tilings[i].StartTileIndexInOverallResource = tile_info->offset; subresource_tilings[i].WidthInTiles = tile_info->extent.width; @@ -1116,14 +1139,17 @@ void d3d12_resource_get_tiling(struct d3d12_device *device, const struct d3d12_r
static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device) { + unsigned int i, start_idx, subresource_count, tile_count, miplevel_idx; + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + VkSparseImageMemoryRequirements sparse_requirements_buf[3]; + VkSparseImageMemoryRequirements sparse_requirements; struct vkd3d_subresource_tile_info *tile_info; - unsigned int subresource_count; + VkMemoryRequirements requirements; + const VkExtent3D *tile_extent; + uint32_t requirement_count;
subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
- if (!d3d12_resource_is_buffer(resource)) - return true; - if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources)))) { ERR("Failed to allocate subresource info array.\n"); @@ -1145,10 +1171,56 @@ static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3 resource->tiles.total_count = tile_info->extent.width; resource->tiles.subresource_count = 1; resource->tiles.standard_mip_count = 1; + resource->tiles.packed_mip_tile_count = 0; } else { - vkd3d_unreachable(); + VK_CALL(vkGetImageMemoryRequirements(device->vk_device, resource->u.vk_image, &requirements)); + if (requirements.alignment > D3D12_TILE_SIZE) + FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n"); + + requirement_count = ARRAY_SIZE(sparse_requirements_buf); + VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image, + &requirement_count, sparse_requirements_buf)); + for (i = 0; i < requirement_count; ++i) + { + if (!(sparse_requirements_buf[i].formatProperties.aspectMask & VK_IMAGE_ASPECT_METADATA_BIT)) + { + sparse_requirements = sparse_requirements_buf[i]; + break; + } + } + + resource->tiles.tile_extent = sparse_requirements.formatProperties.imageGranularity; + resource->tiles.subresource_count = subresource_count; + resource->tiles.standard_mip_count = sparse_requirements.imageMipTailSize + ? sparse_requirements.imageMipTailFirstLod : resource->desc.MipLevels; + resource->tiles.packed_mip_tile_count = (resource->tiles.standard_mip_count < resource->desc.MipLevels) + ? sparse_requirements.imageMipTailSize / requirements.alignment : 0; + + for (i = 0, start_idx = 0; i < subresource_count; ++i) + { + miplevel_idx = i % resource->desc.MipLevels; + + tile_extent = &sparse_requirements.formatProperties.imageGranularity; + tile_info = &resource->tiles.subresources[i]; + compute_image_subresource_size_in_tiles(tile_extent, &resource->desc, miplevel_idx, &tile_info->extent); + tile_info->offset = start_idx; + tile_info->count = 0; + + if (miplevel_idx < resource->tiles.standard_mip_count) + { + tile_count = tile_info->extent.width * tile_info->extent.height * tile_info->extent.depth; + start_idx += tile_count; + tile_info->count = tile_count; + } + else if (miplevel_idx == resource->tiles.standard_mip_count) + { + tile_info->count = 1; /* Non-zero dummy value */ + start_idx += 1; + } + } + resource->tiles.total_count = start_idx; }
return true; diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h index 644cc9065..0cf7c11fe 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -692,6 +692,7 @@ struct d3d12_resource_tile_info VkExtent3D tile_extent; unsigned int total_count; unsigned int standard_mip_count; + unsigned int packed_mip_tile_count; unsigned int subresource_count; struct vkd3d_subresource_tile_info *subresources; }; diff --git a/tests/d3d12.c b/tests/d3d12.c index 2801ec45a..6db1a79d0 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -36588,18 +36588,18 @@ static void test_get_resource_tiling(void)
num_tilings = ARRAY_SIZE(tilings); ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &num_tilings, 10, tilings); - todo ok(num_tilings == 0, "Unexpected tiling count %u.\n", num_tilings); + ok(num_tilings == 0, "Unexpected tiling count %u.\n", num_tilings);
num_tilings = ARRAY_SIZE(tilings); ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &num_tilings, 2, tilings); - todo ok(num_tilings == 8, "Unexpected tiling count %u.\n", num_tilings); - todo ok(tilings[0].StartTileIndexInOverallResource == 20, "Unexpected start tile index %u.\n", tilings[0].StartTileIndexInOverallResource); + ok(num_tilings == 8, "Unexpected tiling count %u.\n", num_tilings); + ok(tilings[0].StartTileIndexInOverallResource == 20, "Unexpected start tile index %u.\n", tilings[0].StartTileIndexInOverallResource);
num_tilings = 1; memset(&tilings, 0xaa, sizeof(tilings)); ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &num_tilings, 2, tilings); ok(num_tilings == 1, "Unexpected tiling count %u.\n", num_tilings); - todo ok(tilings[0].StartTileIndexInOverallResource == 20, "Unexpected start tile index %u.\n", tilings[0].StartTileIndexInOverallResource); + ok(tilings[0].StartTileIndexInOverallResource == 20, "Unexpected start tile index %u.\n", tilings[0].StartTileIndexInOverallResource); ok(tilings[1].StartTileIndexInOverallResource == 0xaaaaaaaa, "Tiling array got modified.\n");
ID3D12Resource_Release(resource); @@ -36619,12 +36619,6 @@ static void test_get_resource_tiling(void) continue; }
- if (tests[i].dim != D3D12_RESOURCE_DIMENSION_BUFFER) - { - skip("Tiled textures not supported.\n"); - continue; - } - memset(&packed_mip_info, 0xaa, sizeof(packed_mip_info)); memset(&tile_shape, 0xaa, sizeof(tile_shape)); memset(&tilings, 0xaa, sizeof(tilings));
+ D3D12_SUBRESOURCE_TILING tilings_alt[17]; + D3D12_PACKED_MIP_INFO packed_mip_info; + D3D12_SUBRESOURCE_TILING tilings[17]; + UINT num_resource_tiles, num_tilings;
17 is a bit of a magic constant. The usual naming convention for "num_resource_tiles" and "num_tilings" would be "resource_tile_count" and "tiling_count".
+ { D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM,»··· 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
Stray tab above.
+ /* If num_tilings is NULL, tilings_alt is ignored. */ + memset(tilings, 0, sizeof(tilings)); + memset(tilings_alt, 0, sizeof(tilings_alt)); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, NULL, 0, tilings_alt); + ok(memcmp(tilings, tilings_alt, sizeof(tilings_alt)) == 0, "Mismatch.\n");
It seems like we don't really need "tilings_alt". I'm also not sure what the test really proves; if we wanted to prove that the ID3D12Device_GetResourceTiling() call doesn't touch "tilings_alt" above, it would seem more useful to initialise it with something other than zeroes.
+ /* Tiled tier is not included in feature support yet so as not to break future bisections. */ + no_tier_3 = is_amd_windows_device(context.device) || is_radv_device(context.device);
I'm not quite sure what issue this is trying to solve, but this doesn't seem quite proper.
+ if (d3d12_resource_is_texture(resource_impl)) + { + FIXME("Not implemented for textures.\n"); + return; + } + + d3d12_resource_get_tiling(device, resource_impl, total_tile_count, packed_mip_info, standard_tile_shape, + sub_resource_tiling_count, first_sub_resource_tiling, sub_resource_tilings);
Any reason we couldn't check the resource type in d3d12_resource_get_tiling()?
+static bool d3d12_resource_init_tiles(struct d3d12_resource *resource, struct d3d12_device *device) +{ + struct vkd3d_subresource_tile_info *tile_info; + unsigned int subresource_count; + + subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc); + + if (!d3d12_resource_is_buffer(resource)) + return true; + + if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources)))) + { + ERR("Failed to allocate subresource info array.\n"); + return false; + } + + if (d3d12_resource_is_buffer(resource)) + { + tile_info = &resource->tiles.subresources[0]; + tile_info->offset = 0; + tile_info->extent.width = align(resource->desc.Width, D3D12_TILE_SIZE) / D3D12_TILE_SIZE; + tile_info->extent.height = 1; + tile_info->extent.depth = 1; + tile_info->count = tile_info->extent.width; + + resource->tiles.tile_extent.width = D3D12_TILE_SIZE; + resource->tiles.tile_extent.height = 1; + resource->tiles.tile_extent.depth = 1; + resource->tiles.total_count = tile_info->extent.width; + resource->tiles.subresource_count = 1; + resource->tiles.standard_mip_count = 1; + } + else + { + vkd3d_unreachable(); + } + + return true; }
The structure here seems odd. We don't need the first "if (!d3d12_resource_is_buffer(resource))" check if we just move the vkd3d_calloc() call into the "if (d3d12_resource_is_buffer(resource))" block, and the else block is just superfluous.
@@ -36619,6 +36619,12 @@ static void test_get_resource_tiling(void) continue; } + if (tests[i].dim != D3D12_RESOURCE_DIMENSION_BUFFER) + { + skip("Tiled textures not supported.\n"); + continue; + }
Ideally we'd just use todo_if() instead of skip(); skip() is intended for functionality that may legitimately be missing, while insufficiencies in vkd3d should be marked with todo.
I'm not quite sure what issue this is trying to solve, but this doesn't seem quite proper.
If we return nonzero in feature option TiledResourcesTier before support is complete, it will break games which use tiled resources only if they are supported, so it is still set to zero. When the tests are complete they will check the tiled tier, but in this patch series that would result in the new tests not running at all. I don't see a tidy solution to this. Perhaps letting it skip the tests is the best option.
I'm not quite sure what issue this is trying to solve, but this doesn't seem quite proper.
If we return nonzero in feature option TiledResourcesTier before support is complete, it will break games which use tiled resources only if they are supported, so it is still set to zero. When the tests are complete they will check the tiled tier, but in this patch series that would result in the new tests not running at all. I don't see a tidy solution to this. Perhaps letting it skip the tests is the best option.
Yeah, I think we should just check TiledResourcesTier against "min_tier" and skip these on vkd3d until we return something non-zero. Even if we were to hack something temporary together for running the test on vkd3d, we should still do the right thing when running the test on Windows, and currently this doesn't.
Evan Tang (@etang-cw) commented about tests/d3d12.c:
- {
/* Test buffers */
{ D3D12_RESOURCE_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 1024, 1, 1, 1, 1, 1, 0, 65536, 1, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_BUFFER, DXGI_FORMAT_UNKNOWN, 16*65536, 1, 1, 1, 16, 1, 0, 65536, 1, 1, D3D12_TILED_RESOURCES_TIER_1 },
/* Test small resource behavior */
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 1, 1, 1, 1, 1, 1, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 2, 2, 1, 2, 1, 2, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 4, 4, 1, 3, 1, 3, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 8, 8, 1, 4, 1, 4, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 16, 16, 1, 5, 1, 5, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 32, 32, 1, 6, 1, 6, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 64, 64, 1, 7, 1, 7, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 128, 128, 1, 8, 1, 8, 0, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 256, 256, 1, 9, 2, 9, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
/* Test various image formats */
{ D3D12_RESOURCE_DIMENSION_TEXTURE2D, DXGI_FORMAT_R8_UNORM, 512, 512, 1, 1, 4, 1, 1, 256, 256, 1, D3D12_TILED_RESOURCES_TIER_1 },
Left a tab in here
Looks good aside from some minor formatting things