diff --git a/renderdoc/driver/d3d12/d3d12_commands.cpp b/renderdoc/driver/d3d12/d3d12_commands.cpp index 57e467384..37e2340d8 100644 --- a/renderdoc/driver/d3d12/d3d12_commands.cpp +++ b/renderdoc/driver/d3d12/d3d12_commands.cpp @@ -1072,6 +1072,7 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu case D3D12Chunk::Device_CreateRootSignatureFromSubobjectInLibrary: case D3D12Chunk::List_SetProgram: case D3D12Chunk::List_DispatchGraph: + case D3D12Chunk::Device_CreateQueryHeap1: RDCERR("Unexpected chunk while processing frame: %s", ToStr(chunk).c_str()); return false; diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index ddcffa969..de0563286 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -1015,6 +1015,7 @@ DECLARE_REFLECTION_ENUM(D3D12_STATE_OBJECT_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_EXPORT_FLAGS); DECLARE_REFLECTION_ENUM(D3D12_HIT_GROUP_TYPE); DECLARE_REFLECTION_ENUM(D3D12_RAYTRACING_PIPELINE_FLAGS); +DECLARE_REFLECTION_ENUM(D3D12_QUERY_HEAP_FLAGS); DECLARE_REFLECTION_STRUCT(D3D12_RESOURCE_DESC); DECLARE_REFLECTION_STRUCT(D3D12_COMMAND_QUEUE_DESC); @@ -1330,5 +1331,6 @@ enum class D3D12Chunk : uint32_t Device_TryCreateSampler2, Device_TryCreateRenderTargetView, Device_TryCreateDepthStencilView, + Device_CreateQueryHeap1, Max, }; diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index c15a0f750..24a36583d 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -5220,6 +5220,8 @@ bool WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context) return Serialise_SetPipelineStackSize(ser, NULL, 0); case D3D12Chunk::Device_CreateRootSignatureFromSubobjectInLibrary: return Serialise_CreateRootSignatureFromSubobjectInLibrary(ser, 0, NULL, 0, NULL, IID(), NULL); + case D3D12Chunk::Device_CreateQueryHeap1: + return Serialise_CreateQueryHeap1(ser, NULL, D3D12_QUERY_HEAP_FLAG_NONE, IID(), NULL); // in order to get a warning if we miss a case, we explicitly handle the list/queue chunks here. // If we actually encounter one it's an error (we should hit CaptureBegin first and switch to diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 70d4920e3..3ac9a6315 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -2011,6 +2011,14 @@ public: ID3D12Resource *pFeedbackResource, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor); + IMPLEMENT_FUNCTION_THREAD_SERIALISED(virtual HRESULT, CreateQueryHeap1, + const D3D12_QUERY_HEAP_DESC *pDesc, + D3D12_QUERY_HEAP_FLAGS Flags, REFIID riid, void **ppvHeap); + + virtual HRESULT STDMETHODCALLTYPE ResolveQueryData(ID3D12QueryHeap *pQueryHeap, + D3D12_QUERY_TYPE Type, UINT StartIndex, + UINT NumQueries, void *pResolvedQueryData); + ////////////////////////////// // implement ID3D12DeviceTools virtual void STDMETHODCALLTYPE SetNextAllocationAddress(UINT64 pVirtualAddress) diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap15.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap15.cpp index bc5dcfaf1..caf23f106 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap15.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap15.cpp @@ -23,6 +23,8 @@ ******************************************************************************/ #include "d3d12_device.h" +#include "driver/dxgi/dxgi_common.h" +#include "d3d12_resources.h" // pass these through unmodified HRESULT STDMETHODCALLTYPE @@ -37,3 +39,106 @@ HRESULT STDMETHODCALLTYPE WrappedID3D12Device::UnregisterTrimNotificationCallbac } // implementations of TryCreate* for descriptors are with their associated non-try functions to share implementations + +template +bool WrappedID3D12Device::Serialise_CreateQueryHeap1(SerialiserType &ser, + const D3D12_QUERY_HEAP_DESC *pDesc, + D3D12_QUERY_HEAP_FLAGS Flags, REFIID riid, + void **ppvHeap) +{ + SERIALISE_ELEMENT_LOCAL(Descriptor, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(Flags); + SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); + SERIALISE_ELEMENT_LOCAL(pQueryHeap, ((WrappedID3D12QueryHeap *)*ppvHeap)->GetResourceID()) + .TypedAs("ID3D12QueryHeap *"_lit); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + if(!m_pDevice15) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires ID3D12Device15 which isn't available"); + return false; + } + + ID3D12QueryHeap *ret = NULL; + HRESULT hr = m_pDevice15->CreateQueryHeap1(&Descriptor, Flags, guid, (void **)&ret); + + if(FAILED(hr)) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, + "Failed creating query heap, HRESULT: %s", ToStr(hr).c_str()); + return false; + } + else + { + ret = new WrappedID3D12QueryHeap(pQueryHeap, ret, Descriptor, this); + } + + AddResource(pQueryHeap, ResourceType::Query, "Query Heap"); + } + + return true; +} + +HRESULT STDMETHODCALLTYPE WrappedID3D12Device::CreateQueryHeap1(const D3D12_QUERY_HEAP_DESC *pDesc, + D3D12_QUERY_HEAP_FLAGS Flags, + REFIID riid, void **ppvHeap) +{ + if(ppvHeap == NULL) + return m_pDevice15->CreateQueryHeap1(pDesc, Flags, riid, NULL); + + if(riid != __uuidof(ID3D12QueryHeap)) + return E_NOINTERFACE; + + ID3D12QueryHeap *real = NULL; + HRESULT ret; + SERIALISE_TIME_CALL(ret = m_pDevice15->CreateQueryHeap1(pDesc, Flags, riid, (void **)&real)); + + if(SUCCEEDED(ret)) + { + WrappedID3D12QueryHeap *wrapped = new WrappedID3D12QueryHeap(ResourceId(), real, *pDesc, this); + + if(IsCaptureMode(m_State)) + { + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreateQueryHeap1); + Serialise_CreateQueryHeap1(ser, pDesc, Flags, riid, (void **)&wrapped); + + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_QueryHeap; + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->AddChunk(scope.Get()); + + if(pDesc->Type == D3D12_QUERY_HEAP_TYPE_OCCLUSION) + GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); + } + + *ppvHeap = (ID3D12QueryHeap *)wrapped; + } + else + { + CHECK_HR(this, ret); + } + + return ret; +} + +HRESULT STDMETHODCALLTYPE WrappedID3D12Device::ResolveQueryData(ID3D12QueryHeap *pQueryHeap, + D3D12_QUERY_TYPE Type, + UINT StartIndex, UINT NumQueries, + void *pResolvedQueryData) +{ + // pass through, without serialising + return m_pDevice15->ResolveQueryData(Unwrap(pQueryHeap), Type, StartIndex, NumQueries, + pResolvedQueryData); +} + +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateQueryHeap1, + const D3D12_QUERY_HEAP_DESC *pDesc, D3D12_QUERY_HEAP_FLAGS Flags, + REFIID riid, void **ppvHeap); diff --git a/renderdoc/driver/d3d12/d3d12_stringise.cpp b/renderdoc/driver/d3d12/d3d12_stringise.cpp index 48a9d6b29..e25d68030 100644 --- a/renderdoc/driver/d3d12/d3d12_stringise.cpp +++ b/renderdoc/driver/d3d12/d3d12_stringise.cpp @@ -28,7 +28,7 @@ template <> rdcstr DoStringise(const D3D12Chunk &el) { - RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1145, "Chunks changed without updating names"); + RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1146, "Chunks changed without updating names"); BEGIN_ENUM_STRINGISE(D3D12Chunk) { @@ -255,6 +255,7 @@ rdcstr DoStringise(const D3D12Chunk &el) "ID3D12Device15::TryCreateRenderTargetView"); STRINGISE_ENUM_CLASS_NAMED(Device_TryCreateDepthStencilView, "ID3D12Device15::TryCreateDepthStencilView"); + STRINGISE_ENUM_CLASS_NAMED(Device_CreateQueryHeap1, "ID3D12Device15::CreateQueryHeap1"); STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk"); } END_ENUM_STRINGISE() @@ -1863,3 +1864,14 @@ rdcstr DoStringise(const D3D12_FEATURE &el) } END_ENUM_STRINGISE(); } + +template <> +rdcstr DoStringise(const D3D12_QUERY_HEAP_FLAGS &el) +{ + BEGIN_BITFIELD_STRINGISE(D3D12_QUERY_HEAP_FLAGS); + { + STRINGISE_BITFIELD_VALUE(D3D12_QUERY_HEAP_FLAG_NONE); + STRINGISE_BITFIELD_VALUE(D3D12_QUERY_HEAP_FLAG_CPU_RESOLVE); + } + END_BITFIELD_STRINGISE(); +}