@@ -5911,6 +5911,8 @@ class AllocatorPimpl
59115911 BOOL IsCacheCoherentUMA () const { return m_D3D12Architecture.CacheCoherentUMA ; }
59125912 bool SupportsResourceHeapTier2 () const { return m_D3D12Options.ResourceHeapTier >= D3D12_RESOURCE_HEAP_TIER_2; }
59135913 bool IsGPUUploadHeapSupported () const { return m_GPUUploadHeapSupported != FALSE ; }
5914+ bool IsTightAlignmentSupported () const { return m_TightAlignmentSupported != FALSE ; }
5915+ bool IsTightAlignmentEnabled () const { return IsTightAlignmentSupported () && m_UseTightAlignment; }
59145916 bool UseMutex () const { return m_UseMutex; }
59155917 AllocationObjectAllocator& GetAllocationObjectAllocator () { return m_AllocationObjectAllocator; }
59165918 UINT GetCurrentFrameIndex () const { return m_CurrentFrameIndex.load (); }
@@ -5998,6 +6000,7 @@ class AllocatorPimpl
59986000 const bool m_AlwaysCommitted;
59996001 const bool m_MsaaAlwaysCommitted;
60006002 const bool m_PreferSmallBuffersCommitted;
6003+ const bool m_UseTightAlignment;
60016004 bool m_DefaultPoolsNotZeroed = false ;
60026005 ID3D12Device* m_Device; // AddRef
60036006#ifdef __ID3D12Device1_INTERFACE_DEFINED__
@@ -6022,6 +6025,7 @@ class AllocatorPimpl
60226025 DXGI_ADAPTER_DESC m_AdapterDesc;
60236026 D3D12_FEATURE_DATA_D3D12_OPTIONS m_D3D12Options;
60246027 BOOL m_GPUUploadHeapSupported = FALSE ;
6028+ BOOL m_TightAlignmentSupported = FALSE ;
60256029 D3D12_FEATURE_DATA_ARCHITECTURE m_D3D12Architecture;
60266030 AllocationObjectAllocator m_AllocationObjectAllocator;
60276031
@@ -6089,7 +6093,8 @@ AllocatorPimpl::AllocatorPimpl(const ALLOCATION_CALLBACKS& allocationCallbacks,
60896093 : m_UseMutex((desc.Flags & ALLOCATOR_FLAG_SINGLETHREADED) == 0),
60906094 m_AlwaysCommitted((desc.Flags & ALLOCATOR_FLAG_ALWAYS_COMMITTED) != 0),
60916095 m_MsaaAlwaysCommitted((desc.Flags & ALLOCATOR_FLAG_MSAA_TEXTURES_ALWAYS_COMMITTED) != 0),
6092- m_PreferSmallBuffersCommitted((desc.Flags & ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED) == 0),
6096+ m_PreferSmallBuffersCommitted((desc.Flags& ALLOCATOR_FLAG_DONT_PREFER_SMALL_BUFFERS_COMMITTED) == 0),
6097+ m_UseTightAlignment((desc.Flags & ALLOCATOR_FLAG_DONT_USE_TIGHT_ALIGNMENT) == 0),
60936098 m_Device(desc.pDevice),
60946099 m_Adapter(desc.pAdapter),
60956100 m_PreferredBlockSize(desc.PreferredBlockSize != 0 ? desc.PreferredBlockSize : D3D12MA_DEFAULT_BLOCK_SIZE),
@@ -6177,6 +6182,20 @@ HRESULT AllocatorPimpl::Init(const ALLOCATOR_DESC& desc)
61776182 }
61786183#endif
61796184
6185+ // You must define macro `#define D3D12MA_TIGHT_ALIGNMENT_SUPPORTED 1` to enable resource tight alignment!
6186+ // Unfortunately there is no way to programmatically check if the included <d3d12.h> defines D3D12_FEATURE_DATA_TIGHT_ALIGNMENT or not.
6187+ // Main interfaces have respective macros like __ID3D12Device4_INTERFACE_DEFINED__, but structures like this do not.
6188+ #if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
6189+ {
6190+ D3D12_FEATURE_DATA_TIGHT_ALIGNMENT tightAlignment = {};
6191+ hr = m_Device->CheckFeatureSupport (D3D12_FEATURE_D3D12_TIGHT_ALIGNMENT, &tightAlignment, sizeof (tightAlignment));
6192+ if (SUCCEEDED (hr))
6193+ {
6194+ m_TightAlignmentSupported = tightAlignment.SupportTier >= D3D12_TIGHT_ALIGNMENT_TIER_1;
6195+ }
6196+ }
6197+ #endif
6198+
61806199 hr = m_Device->CheckFeatureSupport (D3D12_FEATURE_ARCHITECTURE, &m_D3D12Architecture, sizeof (m_D3D12Architecture));
61816200 if (FAILED (hr))
61826201 {
@@ -6861,6 +6880,9 @@ void AllocatorPimpl::BuildStatsString(WCHAR** ppStatsString, BOOL detailedMap)
68616880
68626881 json.WriteString (L" GPUUploadHeapSupported" );
68636882 json.WriteBool (m_GPUUploadHeapSupported != FALSE );
6883+
6884+ json.WriteString (L" TightAlignmentSupported" );
6885+ json.WriteBool (m_TightAlignmentSupported != FALSE );
68646886 }
68656887 json.EndObject ();
68666888 }
@@ -7623,21 +7645,34 @@ template<typename D3D12_RESOURCE_DESC_T>
76237645D3D12_RESOURCE_ALLOCATION_INFO AllocatorPimpl::GetResourceAllocationInfo (D3D12_RESOURCE_DESC_T& inOutResourceDesc) const
76247646{
76257647#ifdef __ID3D12Device1_INTERFACE_DEFINED__
7626- /* Optional optimization: Microsoft documentation says:
7627- https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12device-getresourceallocationinfo
7648+
7649+ #if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
7650+ if (IsTightAlignmentEnabled () &&
7651+ // Don't allow USE_TIGHT_ALIGNMENT together with ALLOW_CROSS_ADAPTER as there is a D3D Debug Layer error:
7652+ // D3D12 ERROR: ID3D12Device::GetResourceAllocationInfo: D3D12_RESOURCE_DESC::Flag D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT will be ignored since D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER is set. [ STATE_CREATION ERROR #599: CREATERESOURCE_INVALIDMISCFLAGS]
7653+ (inOutResourceDesc.Flags & D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER) == 0 )
7654+ {
7655+ inOutResourceDesc.Flags |= D3D12_RESOURCE_FLAG_USE_TIGHT_ALIGNMENT;
7656+ }
7657+ #endif // #if D3D12MA_TIGHT_ALIGNMENT_SUPPORTED
7658+
7659+ /* Optional optimization: Microsoft documentation of the ID3D12Device::
7660+ GetResourceAllocationInfo function says:
76287661
76297662 Your application can forgo using GetResourceAllocationInfo for buffer resources
76307663 (D3D12_RESOURCE_DIMENSION_BUFFER). Buffers have the same size on all adapters,
76317664 which is merely the smallest multiple of 64KB that's greater or equal to
76327665 D3D12_RESOURCE_DESC::Width.
76337666 */
76347667 if (inOutResourceDesc.Alignment == 0 &&
7635- inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
7668+ inOutResourceDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER &&
7669+ !IsTightAlignmentEnabled ())
76367670 {
76377671 return {
76387672 AlignUp<UINT64>(inOutResourceDesc.Width , D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT), // SizeInBytes
76397673 D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT }; // Alignment
76407674 }
7675+
76417676#endif // #ifdef __ID3D12Device1_INTERFACE_DEFINED__
76427677
76437678#if D3D12MA_USE_SMALL_RESOURCE_PLACEMENT_ALIGNMENT
@@ -9552,6 +9587,11 @@ BOOL Allocator::IsGPUUploadHeapSupported() const
95529587 return m_Pimpl->IsGPUUploadHeapSupported ();
95539588}
95549589
9590+ BOOL Allocator::IsTightAlignmentSupported () const
9591+ {
9592+ return m_Pimpl->IsTightAlignmentSupported ();
9593+ }
9594+
95559595UINT64 Allocator::GetMemoryCapacity (UINT memorySegmentGroup) const
95569596{
95579597 return m_Pimpl->GetMemoryCapacity (memorySegmentGroup);
0 commit comments