From 253dfcd603be1a283ad68def5d1fa46591fe6871 Mon Sep 17 00:00:00 2001 From: Bryan Bernhart Date: Tue, 21 Jun 2022 10:58:46 -0700 Subject: [PATCH] Cache resource in page multiples. Previously, the size-cache was limited to powers-of-two. This change also includes page-multiples. For example, {4k, 8k, 12k} vs {4k, 8k, 16k}. Since the size-cache was intended to be always enabled, the build option default was reversed from enable => disable. --- .github/workflows/win_clang_dbg_x64.yaml | 4 +- .github/workflows/win_msvc_dbg_x64.yaml | 2 +- .github/workflows/win_msvc_dbg_x64_cmake.yml | 2 +- CMakeLists.txt | 6 +- build_overrides/gpgmm_features.gni | 6 +- docs/DESIGN.md | 2 +- src/gpgmm/BUILD.gn | 1 + src/gpgmm/common/BUILD.gn | 4 +- src/gpgmm/common/MemorySize.h | 65 ------- src/gpgmm/common/SizeClass.h | 59 +++++++ src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp | 23 +-- src/gpgmm/d3d12/ResourceSizeD3D12.h | 51 ++++++ src/gpgmm/utils/Utils.h | 18 ++ src/tests/D3D12Test.cpp | 6 +- .../end2end/D3D12ResourceAllocatorTests.cpp | 161 ++++++------------ 15 files changed, 206 insertions(+), 204 deletions(-) delete mode 100644 src/gpgmm/common/MemorySize.h create mode 100644 src/gpgmm/common/SizeClass.h create mode 100644 src/gpgmm/d3d12/ResourceSizeD3D12.h diff --git a/.github/workflows/win_clang_dbg_x64.yaml b/.github/workflows/win_clang_dbg_x64.yaml index f97cd5331..5826e9b13 100644 --- a/.github/workflows/win_clang_dbg_x64.yaml +++ b/.github/workflows/win_clang_dbg_x64.yaml @@ -54,7 +54,7 @@ jobs: set "PATH=%CD%\..\depot_tools;%PATH%" set "DEPOT_TOOLS_WIN_TOOLCHAIN=0" cd base - gn gen out\Debug --args="is_debug=true gpgmm_enable_assert_on_warning=true gpgmm_enable_device_checks=true" + gn gen out\Debug --args="is_debug=true gpgmm_enable_assert_on_warning=true gpgmm_enable_device_checks=true gpgmm_disable_size_cache=true" - name: Build for main branch shell: cmd @@ -118,7 +118,7 @@ jobs: set "PATH=%CD%\..\depot_tools;%PATH%" set "DEPOT_TOOLS_WIN_TOOLCHAIN=0" cd test - gn gen out\Debug --args="is_debug=true gpgmm_enable_assert_on_warning=true gpgmm_enable_device_checks=true" + gn gen out\Debug --args="is_debug=true gpgmm_enable_assert_on_warning=true gpgmm_enable_device_checks=true gpgmm_disable_size_cache=true" - name: Build for main branch (with patch) shell: cmd diff --git a/.github/workflows/win_msvc_dbg_x64.yaml b/.github/workflows/win_msvc_dbg_x64.yaml index 1d7b04e39..2ad899548 100644 --- a/.github/workflows/win_msvc_dbg_x64.yaml +++ b/.github/workflows/win_msvc_dbg_x64.yaml @@ -69,7 +69,7 @@ jobs: set "PATH=%CD%\..\depot_tools;%PATH%" set "DEPOT_TOOLS_WIN_TOOLCHAIN=0" cd test - gn gen out\Debug --args="is_debug=true is_clang=false" + gn gen out\Debug --args="is_debug=true is_clang=false gpgmm_disable_size_cache=true" - name: Build for main branch (with patch) shell: cmd diff --git a/.github/workflows/win_msvc_dbg_x64_cmake.yml b/.github/workflows/win_msvc_dbg_x64_cmake.yml index 2fb920b37..207382215 100644 --- a/.github/workflows/win_msvc_dbg_x64_cmake.yml +++ b/.github/workflows/win_msvc_dbg_x64_cmake.yml @@ -71,7 +71,7 @@ jobs: shell: cmd run: | cd test - cmake . -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=OFF -DCMAKE_TOOLCHAIN_FILE=..\vcpkg\scripts\buildsystems\vcpkg.cmake + cmake . -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=OFF -DGPGMM_DISABLE_SIZE_CACHE=ON -DCMAKE_TOOLCHAIN_FILE=..\vcpkg\scripts\buildsystems\vcpkg.cmake - name: Build for main branch (with patch) shell: cmd diff --git a/CMakeLists.txt b/CMakeLists.txt index f65f198c9..f21bb8393 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -119,7 +119,7 @@ option_if_not_defined(GPGMM_FORCE_TRACING "Enables event tracing even in release option_if_not_defined(GPGMM_ENABLE_DEVICE_CHECKS "Enables checking of device leaks" OFF) option_if_not_defined(GPGMM_ENABLE_ALLOCATOR_CHECKS "Enables checking of allocator leaks" ${ENABLE_ALLOCATOR_CHECKS}) option_if_not_defined(GPGMM_ENABLE_ASSERT_ON_WARNING "Enables ASSERT on severity functionality" ${ENABLE_ASSERT_ON_WARNING}) -option_if_not_defined(GPGMM_ENABLE_SIZE_CACHE "Enables warming of caches with common sizes" ON) +option_if_not_defined(GPGMM_DISABLE_SIZE_CACHE "Enables warming of caches with common resource sizes" OFF) # The Vulkan loader is an optional dependency. if (GPGMM_ENABLE_VK) @@ -180,8 +180,8 @@ if(GPGMM_ENABLE_ASSERT_ON_WARNING) target_compile_definitions(gpgmm_common_config INTERFACE "GPGMM_ENABLE_ASSERT_ON_WARNING") endif() -if(GPGMM_ENABLE_SIZE_CACHE) - target_compile_definitions(gpgmm_common_config INTERFACE "GPGMM_ENABLE_SIZE_CACHE") +if(GPGMM_DISABLE_SIZE_CACHE) + target_compile_definitions(gpgmm_common_config INTERFACE "GPGMM_DISABLE_SIZE_CACHE") endif() if(WIN32) diff --git a/build_overrides/gpgmm_features.gni b/build_overrides/gpgmm_features.gni index 89d0540e8..95e86ffcf 100644 --- a/build_overrides/gpgmm_features.gni +++ b/build_overrides/gpgmm_features.gni @@ -52,9 +52,9 @@ declare_args() { # Sets -dGPGMM_ENABLE_ASSERT_ON_WARNING gpgmm_enable_assert_on_warning = is_debug - # Enables warming of caches with common sizes. - # Sets -dGPGMM_ENABLE_SIZE_CACHE - gpgmm_enable_size_cache = true + # Enables warming of caches with common resource sizes. + # Sets -dGPGMM_DISABLE_SIZE_CACHE + gpgmm_disable_size_cache = false # Enables checking of device leaks. # Sets -dGPGMM_ENABLE_DEVICE_CHECKS diff --git a/docs/DESIGN.md b/docs/DESIGN.md index 08e806ac1..f29fb093e 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -176,7 +176,7 @@ GPGMM detects and reports leaks at the allocation-level (vs Memory Object). Shou ### Caching requirements -GPGMM conditionally caches for *known* requests sizes. The size-cache is predefined at compile-time and supports multiple *size classes* (ex. multiples of page or power-of-two). The size-cache can be disabled by not providing `GPGMM_ENABLE_SIZE_CACHE`. +GPGMM caches for common requests sizes. The size-cache is predefined at compile-time and supports multiple *size classes* (ex. page-multiple or power-of-two). The size-cache can be disabled by providing `GPGMM_DISABLE_SIZE_CACHE`. ### Capacity planning diff --git a/src/gpgmm/BUILD.gn b/src/gpgmm/BUILD.gn index 0d5738cf7..03280e0ec 100644 --- a/src/gpgmm/BUILD.gn +++ b/src/gpgmm/BUILD.gn @@ -141,6 +141,7 @@ source_set("gpgmm_sources") { "d3d12/ResourceAllocatorD3D12.h", "d3d12/ResourceHeapAllocatorD3D12.cpp", "d3d12/ResourceHeapAllocatorD3D12.h", + "d3d12/ResourceSizeD3D12.h", "d3d12/UtilsD3D12.cpp", "d3d12/UtilsD3D12.h", "d3d12/d3d12_platform.h", diff --git a/src/gpgmm/common/BUILD.gn b/src/gpgmm/common/BUILD.gn index b92ce1fb8..687929fda 100644 --- a/src/gpgmm/common/BUILD.gn +++ b/src/gpgmm/common/BUILD.gn @@ -73,8 +73,8 @@ config("gpgmm_common_config") { defines += [ "GPGMM_ENABLE_ASSERT_ON_WARNING" ] } - if (gpgmm_enable_size_cache) { - defines += [ "GPGMM_ENABLE_SIZE_CACHE" ] + if (gpgmm_disable_size_cache) { + defines += [ "GPGMM_DISABLE_SIZE_CACHE" ] } if (gpgmm_enable_device_checks) { diff --git a/src/gpgmm/common/MemorySize.h b/src/gpgmm/common/MemorySize.h deleted file mode 100644 index 80d3b5399..000000000 --- a/src/gpgmm/common/MemorySize.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2021 The GPGMM Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef GPGMM_COMMON_MEMORYSIZE_H_ -#define GPGMM_COMMON_MEMORYSIZE_H_ - -namespace gpgmm { - - struct MemorySizeInfo { - uint64_t SizeInBytes; - }; - - class MemorySize { - public: - static const size_t kPowerOfTwoClassSize; - static const MemorySizeInfo kPowerOfTwoCacheSizes[]; - }; - - // clang-format off - const size_t MemorySize::kPowerOfTwoClassSize = 27; - const MemorySizeInfo MemorySize::kPowerOfTwoCacheSizes[MemorySize::kPowerOfTwoClassSize] = { - {1}, - {2}, - {4}, - {8}, - {16}, - {32}, - {64}, - {128}, - {256}, - {512}, - {1024}, - {2048}, - {4096}, - {8192}, - {16384}, - {32768}, - {65536}, - {131072}, - {262144}, - {524288}, - {1048576}, - {2097152}, - {4194304}, - {8388608}, - {16777216}, - {33554432}, - {67108864}, - }; - // clang-format on - -} // namespace gpgmm - -#endif // GPGMM_COMMON_MEMORYSIZE_H_ diff --git a/src/gpgmm/common/SizeClass.h b/src/gpgmm/common/SizeClass.h new file mode 100644 index 000000000..e376b7880 --- /dev/null +++ b/src/gpgmm/common/SizeClass.h @@ -0,0 +1,59 @@ +// Copyright 2021 The GPGMM Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GPGMM_COMMON_SIZECLASS_H_ +#define GPGMM_COMMON_SIZECLASS_H_ + +#include + +namespace gpgmm { + + struct SizeClassInfo { + uint64_t SizeInBytes; + uint64_t Alignment; + }; + + // Generates array containing values in range [2^N1...2^N2], where N2 > N1. + template + static constexpr std::array GeneratePowerOfTwoSizes() { + static_assert(N2 > N1, "Invalid range specified."); + std::array sizeArray{}; + for (size_t i = N1; i < N2; ++i) { + sizeArray[i] = {static_cast(1ull << i), i}; + } + return sizeArray; + } + + template + static constexpr std::array GenerateAlignedSizes() { + std::array sizeArray{}; + for (size_t i = 1; i < N; ++i) { + sizeArray[i] = {i * alignment, alignment}; + } + return sizeArray; + } + + class MemorySizeClass { + protected: + static constexpr auto GenerateAllClassSizes() { + return kPowerOfTwoCacheSizes; + } + + private: + static constexpr auto kPowerOfTwoCacheSizes = GeneratePowerOfTwoSizes<1, 27>(); + }; + +} // namespace gpgmm + +#endif // GPGMM_COMMON_SIZECLASS_H_ diff --git a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp index 761942d34..bf2875f57 100644 --- a/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp +++ b/src/gpgmm/d3d12/ResourceAllocatorD3D12.cpp @@ -18,7 +18,6 @@ #include "gpgmm/common/BuddyMemoryAllocator.h" #include "gpgmm/common/Defaults.h" #include "gpgmm/common/EventMessage.h" -#include "gpgmm/common/MemorySize.h" #include "gpgmm/common/PooledMemoryAllocator.h" #include "gpgmm/common/SegmentedMemoryAllocator.h" #include "gpgmm/common/SlabMemoryAllocator.h" @@ -34,6 +33,7 @@ #include "gpgmm/d3d12/ResidencyManagerD3D12.h" #include "gpgmm/d3d12/ResourceAllocationD3D12.h" #include "gpgmm/d3d12/ResourceHeapAllocatorD3D12.h" +#include "gpgmm/d3d12/ResourceSizeD3D12.h" #include "gpgmm/d3d12/UtilsD3D12.h" namespace gpgmm::d3d12 { @@ -454,7 +454,7 @@ namespace gpgmm::d3d12 { // increasing memory footprint. Since resources are always sized-aligned, the // cached size must be requested per alignment {4KB, 64KB, or 4MB}. To avoid unbounded // cache growth, a known set of pre-defined sizes initializes the allocators. -#if defined(GPGMM_ENABLE_SIZE_CACHE) +#if !defined(GPGMM_DISABLE_SIZE_CACHE) { // Temporary suppress log messages emitted from internal cache-miss requests. ScopedLogLevel scopedLogLevel(LogSeverity::Info); @@ -465,36 +465,31 @@ namespace gpgmm::d3d12 { cacheRequest.AlwaysPrefetch = false; cacheRequest.AvailableForAllocation = kInvalidSize; - for (uint64_t i = 0; i < MemorySize::kPowerOfTwoClassSize; i++) { + for (const SizeClassInfo& sizeInfo : ResourceSize::GenerateAllClassSizes()) { MemoryAllocator* allocator = nullptr; - cacheRequest.SizeInBytes = MemorySize::kPowerOfTwoCacheSizes[i].SizeInBytes; + cacheRequest.SizeInBytes = sizeInfo.SizeInBytes; + cacheRequest.Alignment = sizeInfo.Alignment; allocator = mSmallBufferAllocatorOfType[resourceHeapTypeIndex].get(); if (cacheRequest.SizeInBytes <= allocator->GetMemorySize() && - IsAligned(cacheRequest.SizeInBytes, - D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT)) { - cacheRequest.Alignment = D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT; + sizeInfo.Alignment == D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT) { allocator->TryAllocateMemory(cacheRequest); } allocator = mResourceAllocatorOfType[resourceHeapTypeIndex].get(); if (cacheRequest.SizeInBytes <= allocator->GetMemorySize() && - IsAligned(cacheRequest.SizeInBytes, - D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)) { - cacheRequest.Alignment = D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT; + sizeInfo.Alignment == D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT) { allocator->TryAllocateMemory(cacheRequest); } allocator = mMSAAResourceAllocatorOfType[resourceHeapTypeIndex].get(); if (cacheRequest.SizeInBytes <= allocator->GetMemorySize() && - IsAligned(cacheRequest.SizeInBytes, - D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT)) { - cacheRequest.Alignment = D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT; + sizeInfo.Alignment == D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT) { allocator->TryAllocateMemory(cacheRequest); } } } -#endif // defined(GPGMM_ENABLE_SIZE_CACHE) +#endif // !defined(GPGMM_DISABLE_SIZE_CACHE) } } diff --git a/src/gpgmm/d3d12/ResourceSizeD3D12.h b/src/gpgmm/d3d12/ResourceSizeD3D12.h new file mode 100644 index 000000000..c162c67f6 --- /dev/null +++ b/src/gpgmm/d3d12/ResourceSizeD3D12.h @@ -0,0 +1,51 @@ +// Copyright 2021 The GPGMM Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef GPGMM_D3D12_RESOURCESIZE_H_ +#define GPGMM_D3D12_RESOURCESIZE_H_ + +#include "gpgmm/common/SizeClass.h" +#include "gpgmm/d3d12/d3d12_platform.h" +#include "gpgmm/utils/Utils.h" + +namespace gpgmm::d3d12 { + + // Generates array of resource sizes aligned per resource type. + class ResourceSize : public gpgmm::MemorySizeClass { + public: + static constexpr auto GenerateAllClassSizes() { + auto tmp0 = gpgmm::MemorySizeClass::GenerateAllClassSizes(); + auto tmp1 = ConstexprConcat(tmp0, kSmallResourceSizes); + auto tmp2 = ConstexprConcat(tmp1, kDefaultResourceCacheSizes); + auto tmp3 = ConstexprConcat(tmp2, kMSAAResourceCacheSizes); + return tmp3; + } + + private: + // Small textures but non-MSAA (from 4KB to 64KB). + static constexpr auto kSmallResourceSizes = + GenerateAlignedSizes<16, D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT>(); + + // Buffer or textures and also MSAA (from 64KB to 1MB). + static constexpr auto kDefaultResourceCacheSizes = + GenerateAlignedSizes<16, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT>(); + + // MSAA only textures (from 4MB to 64MB). + static constexpr auto kMSAAResourceCacheSizes = + GenerateAlignedSizes<16, D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT>(); + }; + +} // namespace gpgmm::d3d12 + +#endif // GPGMM_D3D12_RESOURCESIZE_H_ diff --git a/src/gpgmm/utils/Utils.h b/src/gpgmm/utils/Utils.h index 0164d2094..bd21c5188 100644 --- a/src/gpgmm/utils/Utils.h +++ b/src/gpgmm/utils/Utils.h @@ -65,6 +65,24 @@ namespace gpgmm { return ToString(object) + ToString(args...); } + template + constexpr auto ConstexprConcat(A1 lhs, A2 rhs) { + std::array sizeArray{}; + size_t i = 0; + + for (auto& item : lhs) { + sizeArray[i] = std::move(item); + ++i; + } + + for (auto& item : rhs) { + sizeArray[i] = std::move(item); + ++i; + } + + return sizeArray; + } + } // namespace gpgmm #endif // GPGMM_UTILS_UTILS_H_ diff --git a/src/tests/D3D12Test.cpp b/src/tests/D3D12Test.cpp index 11ed4d414..f294a3edc 100644 --- a/src/tests/D3D12Test.cpp +++ b/src/tests/D3D12Test.cpp @@ -135,10 +135,10 @@ namespace gpgmm::d3d12 { } bool D3D12TestBase::IsSizeCacheEnabled() const { -#if defined(GPGMM_ENABLE_SIZE_CACHE) - return true; -#else +#if defined(GPGMM_DISABLE_SIZE_CACHE) return false; +#else + return true; #endif } diff --git a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp index 2ad0c7da6..88653f36a 100644 --- a/src/tests/end2end/D3D12ResourceAllocatorTests.cpp +++ b/src/tests/end2end/D3D12ResourceAllocatorTests.cpp @@ -1121,154 +1121,97 @@ TEST_F(D3D12ResourceAllocatorTests, CreateBufferWithinManyThreaded) { } TEST_F(D3D12ResourceAllocatorTests, CreateBufferCacheSize) { - GPGMM_SKIP_TEST_IF(!IsSizeCacheEnabled()); + // Since we cannot determine which resource sizes will be cached upon CreateAllocator, skip the + // test. + GPGMM_SKIP_TEST_IF(IsSizeCacheEnabled()); ComPtr resourceAllocator; ASSERT_SUCCEEDED( ResourceAllocator::CreateAllocator(CreateBasicAllocatorDesc(), &resourceAllocator)); ASSERT_NE(resourceAllocator, nullptr); - // Upon creating the resource allocator, min. buffer size-alignment is always cached. + // First request is always a cache miss. + ALLOCATION_DESC allocationDesc = {}; + allocationDesc.Flags |= ALLOCATION_FLAG_ALWAYS_CACHE_SIZE; + { - ComPtr cachedAllocation; + ComPtr allocation; - ALLOCATION_DESC smallResourceAllocDesc = {}; + ALLOCATION_DESC smallResourceAllocDesc = allocationDesc; smallResourceAllocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD; smallResourceAllocDesc.Flags |= ALLOCATION_FLAG_ALLOW_SUBALLOCATE_WITHIN_RESOURCE; - EXPECT_SIZE_CACHE_HIT(resourceAllocator, - resourceAllocator->CreateResource( - smallResourceAllocDesc, - CreateBasicBufferDesc(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT), - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &cachedAllocation)); - ASSERT_NE(cachedAllocation, nullptr); - EXPECT_EQ(cachedAllocation->GetSize(), + EXPECT_SIZE_CACHE_MISS(resourceAllocator, + resourceAllocator->CreateResource( + smallResourceAllocDesc, + CreateBasicBufferDesc(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT), + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &allocation)); + ASSERT_NE(allocation, nullptr); + EXPECT_EQ(allocation->GetSize(), static_cast(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT)); } { - ComPtr cachedAllocation; - EXPECT_SIZE_CACHE_HIT( + ComPtr allocation; + EXPECT_SIZE_CACHE_MISS( resourceAllocator, resourceAllocator->CreateResource( - {}, CreateBasicBufferDesc(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), - D3D12_RESOURCE_STATE_COMMON, nullptr, &cachedAllocation)); - ASSERT_NE(cachedAllocation, nullptr); - EXPECT_EQ(cachedAllocation->GetSize(), + allocationDesc, CreateBasicBufferDesc(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), + D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); + ASSERT_NE(allocation, nullptr); + EXPECT_EQ(allocation->GetSize(), static_cast(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)); } { - ComPtr cachedAllocation; - EXPECT_SIZE_CACHE_HIT( - resourceAllocator, - resourceAllocator->CreateResource( - {}, CreateBasicBufferDesc(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT), - D3D12_RESOURCE_STATE_COMMON, nullptr, &cachedAllocation)); - ASSERT_NE(cachedAllocation, nullptr); - EXPECT_EQ(cachedAllocation->GetSize(), - static_cast(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT)); - } - - // Verify misaligned allocations are uncached. - { - ComPtr uncachedAllocation; - - ALLOCATION_DESC smallResourceAllocDesc = {}; - smallResourceAllocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD; - smallResourceAllocDesc.Flags |= ALLOCATION_FLAG_ALLOW_SUBALLOCATE_WITHIN_RESOURCE; - + ComPtr allocation; EXPECT_SIZE_CACHE_MISS( resourceAllocator, resourceAllocator->CreateResource( - smallResourceAllocDesc, - CreateBasicBufferDesc(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &uncachedAllocation)); - - ASSERT_NE(uncachedAllocation, nullptr); - EXPECT_EQ(uncachedAllocation->GetSize(), - static_cast(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT * 3)); + allocationDesc, + CreateBasicBufferDesc(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT), + D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); + ASSERT_NE(allocation, nullptr); + EXPECT_EQ(allocation->GetSize(), + static_cast(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT)); } - { - ComPtr uncachedAllocation; - EXPECT_SIZE_CACHE_MISS( - resourceAllocator, - resourceAllocator->CreateResource( - {}, CreateBasicBufferDesc(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_COMMON, nullptr, &uncachedAllocation)); - ASSERT_NE(uncachedAllocation, nullptr); - EXPECT_EQ(uncachedAllocation->GetSize(), - static_cast(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 3)); - } + // Second request is always a cache hit. { - ComPtr uncachedAllocation; - EXPECT_SIZE_CACHE_MISS( - resourceAllocator, - resourceAllocator->CreateResource( - {}, CreateBasicBufferDesc(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_COMMON, nullptr, &uncachedAllocation)); - - ASSERT_NE(uncachedAllocation, nullptr); - EXPECT_EQ(uncachedAllocation->GetSize(), - static_cast(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT * 3)); - } + ComPtr allocation; - // Verify requesting for cached always caches. - ALLOCATION_DESC allocationWithSizeCached = {}; - allocationWithSizeCached.Flags = ALLOCATION_FLAG_ALWAYS_CACHE_SIZE; - { - ALLOCATION_DESC smallResourceAllocDesc = allocationWithSizeCached; + ALLOCATION_DESC smallResourceAllocDesc = allocationDesc; smallResourceAllocDesc.HeapType = D3D12_HEAP_TYPE_UPLOAD; smallResourceAllocDesc.Flags |= ALLOCATION_FLAG_ALLOW_SUBALLOCATE_WITHIN_RESOURCE; - ComPtr uncachedAllocation; - EXPECT_SIZE_CACHE_MISS( - resourceAllocator, - resourceAllocator->CreateResource( - smallResourceAllocDesc, - CreateBasicBufferDesc(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &uncachedAllocation)); - - ComPtr cachedAllocation; - EXPECT_SIZE_CACHE_HIT( - resourceAllocator, - resourceAllocator->CreateResource( - smallResourceAllocDesc, - CreateBasicBufferDesc(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &cachedAllocation)); + EXPECT_SIZE_CACHE_HIT(resourceAllocator, + resourceAllocator->CreateResource( + smallResourceAllocDesc, + CreateBasicBufferDesc(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT), + D3D12_RESOURCE_STATE_GENERIC_READ, nullptr, &allocation)); + ASSERT_NE(allocation, nullptr); + EXPECT_EQ(allocation->GetSize(), + static_cast(D3D12_SMALL_RESOURCE_PLACEMENT_ALIGNMENT)); } { - ComPtr uncachedAllocation; - EXPECT_SIZE_CACHE_MISS( - resourceAllocator, - resourceAllocator->CreateResource( - allocationWithSizeCached, - CreateBasicBufferDesc(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_COMMON, nullptr, &uncachedAllocation)); - - ComPtr cachedAllocation; + ComPtr allocation; EXPECT_SIZE_CACHE_HIT( resourceAllocator, resourceAllocator->CreateResource( - allocationWithSizeCached, - CreateBasicBufferDesc(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_COMMON, nullptr, &cachedAllocation)); + {}, CreateBasicBufferDesc(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), + D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); + ASSERT_NE(allocation, nullptr); + EXPECT_EQ(allocation->GetSize(), + static_cast(D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT)); } { - ComPtr uncachedAllocation; - EXPECT_SIZE_CACHE_MISS( - resourceAllocator, - resourceAllocator->CreateResource( - allocationWithSizeCached, - CreateBasicBufferDesc(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_COMMON, nullptr, &uncachedAllocation)); - - ComPtr cachedAllocation; + ComPtr allocation; EXPECT_SIZE_CACHE_HIT( resourceAllocator, resourceAllocator->CreateResource( - allocationWithSizeCached, - CreateBasicBufferDesc(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT * 3), - D3D12_RESOURCE_STATE_COMMON, nullptr, &cachedAllocation)); + {}, CreateBasicBufferDesc(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT), + D3D12_RESOURCE_STATE_COMMON, nullptr, &allocation)); + ASSERT_NE(allocation, nullptr); + EXPECT_EQ(allocation->GetSize(), + static_cast(D3D12_DEFAULT_MSAA_RESOURCE_PLACEMENT_ALIGNMENT)); } }