-- v5: vkd3d: Implement ID3D12Device::GetResourceTiling() for textures. vkd3d: Implement ID3D12Device::GetResourceTiling() for buffers.
From: Conor McCarthy cmccarthy@codeweavers.com
Based on vkd3d-proton patches by Philip Rebohle and Hans-Kristian Arntzen. --- tests/d3d12.c | 279 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+)
diff --git a/tests/d3d12.c b/tests/d3d12.c index 2f1c905f2..e2dcbde69 100644 --- a/tests/d3d12.c +++ b/tests/d3d12.c @@ -36438,6 +36438,284 @@ 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) +{ + UINT resource_tile_count, tilings_count; + D3D12_TILED_RESOURCES_TIER tiled_tier; + D3D12_PACKED_MIP_INFO packed_mip_info; + D3D12_SUBRESOURCE_TILING tilings[64]; + 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; + 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 }, + }; + static const D3D12_SUBRESOURCE_TILING uninit_tiling = {0xdeadbeef, 0xdead, 0xbeef, 0xdeadbeef}; + + 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; + + if ((tiled_tier = get_tiled_resources_tier(context.device)) < D3D12_TILED_RESOURCES_TIER_1) + { + skip("Tiled resources not supported by device.\n"); + destroy_test_context(&context); + 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 tilings_count is NULL, tilings is ignored. */ + tilings[0] = uninit_tiling; + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, NULL, 0, tilings); + ok(!memcmp(&tilings[0], &uninit_tiling, sizeof(uninit_tiling)), "Mismatch.\n"); + + tilings_count = 0; + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &tilings_count, 0, NULL); + ok(tilings_count == 0, "Unexpected tiling count %u.\n", tilings_count); + + tilings_count = ARRAY_SIZE(tilings); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &tilings_count, 10, tilings); + ok(tilings_count == 0, "Unexpected tiling count %u.\n", tilings_count); + + tilings_count = ARRAY_SIZE(tilings); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &tilings_count, 2, tilings); + ok(tilings_count == 8, "Unexpected tiling count %u.\n", tilings_count); + ok(tilings[0].StartTileIndexInOverallResource == 20, "Unexpected start tile index %u.\n", tilings[0].StartTileIndexInOverallResource); + + tilings_count = 1; + memset(&tilings, 0xaa, sizeof(tilings)); + ID3D12Device_GetResourceTiling(context.device, resource, NULL, NULL, NULL, &tilings_count, 2, tilings); + ok(tilings_count == 1, "Unexpected tiling count %u.\n", tilings_count); + 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); + + /* 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 (tests[i].min_tier > tiled_tier) + { + 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)); + + resource_tile_count = 0xdeadbeef; + tilings_count = 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, &resource_tile_count, &packed_mip_info, &tile_shape, &tilings_count, 0, tilings); + assert(tilings_count <= ARRAY_SIZE(tilings)); + + ok(resource_tile_count != 0xdeadbeef && resource_tile_count >= tests[i].expected_tile_count, + "Unexpected resource tile count %u.\n", resource_tile_count); + ok(tilings_count == tests[i].expected_tiling_count, "Unexpected subresource tiling count %u.\n", tilings_count); + + 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); + 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); + 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. */ + 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++) + { + 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); + + 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); + + 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 + { + 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); + ok(tilings[j].StartTileIndexInOverallResource == 0xffffffff, "Unexpected start tile index %u for packed subresource %u.\n", + tilings[j].StartTileIndexInOverallResource, j); + } + } + + ok(resource_tile_count == tile_index + packed_mip_info.NumTilesForPackedMips, + "Unexpected resource tile count %u.\n", resource_tile_count); + 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 +36895,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
--- include/vkd3d_d3d12.idl | 1 + libs/vkd3d/device.c | 10 +++- libs/vkd3d/resource.c | 109 ++++++++++++++++++++++++++++++++++++- libs/vkd3d/vkd3d_private.h | 22 ++++++++ 4 files changed, 137 insertions(+), 5 deletions(-)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 06287f5a8..9af75f402 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -72,6 +72,7 @@ const UINT D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT = 4096; const UINT D3D12_STANDARD_MAXIMUM_ELEMENT_ALIGNMENT_BYTE_MULTIPLE = 4; const UINT D3D12_TEXTURE_DATA_PITCH_ALIGNMENT = 256; const UINT D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT = 512; +const UINT D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES = 65536; 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; diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c index b9a8943cc..d461256be 100644 --- a/libs/vkd3d/device.c +++ b/libs/vkd3d/device.c @@ -3891,12 +3891,18 @@ 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); + + 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..07a74e0b4 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,101 @@ 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; + + if (d3d12_resource_is_texture(resource)) + { + FIXME("Not implemented for textures.\n"); + return; + } + + 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) +{ + const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs; + struct vkd3d_subresource_tile_info *tile_info; + VkMemoryRequirements requirements; + unsigned int subresource_count; + + subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc); + + if (d3d12_resource_is_buffer(resource)) + { + assert(subresource_count == 1); + if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources)))) + { + ERR("Failed to allocate subresource info array.\n"); + return false; + } + + VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements)); + if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) + FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n"); + + tile_info = &resource->tiles.subresources[0]; + tile_info->offset = 0; + tile_info->extent.width = align(resource->desc.Width, D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) + / D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + tile_info->extent.height = 1; + tile_info->extent.depth = 1; + tile_info->count = tile_info->extent.width; + + resource->tiles.tile_extent.width = D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES; + 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; + } + + return true; }
/* ID3D12Resource */ @@ -2013,7 +2112,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..459354b07 100644 --- a/libs/vkd3d/vkd3d_private.h +++ b/libs/vkd3d/vkd3d_private.h @@ -673,9 +673,27 @@ 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; };
/* ID3D12Resource */ @@ -728,6 +746,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,
From: Conor McCarthy cmccarthy@codeweavers.com
--- include/vkd3d_d3d12.idl | 1 + libs/vkd3d/resource.c | 124 ++++++++++++++++++++++++++++++++----- libs/vkd3d/vkd3d_private.h | 1 + 3 files changed, 110 insertions(+), 16 deletions(-)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl index 9af75f402..4db9e10f4 100644 --- a/include/vkd3d_d3d12.idl +++ b/include/vkd3d_d3d12.idl @@ -45,6 +45,7 @@ const UINT D3D12_DEFAULT_STENCIL_WRITE_MASK = 0xff; const UINT D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND = 0xffffffff; cpp_quote("#define D3D12_FLOAT32_MAX (3.402823466e+38f)") const UINT D3D12_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = 32; +const UINT D3D12_PACKED_TILE = 0xffffffff; const UINT D3D12_UAV_SLOT_COUNT = 64; const UINT D3D12_REQ_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; const UINT D3D12_REQ_IMMEDIATE_CONSTANT_BUFFER_ELEMENT_COUNT = 4096; diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c index 07a74e0b4..a7b5623e3 100644 --- a/libs/vkd3d/resource.c +++ b/libs/vkd3d/resource.c @@ -1064,29 +1064,38 @@ 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;
- if (d3d12_resource_is_texture(resource)) - { - FIXME("Not implemented for textures.\n"); - return; - } - 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; + 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) @@ -1111,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; @@ -1122,21 +1139,26 @@ 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_array; + VkSparseImageMemoryRequirements sparse_requirements = {0}; struct vkd3d_subresource_tile_info *tile_info; VkMemoryRequirements requirements; - unsigned int subresource_count; + const VkExtent3D *tile_extent; + uint32_t requirement_count;
subresource_count = d3d12_resource_desc_get_sub_resource_count(&resource->desc);
+ 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)) { assert(subresource_count == 1); - if (!(resource->tiles.subresources = vkd3d_calloc(subresource_count, sizeof(*resource->tiles.subresources)))) - { - ERR("Failed to allocate subresource info array.\n"); - return false; - }
VK_CALL(vkGetBufferMemoryRequirements(device->vk_device, resource->u.vk_buffer, &requirements)); if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) @@ -1156,6 +1178,76 @@ 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 + { + VK_CALL(vkGetImageMemoryRequirements(device->vk_device, resource->u.vk_image, &requirements)); + if (requirements.alignment > D3D12_TILED_RESOURCE_TILE_SIZE_IN_BYTES) + FIXME("Vulkan device tile size is greater than the standard D3D12 tile size.\n"); + + requirement_count = 0; + VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image, &requirement_count, NULL)); + if (!(sparse_requirements_array = vkd3d_calloc(requirement_count, sizeof(*sparse_requirements_array)))) + { + ERR("Failed to allocate sparse requirements array.\n"); + return false; + } + VK_CALL(vkGetImageSparseMemoryRequirements(device->vk_device, resource->u.vk_image, + &requirement_count, sparse_requirements_array)); + + for (i = 0; i < requirement_count; ++i) + { + if (sparse_requirements_array[i].formatProperties.aspectMask & resource->format->vk_aspect_mask) + { + if (sparse_requirements.formatProperties.aspectMask) + { + WARN("Ignoring properties for aspect mask %#x.\n", + sparse_requirements_array[i].formatProperties.aspectMask); + } + else + { + sparse_requirements = sparse_requirements_array[i]; + } + } + } + vkd3d_free(sparse_requirements_array); + if (!sparse_requirements.formatProperties.aspectMask) + { + WARN("Failed to get sparse requirements.\n"); + return false; + } + + 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 459354b07..efb0bffa2 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; };
On Tue Jul 25 13:09:08 2023 +0000, Giovanni Mascellani wrote:
Why is this a `>=`? In which cases more tiles than expected are declared? Later you even check the exact value for `resource_tile_count`, so maybe this check (and the corresponding field in the test array) is redundant?
This `>=` is required for the tests to pass, on RADV at least.
On Tue Jul 25 13:09:10 2023 +0000, Giovanni Mascellani wrote:
Why are you using this dummy value? It seems that Vulkan tells you how long the miptail/packed region should be in the field `imageMipTailSize`.
To support tiled resources where a single mip tail is used (as you mentioned below), mip tails are bound on resource creation (in a later patch), hence the dummy value.
On Tue Jul 25 13:09:11 2023 +0000, Giovanni Mascellani wrote:
Not sure if you consider array already supported, but if so I think you should check that Vulkan doesn't use a single mip tail, which AFAICT is not supported by D3D12. Also, `residencyAlignedMipSize` should probably be used to determine the supported tiled resource tier.
Yes, `residencyAlignedMipSize` should be used in the patch which enables tiled resource support. Strictly speaking I think we also need to check `residencyStandard2DBlockShape`, `shaderResourceResidency` and `shaderResourceMinLod`.
On Tue Jul 25 14:28:36 2023 +0000, Conor McCarthy wrote:
Yes, `residencyAlignedMipSize` should be used in the patch which enables tiled resource support. Strictly speaking I think we also need to check `residencyStandard2DBlockShape`, `shaderResourceResidency` and `shaderResourceMinLod`.
Yeah, even if the documentation is not really clear, it seems that D3D12 is quite more prescriptive about the tiling geometry that is allowed, so we have to detect whether we can offer that and hope that most Vulkan driver actually agree with D3D12.
On Tue Jul 25 14:24:23 2023 +0000, Conor McCarthy wrote:
To support tiled resources where a single mip tail is used (as you mentioned below), mip tails are bound on resource creation (in a later patch), hence the dummy value.
You mean that memory for mip tails is not directly managed by the application, but by vkd3d? It feels a departure from the usual Vulkan and D3D12 philosophy. I'm not saying it can't be done, especially if it enables working around single mip tails (which I don't know how common are on desktop Vulkan drivers), but it feels a bit strange as a default choice. Maybe (now or in the future) this could be architected so that dummy packed tiles are used only if the Vulkan driver requires a geometry that cannot be described by the D3D12 API.
This merge request was approved by Giovanni Mascellani.
On Tue Jul 25 15:10:26 2023 +0000, Giovanni Mascellani wrote:
You mean that memory for mip tails is not directly managed by the application, but by vkd3d? It feels a departure from the usual Vulkan and D3D12 philosophy. I'm not saying it can't be done, especially if it enables working around single mip tails (which I don't know how common are on desktop Vulkan drivers), but it feels a bit strange as a default choice. Maybe (now or in the future) this could be architected so that dummy packed tiles are used only if the Vulkan driver requires a geometry that cannot be described by the D3D12 API.
RADV uses a single mip tail on all AMD hardware before Vega. At the moment I think tiled resources are not used widely enough to justify extra code paths for separate handling.
This merge request was approved by Henri Verbeet.