yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// d3d12-transient-heap.cpp 2#include "d3d12-transient-heap.h" 3 4#include "d3d12-buffer.h" 5#include "d3d12-command-buffer.h" 6#include "d3d12-device.h" 7 8namespace gfx 9{ 10namespace d3d12 11{ 12 13using namespace Slang ; 14 15Result TransientResourceHeapImpl ::synchronize () 16{ 17WaitForMultipleObjects ( 18 (DWORD )m_waitHandles .getCount (), 19m_waitHandles .getArrayView ().getBuffer (), 20 TRUE, 21INFINITE ); 22m_waitHandles .clear (); 23return SLANG_OK ; 24} 25 26Result TransientResourceHeapImpl ::synchronizeAndReset () 27{ 28synchronize (); 29 30m_currentViewHeapIndex = -1 ; 31m_currentSamplerHeapIndex = -1 ; 32allocateNewViewDescriptorHeap (m_device ); 33allocateNewSamplerDescriptorHeap (m_device ); 34m_stagingCpuSamplerHeap .freeAll (); 35m_stagingCpuViewHeap .freeAll (); 36m_commandListAllocId = 0 ; 37SLANG_RETURN_ON_FAIL (m_commandAllocator -> Reset ()); 38Super ::reset (); 39return SLANG_OK ; 40} 41 42Result TransientResourceHeapImpl ::finish () 43{ 44for (auto & waitInfo :m_waitInfos ) 45 { 46if (waitInfo .waitValue == 0 ) 47continue ; 48if (waitInfo .fence ) 49 { 50waitInfo .queue -> Signal (waitInfo .fence ,waitInfo .waitValue ); 51waitInfo .fence -> SetEventOnCompletion (waitInfo .waitValue ,waitInfo .fenceEvent ); 52m_waitHandles .add (waitInfo .fenceEvent ); 53 } 54 } 55return SLANG_OK ; 56} 57 58TransientResourceHeapImpl ::QueueWaitInfo & TransientResourceHeapImpl ::getQueueWaitInfo ( 59uint32_t queueIndex ) 60{ 61if (queueIndex < (uint32_t )m_waitInfos .getCount ()) 62 { 63return m_waitInfos [queueIndex ]; 64 } 65auto oldCount = m_waitInfos .getCount (); 66m_waitInfos .setCount (queueIndex + 1 ); 67for (auto i = oldCount ;i < m_waitInfos .getCount ();i ++ ) 68 { 69m_waitInfos [i ].waitValue = 0 ; 70m_waitInfos [i ].fenceEvent = CreateEventEx (nullptr , FALSE,0 ,EVENT_ALL_ACCESS ); 71 } 72return m_waitInfos [queueIndex ]; 73} 74 75D3D12DescriptorHeap & TransientResourceHeapImpl ::getCurrentViewHeap () 76{ 77return m_viewHeaps [m_currentViewHeapIndex ]; 78} 79 80D3D12DescriptorHeap & TransientResourceHeapImpl ::getCurrentSamplerHeap () 81{ 82return m_samplerHeaps [m_currentSamplerHeapIndex ]; 83} 84 85Result TransientResourceHeapImpl ::queryInterface (SlangUUID const & uuid ,void ** outObject ) 86{ 87if (uuid == GfxGUID ::IID_ITransientResourceHeapD3D12 ) 88 { 89* outObject = static_cast < ITransientResourceHeapD3D12 *> (this ); 90addRef (); 91return SLANG_OK ; 92 } 93return Super ::queryInterface (uuid ,outObject ); 94} 95 96Result TransientResourceHeapImpl ::allocateTransientDescriptorTable ( 97DescriptorType type , 98GfxCount count , 99Offset & outDescriptorOffset , 100void ** outD3DDescriptorHeapHandle ) 101{ 102auto & heap = 103 (type == DescriptorType ::ResourceView ) ?getCurrentViewHeap () :getCurrentSamplerHeap (); 104int allocResult = heap .allocate ((int )count ); 105if (allocResult == -1 ) 106 { 107return SLANG_E_OUT_OF_MEMORY ; 108 } 109outDescriptorOffset = (Offset )allocResult ; 110* outD3DDescriptorHeapHandle = heap .getHeap (); 111return SLANG_OK ; 112} 113 114TransientResourceHeapImpl ::~TransientResourceHeapImpl () 115{ 116synchronize (); 117for (auto & waitInfo :m_waitInfos ) 118CloseHandle (waitInfo .fenceEvent ); 119} 120 121Result TransientResourceHeapImpl ::init ( 122const ITransientResourceHeap ::Desc & desc , 123DeviceImpl * device , 124uint32_t viewHeapSize , 125uint32_t samplerHeapSize ) 126{ 127Super ::init (desc ,D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT ,device ); 128m_canResize = (desc .flags & ITransientResourceHeap ::Flags ::AllowResizing )!= 0 ; 129m_viewHeapSize = viewHeapSize ; 130m_samplerHeapSize = samplerHeapSize ; 131 132m_stagingCpuViewHeap .init ( 133device -> m_device , 1341000000 , 135D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 136D3D12_DESCRIPTOR_HEAP_FLAG_NONE ); 137m_stagingCpuSamplerHeap .init ( 138device -> m_device , 1391000000 , 140D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 141D3D12_DESCRIPTOR_HEAP_FLAG_NONE ); 142 143auto d3dDevice = device -> m_device ; 144SLANG_RETURN_ON_FAIL (d3dDevice -> CreateCommandAllocator ( 145D3D12_COMMAND_LIST_TYPE_DIRECT , 146IID_PPV_ARGS (m_commandAllocator .writeRef ()))); 147 148allocateNewViewDescriptorHeap (device ); 149allocateNewSamplerDescriptorHeap (device ); 150 151return SLANG_OK ; 152} 153 154Result TransientResourceHeapImpl ::allocateNewViewDescriptorHeap (DeviceImpl * device ) 155{ 156auto nextHeapIndex = m_currentViewHeapIndex + 1 ; 157if (nextHeapIndex < m_viewHeaps .getCount ()) 158 { 159m_viewHeaps [nextHeapIndex ].deallocateAll (); 160m_currentViewHeapIndex = nextHeapIndex ; 161return SLANG_OK ; 162 } 163auto d3dDevice = device -> m_device ; 164D3D12DescriptorHeap viewHeap ; 165SLANG_RETURN_ON_FAIL (viewHeap .init ( 166d3dDevice , 167m_viewHeapSize , 168D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV , 169D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE )); 170m_currentViewHeapIndex = (int32_t )m_viewHeaps .getCount (); 171m_viewHeaps .add (_Move (viewHeap )); 172return SLANG_OK ; 173} 174 175Result TransientResourceHeapImpl ::allocateNewSamplerDescriptorHeap (DeviceImpl * device ) 176{ 177auto nextHeapIndex = m_currentSamplerHeapIndex + 1 ; 178if (nextHeapIndex < m_samplerHeaps .getCount ()) 179 { 180m_samplerHeaps [nextHeapIndex ].deallocateAll (); 181m_currentSamplerHeapIndex = nextHeapIndex ; 182return SLANG_OK ; 183 } 184auto d3dDevice = device -> m_device ; 185D3D12DescriptorHeap samplerHeap ; 186SLANG_RETURN_ON_FAIL (samplerHeap .init ( 187d3dDevice , 188m_samplerHeapSize , 189D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER , 190D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE )); 191m_currentSamplerHeapIndex = (int32_t )m_samplerHeaps .getCount (); 192m_samplerHeaps .add (_Move (samplerHeap )); 193return SLANG_OK ; 194} 195 196Result TransientResourceHeapImpl ::createCommandBuffer (ICommandBuffer ** outCmdBuffer ) 197{ 198if ((Index )m_commandListAllocId < m_commandBufferPool .getCount ()) 199 { 200auto result = 201static_cast < CommandBufferImpl *> (m_commandBufferPool [m_commandListAllocId ].Ptr ()); 202m_d3dCommandListPool [m_commandListAllocId ]-> Reset (m_commandAllocator ,nullptr ); 203result -> reinit (); 204++ m_commandListAllocId ; 205returnComPtr (outCmdBuffer ,result ); 206return SLANG_OK ; 207 } 208ComPtr < ID3D12GraphicsCommandList > cmdList ; 209SLANG_RETURN_ON_FAIL (m_device -> m_device -> CreateCommandList ( 2100 , 211D3D12_COMMAND_LIST_TYPE_DIRECT , 212m_commandAllocator , 213nullptr , 214IID_PPV_ARGS (cmdList .writeRef ()))); 215 216m_d3dCommandListPool .add (cmdList ); 217RefPtr < CommandBufferImpl > cmdBuffer = new CommandBufferImpl (); 218cmdBuffer -> init (m_device ,cmdList ,this ); 219m_commandBufferPool .add (cmdBuffer ); 220++ m_commandListAllocId ; 221returnComPtr (outCmdBuffer ,cmdBuffer ); 222return SLANG_OK ; 223} 224 225}// namespace d3d12 226}// namespace gfx