diff options
| author | lucy96chen <47800040+lucy96chen@users.noreply.github.com> | 2022-05-17 10:56:14 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-05-17 10:56:14 -0700 |
| commit | 5a3aa6159e0ef0241b528812e1d138f0d7055f22 (patch) | |
| tree | 71d286e06030ee73f0b739e071cd58dd05d507d1 /tools/gfx/d3d12/d3d12-query.cpp | |
| parent | 716e75b9ed1acfaee3dc7f3bc347ad17fca65e05 (diff) | |
Split render-d3d12.h/cpp into a set of smaller files (#2231)
* Split render-d3d12 into numerous smaller files to make the code easier to parse
* Added all new D3D12 files created from splitting render-d3d12
* Fixed several uses of attachment still floating around; Changed resource-d3d12 and descriptor-heap-d3d12 to match naming conventions of new d3d12 implementation header files
* Readded files with name changes because changing them from inside VS apparently results in them being treated as new files
* Merged in externals changes from master
* Small cleanup changes
* Rerun CI
Co-authored-by: Theresa Foley <10618364+tangent-vector@users.noreply.github.com>
Diffstat (limited to 'tools/gfx/d3d12/d3d12-query.cpp')
| -rw-r--r-- | tools/gfx/d3d12/d3d12-query.cpp | 207 |
1 files changed, 207 insertions, 0 deletions
diff --git a/tools/gfx/d3d12/d3d12-query.cpp b/tools/gfx/d3d12/d3d12-query.cpp new file mode 100644 index 000000000..319976bbc --- /dev/null +++ b/tools/gfx/d3d12/d3d12-query.cpp @@ -0,0 +1,207 @@ +// d3d12-query.cpp +#include "d3d12-query.h" + +#include "d3d12-command-queue.h" + +#include "d3d12-helper-functions.h" + +namespace gfx +{ +namespace d3d12 +{ + +using namespace Slang; + +Result QueryPoolImpl::init(const IQueryPool::Desc& desc, DeviceImpl* device) +{ + m_desc = desc; + + // Translate query type. + D3D12_QUERY_HEAP_DESC heapDesc = {}; + heapDesc.Count = (UINT)desc.count; + heapDesc.NodeMask = 1; + switch (desc.type) + { + case QueryType::Timestamp: + heapDesc.Type = D3D12_QUERY_HEAP_TYPE_TIMESTAMP; + m_queryType = D3D12_QUERY_TYPE_TIMESTAMP; + break; + default: + return SLANG_E_INVALID_ARG; + } + + // Create query heap. + auto d3dDevice = device->m_device; + SLANG_RETURN_ON_FAIL( + d3dDevice->CreateQueryHeap(&heapDesc, IID_PPV_ARGS(m_queryHeap.writeRef()))); + + // Create readback buffer. + D3D12_HEAP_PROPERTIES heapProps; + heapProps.Type = D3D12_HEAP_TYPE_READBACK; + heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + D3D12_RESOURCE_DESC resourceDesc = {}; + initBufferResourceDesc(sizeof(uint64_t) * desc.count, resourceDesc); + SLANG_RETURN_ON_FAIL(m_readBackBuffer.initCommitted( + d3dDevice, + heapProps, + D3D12_HEAP_FLAG_NONE, + resourceDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + nullptr)); + + // Create command allocator. + SLANG_RETURN_ON_FAIL(d3dDevice->CreateCommandAllocator( + D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(m_commandAllocator.writeRef()))); + + // Create command list. + SLANG_RETURN_ON_FAIL(d3dDevice->CreateCommandList( + 0, + D3D12_COMMAND_LIST_TYPE_DIRECT, + m_commandAllocator, + nullptr, + IID_PPV_ARGS(m_commandList.writeRef()))); + m_commandList->Close(); + + // Create fence. + SLANG_RETURN_ON_FAIL( + d3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(m_fence.writeRef()))); + + // Get command queue from device. + m_commandQueue = device->m_resourceCommandQueue->m_d3dQueue; + + // Create wait event. + m_waitEvent = CreateEventEx(nullptr, false, 0, EVENT_ALL_ACCESS); + + return SLANG_OK; +} + +Result QueryPoolImpl::getResult(GfxIndex queryIndex, GfxCount count, uint64_t* data) +{ + m_commandList->Reset(m_commandAllocator, nullptr); + m_commandList->ResolveQueryData( + m_queryHeap, + m_queryType, + (UINT)queryIndex, + (UINT)count, + m_readBackBuffer, + sizeof(uint64_t) * queryIndex); + m_commandList->Close(); + ID3D12CommandList* cmdList = m_commandList; + m_commandQueue->ExecuteCommandLists(1, &cmdList); + m_eventValue++; + m_fence->SetEventOnCompletion(m_eventValue, m_waitEvent); + m_commandQueue->Signal(m_fence, m_eventValue); + WaitForSingleObject(m_waitEvent, INFINITE); + m_commandAllocator->Reset(); + + int8_t* mappedData = nullptr; + D3D12_RANGE readRange = { + sizeof(uint64_t) * queryIndex, sizeof(uint64_t) * (queryIndex + count) }; + m_readBackBuffer.getResource()->Map(0, &readRange, (void**)&mappedData); + memcpy(data, mappedData + sizeof(uint64_t) * queryIndex, sizeof(uint64_t) * count); + m_readBackBuffer.getResource()->Unmap(0, nullptr); + return SLANG_OK; +} + +void QueryPoolImpl::writeTimestamp(ID3D12GraphicsCommandList* cmdList, GfxIndex index) +{ + cmdList->EndQuery(m_queryHeap, D3D12_QUERY_TYPE_TIMESTAMP, (UINT)index); +} + +IQueryPool* PlainBufferProxyQueryPoolImpl::getInterface(const Guid& guid) +{ + if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IQueryPool) + return static_cast<IQueryPool*>(this); + return nullptr; +} + +Result PlainBufferProxyQueryPoolImpl::init( + const IQueryPool::Desc& desc, DeviceImpl* device, uint32_t stride) +{ + ComPtr<IBufferResource> bufferResource; + IBufferResource::Desc bufferDesc = {}; + bufferDesc.defaultState = ResourceState::CopySource; + bufferDesc.elementSize = 0; + bufferDesc.type = IResource::Type::Buffer; + bufferDesc.sizeInBytes = desc.count * stride; + bufferDesc.format = Format::Unknown; + bufferDesc.allowedStates.add(ResourceState::UnorderedAccess); + SLANG_RETURN_ON_FAIL( + device->createBufferResource(bufferDesc, nullptr, bufferResource.writeRef())); + m_bufferResource = static_cast<BufferResourceImpl*>(bufferResource.get()); + m_queryType = desc.type; + m_device = device; + m_stride = stride; + m_count = (uint32_t)desc.count; + m_desc = desc; + return SLANG_OK; +} + +Result PlainBufferProxyQueryPoolImpl::reset() +{ + m_resultDirty = true; + auto encodeInfo = m_device->encodeResourceCommands(); + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_SOURCE; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + barrier.Transition.pResource = m_bufferResource->m_resource.getResource(); + encodeInfo.d3dCommandList->ResourceBarrier(1, &barrier); + m_device->submitResourceCommandsAndWait(encodeInfo); + return SLANG_OK; +} + +Result PlainBufferProxyQueryPoolImpl::getResult(GfxIndex queryIndex, GfxCount count, uint64_t* data) +{ + if (m_resultDirty) + { + auto encodeInfo = m_device->encodeResourceCommands(); + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COPY_SOURCE; + barrier.Transition.pResource = m_bufferResource->m_resource.getResource(); + encodeInfo.d3dCommandList->ResourceBarrier(1, &barrier); + + D3D12Resource stageBuf; + + auto size = (Size)m_count * m_stride; + D3D12_HEAP_PROPERTIES heapProps; + heapProps.Type = D3D12_HEAP_TYPE_READBACK; + heapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + heapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + heapProps.CreationNodeMask = 1; + heapProps.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC stagingDesc; + initBufferResourceDesc(size, stagingDesc); + + SLANG_RETURN_ON_FAIL(stageBuf.initCommitted( + m_device->m_device, + heapProps, + D3D12_HEAP_FLAG_NONE, + stagingDesc, + D3D12_RESOURCE_STATE_COPY_DEST, + nullptr)); + + encodeInfo.d3dCommandList->CopyBufferRegion( + stageBuf, 0, m_bufferResource->m_resource.getResource(), 0, size); + m_device->submitResourceCommandsAndWait(encodeInfo); + void* ptr = nullptr; + stageBuf.getResource()->Map(0, nullptr, &ptr); + m_result.setCount(m_count * m_stride); + memcpy(m_result.getBuffer(), ptr, m_result.getCount()); + + m_resultDirty = false; + } + + memcpy(data, m_result.getBuffer() + queryIndex * m_stride, count * m_stride); + + return SLANG_OK; +} + +} // namespace d3d12 +} // namespace gfx |
