gpuopen-librariesandsdks / d3d12memoryallocator Goto Github PK
View Code? Open in Web Editor NEWEasy to integrate memory allocation library for Direct3D 12
License: MIT License
Easy to integrate memory allocation library for Direct3D 12
License: MIT License
If you integrate the library in project building for UWP with ARM architecture there is json.WriteNumber ambiguity:
cmake . -G "Visual Studio 16 2019" -A ARM -Bbuild_uwp_arm -DCMAKE_SYSTEM_NAME:String=WindowsStore -DCMAKE_SYSTEM_VERSION:String="10.0"
Error below:
1>C:\projects\vgpu\src\lib\D3D12MemAlloc.cpp(7194,68): error C2668: 'D3D12MA::JsonWriter::WriteNumber': ambiguous call to overloaded function
1>C:\projects\vgpu\src\lib\D3D12MemAlloc.cpp(1505,18): message : could be 'void D3D12MA::JsonWriter::WriteNumber(UINT64)'
1>C:\projects\vgpu\src\lib\D3D12MemAlloc.cpp(1498,18): message : or 'void D3D12MA::JsonWriter::WriteNumber(UINT)'
1>C:\projects\vgpu\src\lib\D3D12MemAlloc.cpp(7194,68): message : while trying to match the argument list '(SIZE_T)'
Hi
In order to have the best CPU write performance, we should have D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE
when creating the heap.
I may be missing things, but it doesn't look like to me this library allows its user to set this flag and it doesn't create heaps with this flag internally by default either.
It would be nice if this option could be exposed through the library interface or simply use D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE
as the default Cpu page property since most game developers use it to pass data from CPU to GPU.
Thanks
Jiayin
Building with GDK tools for console I'm getting a compile error with the latest release:
d3d12memalloc.cpp(3557): error C2440: 'return': cannot convert from 'D3D12MA::List<D3D12MA::Suballocation>::const_reverse_iterator' to 'D3D12MA::List<D3D12MA::Suballocation>::const_iterator'
My fix was to forward declare const_reverse_iterator right after the forward declaration of reverse_iterator on line 1564;
class const_reverse_iterator;
It seems as though "friend class const_reverse_iterator" automatically forward-declares the type for VS2017 but it's somehow ambiguous with the GDK toolchain so the conversion constructors aren't triggered automatically.
Sorry if this should be a PR instead -- it's a one-line fix.
Is it possible to let the D3D12MA::Allocator
inherit from IUnknown
and provide implementations for AddRef
(this won't conflict with the current use of the member method, AddRef
), Release
and QueryInterface
to be used with Microsoft's intrusive ComPtr
? This would be consistent with D3D12 types themselves and with 3th-party tools such as DirectXShaderCompiler which also mimic this former behavior.
D3D12MemoryAllocator\src\D3D12MemAlloc.cpp(7184,21): error C2668: 'D3D12MA::JsonWriter::WriteNumber': ambiguous call to overloaded function
D3D12MemoryAllocator\src\D3D12MemAlloc.cpp(1505,18): message : could be 'void D3D12MA::JsonWriter::WriteNumber(UINT64)'
D3D12MemoryAllocator\src\D3D12MemAlloc.cpp(1498,18): message : or 'void D3D12MA::JsonWriter::WriteNumber(UINT)'
coming from:
json.WriteNumber(m_AdapterDesc.DedicatedVideoMemory);
json.WriteNumber(m_AdapterDesc.DedicatedSystemMemory);
json.WriteNumber(m_AdapterDesc.SharedSystemMemory);
Hello,
after updating the allocator in our project from an older version, I've noticed, that ebf4f8de094c41b10f5b111fe88189f85d9ea8f0 introduced a new condition to when is the D3D12MA_DXGI_1_4
macro defined to 1
.
#ifdef __IDXGIAdapter3_INTERFACE_DEFINED__
#define D3D12MA_DXGI_1_4 1
#else
#define D3D12MA_DXGI_1_4 0
#endif
Correct me if I'm wrong but since there are no includes before this block, unless someone either includes dxgi1_4.h
before their D3D12MemAlloc.h
or define the macro manually (which is not advised in my opinion) the D3D12MA_DXGI_1_4
will always be 0
.
I understand the usage of the other ..._INTERFACE_DEFINED__
conditions since they are defined in the d3d12.h
. However, even if we moved the block in question after the dxgi.h
include it would not help since the dxgi headers are versioned. So to have the __IDXGIAdapter3_INTERFACE_DEFINED__
defined we would need to include dxgi1_4.h
or greater which is actually predicated in the .cpp
by D3D12MA_DXGI_1_4
being non-zero.
Is this a bug or did I misuderstand the intention/usage?
Hello Adam !
Small question regarding defragmentation.
In the documentation it is written :
What it means in practice is that you shouldn't free any allocations from the defragmented pool since the moment a call to BeginPass begins.
One solution that you give is :
A solution to freeing allocations during defragmentation is to find such allocation on the list pass.pMoves[i] and set its operation to D3D12MA::DEFRAGMENTATION_MOVE_OPERATION_DESTROY instead of calling allocation->Release()
However, it is only possible to set the operation after having the pass moves (after the return of the call). Do I need to keep track of allocations that want to be released during computation time or won't it be an issue if releasing occurs ? Could it be simpler to just add a reference to allocations that ends up being part of a move and remove a reference at the end of the pass ?
Hope those questions are not stupid :)
Have a nice day !
Hi ! Long time no see !
I'm encountering an issue while creating a resource with CreateResource3 and castable formats.
I'm creating a BC3_UNORM 2D texture with UAV allowed and it can cast to R32G32B32A32_UINT and BC3_UNORM_SRGB. CreatePlacedResource2 or CreateCommittedResource3 accepts this compressed UAV as it can cast to uncompressed format that is coherent.
The issue is that CreateResource3 will do a GetResourceAllocationInfo1 or GetResourceAllocationInfo2 that don't accept castable format, lead to D3D12 errors and return an allocation info with SizeInBytes == (uint64_t)-1. As you save this size and give it to RemoveAllocation, it leads to a failed assert.
To avoid this and errors in D3D12, it seems that it should use GetResourceAllocationInfo3 in ID3D12Device12 interface. I can't create a pull request from a private repo but this is my patch to fix the issue. It fixes for me but it is not perfect and I'm not sure it respects guideline when ID3D12Device12 is not supported ๐ค.
resourceAllocation3.patch
Have a nice day !
Robin
With the memory allocator there are some issues from the gpu based validator.
there is an uav which runs fine on the gpu, however i get warnings in the validator.
They do not happen on the cpu validator.
If i use only committed memory, there are no such errors.
I am looking where this may come from
D3D12 ERROR: GPU-BASED VALIDATION: Dispatch, Incompatible resource state: Resource: 0x000002BA10D56500:'Unnamed ID3D12Resource Object', Subresource Index: [0], Root descriptor type: UAV, Resource State: D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE(0x40) (Promoted from COMMON state), Shader Stage: COMPUTE, Root Parameter Index: [2], Dispatch Index: [21], Shader Code: <couldn't find file location in debug info>, Asm Instruction Range: [0xa-0xffffffff], Asm Operand Index: [0], Command List: 0x000002BA10951520:'CommandList 2, Allocator 0', SRV/UAV/CBV Descriptor Heap: 0x000002BA10693200:'StaticHeapDX12', Sampler Descriptor Heap: 0x000002BA10696300:'StaticHeapDX12', Pipeline State: 0x000002BA4D5C6A00:'TressFXSDFCollision.hlslCollideHairVerticesWithSdf_forward', [ EXECUTION ERROR #942: GPU_BASED_VALIDATION_INCOMPATIBLE_RESOURCE_STATE]
We upgraded D3D12MA and immediately started seeing an uptick in a crash in the wild. From what we can tell MemoryBlock::Init is blindly using GetDevice4() which may not be available in earlier versions of Windows 10 and code like this will GPF:
#ifdef __ID3D12Device4_INTERFACE_DEFINED__
HRESULT hr = m_Allocator->GetDevice4()->CreateHeap1(&heapDesc, pProtectedSession, D3D12MA_IID_PPV_ARGS(&m_Heap));
#else
D3D12MA_ASSERT(pProtectedSession == NULL);
HRESULT hr = m_Allocator->GetDevice()->CreateHeap(&heapDesc, D3D12MA_IID_PPV_ARGS(&m_Heap));
#endif
Hello there, would it be possible to create C bindings for this project? I might want to try contributing to it, but I sort of am not sure how you folks would want these to look like.
Would it go a similar way that Microsoft went about creating C bindings for Direct3D 12 API?
StrStrI is undefined no matter what I do.
I've included it like this:
#include <shlwapi.h>
#inc....
#pragma comment (lib, "Shlwapi.lib")
Please help.
Is there a plan to support pure C interface like in VMA?
Hi.
I tried to use D3D12MemAlloc.h/cpp
in our VS2015 project, and it had many compilation errors. Could we get VS2015 fix?
Should be DivideRoundingUp()
hello. when I run the program I'm getting this error: CommandQueue::ExecuteCommandLists ' Using IASetIndexBuffer on Command List Resource state (D3D12_RESOURCE_STATE_COPY_DEST) of resource (' Index Buffer Resource Heap') (is invalid for use as a index buffer. Expected State Bits (all): 0x2: D3D12_RESOURCE_STATE_INDEX_BUFFER, Actual State: 0x400: D3D12_RESOURCE_STATE_COPY_DEST, Missing State: 0x2: D3D12_RESOURCE_STATE_INDEX_BUFFER. '
even though I transit index buffer like this:
D3D12Backend::TransitBuffer(indexBuffer, D3D12_RESOURCE_STATE_COPY_DEST,
D3D12_RESOURCE_STATE_INDEX_BUFFER,
D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES);
void D3D12Backend::TransitBuffer(ComPtr<ID3D12Resource>& buffer,
D3D12_RESOURCE_STATES StateBefore,
D3D12_RESOURCE_STATES StateAfter ,
UINT Subresource)
{
D3D12_RESOURCE_BARRIER barrier = {};
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Transition.pResource = buffer.Get();
barrier.Transition.StateBefore = StateBefore;
barrier.Transition.StateAfter = StateAfter;
barrier.Transition.Subresource = Subresource;
g_pd3dCommandList->ResourceBarrier(1, &barrier);
}
this is index buffer code: https://gist.github.com/benanil/c700bd6686ba14e7fdd1b3fcbea2dfd5
I also get these warnings
D3D12 WARNING: ID3D12CommandList::IASetIndexBuffer: pDesc->BufferLocation 0x0000000303010000 belongs to a Heap (0x000001C32BCCE9D0:'Unnamed ID3D12Heap Object') however there are no Placed Resources fully containing the GPU Virtual Address range [0x0000000303010000, 0x000000030301000b]. This may be OK since the heap memory can still be accessed from within shaders. However there may be no way to express resource barriers or perform any other operations requiring a Resource interface. The developer probably did not intend to make use of this behavior. [ EXECUTION WARNING #923: HEAP_ADDRESS_RANGE_HAS_NO_RESOURCE]
D3D12 WARNING: ID3D12CommandList::IASetIndexBuffer: Resource 0x000001C32BCEE9B0:'HS Index Buffer Resource Heap' and 0 other resources only cover a portion of the GPU Virtual Address range [0x0000000303010000, 0x000000030301000b] on a Heap (0x000001C32BCCE9D0:'Unnamed ID3D12Heap Object'). This may be OK as long as all of these resources are in the same state however developer probably did not intend to make use of this behavior. [ STATE_CREATION WARNING #926: HEAP_ADDRESS_RANGE_INTERSECTS_MULTIPLE_BUFFERS]
When trying this code out I got a warning: warning C4706: assignment within conditional expression
it looks like if the assert isn't defined, the assignment will not be made. Is this intentional?
D3D12MemoryAllocator/src/D3D12MemAlloc.cpp
Line 7026 in d0cc54c
D3D12MemoryAllocator/src/D3D12MemAlloc.cpp
Line 8023 in 7597f71
If you are using the same heap for buffers and textures, it would be possible for a "small" texture with 4kb alignment to be placed in that memory space after the buffer, if the size is not aligned up. Is there any other reason you align up the size when you allocate memory for a buffer?
Or is the intention to always use separate heaps for buffers and textures?
Hi, I am doing d3d12 programing. it's a few people do the similar work and it's very difficult to find someone to communication.
I am try to create a texture, my code like this:
`
D3D12_HEAP_PROPERTIES HeapPro;
BuildTextureHeapPro(HeapPro);
D3D12_RESOURCE_DESC TextureDesc;
BuildTextureDesc(TextureDesc);
TextureDesc.Alignment = 65536;
D3D12_RESOURCE_ALLOCATION_INFO Info;
Info = Device->GetResourceAllocationInfo(0, 1, &TextureDesc);
mTextureLen = (int)Info.SizeInBytes;
`
It works ok in most times.
But when the texture width is 1108 and the height is 1440, B8G8R8A8 format, Info.SizeInBytes return a wrong size, which return 6619136. and 1108 * 1440 * 4 = 6382080. I try another way, for example, i try "Device->GetCopyableFootprints(&TextureDesc, 0, 1, 0, &Layouts, nullptr, &RowSizeInBytes, &RequiredSize);", and RequiredSize is 6635344, and it is not the right value. I think the right value is 6635520. Because the row pitch is 4608 and the right value is 4608 * 1440 = 6635520.
what is the problem? i google for days and can't find the solution.
please help, thankyou!
Hi, I'm currently trying to implement this library with com smart pointers, but I've run into a problem.
When I use Microsoft::WRL::ComPtrD3D12MA::Allocator allocator, I get the following compiler warning.
C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt\wrl/client.h(235,1): error C2440: '=': cannot convert from 'void' to 'unsigned long' [C:\Users\username\source\repos\D3D12\build\D3D12.vcxproj]
[build] C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt\wrl/client.h(235,32): message : Expressions of type void cannot be converted to other types [C:\Users\username\source\repos\D3D12\build\D3D12.vcxproj]
[build] C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt\wrl/client.h(228): message : while compiling class template member function 'unsigned long Microsoft::WRL::ComPtrD3D12MA::Allocator::InternalRelease(void) noexcept' [C:\Users\username\source\repos\D3D12\build\D3D12.vcxproj]
[build] C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\winrt\wrl/client.h(290): message : see reference to function template instantiation 'unsigned long Microsoft::WRL::ComPtrD3D12MA::Allocator::InternalRelease(void) noexcept' being compiled [C:\Users\username\source\repos\D3D12\build\D3D12.vcxproj]
[build] C:\Users\username\source\repos\D3D12\src\DXWindow.hpp(73): message : see reference to class template instantiation 'Microsoft::WRL::ComPtrD3D12MA::Allocator' being compiled [C:\Users\username\source\repos\D3D12\build\D3D12.vcxproj]
However if I use CComPtrD3D12MA::Allocator allocator everything works fine.
The gpuopen docs says this library should work with WRL pointers.
I don't know if I should be mixing both types of smart pointer as my other com objects are using WRL.
Any help is appreciated, thanks.
Hello,
I was trying out D3D12MA
when using the WARP device and I noticed that 4 tests are failing in that case.
Specifically: TestPlacedResources
, TestCustomPools
, TestDevice4
and TestDevice8
.
!= 0
to select the WARP device:D3D12MemoryAllocator/src/D3D12Sample.cpp
Line 388 in 5457bcd
I get the following failures (each seen after commenting out the previously failing test and re-running the tests):
Test placed resources
Assertion failed: 0 && "C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp" "(" "455" "): !( " "resources[i].allocation->GetHeap() != NULL" " )", file C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp, line 455
Test custom pools
Assertion failed: 0 && "C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp" "(" "683" "): FAILED( " "hr" " )", file C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp, line 683
Test ID3D12Device4
Assertion failed: 0 && "C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp" "(" "1348" "): FAILED( " "dev4->CreateProtectedResourceSession(&sessionDesc, IID_PPV_ARGS(&session))" " )", file C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp, line 1348
Test ID3D12Device8
Assertion failed: 0 && "C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp" "(" "1412" "): !( " "alloc1->GetHeap()!= NULL" " )", file C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp, line 1412
TestDevice4
Not sure about the failures in the other tests, but I could investigate and fix the one in this one.
Turns out the WARP device doesn't support ID3D12Device4::CreateProtectedResourceSession
, so the call to this method at the start of the test just causes ERROR_INVALID_PARAMETER
to be returned. The fix is to just do something like:
D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT support;
CHECK_HR(ctx.device->CheckFeatureSupport(
D3D12_FEATURE::D3D12_FEATURE_PROTECTED_RESOURCE_SESSION_SUPPORT,
&support,
sizeof(D3D12_FEATURE_DATA_PROTECTED_RESOURCE_SESSION_SUPPORT)));
if (support.Support == D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAGS::D3D12_PROTECTED_RESOURCE_SESSION_SUPPORT_FLAG_NONE)
{
wprintf(L"Skipping ID3D12Device4\n");
return;
}
Hope this helps! ๐
Defining D3D12MA_DEBUG_GLOBAL_MUTEX causes double locking of static debug std::mutex when releasing resources.
See IUnknownImpl::Release():
ULONG STDMETHODCALLTYPE IUnknownImpl::Release()
{
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
const uint32_t newRefCount = --m_RefCount;
if(newRefCount == 0)
ReleaseThis();
return newRefCount;
}
When m_RefCount == 0, ReleaseThis(), tries to acquire debug lock again:
void Allocator::ReleaseThis()
{
D3D12MA_DEBUG_GLOBAL_MUTEX_LOCK
...
}
Resulting in std::system_exception being thrown.
DX12 (like most Microsoft COM API) is available in C. However, this memory allocator is not.
Would it be possible to expose a C interface for the allocator?
The latest vcpkg port is on 10f148cef0dfd34ae1a9373b9396beb1581c992a
, which seems to be a bit over two years old:
// D3D12MemAlloc.h
<b>Version 2.0.0-development</b> (2021-03-11)
There seems to be a bug in the release build that prevents me from compiling the allocator.
In particular on line 596 m_Allocator
is referenced but not declared anywhere I can find.
596: Free(m_Allocator.m_pCallbacks, m_pArray)
The issue seems to be fixed on the master branch as I can compile without issues there, I thought I'd open an issue to let you know though. Thanks for the work!
Hi !
After diving into a json detailed allocation map, I found a lot of offset that had the same value.
It looks like it is a simple switch of arguments :
The definition of PrintDetailedMap_Allocation is this one :
void BlockMetadata::PrintDetailedMap_Allocation(JsonWriter& json, UINT64 offset, UINT64 size, void* privateData) const
but it is called like that
PrintDetailedMap_Allocation(json, block->size, block->offset, block->PrivateData());
in BlockMetadata_TLSF::WriteAllocationInfoToJson
(D3D12MemAlloc.cpp:5606).
If it is not this simple thing, I don't understand why nearly all my allocations have the same offset as my size. If it is, it could have be a PR but I wasn't sure.
Our in-house engine use D3D12MA as D3D12 backend's native memory allocator, and I found that placed memory fragments get more and more with game running. By read document, I found there is a interface called D3D12MA::Allocator::BeginDefragmentation
can help heap allocation defragment. But after transplanted code from official sample, I just got some overlapped placed resources in heaps, like this in NSight Graphics:
Our resources' copy, create, access and destroy can happened on multi-thread, and resources' lifecycle is managed by intelligent pointers, but I have checked if a defragment action scheduled, any of resources' operation will blocked by mutex, and old resources' ref count will be set to 0 after defragment action.
So I got puzzled, I can not find any meaningful code on web except official sample, is D3D12MA really support defragment ? Could you have some more complex sample which can shared with us ?
Is it possible to use this library to port game\engine DX12 renderer from Windows to consoles (XBOX ONE S/X, XBOX SERIES S/X) ? Or we need to do some adjustments?
Hi there, does setting the ALLOCATION_FLAG_WITHIN_BUDGET
flag enforce using only gpu/device memory or does it also include system memory that is shared for gpu? In other words, how can we specify the followings?
Hello,
I noticed that a couple of tests are currently failing, in particular TestStats
and TestID3D12Device4
.
This happens both when running the pre-built executable, as well as when manually building and running the sample.
I'm getting these two errors (the second is after commenting out the first and re-running the tests):
Test stats
Assertion failed: 0 && "C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp" "(" "924" "): !( " "endStats.Total.AllocationCount == begStats.Total.AllocationCount + count" " )", file C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp, line 924
Test ID3D12Device4
Assertion failed: 0 && "C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp" "(" "1372" "): FAILED( " "ctx.allocator->AllocateMemory1(&allocDesc, &heapAllocInfo, session, &alloc)" " )", file C:\Users\Sergio\Documents\GitHub\D3D12MemoryAllocator\src\Tests.cpp, line 1372
System info:
Hope this helps, keep up the good work! ๐
Let me start by saying that D3D12MA is a great project and it's super easy to integrate, which is awesome ๐
There's one big limitation currently in the way D3D12MA can be used, which is that there is no support for custom heaps. Even when using Allocator::CreatePool
to create a custom pool, the POOL_DESC.HeapType
specifically mentions in the documentation not to use the CUSTOM
heap type, and there is also no way to pass other heap properties for the pool. In general, it would be necessary for POOL_DESC
to allow callers to pass a D3D12_HEAP_PROPERTIES
value directly (eg. replacing that single HeapType
field), so that consumers would have full control on the target heap used for allocations when using that pool.
This would enable a number of scenarios not possible today when using D3D12MA, such as:
DEFAULT
heap that's also CPU visible (using POOL_L0
and PAGE_ACCESS_WRITE_BACK
)READBACK
heap for transfer buffers that can be both read to and written to by the GPUThe simplest solution I can think of would be to just change this field in POOL_DESC
:
struct POOL_DESC
{
- D3D12_HEAP_TYPE HeapType;
+ D3D12_HEAP_PROPERTIES HeapProperties;
};
That HeapProperties
would then be passed internally just like HeapType
is today, and then MemoryBlock::Init
would use that HeapProperties
value to setup the D3D12_HEAP_DESC
value before calling ID3D12Device::CreateHeap
, instead of just setting the heap type like it does today. As in, minor changes would need to be done here:
D3D12MemoryAllocator/src/D3D12MemAlloc.cpp
Lines 3425 to 3435 in e56c26d
This would give consumers of the library much greater flexibility, and it'd make the ability to create custom allocation pools much more worthwhile, as there could be way more customization done on the allocation parameters used by them.
Hi there! ๐
I've stumbled upon a weird issue while writing unit tests for my library ComputeSharp, which uses a 1:1 C# port of D3D12MA, and I'm investigating it to try to narrow down the root cause. I thought I'd also open an issue here for tracking as it seems to be related to D3D12MA (I've verified I cannot repro it if I just allocate my resources with ID3D12Device::CreateCommittedResource
) in some way.
I don't yet have a full minimal repro, but here's the general idea:
The repro steps I have so far:
D3D_FEATURE_LEVEL_11_0
D3D12MA_POOL_DESC poolDesc = default;
poolDesc.HeapProperties.CreationNodeMask = 1;
poolDesc.HeapProperties.VisibleNodeMask = 1;
poolDesc.HeapProperties.Type = D3D12_HEAP_TYPE_CUSTOM;
poolDesc.HeapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
poolDesc.HeapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
DXGI_FORMAT_R32_FLOAT
format, D3D12_RESOURCE_FLAG_NONE
flags, D3D12_RESOURCE_STATE_COMMON
state, D3D12_HEAP_TYPE_DEFAULT
heap, D3D12MA_ALLOCATION_FLAG_NONE
D3D12MA flags, with the UMA pool.D3D12_HEAP_TYPE_UPLOAD
, D3D12_RESOURCE_FLAG_NONE
, D3D12_RESOURCE_STATE_GENERIC_READ
), using the right byte size depending on the copyable footprint retrieved from the previously allocated 3D texture. Map this resource, write the sample data to it, then create a copy command list and use ID3D12GraphicsCommandList::CopyTextureRegion
to copy this data to the actual texture.D3D12MA_ALLOCATION_FLAG_COMMITTED
to force zeroing).ID3D12GraphicsCommandList::CopyTextureRegion
).ID3D12GraphicsCommandList::CopyTextureRegion
to it, then map it and copy its contents somewhere you can easily read from (or alternatively just map the buffer and then read directly from there).Now, running these 2 tests one after the other causes the second one to fail:
By "test failing", I mean that when verifying the data read back from the second texture (the destination one), I get this:
D3D12MA_ALLOCATION_FLAG_COMMITTED
for the destination texture, so it should always be a new allocation with no previous data in it. โJust a random thought, but if D3D12MA is in fact accidentlaly not using a committed allocation here and reusing a previous one, it might explain why the behavior is so inconsistent across different OS versions and machines, as the exact way previous allocations are reused and cleared by the OS/driver is undefined? Anyway this is as detailed I could be for this, let me know if there's anything else I can do! I can also try to actually come up with a minimal repro if it helps (though that'd be in C#).
Thanks! ๐
Hello,
How do you recommend using this library with residency management.
Microsoft has an example about this.
Do you have any recommendations about this?
Thank you
Hi Adam ! Hope everything is ok !
I wanted to know if something was a feature or more of a bug.
I have a resource that is created with the allocator. By default, this resource (because it can be created without the allocator) is using the D3D12_HEAP_FLAGS : D3D12_HEAP_FLAG_CREATE_NOT_ZEROED. Because of this extra flag, the function CalcDefaultPoolIndex
considers that the resource should not be created in a default pool, return -1 and the resource will be created as committed.
Is it the correct behaviour or should it be created as placed (since a placed resource will never be zeroed) ?
Hi, I'm attempting to replicate an allocation scheme used on non-PC platforms for transient resources visible to the GPU only which relies on aliasing the same memory across the frame. This relies on being able to "free" (from the application's POV) the resource memory as soon as it is no longer needed, even if midway through recording a command list, and then allocate new placed resources on top of the same memory so that within a frame GPU memory can be reused via aliasing.
It seems like using a D3D12MA::Pool object almost supports this since I could make one for these transient allocations and then use AllocateMemory to suballocate the heaps it manages. However, the problem is that releasing the D3D12MA::Allocator will immediately free the underlying ID3D12Heap if that block has now become empty even though the frames using that memory are still in flight. I could avoid this by holding onto the Allocation object until I'm sure the GPU is is finished with the last frame using that memory, although that would prevent any aliasing and frames N, N+1, N+2 would then each have their own copy instead of reusing the same memory, which is undesirable.
Is there some existing mechanism to prevent the underlying heaps from being actually freed when the pool shrinks for some N frames as observed via Allocator::SetCurrentFrameIndex()? I see POOL_DESC::MinBlockCount, which keeps empty blocks around, but I don't have a specific minimum size. Ideally the pool would resize dynamically, but the empty blocks would stick around for N frames after they were last used via a cooldown, where N is the number of frames my application has in flight at a given time. It would also be valid for them to be reused to allocate new resources, similar to reuse within a frame since my application ensures work using the memory doesn't overlap, which is why it seems like the existing behavior is so close to what I'm trying to do.
Am I missing something here? Maybe there is a non-obvious D3D12 behavior that makes this kind of setup impossible? :)
Thanks!
EDIT: I just realized after writing this that if it was possible to dynamically change MinBlockCount on a Pool I could call Pool::GetStatistics() each frame then set the MinBlockCount to the N-frame max of Statistics::BlockCount which would essentially do this behavior
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.