yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
b118451e3
master
1// d3d12-query.cpp 2#include "d3d12-query.h" 3 4#include "d3d12-command-queue.h" 5#include "d3d12-helper-functions.h" 6 7namespace gfx 8{ 9namespace d3d12 10{ 11 12using namespace Slang ; 13 14Result QueryPoolImpl ::init (const IQueryPool ::Desc & desc ,DeviceImpl * device ) 15{ 16m_desc = desc ; 17 18// Translate query type. 19D3D12_QUERY_HEAP_DESC heapDesc = {}; 20heapDesc .Count = (UINT )desc .count ; 21heapDesc .NodeMask = 1 ; 22switch (desc .type ) 23 { 24case QueryType ::Timestamp : 25heapDesc .Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP ; 26m_queryType = D3D12_QUERY_TYPE_TIMESTAMP ; 27break ; 28default : 29return SLANG_E_INVALID_ARG ; 30 } 31 32// Create query heap. 33auto d3dDevice = device -> m_device ; 34SLANG_RETURN_ON_FAIL ( 35d3dDevice -> CreateQueryHeap (& heapDesc ,IID_PPV_ARGS (m_queryHeap .writeRef ()))); 36 37// Create readback buffer. 38D3D12_HEAP_PROPERTIES heapProps ; 39heapProps .Type = D3D12_HEAP_TYPE_READBACK ; 40heapProps .CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN ; 41heapProps .MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN ; 42heapProps .CreationNodeMask = 1 ; 43heapProps .VisibleNodeMask = 1 ; 44D3D12_RESOURCE_DESC resourceDesc = {}; 45initBufferResourceDesc (sizeof (uint64_t )* desc .count ,resourceDesc ); 46SLANG_RETURN_ON_FAIL (m_readBackBuffer .initCommitted ( 47d3dDevice , 48heapProps , 49D3D12_HEAP_FLAG_NONE , 50resourceDesc , 51D3D12_RESOURCE_STATE_COPY_DEST , 52nullptr )); 53 54// Create command allocator. 55SLANG_RETURN_ON_FAIL (d3dDevice -> CreateCommandAllocator ( 56D3D12_COMMAND_LIST_TYPE_DIRECT , 57IID_PPV_ARGS (m_commandAllocator .writeRef ()))); 58 59// Create command list. 60SLANG_RETURN_ON_FAIL (d3dDevice -> CreateCommandList ( 610 , 62D3D12_COMMAND_LIST_TYPE_DIRECT , 63m_commandAllocator , 64nullptr , 65IID_PPV_ARGS (m_commandList .writeRef ()))); 66m_commandList -> Close (); 67 68// Create fence. 69SLANG_RETURN_ON_FAIL ( 70d3dDevice -> CreateFence (0 ,D3D12_FENCE_FLAG_NONE ,IID_PPV_ARGS (m_fence .writeRef ()))); 71 72// Get command queue from device. 73m_commandQueue = device -> m_resourceCommandQueue -> m_d3dQueue ; 74 75// Create wait event. 76m_waitEvent = CreateEventEx (nullptr , FALSE,0 ,EVENT_ALL_ACCESS ); 77 78return SLANG_OK ; 79} 80 81Result QueryPoolImpl ::getResult (GfxIndex queryIndex ,GfxCount count ,uint64_t * data ) 82{ 83m_commandList -> Reset (m_commandAllocator ,nullptr ); 84m_commandList -> ResolveQueryData ( 85m_queryHeap , 86m_queryType , 87 (UINT )queryIndex , 88 (UINT )count , 89m_readBackBuffer , 90sizeof (uint64_t )* queryIndex ); 91m_commandList -> Close (); 92ID3D12CommandList * cmdList = m_commandList ; 93m_commandQueue -> ExecuteCommandLists (1 ,& cmdList ); 94m_eventValue ++ ; 95m_fence -> SetEventOnCompletion (m_eventValue ,m_waitEvent ); 96m_commandQueue -> Signal (m_fence ,m_eventValue ); 97WaitForSingleObject (m_waitEvent ,INFINITE ); 98m_commandAllocator -> Reset (); 99 100int8_t * mappedData = nullptr ; 101D3D12_RANGE readRange = { 102sizeof (uint64_t )* queryIndex , 103sizeof (uint64_t )* (queryIndex + count )}; 104m_readBackBuffer .getResource ()-> Map (0 ,& readRange , (void ** )& mappedData ); 105memcpy (data ,mappedData + sizeof (uint64_t )* queryIndex ,sizeof (uint64_t )* count ); 106m_readBackBuffer .getResource ()-> Unmap (0 ,nullptr ); 107return SLANG_OK ; 108} 109 110void QueryPoolImpl ::writeTimestamp (ID3D12GraphicsCommandList * cmdList ,GfxIndex index ) 111{ 112cmdList -> EndQuery (m_queryHeap ,D3D12_QUERY_TYPE_TIMESTAMP , (UINT )index ); 113} 114 115IQueryPool * PlainBufferProxyQueryPoolImpl ::getInterface (const Guid & guid ) 116{ 117if (guid == GfxGUID ::IID_ISlangUnknown || guid == GfxGUID ::IID_IQueryPool ) 118return static_cast < IQueryPool *> (this ); 119return nullptr ; 120} 121 122Result PlainBufferProxyQueryPoolImpl ::init ( 123const IQueryPool ::Desc & desc , 124DeviceImpl * device , 125uint32_t stride ) 126{ 127ComPtr < IBufferResource > bufferResource ; 128IBufferResource ::Desc bufferDesc = {}; 129bufferDesc .defaultState = ResourceState ::CopySource ; 130bufferDesc .elementSize = 0 ; 131bufferDesc .type = IResource ::Type ::Buffer ; 132bufferDesc .sizeInBytes = desc .count * stride ; 133bufferDesc .format = Format ::Unknown ; 134bufferDesc .allowedStates .add (ResourceState ::UnorderedAccess ); 135SLANG_RETURN_ON_FAIL ( 136device -> createBufferResource (bufferDesc ,nullptr ,bufferResource .writeRef ())); 137m_bufferResource = static_cast < BufferResourceImpl *> (bufferResource .get ()); 138m_queryType = desc .type ; 139m_device = device ; 140m_stride = stride ; 141m_count = (uint32_t )desc .count ; 142m_desc = desc ; 143return SLANG_OK ; 144} 145 146Result PlainBufferProxyQueryPoolImpl ::reset () 147{ 148m_resultDirty = true; 149auto encodeInfo = m_device -> encodeResourceCommands (); 150D3D12_RESOURCE_BARRIER barrier = {}; 151barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ; 152barrier .Transition .StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE ; 153barrier .Transition .StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS ; 154barrier .Transition .pResource = m_bufferResource -> m_resource .getResource (); 155encodeInfo .d3dCommandList -> ResourceBarrier (1 ,& barrier ); 156m_device -> submitResourceCommandsAndWait (encodeInfo ); 157return SLANG_OK ; 158} 159 160Result PlainBufferProxyQueryPoolImpl ::getResult (GfxIndex queryIndex ,GfxCount count ,uint64_t * data ) 161{ 162if (m_resultDirty ) 163 { 164auto encodeInfo = m_device -> encodeResourceCommands (); 165D3D12_RESOURCE_BARRIER barrier = {}; 166barrier .Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION ; 167barrier .Transition .StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS ; 168barrier .Transition .StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE ; 169barrier .Transition .pResource = m_bufferResource -> m_resource .getResource (); 170encodeInfo .d3dCommandList -> ResourceBarrier (1 ,& barrier ); 171 172D3D12Resource stageBuf ; 173 174auto size = (Size )m_count * m_stride ; 175D3D12_HEAP_PROPERTIES heapProps ; 176heapProps .Type = D3D12_HEAP_TYPE_READBACK ; 177heapProps .CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN ; 178heapProps .MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN ; 179heapProps .CreationNodeMask = 1 ; 180heapProps .VisibleNodeMask = 1 ; 181 182D3D12_RESOURCE_DESC stagingDesc ; 183initBufferResourceDesc (size ,stagingDesc ); 184 185SLANG_RETURN_ON_FAIL (stageBuf .initCommitted ( 186m_device -> m_device , 187heapProps , 188D3D12_HEAP_FLAG_NONE , 189stagingDesc , 190D3D12_RESOURCE_STATE_COPY_DEST , 191nullptr )); 192 193encodeInfo .d3dCommandList 194-> CopyBufferRegion (stageBuf ,0 ,m_bufferResource -> m_resource .getResource (),0 ,size ); 195m_device -> submitResourceCommandsAndWait (encodeInfo ); 196void * ptr = nullptr ; 197stageBuf .getResource ()-> Map (0 ,nullptr ,& ptr ); 198m_result .setCount (m_count * m_stride ); 199memcpy (m_result .getBuffer (),ptr ,m_result .getCount ()); 200 201m_resultDirty = false; 202 } 203 204memcpy (data ,m_result .getBuffer ()+ queryIndex * m_stride ,count * m_stride ); 205 206return SLANG_OK ; 207} 208 209}// namespace d3d12 210}// namespace gfx