From 2777a25345d47057465f0c996c008fa464d4e43f Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 19 May 2023 20:10:24 +0100 Subject: [PATCH] Refactor resource creation functions to use common path * This does require some awkward dispatching as the functions are almost but not entirely the same. --- renderdoc/driver/d3d12/d3d12_common.h | 7 + renderdoc/driver/d3d12/d3d12_device.cpp | 3 + renderdoc/driver/d3d12/d3d12_device.h | 44 + .../d3d12/d3d12_device_rescreate_wrap.cpp | 1258 +++++++++++++++++ renderdoc/driver/d3d12/d3d12_device_wrap.cpp | 1190 +--------------- .../driver/d3d12/d3d12_device_wrap10.cpp | 58 - renderdoc/driver/d3d12/d3d12_device_wrap4.cpp | 261 ---- renderdoc/driver/d3d12/d3d12_device_wrap8.cpp | 507 ------- .../driver/d3d12/renderdoc_d3d12.vcxproj | 2 +- .../d3d12/renderdoc_d3d12.vcxproj.filters | 6 +- 10 files changed, 1337 insertions(+), 1999 deletions(-) create mode 100644 renderdoc/driver/d3d12/d3d12_device_rescreate_wrap.cpp delete mode 100644 renderdoc/driver/d3d12/d3d12_device_wrap10.cpp diff --git a/renderdoc/driver/d3d12/d3d12_common.h b/renderdoc/driver/d3d12/d3d12_common.h index 232e12dcc..a81755dd2 100644 --- a/renderdoc/driver/d3d12/d3d12_common.h +++ b/renderdoc/driver/d3d12/d3d12_common.h @@ -227,6 +227,13 @@ D3D12_RASTERIZER_DESC2 Upconvert(const D3D12_RASTERIZER_DESC &desc); ShaderStageMask ConvertVisibility(D3D12_SHADER_VISIBILITY ShaderVisibility); UINT GetNumSubresources(ID3D12Device *dev, const D3D12_RESOURCE_DESC *desc); +inline UINT GetNumSubresources(ID3D12Device *dev, const D3D12_RESOURCE_DESC1 *desc) +{ + // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 + D3D12_RESOURCE_DESC desc0; + memcpy(&desc0, desc, sizeof(desc0)); + return GetNumSubresources(dev, &desc0); +} class WrappedID3D12Device; diff --git a/renderdoc/driver/d3d12/d3d12_device.cpp b/renderdoc/driver/d3d12/d3d12_device.cpp index cb7663da9..44347ef3c 100644 --- a/renderdoc/driver/d3d12/d3d12_device.cpp +++ b/renderdoc/driver/d3d12/d3d12_device.cpp @@ -4327,6 +4327,9 @@ void WrappedID3D12Device::AddResource(ResourceId id, ResourceType type, const ch void WrappedID3D12Device::DerivedResource(ID3D12DeviceChild *parent, ResourceId child) { + if(!parent) + return; + ResourceId parentId = GetResourceManager()->GetOriginalID(GetResID(parent)); DerivedResource(parentId, child); diff --git a/renderdoc/driver/d3d12/d3d12_device.h b/renderdoc/driver/d3d12/d3d12_device.h index 59cbd52f5..100156e00 100644 --- a/renderdoc/driver/d3d12/d3d12_device.h +++ b/renderdoc/driver/d3d12/d3d12_device.h @@ -1360,6 +1360,50 @@ public: GetCustomHeapProperties, UINT nodeMask, D3D12_HEAP_TYPE heapType); + bool Serialise_CreateResource(D3D12Chunk chunkType, ID3D12Heap *pHeap, UINT64 HeapOffset, + D3D12_HEAP_PROPERTIES &props, D3D12_HEAP_FLAGS HeapFlags, + D3D12_RESOURCE_DESC1 &desc, D3D12ResourceLayout InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, ResourceId pResource, + uint64_t gpuAddress); + bool Serialise_CreateResource(D3D12Chunk chunkType, ID3D12Heap *pHeap, UINT64 HeapOffset, + D3D12_HEAP_PROPERTIES &props, D3D12_HEAP_FLAGS HeapFlags, + D3D12_RESOURCE_DESC &desc, D3D12ResourceLayout InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, ResourceId pResource, + uint64_t gpuAddress) + { + // upconvert to the DESC1 by just memcpy, since it's a superset and the remainder can be + // 0-initialised + D3D12_RESOURCE_DESC1 desc1 = {}; + memcpy(&desc1, &desc, sizeof(desc)); + + return Serialise_CreateResource(chunkType, pHeap, HeapOffset, props, HeapFlags, desc1, + InitialResourceState, pOptimizedClearValue, pResource, + gpuAddress); + } + + HRESULT CreateResource(D3D12Chunk chunkType, ID3D12Heap *pHeap, UINT64 HeapOffset, + const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + D3D12_RESOURCE_DESC1 pDesc, D3D12ResourceLayout InitialLayout, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, + void **ppvResource); + HRESULT CreateResource(D3D12Chunk chunkType, ID3D12Heap *pHeap, UINT64 HeapOffset, + const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + D3D12_RESOURCE_DESC pDesc, D3D12ResourceLayout InitialLayout, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, + void **ppvResource) + { + // upconvert to the DESC1 by just memcpy, since it's a superset and the remainder can be + // 0-initialised + D3D12_RESOURCE_DESC1 desc1 = {}; + memcpy(&desc1, &pDesc, sizeof(D3D12_RESOURCE_DESC)); + + return CreateResource(chunkType, pHeap, HeapOffset, pHeapProperties, HeapFlags, desc1, + InitialLayout, pOptimizedClearValue, pProtectedSession, riidResource, + ppvResource); + } + IMPLEMENT_FUNCTION_THREAD_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, CreateCommittedResource, const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC *pDesc, diff --git a/renderdoc/driver/d3d12/d3d12_device_rescreate_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_rescreate_wrap.cpp new file mode 100644 index 000000000..d772b9925 --- /dev/null +++ b/renderdoc/driver/d3d12/d3d12_device_rescreate_wrap.cpp @@ -0,0 +1,1258 @@ +/****************************************************************************** + * The MIT License (MIT) + * + * Copyright (c) 2021-2023 Baldur Karlsson + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + ******************************************************************************/ + +#include "d3d12_device.h" +#include "driver/dxgi/dxgi_common.h" +#include "d3d12_resources.h" + +bool WrappedID3D12Device::Serialise_CreateResource( + D3D12Chunk chunkType, ID3D12Heap *pHeap, UINT64 HeapOffset, D3D12_HEAP_PROPERTIES &props, + D3D12_HEAP_FLAGS HeapFlags, D3D12_RESOURCE_DESC1 &desc, D3D12ResourceLayout InitialLayout, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, ResourceId pResource, uint64_t gpuAddress) +{ + // if we're creating a placed resource + if(pHeap) + { + D3D12_HEAP_DESC heapDesc = pHeap->GetDesc(); + + // if the heap was from OpenExistingHeap* then we will have removed the shared flags from it + // as it's CPU-visible and impossible to share. + // That means any resources placed to it would have had this flag that we then need to remove + // as well. + if((heapDesc.Flags & D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER) == 0) + desc.Flags &= ~D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER; + } + + // if we're creating a committed resource (only place where heap properties is set) + if(props.Type == D3D12_HEAP_TYPE_UPLOAD && desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + // place large resources in local memory so that initial contents and maps can + // be cached and copied on the GPU instead of memcpy'd from the CPU every time. + // smaller resources it's better to just leave them as upload and map into them + if(desc.Width >= 1024 * 1024) + { + RDCLOG("Remapping committed resource %s from upload to default for efficient replay", + ToStr(pResource).c_str()); + props.Type = D3D12_HEAP_TYPE_DEFAULT; + m_UploadResourceIds.insert(pResource); + } + } + + APIProps.YUVTextures |= IsYUVFormat(desc.Format); + + // always allow SRVs on replay so we can inspect resources + desc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; + + // don't create resources non-resident + HeapFlags &= ~D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT; + + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && gpuAddress != 0) + { + GPUAddressRange range; + range.start = gpuAddress; + range.end = gpuAddress + desc.Width; + range.id = pResource; + + m_GPUAddresses.AddTo(range); + } + + // check for device requirement + switch(chunkType) + { + case D3D12Chunk::Device_CreateCommittedResource1: + case D3D12Chunk::Device_CreateReservedResource1: + if(!m_pDevice4) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires ID3D12Device4 which isn't available"); + return false; + } + break; + case D3D12Chunk::Device_CreateCommittedResource2: + case D3D12Chunk::Device_CreatePlacedResource1: + if(!m_pDevice8) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires ID3D12Device8 which isn't available"); + return false; + } + break; + case D3D12Chunk::Device_CreateCommittedResource3: + case D3D12Chunk::Device_CreatePlacedResource2: + case D3D12Chunk::Device_CreateReservedResource2: + if(!m_pDevice10) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, + "Capture requires ID3D12Device10 which isn't available"); + return false; + } + break; + default: break; + } + + D3D12_RESOURCE_DESC desc0 = {}; + memcpy(&desc0, &desc, sizeof(desc0)); + + ID3D12Resource *ret = NULL; + HRESULT hr = S_OK; + + // dispatch actual creation + switch(chunkType) + { + case D3D12Chunk::Device_OpenSharedHandle: + case D3D12Chunk::Device_CreateCommittedResource: + { + hr = m_pDevice->CreateCommittedResource(&props, HeapFlags, &desc0, InitialLayout.ToStates(), + pOptimizedClearValue, __uuidof(ID3D12Resource), + (void **)&ret); + break; + } + case D3D12Chunk::Device_CreateCommittedResource1: + { + hr = m_pDevice4->CreateCommittedResource1(&props, HeapFlags, &desc0, InitialLayout.ToStates(), + pOptimizedClearValue, NULL, + __uuidof(ID3D12Resource), (void **)&ret); + break; + } + case D3D12Chunk::Device_CreateCommittedResource2: + { + hr = m_pDevice8->CreateCommittedResource2(&props, HeapFlags, &desc, InitialLayout.ToStates(), + pOptimizedClearValue, NULL, + __uuidof(ID3D12Resource), (void **)&ret); + break; + } + case D3D12Chunk::Device_CreatePlacedResource: + { + hr = m_pDevice->CreatePlacedResource(Unwrap(pHeap), HeapOffset, &desc0, + InitialLayout.ToStates(), pOptimizedClearValue, + __uuidof(ID3D12Resource), (void **)&ret); + break; + } + case D3D12Chunk::Device_CreatePlacedResource1: + { + hr = m_pDevice8->CreatePlacedResource1(Unwrap(pHeap), HeapOffset, &desc, + InitialLayout.ToStates(), pOptimizedClearValue, + __uuidof(ID3D12Resource), (void **)&ret); + break; + } + case D3D12Chunk::Device_CreateReservedResource: + { + hr = m_pDevice->CreateReservedResource(&desc0, InitialLayout.ToStates(), pOptimizedClearValue, + __uuidof(ID3D12Resource), (void **)&ret); + break; + } + case D3D12Chunk::Device_CreateReservedResource1: + { + hr = m_pDevice4->CreateReservedResource1(&desc0, InitialLayout.ToStates(), pOptimizedClearValue, + NULL, __uuidof(ID3D12Resource), (void **)&ret); + break; + } + default: break; + } + + if(FAILED(hr)) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, + "Failed recreating %s, HRESULT: %s", ToStr(chunkType).c_str(), + ToStr(hr).c_str()); + return false; + } + + const char *ResourceTypeName = "?"; + + switch(chunkType) + { + case D3D12Chunk::Device_OpenSharedHandle: ResourceTypeName = "Shared"; break; + case D3D12Chunk::Device_CreateCommittedResource: + case D3D12Chunk::Device_CreateCommittedResource1: + case D3D12Chunk::Device_CreateCommittedResource2: + case D3D12Chunk::Device_CreateCommittedResource3: ResourceTypeName = "Committed"; break; + case D3D12Chunk::Device_CreatePlacedResource: + case D3D12Chunk::Device_CreatePlacedResource1: + case D3D12Chunk::Device_CreatePlacedResource2: ResourceTypeName = "Placed"; break; + case D3D12Chunk::Device_CreateReservedResource: + case D3D12Chunk::Device_CreateReservedResource1: + case D3D12Chunk::Device_CreateReservedResource2: ResourceTypeName = "Reserved"; break; + default: + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::InternalError, + "Invalid call to Serialise_CreateResource"); + return false; + } + } + + SetObjName(ret, StringFormat::Fmt("%s Resource %s %s", ResourceTypeName, + ToStr(desc.Dimension).c_str(), ToStr(pResource).c_str())); + + ret = new WrappedID3D12Resource(ret, this); + + switch(chunkType) + { + case D3D12Chunk::Device_CreateReservedResource: + case D3D12Chunk::Device_CreateReservedResource1: + case D3D12Chunk::Device_CreateReservedResource2: + APIProps.SparseResources = true; + m_SparseResources.insert(GetResID(ret)); + default: break; + } + + GetResourceManager()->AddLiveResource(pResource, ret); + + if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) + m_ModResources.insert(GetResID(ret)); + + SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; + states.fill(GetNumSubresources(m_pDevice, &desc), InitialLayout); + + ResourceType type = ResourceType::Texture; + const char *prefix = "Texture"; + + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + type = ResourceType::Buffer; + prefix = "Buffer"; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) + { + prefix = desc.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; + + if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "1D Render Target"; + else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "1D Depth Target"; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) + { + prefix = desc.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; + + if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "2D Render Target"; + else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "2D Depth Target"; + } + else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + prefix = "3D Texture"; + + if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) + prefix = "3D Render Target"; + else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) + prefix = "3D Depth Target"; + } + + AddResource(pResource, type, prefix); + // ignored if there's no heap + DerivedResource(pHeap, pResource); + + return true; +} + +HRESULT WrappedID3D12Device::CreateResource(D3D12Chunk chunkType, ID3D12Heap *pHeap, + UINT64 HeapOffset, + const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, D3D12_RESOURCE_DESC1 desc, + D3D12ResourceLayout InitialLayout, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riidResource, void **ppvResource) +{ + if(riidResource != __uuidof(ID3D12Resource) && riidResource != __uuidof(ID3D12Resource1) && + riidResource != __uuidof(ID3D12Resource2)) + return E_NOINTERFACE; + + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && desc.SampleDesc.Count > 1) + { + // need to be able to create SRVs of MSAA textures to copy out their contents + desc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; + } + + D3D12_RESOURCE_DESC desc0 = {}; + memcpy(&desc0, &desc, sizeof(desc0)); + + ID3D12Resource *realRes = NULL; + HRESULT ret = E_NOINTERFACE; + + void **outPtr = (void **)&realRes; + + if(ppvResource == NULL) + outPtr = NULL; + + switch(chunkType) + { + case D3D12Chunk::Device_OpenSharedHandle: + { + // already created externally + realRes = (ID3D12Resource *)*ppvResource; + ret = S_OK; + break; + } + case D3D12Chunk::Device_CreateCommittedResource: + { + SERIALISE_TIME_CALL(ret = m_pDevice->CreateCommittedResource( + pHeapProperties, HeapFlags, &desc0, InitialLayout.ToStates(), + pOptimizedClearValue, __uuidof(ID3D12Resource), outPtr)); + break; + } + case D3D12Chunk::Device_CreateCommittedResource1: + { + SERIALISE_TIME_CALL(ret = m_pDevice4->CreateCommittedResource1( + pHeapProperties, HeapFlags, &desc0, InitialLayout.ToStates(), + pOptimizedClearValue, pProtectedSession, __uuidof(ID3D12Resource), + outPtr)); + break; + } + case D3D12Chunk::Device_CreateCommittedResource2: + { + SERIALISE_TIME_CALL(ret = m_pDevice8->CreateCommittedResource2( + pHeapProperties, HeapFlags, &desc, InitialLayout.ToStates(), + pOptimizedClearValue, pProtectedSession, __uuidof(ID3D12Resource), + outPtr)); + break; + } + case D3D12Chunk::Device_CreateCommittedResource3: { break; + } + case D3D12Chunk::Device_CreatePlacedResource: + { + SERIALISE_TIME_CALL(ret = m_pDevice->CreatePlacedResource( + Unwrap(pHeap), HeapOffset, &desc0, InitialLayout.ToStates(), + pOptimizedClearValue, __uuidof(ID3D12Resource), outPtr)); + break; + } + case D3D12Chunk::Device_CreatePlacedResource1: + { + SERIALISE_TIME_CALL(ret = m_pDevice8->CreatePlacedResource1( + Unwrap(pHeap), HeapOffset, &desc, InitialLayout.ToStates(), + pOptimizedClearValue, __uuidof(ID3D12Resource), outPtr)); + break; + } + case D3D12Chunk::Device_CreatePlacedResource2: { break; + } + case D3D12Chunk::Device_CreateReservedResource: + { + SERIALISE_TIME_CALL(ret = m_pDevice->CreateReservedResource(&desc0, InitialLayout.ToStates(), + pOptimizedClearValue, + __uuidof(ID3D12Resource), outPtr)); + break; + } + case D3D12Chunk::Device_CreateReservedResource1: + { + SERIALISE_TIME_CALL(ret = m_pDevice4->CreateReservedResource1( + &desc0, InitialLayout.ToStates(), pOptimizedClearValue, + pProtectedSession, __uuidof(ID3D12Resource), outPtr)); + break; + } + case D3D12Chunk::Device_CreateReservedResource2: { break; + } + default: break; + } + + if(FAILED(ret)) + { + CheckHRESULT(ret); + return ret; + } + + if(ppvResource == NULL) + return ret; + + UINT NumSubresources = GetNumSubresources(m_pDevice, &desc); + + WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(realRes, this); + + wrapped->SetHeap(pHeap); + + if(IsCaptureMode(m_State)) + { + if(HeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT) + wrapped->Evict(); + + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(chunkType); + + switch(chunkType) + { + case D3D12Chunk::Device_OpenSharedHandle: + { + ID3D12DeviceChild *wrappedDeviceChild = wrapped; + Serialise_OpenSharedHandle(ser, 0, riidResource, (void **)&wrappedDeviceChild); + break; + } + case D3D12Chunk::Device_CreateCommittedResource: + { + Serialise_CreateCommittedResource(ser, pHeapProperties, HeapFlags, &desc0, + InitialLayout.ToStates(), pOptimizedClearValue, + riidResource, (void **)&wrapped); + break; + } + case D3D12Chunk::Device_CreateCommittedResource1: + { + Serialise_CreateCommittedResource1(ser, pHeapProperties, HeapFlags, &desc0, + InitialLayout.ToStates(), pOptimizedClearValue, + pProtectedSession, riidResource, (void **)&wrapped); + break; + } + case D3D12Chunk::Device_CreateCommittedResource2: + { + Serialise_CreateCommittedResource2(ser, pHeapProperties, HeapFlags, &desc, + InitialLayout.ToStates(), pOptimizedClearValue, + pProtectedSession, riidResource, (void **)&wrapped); + break; + } + case D3D12Chunk::Device_CreateCommittedResource3: { break; + } + case D3D12Chunk::Device_CreatePlacedResource: + { + Serialise_CreatePlacedResource(ser, pHeap, HeapOffset, &desc0, InitialLayout.ToStates(), + pOptimizedClearValue, riidResource, (void **)&wrapped); + break; + } + case D3D12Chunk::Device_CreatePlacedResource1: + { + Serialise_CreatePlacedResource1(ser, pHeap, HeapOffset, &desc, InitialLayout.ToStates(), + pOptimizedClearValue, riidResource, (void **)&wrapped); + break; + } + case D3D12Chunk::Device_CreatePlacedResource2: { break; + } + case D3D12Chunk::Device_CreateReservedResource: + { + Serialise_CreateReservedResource(ser, &desc0, InitialLayout.ToStates(), + pOptimizedClearValue, riidResource, (void **)&wrapped); + break; + } + case D3D12Chunk::Device_CreateReservedResource1: + { + Serialise_CreateReservedResource1(ser, &desc0, InitialLayout.ToStates(), pOptimizedClearValue, + pProtectedSession, riidResource, (void **)&wrapped); + break; + } + case D3D12Chunk::Device_CreateReservedResource2: { break; + } + default: break; + } + + D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_Resource; + record->Length = 0; + wrapped->SetResourceRecord(record); + + record->m_MapsCount = NumSubresources; + record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; + + if(chunkType == D3D12Chunk::Device_CreateReservedResource || + chunkType == D3D12Chunk::Device_CreateReservedResource1 || + chunkType == D3D12Chunk::Device_CreateReservedResource2) + { + const UINT pageSize = 64 * 1024; + + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + record->sparseTable = new Sparse::PageTable; + record->sparseTable->Initialise(desc.Width, pageSize); + } + else + { + D3D12_PACKED_MIP_INFO mipTail = {}; + D3D12_TILE_SHAPE tileShape = {}; + + m_pDevice->GetResourceTiling(wrapped->GetReal(), NULL, &mipTail, &tileShape, NULL, 0, NULL); + + UINT texDepth = 1; + UINT texSlices = desc.DepthOrArraySize; + if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) + { + texDepth = desc.DepthOrArraySize; + texSlices = 1; + } + + RDCASSERT(mipTail.NumStandardMips + mipTail.NumPackedMips == desc.MipLevels, + mipTail.NumStandardMips, mipTail.NumPackedMips, desc.MipLevels); + record->sparseTable = new Sparse::PageTable; + record->sparseTable->Initialise( + {(uint32_t)desc.Width, desc.Height, texDepth}, desc.MipLevels, texSlices, pageSize, + {tileShape.WidthInTexels, tileShape.HeightInTexels, tileShape.DepthInTexels}, + mipTail.NumStandardMips, mipTail.StartTileIndexInOverallResource * pageSize, + (mipTail.StartTileIndexInOverallResource + mipTail.NumTilesForPackedMips) * pageSize, + mipTail.NumTilesForPackedMips * pageSize * texSlices); + } + + { + SCOPED_LOCK(m_SparseLock); + m_SparseResources.insert(wrapped->GetResourceID()); + } + } + + record->AddChunk(scope.Get()); + if(pHeap) + record->AddParent(GetRecord(pHeap)); + + GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); + } + else + { + GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped); + } + + { + SCOPED_LOCK(m_ResourceStatesLock); + SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; + + states.fill(NumSubresources, InitialLayout); + + m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); + } + + // while actively capturing we keep all buffers around to prevent the address lookup from + // losing addresses we might need (or the manageable but annoying problem of an address being + // re-used) + { + SCOPED_READLOCK(m_CapTransitionLock); + if(IsActiveCapturing(m_State)) + { + wrapped->AddRef(); + m_RefBuffers.push_back(wrapped); + if(m_BindlessResourceUseActive) + GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), + BindlessRefTypeForRes(wrapped)); + } + } + + *ppvResource = (ID3D12Resource *)wrapped; + + return ret; +} + +template +bool WrappedID3D12Device::Serialise_CreateCommittedResource( + SerialiserType &ser, const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riidResource, void **ppvResource) +{ + SERIALISE_ELEMENT_LOCAL(props, *pHeapProperties).Named("pHeapProperties"_lit); + SERIALISE_ELEMENT(HeapFlags); + SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(InitialResourceState); + SERIALISE_ELEMENT_OPT(pOptimizedClearValue); + SERIALISE_ELEMENT_LOCAL(guid, riidResource).Named("riidResource"_lit); + SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) + .TypedAs("ID3D12Resource *"_lit); + + SERIALISE_ELEMENT_LOCAL(gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) + .Hidden(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + return Serialise_CreateResource(D3D12Chunk::Device_CreateCommittedResource, NULL, 0, props, + HeapFlags, desc, + D3D12ResourceLayout::FromStates(InitialResourceState), + pOptimizedClearValue, pResource, gpuAddress); + } + + return true; +} + +HRESULT WrappedID3D12Device::CreateCommittedResource(const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, + const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riidResource, void **ppvResource) +{ + return CreateResource(D3D12Chunk::Device_CreateCommittedResource, NULL, 0, pHeapProperties, + HeapFlags, *pDesc, D3D12ResourceLayout::FromStates(InitialResourceState), + pOptimizedClearValue, NULL, riidResource, ppvResource); +} + +template +bool WrappedID3D12Device::Serialise_CreatePlacedResource( + SerialiserType &ser, ID3D12Heap *pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, + void **ppvResource) +{ + SERIALISE_ELEMENT(pHeap).Important(); + SERIALISE_ELEMENT(HeapOffset); + SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(InitialState); + SERIALISE_ELEMENT_OPT(pOptimizedClearValue); + SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); + SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) + .TypedAs("ID3D12Resource *"_lit); + + SERIALISE_ELEMENT_LOCAL(gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) + .Hidden(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + D3D12_HEAP_PROPERTIES props = {}; + return Serialise_CreateResource(D3D12Chunk::Device_CreatePlacedResource, pHeap, HeapOffset, + props, D3D12_HEAP_FLAG_NONE, desc, + D3D12ResourceLayout::FromStates(InitialState), + pOptimizedClearValue, pResource, gpuAddress); + } + + return true; +} + +HRESULT WrappedID3D12Device::CreatePlacedResource(ID3D12Heap *pHeap, UINT64 HeapOffset, + const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, void **ppvResource) +{ + return CreateResource(D3D12Chunk::Device_CreatePlacedResource, pHeap, HeapOffset, NULL, + D3D12_HEAP_FLAG_NONE, *pDesc, D3D12ResourceLayout::FromStates(InitialState), + pOptimizedClearValue, NULL, riid, ppvResource); +} + +template +bool WrappedID3D12Device::Serialise_CreateReservedResource( + SerialiserType &ser, const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, void **ppvResource) +{ + SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(InitialState); + SERIALISE_ELEMENT_OPT(pOptimizedClearValue); + SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); + SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) + .TypedAs("ID3D12Resource *"_lit); + + SERIALISE_ELEMENT_LOCAL(gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) + .Hidden(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + D3D12_HEAP_PROPERTIES props = {}; + return Serialise_CreateResource( + D3D12Chunk::Device_CreateReservedResource, NULL, 0, props, D3D12_HEAP_FLAG_NONE, desc, + D3D12ResourceLayout::FromStates(InitialState), pOptimizedClearValue, pResource, gpuAddress); + } + + return true; +} + +HRESULT WrappedID3D12Device::CreateReservedResource(const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, void **ppvResource) +{ + return CreateResource(D3D12Chunk::Device_CreateReservedResource, NULL, 0, NULL, + D3D12_HEAP_FLAG_NONE, *pDesc, D3D12ResourceLayout::FromStates(InitialState), + pOptimizedClearValue, NULL, riid, ppvResource); +} + +template +bool WrappedID3D12Device::Serialise_OpenSharedHandle(SerialiserType &ser, HANDLE, REFIID riid, + void **ppvObj) +{ + SERIALISE_ELEMENT_LOCAL(ResourceRIID, riid).Important(); + + SERIALISE_CHECK_READ_ERRORS(); + + bool isRes = ResourceRIID == __uuidof(ID3D12Resource) || + ResourceRIID == __uuidof(ID3D12Resource1) || + ResourceRIID == __uuidof(ID3D12Resource2); + bool isFence = ResourceRIID == __uuidof(ID3D12Fence) || ResourceRIID == __uuidof(ID3D12Fence1); + bool isHeap = ResourceRIID == __uuidof(ID3D12Heap) || ResourceRIID == __uuidof(ID3D12Heap1); + if(isFence) + { + ID3D12Fence *fence = NULL; + if(ser.IsWriting()) + { + fence = (ID3D12Fence *)(ID3D12DeviceChild *)*ppvObj; + if(ResourceRIID == __uuidof(ID3D12Fence1)) + fence = (ID3D12Fence1 *)(ID3D12DeviceChild *)*ppvObj; + } + + SERIALISE_ELEMENT_LOCAL(resourceId, GetResID(fence)); + + UINT64 fakeInitialValue = 0; + D3D12_FENCE_FLAGS fakeFlags = D3D12_FENCE_FLAG_NONE; + + // maybe in future this can be determined? + SERIALISE_ELEMENT_LOCAL(initialValue, fakeInitialValue); + SERIALISE_ELEMENT_LOCAL(flags, fakeFlags); + + if(IsReplayingAndReading()) + { + HRESULT hr; + ID3D12Fence *ret; + hr = m_pDevice->CreateFence(initialValue, flags, __uuidof(ID3D12Fence), (void **)&ret); + if(FAILED(hr)) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, + "Failed creating shared fence, HRESULT: %s", ToStr(hr).c_str()); + return false; + } + else + { + ret = new WrappedID3D12Fence(ret, this); + + GetResourceManager()->AddLiveResource(resourceId, ret); + } + + AddResource(resourceId, ResourceType::Sync, "Fence"); + } + } + else if(isRes) + { + D3D12_RESOURCE_DESC desc; + D3D12_HEAP_PROPERTIES heapProperties; + D3D12_HEAP_FLAGS heapFlags; + + ID3D12Resource *res = NULL; + if(ser.IsWriting()) + { + res = (ID3D12Resource *)(ID3D12DeviceChild *)*ppvObj; + if(ResourceRIID == __uuidof(ID3D12Resource1)) + res = (ID3D12Resource1 *)(ID3D12DeviceChild *)*ppvObj; + else if(ResourceRIID == __uuidof(ID3D12Resource2)) + res = (ID3D12Resource2 *)(ID3D12DeviceChild *)*ppvObj; + desc = res->GetDesc(); + res->GetHeapProperties(&heapProperties, &heapFlags); + } + + SERIALISE_ELEMENT_LOCAL(resourceId, GetResID(res)); + SERIALISE_ELEMENT(desc); + SERIALISE_ELEMENT(heapProperties); + SERIALISE_ELEMENT(heapFlags); + + if(IsReplayingAndReading()) + { + // the runtime doesn't like us telling it what DENY heap flags will be set, remove them + heapFlags &= ~(D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES | + D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES); + + Serialise_CreateResource( + D3D12Chunk::Device_OpenSharedHandle, NULL, 0, heapProperties, heapFlags, desc, + D3D12ResourceLayout::FromStates(D3D12_RESOURCE_STATE_COMMON), NULL, resourceId, 0); + } + } + else if(isHeap) + { + D3D12_HEAP_DESC desc; + + ID3D12Heap *heap = NULL; + if(ser.IsWriting()) + { + heap = (ID3D12Heap *)(ID3D12DeviceChild *)*ppvObj; + if(ResourceRIID == __uuidof(ID3D12Heap1)) + heap = (ID3D12Heap1 *)(ID3D12DeviceChild *)*ppvObj; + desc = heap->GetDesc(); + } + + SERIALISE_ELEMENT_LOCAL(resourceId, GetResID(heap)); + SERIALISE_ELEMENT(desc); + + if(IsReplayingAndReading()) + { + HRESULT hr; + ID3D12Heap *ret; + hr = m_pDevice->CreateHeap(&desc, __uuidof(ID3D12Heap), (void **)&ret); + if(FAILED(hr)) + { + SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, + "Failed creating shared heap, HRESULT: %s", ToStr(hr).c_str()); + return false; + } + else + { + ret = new WrappedID3D12Heap(ret, this); + + GetResourceManager()->AddLiveResource(resourceId, ret); + } + + AddResource(resourceId, ResourceType::Memory, "Heap"); + } + } + else + { + RDCERR("Unknown type of resource being shared"); + } + + return true; +} + +HRESULT WrappedID3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void **ppvObj) +{ + if(ppvObj == NULL) + return E_INVALIDARG; + + HRESULT hr; + + SERIALISE_TIME_CALL(hr = m_pDevice->OpenSharedHandle(NTHandle, riid, ppvObj)); + + if(FAILED(hr)) + { + IUnknown *unk = (IUnknown *)*ppvObj; + SAFE_RELEASE(unk); + return hr; + } + + return OpenSharedHandleInternal(D3D12Chunk::Device_OpenSharedHandle, D3D12_HEAP_FLAG_NONE, riid, + ppvObj); +} + +HRESULT WrappedID3D12Device::OpenSharedHandleInternal(D3D12Chunk chunkType, + D3D12_HEAP_FLAGS HeapFlags, REFIID riid, + void **ppvObj) +{ + if(IsReplayMode(m_State)) + { + RDCERR("Don't support opening shared handle during replay."); + return E_NOTIMPL; + } + + bool isDXGIRes = riid == __uuidof(IDXGIResource) || riid == __uuidof(IDXGIResource1); + bool isRes = riid == __uuidof(ID3D12Resource) || riid == __uuidof(ID3D12Resource1) || + riid == __uuidof(ID3D12Resource2); + bool isFence = riid == __uuidof(ID3D12Fence) || riid == __uuidof(ID3D12Fence1); + bool isHeap = riid == __uuidof(ID3D12Heap) || riid == __uuidof(ID3D12Heap1); + bool isDeviceChild = riid == __uuidof(ID3D12DeviceChild); + bool isIUnknown = riid == __uuidof(IUnknown); + + IID riid_internal = riid; + void *ret = *ppvObj; + + if(isIUnknown) + { + // same as device child but we're even more in the dark. Hope against hope it's a + // ID3D12DeviceChild + IUnknown *real = (IUnknown *)ret; + + ID3D12DeviceChild *d3d12child = NULL; + isDeviceChild = + SUCCEEDED(real->QueryInterface(__uuidof(ID3D12DeviceChild), (void **)&d3d12child)) && + d3d12child; + SAFE_RELEASE(real); + + if(isDeviceChild) + { + riid_internal = __uuidof(ID3D12DeviceChild); + ret = (void *)d3d12child; + } + else + { + SAFE_RELEASE(d3d12child); + return E_NOINTERFACE; + } + } + + if(isDeviceChild) + { + // In this case we need to find out what the actual underlying type is + // Should be one of ID3D12Heap, ID3D12Resource, ID3D12Fence + ID3D12DeviceChild *real = (ID3D12DeviceChild *)ret; + + ID3D12Resource *d3d12Res = NULL; + ID3D12Fence *d3d12Fence = NULL; + ID3D12Heap *d3d12Heap = NULL; + isRes = SUCCEEDED(real->QueryInterface(__uuidof(ID3D12Resource), (void **)&d3d12Res)) && d3d12Res; + isFence = + SUCCEEDED(real->QueryInterface(__uuidof(ID3D12Fence), (void **)&d3d12Fence)) && d3d12Fence; + isHeap = SUCCEEDED(real->QueryInterface(__uuidof(ID3D12Heap), (void **)&d3d12Heap)) && d3d12Heap; + SAFE_RELEASE(real); + + if(isRes) + { + riid_internal = __uuidof(ID3D12Resource); + ret = (void *)d3d12Res; + } + else if(isFence) + { + riid_internal = __uuidof(ID3D12Fence); + ret = (void *)d3d12Fence; + } + else if(isHeap) + { + riid_internal = __uuidof(ID3D12Heap); + ret = (void *)d3d12Heap; + } + else + { + SAFE_RELEASE(d3d12Res); + SAFE_RELEASE(d3d12Fence); + SAFE_RELEASE(d3d12Heap); + return E_NOINTERFACE; + } + } + + if(isDXGIRes || isRes || isFence || isHeap) + { + HRESULT hr = S_OK; + + if(isDXGIRes) + { + IDXGIResource *dxgiRes = (IDXGIResource *)ret; + if(riid_internal == __uuidof(IDXGIResource1)) + dxgiRes = (IDXGIResource1 *)ret; + + ID3D12Resource *d3d12Res = NULL; + hr = dxgiRes->QueryInterface(__uuidof(ID3D12Resource), (void **)&d3d12Res); + + // if we can't get a d3d11Res then we can't properly wrap this resource, + // whatever it is. + if(FAILED(hr) || d3d12Res == NULL) + { + SAFE_RELEASE(d3d12Res); + SAFE_RELEASE(dxgiRes); + return E_NOINTERFACE; + } + + // release this interface + SAFE_RELEASE(dxgiRes); + + // and use this one, so it'll be casted back below + ret = (void *)d3d12Res; + isRes = true; + } + + ID3D12DeviceChild *wrappedDeviceChild = NULL; + D3D12ResourceRecord *record = NULL; + + if(isFence) + { + ID3D12Fence *real = (ID3D12Fence *)ret; + if(riid_internal == __uuidof(ID3D12Fence1)) + real = (ID3D12Fence1 *)ret; + + WrappedID3D12Fence *wrapped = new WrappedID3D12Fence(real, this); + + wrappedDeviceChild = wrapped; + + record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_Fence; + record->Length = 0; + wrapped->SetResourceRecord(record); + } + else if(isRes) + { + ID3D12Resource *real = (ID3D12Resource *)ret; + hr = CreateResource(D3D12Chunk::Device_OpenSharedHandle, NULL, 0, NULL, D3D12_HEAP_FLAG_NONE, + real->GetDesc(), + D3D12ResourceLayout::FromStates(D3D12_RESOURCE_STATE_COMMON), NULL, NULL, + riid_internal, (void **)&real); + + // use queryinterface to get the right interface into ppvObj, then release the reference + real->QueryInterface(riid, ppvObj); + real->Release(); + + return hr; + } + else if(isHeap) + { + WrappedID3D12Heap *wrapped = new WrappedID3D12Heap((ID3D12Heap *)ret, this); + + if(HeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT) + wrapped->Evict(); + + wrappedDeviceChild = wrapped; + + record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); + record->type = Resource_Heap; + record->Length = 0; + wrapped->SetResourceRecord(record); + } + + // use queryinterface to get the right interface into ppvObj, then release the reference + wrappedDeviceChild->QueryInterface(riid, ppvObj); + wrappedDeviceChild->Release(); + + CACHE_THREAD_SERIALISER(); + + SCOPED_SERIALISE_CHUNK(chunkType); + Serialise_OpenSharedHandle(ser, 0, riid_internal, (void **)&wrappedDeviceChild); + + record->AddChunk(scope.Get()); + + return S_OK; + } + + RDCERR("Unknown OpenSharedResourceInternal GUID: %s", ToStr(riid).c_str()); + + IUnknown *unk = (IUnknown *)*ppvObj; + SAFE_RELEASE(unk); + + return E_NOINTERFACE; +} + +template +bool WrappedID3D12Device::Serialise_CreateCommittedResource1( + SerialiserType &ser, const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) +{ + SERIALISE_ELEMENT_LOCAL(props, *pHeapProperties).Named("pHeapProperties"_lit); + SERIALISE_ELEMENT(HeapFlags); + SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(InitialResourceState); + SERIALISE_ELEMENT_OPT(pOptimizedClearValue); + // placeholder for future use if we properly capture & replay protected sessions + SERIALISE_ELEMENT_LOCAL(ProtectedSession, ResourceId()).Named("pProtectedSession"_lit); + SERIALISE_ELEMENT_LOCAL(guid, riidResource).Named("riidResource"_lit); + SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) + .TypedAs("ID3D12Resource *"_lit); + + SERIALISE_ELEMENT_LOCAL(gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) + .Hidden(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + return Serialise_CreateResource(D3D12Chunk::Device_CreateCommittedResource1, NULL, 0, props, + HeapFlags, desc, + D3D12ResourceLayout::FromStates(InitialResourceState), + pOptimizedClearValue, pResource, gpuAddress); + } + + return true; +} + +HRESULT WrappedID3D12Device::CreateCommittedResource1( + const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) +{ + return CreateResource(D3D12Chunk::Device_CreateCommittedResource1, NULL, 0, pHeapProperties, + HeapFlags, *pDesc, D3D12ResourceLayout::FromStates(InitialResourceState), + pOptimizedClearValue, pProtectedSession, riidResource, ppvResource); +} + +template +bool WrappedID3D12Device::Serialise_CreateReservedResource1( + SerialiserType &ser, const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riid, void **ppvResource) +{ + SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(InitialState); + SERIALISE_ELEMENT_OPT(pOptimizedClearValue); + // placeholder for future use if we properly capture & replay protected sessions + SERIALISE_ELEMENT_LOCAL(ProtectedSession, ResourceId()).Named("pProtectedSession"_lit); + SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); + SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) + .TypedAs("ID3D12Resource *"_lit); + + SERIALISE_ELEMENT_LOCAL(gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) + .Hidden(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + D3D12_HEAP_PROPERTIES props = {}; + return Serialise_CreateResource( + D3D12Chunk::Device_CreateReservedResource, NULL, 0, props, D3D12_HEAP_FLAG_NONE, desc, + D3D12ResourceLayout::FromStates(InitialState), pOptimizedClearValue, pResource, gpuAddress); + } + + return true; +} + +HRESULT WrappedID3D12Device::CreateReservedResource1( + _In_ const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, REFIID riid, + _COM_Outptr_opt_ void **ppvResource) +{ + return CreateResource(D3D12Chunk::Device_CreateReservedResource1, NULL, 0, NULL, + D3D12_HEAP_FLAG_NONE, *pDesc, D3D12ResourceLayout::FromStates(InitialState), + pOptimizedClearValue, pProtectedSession, riid, ppvResource); +} + +template +bool WrappedID3D12Device::Serialise_CreateCommittedResource2( + SerialiserType &ser, const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + const D3D12_RESOURCE_DESC1 *pDesc, D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) +{ + SERIALISE_ELEMENT_LOCAL(props, *pHeapProperties).Named("pHeapProperties"_lit); + SERIALISE_ELEMENT(HeapFlags); + SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(InitialResourceState); + SERIALISE_ELEMENT_OPT(pOptimizedClearValue); + // placeholder for future use if we properly capture & replay protected sessions + SERIALISE_ELEMENT_LOCAL(ProtectedSession, ResourceId()).Named("pProtectedSession"_lit); + SERIALISE_ELEMENT_LOCAL(guid, riidResource).Named("riidResource"_lit); + SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) + .TypedAs("ID3D12Resource *"_lit); + + SERIALISE_ELEMENT_LOCAL(gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) + .Hidden(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + return Serialise_CreateResource(D3D12Chunk::Device_CreateCommittedResource2, NULL, 0, props, + HeapFlags, desc, + D3D12ResourceLayout::FromStates(InitialResourceState), + pOptimizedClearValue, pResource, gpuAddress); + } + + return true; +} + +HRESULT WrappedID3D12Device::CreateCommittedResource2( + const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + const D3D12_RESOURCE_DESC1 *pDesc, D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) +{ + return CreateResource(D3D12Chunk::Device_CreateCommittedResource2, NULL, 0, pHeapProperties, + HeapFlags, *pDesc, D3D12ResourceLayout::FromStates(InitialResourceState), + pOptimizedClearValue, pProtectedSession, riidResource, ppvResource); +} + +template +bool WrappedID3D12Device::Serialise_CreatePlacedResource1( + SerialiserType &ser, ID3D12Heap *pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC1 *pDesc, + D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, + void **ppvResource) +{ + SERIALISE_ELEMENT(pHeap).Important(); + SERIALISE_ELEMENT(HeapOffset); + SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); + SERIALISE_ELEMENT(InitialState); + SERIALISE_ELEMENT_OPT(pOptimizedClearValue); + SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); + SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) + .TypedAs("ID3D12Resource *"_lit); + + SERIALISE_ELEMENT_LOCAL(gpuAddress, + ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) + .Hidden(); + + SERIALISE_CHECK_READ_ERRORS(); + + if(IsReplayingAndReading()) + { + D3D12_HEAP_PROPERTIES props = {}; + return Serialise_CreateResource(D3D12Chunk::Device_CreatePlacedResource1, pHeap, HeapOffset, + props, D3D12_HEAP_FLAG_NONE, desc, + D3D12ResourceLayout::FromStates(InitialState), + pOptimizedClearValue, pResource, gpuAddress); + } + + return true; +} + +HRESULT WrappedID3D12Device::CreatePlacedResource1(ID3D12Heap *pHeap, UINT64 HeapOffset, + const D3D12_RESOURCE_DESC1 *pDesc, + D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + REFIID riid, void **ppvResource) +{ + return CreateResource(D3D12Chunk::Device_CreatePlacedResource1, pHeap, HeapOffset, NULL, + D3D12_HEAP_FLAG_NONE, *pDesc, D3D12ResourceLayout::FromStates(InitialState), + pOptimizedClearValue, NULL, riid, ppvResource); +} + +HRESULT WrappedID3D12Device::CreateCommittedResource3( + _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, + _In_ const D3D12_RESOURCE_DESC1 *pDesc, D3D12_BARRIER_LAYOUT InitialLayout, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, UINT32 NumCastableFormats, + _In_opt_count_(NumCastableFormats) const DXGI_FORMAT *pCastableFormats, REFIID riidResource, + _COM_Outptr_opt_ void **ppvResource) +{ + return E_NOTIMPL; +} + +HRESULT WrappedID3D12Device::CreatePlacedResource2( + _In_ ID3D12Heap *pHeap, UINT64 HeapOffset, _In_ const D3D12_RESOURCE_DESC1 *pDesc, + D3D12_BARRIER_LAYOUT InitialLayout, _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + UINT32 NumCastableFormats, _In_opt_count_(NumCastableFormats) const DXGI_FORMAT *pCastableFormats, + REFIID riid, _COM_Outptr_opt_ void **ppvResource) +{ + return E_NOTIMPL; +} + +HRESULT WrappedID3D12Device::CreateReservedResource2( + _In_ const D3D12_RESOURCE_DESC *pDesc, D3D12_BARRIER_LAYOUT InitialLayout, + _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, + _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, UINT32 NumCastableFormats, + _In_opt_count_(NumCastableFormats) const DXGI_FORMAT *pCastableFormats, REFIID riid, + _COM_Outptr_opt_ void **ppvResource) +{ + return E_NOTIMPL; +} + +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommittedResource, + const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riidResource, + void **ppvResource); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreatePlacedResource, ID3D12Heap *pHeap, + UINT64 HeapOffset, const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, + void **ppvResource); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateReservedResource, + const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, + void **ppvResource); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, OpenSharedHandle, HANDLE NTHandle, + REFIID riid, void **ppvObj); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommittedResource1, + const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riidResource, void **ppvResource); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateReservedResource1, + const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, REFIID riid, + void **ppvResource); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommittedResource2, + const D3D12_HEAP_PROPERTIES *pHeapProperties, + D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC1 *pDesc, + D3D12_RESOURCE_STATES InitialResourceState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, + ID3D12ProtectedResourceSession *pProtectedSession, + REFIID riidResource, void **ppvResource); +INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreatePlacedResource1, ID3D12Heap *pHeap, + UINT64 HeapOffset, const D3D12_RESOURCE_DESC1 *pDesc, + D3D12_RESOURCE_STATES InitialState, + const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, + void **ppvResource); diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp index eee8aa2ac..5af3bf11f 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap.cpp @@ -1439,242 +1439,6 @@ void WrappedID3D12Device::CreateSampler(const D3D12_SAMPLER_DESC *pDesc, GetWrapped(DestDescriptor)->Init(pDesc); } -template -bool WrappedID3D12Device::Serialise_CreateCommittedResource( - SerialiserType &ser, const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, - const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riidResource, void **ppvResource) -{ - SERIALISE_ELEMENT_LOCAL(props, *pHeapProperties).Named("pHeapProperties"_lit); - SERIALISE_ELEMENT(HeapFlags); - SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); - SERIALISE_ELEMENT(InitialResourceState); - SERIALISE_ELEMENT_OPT(pOptimizedClearValue); - SERIALISE_ELEMENT_LOCAL(guid, riidResource).Named("riidResource"_lit); - SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) - .TypedAs("ID3D12Resource *"_lit); - - SERIALISE_ELEMENT_LOCAL(gpuAddress, - ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) - .Hidden(); - - SERIALISE_CHECK_READ_ERRORS(); - - if(IsReplayingAndReading()) - { - if(props.Type == D3D12_HEAP_TYPE_UPLOAD && desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - // place large resources in local memory so that initial contents and maps can - // be cached and copied on the GPU instead of memcpy'd from the CPU every time. - // smaller resources it's better to just leave them as upload and map into them - if(desc.Width >= 1024 * 1024) - { - RDCLOG("Remapping committed resource %s from upload to default for efficient replay", - ToStr(pResource).c_str()); - props.Type = D3D12_HEAP_TYPE_DEFAULT; - m_UploadResourceIds.insert(pResource); - } - } - - APIProps.YUVTextures |= IsYUVFormat(desc.Format); - - // always allow SRVs on replay so we can inspect resources - desc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - // don't create resources non-resident - HeapFlags &= ~D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT; - - if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - GPUAddressRange range; - range.start = gpuAddress; - range.end = gpuAddress + desc.Width; - range.id = pResource; - - m_GPUAddresses.AddTo(range); - } - - ID3D12Resource *ret = NULL; - HRESULT hr = m_pDevice->CreateCommittedResource(&props, HeapFlags, &desc, InitialResourceState, - pOptimizedClearValue, guid, (void **)&ret); - - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating committed resource, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - SetObjName(ret, StringFormat::Fmt("Committed Resource %s %s", ToStr(desc.Dimension).c_str(), - ToStr(pResource).c_str())); - - ret = new WrappedID3D12Resource(ret, this); - - GetResourceManager()->AddLiveResource(pResource, ret); - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - m_ModResources.insert(GetResID(ret)); - - SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - ResourceType type = ResourceType::Texture; - const char *prefix = "Texture"; - - if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - type = ResourceType::Buffer; - prefix = "Buffer"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - prefix = desc.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "1D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "1D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - prefix = desc.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "2D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "2D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - prefix = "3D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "3D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "3D Depth Target"; - } - - AddResource(pResource, type, prefix); - } - } - - return true; -} - -HRESULT WrappedID3D12Device::CreateCommittedResource(const D3D12_HEAP_PROPERTIES *pHeapProperties, - D3D12_HEAP_FLAGS HeapFlags, - const D3D12_RESOURCE_DESC *pDesc, - D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - REFIID riidResource, void **ppvResource) -{ - if(ppvResource == NULL) - return m_pDevice->CreateCommittedResource(pHeapProperties, HeapFlags, pDesc, InitialResourceState, - pOptimizedClearValue, riidResource, NULL); - - if(riidResource != __uuidof(ID3D12Resource) && riidResource != __uuidof(ID3D12Resource1) && - riidResource != __uuidof(ID3D12Resource2)) - return E_NOINTERFACE; - - const D3D12_RESOURCE_DESC *pCreateDesc = pDesc; - D3D12_RESOURCE_DESC localDesc; - - if(pDesc && pDesc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && pDesc->SampleDesc.Count > 1) - { - localDesc = *pDesc; - // need to be able to create SRVs of MSAA textures to copy out their contents - localDesc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - pCreateDesc = &localDesc; - } - - void *realptr = NULL; - HRESULT ret; - SERIALISE_TIME_CALL(ret = m_pDevice->CreateCommittedResource( - pHeapProperties, HeapFlags, pCreateDesc, InitialResourceState, - pOptimizedClearValue, riidResource, &realptr)); - - ID3D12Resource *real = NULL; - if(riidResource == __uuidof(ID3D12Resource)) - real = (ID3D12Resource *)realptr; - else if(riidResource == __uuidof(ID3D12Resource1)) - real = (ID3D12Resource1 *)realptr; - else if(riidResource == __uuidof(ID3D12Resource2)) - real = (ID3D12Resource2 *)realptr; - - if(SUCCEEDED(ret)) - { - WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(real, this); - - if(IsCaptureMode(m_State)) - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreateCommittedResource); - Serialise_CreateCommittedResource(ser, pHeapProperties, HeapFlags, pDesc, InitialResourceState, - pOptimizedClearValue, riidResource, (void **)&wrapped); - - if(HeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT) - wrapped->Evict(); - - D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Resource; - record->Length = 0; - wrapped->SetResourceRecord(record); - - record->m_MapsCount = GetNumSubresources(this, pDesc); - record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; - - record->AddChunk(scope.Get()); - - GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); - } - else - { - GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped); - } - - { - SCOPED_LOCK(m_ResourceStatesLock); - SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - - states.fill(GetNumSubresources(m_pDevice, pDesc), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); - } - - if(riidResource == __uuidof(ID3D12Resource)) - *ppvResource = (ID3D12Resource *)wrapped; - else if(riidResource == __uuidof(ID3D12Resource1)) - *ppvResource = (ID3D12Resource1 *)wrapped; - else if(riidResource == __uuidof(ID3D12Resource2)) - *ppvResource = (ID3D12Resource2 *)wrapped; - - // while actively capturing we keep all buffers around to prevent the address lookup from - // losing addresses we might need (or the manageable but annoying problem of an address being - // re-used) - { - SCOPED_READLOCK(m_CapTransitionLock); - if(IsActiveCapturing(m_State)) - { - wrapped->AddRef(); - m_RefBuffers.push_back(wrapped); - if(m_BindlessResourceUseActive) - GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), - BindlessRefTypeForRes(wrapped)); - } - } - } - else - { - CheckHRESULT(ret); - } - - return ret; -} - template bool WrappedID3D12Device::Serialise_CreateHeap(SerialiserType &ser, const D3D12_HEAP_DESC *pDesc, REFIID riid, void **ppvHeap) @@ -1779,473 +1543,6 @@ HRESULT WrappedID3D12Device::CreateHeap(const D3D12_HEAP_DESC *pDesc, REFIID rii return ret; } -template -bool WrappedID3D12Device::Serialise_CreatePlacedResource( - SerialiserType &ser, ID3D12Heap *pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC *pDesc, - D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, - void **ppvResource) -{ - SERIALISE_ELEMENT(pHeap).Important(); - SERIALISE_ELEMENT(HeapOffset); - SERIALISE_ELEMENT_LOCAL(Descriptor, *pDesc).Named("pDesc"_lit).Important(); - SERIALISE_ELEMENT(InitialState); - SERIALISE_ELEMENT_OPT(pOptimizedClearValue); - SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); - SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) - .TypedAs("ID3D12Resource *"_lit); - - SERIALISE_ELEMENT_LOCAL(gpuAddress, - ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) - .Hidden(); - - SERIALISE_CHECK_READ_ERRORS(); - - if(IsReplayingAndReading()) - { - if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - GPUAddressRange range; - range.start = gpuAddress; - range.end = gpuAddress + Descriptor.Width; - range.id = pResource; - - m_GPUAddresses.AddTo(range); - } - - APIProps.YUVTextures |= IsYUVFormat(Descriptor.Format); - - // always allow SRVs on replay so we can inspect resources - Descriptor.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - D3D12_HEAP_DESC heapDesc = pHeap->GetDesc(); - - // if the heap was from OpenExistingHeap* then we will have removed the shared flags from it as - // it's CPU-visible and impossible to share. - // That means any resources placed to it would have had this flag that we then need to remove as - // well. - if((heapDesc.Flags & D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER) == 0) - Descriptor.Flags &= ~D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER; - - ID3D12Resource *ret = NULL; - HRESULT hr = m_pDevice->CreatePlacedResource(Unwrap(pHeap), HeapOffset, &Descriptor, InitialState, - pOptimizedClearValue, guid, (void **)&ret); - - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating placed resource, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - SetObjName(ret, StringFormat::Fmt("Placed Resource %s %s", ToStr(Descriptor.Dimension).c_str(), - ToStr(pResource).c_str())); - - ret = new WrappedID3D12Resource(ret, this); - - GetResourceManager()->AddLiveResource(pResource, ret); - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - m_ModResources.insert(GetResID(ret)); - - SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &Descriptor), - D3D12ResourceLayout::FromStates(InitialState)); - } - - ResourceType type = ResourceType::Texture; - const char *prefix = "Texture"; - - if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - type = ResourceType::Buffer; - prefix = "Buffer"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - prefix = Descriptor.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "1D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "1D Depth Target"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - prefix = Descriptor.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "2D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "2D Depth Target"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - prefix = "3D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "3D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "3D Depth Target"; - } - - AddResource(pResource, type, prefix); - DerivedResource(pHeap, pResource); - } - - return true; -} - -HRESULT WrappedID3D12Device::CreatePlacedResource(ID3D12Heap *pHeap, UINT64 HeapOffset, - const D3D12_RESOURCE_DESC *pDesc, - D3D12_RESOURCE_STATES InitialState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - REFIID riid, void **ppvResource) -{ - if(ppvResource == NULL) - return m_pDevice->CreatePlacedResource(Unwrap(pHeap), HeapOffset, pDesc, InitialState, - pOptimizedClearValue, riid, NULL); - - if(riid != __uuidof(ID3D12Resource) && riid != __uuidof(ID3D12Resource1) && - riid != __uuidof(ID3D12Resource2)) - return E_NOINTERFACE; - - const D3D12_RESOURCE_DESC *pCreateDesc = pDesc; - D3D12_RESOURCE_DESC localDesc; - - if(pDesc && pDesc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && pDesc->SampleDesc.Count > 1) - { - localDesc = *pDesc; - // need to be able to create SRVs of MSAA textures to copy out their contents - localDesc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - pCreateDesc = &localDesc; - } - - ID3D12Resource *real = NULL; - HRESULT ret; - SERIALISE_TIME_CALL(ret = m_pDevice->CreatePlacedResource( - Unwrap(pHeap), HeapOffset, pCreateDesc, InitialState, - pOptimizedClearValue, __uuidof(ID3D12Resource), (void **)&real)); - - if(SUCCEEDED(ret)) - { - WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(real, this); - - wrapped->SetHeap(pHeap); - - if(IsCaptureMode(m_State)) - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreatePlacedResource); - Serialise_CreatePlacedResource(ser, pHeap, HeapOffset, pDesc, InitialState, - pOptimizedClearValue, riid, (void **)&wrapped); - - D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Resource; - record->Length = 0; - wrapped->SetResourceRecord(record); - - record->m_MapsCount = GetNumSubresources(this, pDesc); - record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; - - RDCASSERT(pHeap); - - record->AddParent(GetRecord(pHeap)); - record->AddChunk(scope.Get()); - - GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); - } - else - { - GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped); - } - - { - SCOPED_LOCK(m_ResourceStatesLock); - SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - - states.fill(GetNumSubresources(m_pDevice, pDesc), - D3D12ResourceLayout::FromStates(InitialState)); - - m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); - } - - if(riid == __uuidof(ID3D12Resource)) - *ppvResource = (ID3D12Resource *)wrapped; - else if(riid == __uuidof(ID3D12Resource1)) - *ppvResource = (ID3D12Resource1 *)wrapped; - else if(riid == __uuidof(ID3D12Resource2)) - *ppvResource = (ID3D12Resource2 *)wrapped; - - // while actively capturing we keep all buffers around to prevent the address lookup from - // losing addresses we might need (or the manageable but annoying problem of an address being - // re-used) - { - SCOPED_READLOCK(m_CapTransitionLock); - if(IsActiveCapturing(m_State)) - { - wrapped->AddRef(); - m_RefBuffers.push_back(wrapped); - if(m_BindlessResourceUseActive) - GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), - BindlessRefTypeForRes(wrapped)); - } - } - } - else - { - CheckHRESULT(ret); - } - - return ret; -} - -template -bool WrappedID3D12Device::Serialise_CreateReservedResource( - SerialiserType &ser, const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, void **ppvResource) -{ - SERIALISE_ELEMENT_LOCAL(Descriptor, *pDesc).Named("pDesc"_lit).Important(); - SERIALISE_ELEMENT(InitialState); - SERIALISE_ELEMENT_OPT(pOptimizedClearValue); - SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); - SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) - .TypedAs("ID3D12Resource *"_lit); - - SERIALISE_ELEMENT_LOCAL(gpuAddress, - ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) - .Hidden(); - - SERIALISE_CHECK_READ_ERRORS(); - - if(IsReplayingAndReading()) - { - APIProps.SparseResources = true; - - if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - GPUAddressRange range; - range.start = gpuAddress; - range.end = gpuAddress + Descriptor.Width; - range.id = pResource; - - m_GPUAddresses.AddTo(range); - } - - APIProps.YUVTextures |= IsYUVFormat(Descriptor.Format); - - // always allow SRVs on replay so we can inspect resources - Descriptor.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - ID3D12Resource *ret = NULL; - HRESULT hr = m_pDevice->CreateReservedResource(&Descriptor, InitialState, pOptimizedClearValue, - guid, (void **)&ret); - - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating reserved resource, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - SetObjName(ret, - StringFormat::Fmt("Reserved Resource %s %s", ToStr(Descriptor.Dimension).c_str(), - ToStr(pResource).c_str())); - - ret = new WrappedID3D12Resource(ret, this); - - GetResourceManager()->AddLiveResource(pResource, ret); - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - m_ModResources.insert(GetResID(ret)); - - SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &Descriptor), - D3D12ResourceLayout::FromStates(InitialState)); - } - - m_SparseResources.insert(GetResID(ret)); - - ResourceType type = ResourceType::Texture; - const char *prefix = "Texture"; - - if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - type = ResourceType::Buffer; - prefix = "Buffer"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - prefix = Descriptor.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "1D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "1D Depth Target"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - prefix = Descriptor.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "2D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "2D Depth Target"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - prefix = "3D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "3D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "3D Depth Target"; - } - - AddResource(pResource, type, prefix); - } - - return true; -} - -HRESULT WrappedID3D12Device::CreateReservedResource(const D3D12_RESOURCE_DESC *pDesc, - D3D12_RESOURCE_STATES InitialState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - REFIID riid, void **ppvResource) -{ - if(ppvResource == NULL) - return m_pDevice->CreateReservedResource(pDesc, InitialState, pOptimizedClearValue, riid, NULL); - - if(riid != __uuidof(ID3D12Resource) && riid != __uuidof(ID3D12Resource1) && - riid != __uuidof(ID3D12Resource2)) - return E_NOINTERFACE; - - const D3D12_RESOURCE_DESC *pCreateDesc = pDesc; - D3D12_RESOURCE_DESC localDesc; - - if(pDesc && pDesc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && pDesc->SampleDesc.Count > 1) - { - localDesc = *pDesc; - // need to be able to create SRVs of MSAA textures to copy out their contents - localDesc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - pCreateDesc = &localDesc; - } - - ID3D12Resource *real = NULL; - HRESULT ret; - SERIALISE_TIME_CALL( - ret = m_pDevice->CreateReservedResource(pCreateDesc, InitialState, pOptimizedClearValue, - __uuidof(ID3D12Resource), (void **)&real)); - - if(SUCCEEDED(ret)) - { - WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(real, this); - - if(IsCaptureMode(m_State)) - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreateReservedResource); - Serialise_CreateReservedResource(ser, pDesc, InitialState, pOptimizedClearValue, riid, - (void **)&wrapped); - - D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Resource; - record->Length = 0; - wrapped->SetResourceRecord(record); - - record->m_MapsCount = GetNumSubresources(this, pDesc); - record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; - - const UINT pageSize = 64 * 1024; - - if(pDesc->Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - record->sparseTable = new Sparse::PageTable; - record->sparseTable->Initialise(pDesc->Width, pageSize); - } - else - { - D3D12_PACKED_MIP_INFO mipTail = {}; - D3D12_TILE_SHAPE tileShape = {}; - - m_pDevice->GetResourceTiling(wrapped->GetReal(), NULL, &mipTail, &tileShape, NULL, 0, NULL); - - UINT texDepth = 1; - UINT texSlices = pDesc->DepthOrArraySize; - if(pDesc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - texDepth = pDesc->DepthOrArraySize; - texSlices = 1; - } - - RDCASSERT(mipTail.NumStandardMips + mipTail.NumPackedMips == pDesc->MipLevels, - mipTail.NumStandardMips, mipTail.NumPackedMips, pDesc->MipLevels); - record->sparseTable = new Sparse::PageTable; - record->sparseTable->Initialise( - {(uint32_t)pDesc->Width, pDesc->Height, texDepth}, pDesc->MipLevels, texSlices, - pageSize, {tileShape.WidthInTexels, tileShape.HeightInTexels, tileShape.DepthInTexels}, - mipTail.NumStandardMips, mipTail.StartTileIndexInOverallResource * pageSize, - (mipTail.StartTileIndexInOverallResource + mipTail.NumTilesForPackedMips) * pageSize, - mipTail.NumTilesForPackedMips * pageSize * texSlices); - } - - { - SCOPED_LOCK(m_SparseLock); - m_SparseResources.insert(wrapped->GetResourceID()); - } - - record->AddChunk(scope.Get()); - - GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); - } - else - { - GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped); - } - - { - SCOPED_LOCK(m_ResourceStatesLock); - SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - - states.fill(GetNumSubresources(m_pDevice, pDesc), - D3D12ResourceLayout::FromStates(InitialState)); - - m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); - } - - if(riid == __uuidof(ID3D12Resource)) - *ppvResource = (ID3D12Resource *)wrapped; - else if(riid == __uuidof(ID3D12Resource1)) - *ppvResource = (ID3D12Resource1 *)wrapped; - else if(riid == __uuidof(ID3D12Resource2)) - *ppvResource = (ID3D12Resource2 *)wrapped; - - // while actively capturing we keep all buffers around to prevent the address lookup from - // losing addresses we might need (or the manageable but annoying problem of an address being - // re-used) - { - SCOPED_READLOCK(m_CapTransitionLock); - if(IsActiveCapturing(m_State)) - { - wrapped->AddRef(); - m_RefBuffers.push_back(wrapped); - if(m_BindlessResourceUseActive) - GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), - BindlessRefTypeForRes(wrapped)); - } - } - } - else - { - CheckHRESULT(ret); - } - - return ret; -} - template bool WrappedID3D12Device::Serialise_CreateFence(SerialiserType &ser, UINT64 InitialValue, D3D12_FENCE_FLAGS Flags, REFIID riid, void **ppFence) @@ -2782,455 +2079,6 @@ void WrappedID3D12Device::CopyDescriptorsSimple(UINT NumDescriptors, dst[i].CopyFrom(src[i]); } -template -bool WrappedID3D12Device::Serialise_OpenSharedHandle(SerialiserType &ser, HANDLE, REFIID riid, - void **ppvObj) -{ - SERIALISE_ELEMENT_LOCAL(ResourceRIID, riid).Important(); - - SERIALISE_CHECK_READ_ERRORS(); - - bool isRes = ResourceRIID == __uuidof(ID3D12Resource) || - ResourceRIID == __uuidof(ID3D12Resource1) || - ResourceRIID == __uuidof(ID3D12Resource2); - bool isFence = ResourceRIID == __uuidof(ID3D12Fence) || ResourceRIID == __uuidof(ID3D12Fence1); - bool isHeap = ResourceRIID == __uuidof(ID3D12Heap) || ResourceRIID == __uuidof(ID3D12Heap1); - if(isFence) - { - ID3D12Fence *fence = NULL; - if(ser.IsWriting()) - { - fence = (ID3D12Fence *)(ID3D12DeviceChild *)*ppvObj; - if(ResourceRIID == __uuidof(ID3D12Fence1)) - fence = (ID3D12Fence1 *)(ID3D12DeviceChild *)*ppvObj; - } - - SERIALISE_ELEMENT_LOCAL(resourceId, GetResID(fence)); - - UINT64 fakeInitialValue = 0; - D3D12_FENCE_FLAGS fakeFlags = D3D12_FENCE_FLAG_NONE; - - // maybe in future this can be determined? - SERIALISE_ELEMENT_LOCAL(initialValue, fakeInitialValue); - SERIALISE_ELEMENT_LOCAL(flags, fakeFlags); - - if(IsReplayingAndReading()) - { - HRESULT hr; - ID3D12Fence *ret; - hr = m_pDevice->CreateFence(initialValue, flags, __uuidof(ID3D12Fence), (void **)&ret); - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating shared fence, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - ret = new WrappedID3D12Fence(ret, this); - - GetResourceManager()->AddLiveResource(resourceId, ret); - } - - AddResource(resourceId, ResourceType::Sync, "Fence"); - } - } - else if(isRes) - { - D3D12_RESOURCE_DESC desc; - D3D12_HEAP_PROPERTIES heapProperties; - D3D12_HEAP_FLAGS heapFlags; - - ID3D12Resource *res = NULL; - if(ser.IsWriting()) - { - res = (ID3D12Resource *)(ID3D12DeviceChild *)*ppvObj; - if(ResourceRIID == __uuidof(ID3D12Resource1)) - res = (ID3D12Resource1 *)(ID3D12DeviceChild *)*ppvObj; - else if(ResourceRIID == __uuidof(ID3D12Resource2)) - res = (ID3D12Resource2 *)(ID3D12DeviceChild *)*ppvObj; - desc = res->GetDesc(); - res->GetHeapProperties(&heapProperties, &heapFlags); - } - - SERIALISE_ELEMENT_LOCAL(resourceId, GetResID(res)); - SERIALISE_ELEMENT(desc); - SERIALISE_ELEMENT(heapProperties); - SERIALISE_ELEMENT(heapFlags); - - if(IsReplayingAndReading()) - { - D3D12_RESOURCE_STATES InitialResourceState = D3D12_RESOURCE_STATE_COMMON; - const D3D12_CLEAR_VALUE *pOptimizedClearValue = NULL; - - // always allow SRVs on replay so we can inspect resources - desc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - // the runtime doesn't like us telling it what DENY heap flags will be set, remove them - heapFlags &= ~(D3D12_HEAP_FLAG_DENY_BUFFERS | D3D12_HEAP_FLAG_DENY_NON_RT_DS_TEXTURES | - D3D12_HEAP_FLAG_DENY_RT_DS_TEXTURES); - - // don't create resources non-resident - heapFlags &= ~D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT; - - HRESULT hr; - ID3D12Resource *ret; - hr = m_pDevice->CreateCommittedResource(&heapProperties, heapFlags, &desc, - InitialResourceState, pOptimizedClearValue, - __uuidof(ID3D12Resource), (void **)&ret); - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating shared committed resource, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - SetObjName(ret, StringFormat::Fmt("Shared Resource %s %s", ToStr(desc.Dimension).c_str(), - ToStr(resourceId).c_str())); - - ret = new WrappedID3D12Resource(ret, this); - - GetResourceManager()->AddLiveResource(resourceId, ret); - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - m_ModResources.insert(GetResID(ret)); - - SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - ResourceType type = ResourceType::Texture; - const char *prefix = "Texture"; - - if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - type = ResourceType::Buffer; - prefix = "Buffer"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - prefix = desc.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "1D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "1D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - prefix = desc.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "2D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "2D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - prefix = "3D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "3D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "3D Depth Target"; - } - - AddResource(resourceId, type, prefix); - } - } - } - else if(isHeap) - { - D3D12_HEAP_DESC desc; - - ID3D12Heap *heap = NULL; - if(ser.IsWriting()) - { - heap = (ID3D12Heap *)(ID3D12DeviceChild *)*ppvObj; - if(ResourceRIID == __uuidof(ID3D12Heap1)) - heap = (ID3D12Heap1 *)(ID3D12DeviceChild *)*ppvObj; - desc = heap->GetDesc(); - } - - SERIALISE_ELEMENT_LOCAL(resourceId, GetResID(heap)); - SERIALISE_ELEMENT(desc); - - if(IsReplayingAndReading()) - { - HRESULT hr; - ID3D12Heap *ret; - hr = m_pDevice->CreateHeap(&desc, __uuidof(ID3D12Heap), (void **)&ret); - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating shared heap, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - ret = new WrappedID3D12Heap(ret, this); - - GetResourceManager()->AddLiveResource(resourceId, ret); - } - - AddResource(resourceId, ResourceType::Memory, "Heap"); - } - } - else - { - RDCERR("Unknown type of resource being shared"); - } - - return true; -} - -HRESULT WrappedID3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void **ppvObj) -{ - if(ppvObj == NULL) - return E_INVALIDARG; - - HRESULT hr; - - SERIALISE_TIME_CALL(hr = m_pDevice->OpenSharedHandle(NTHandle, riid, ppvObj)); - - if(FAILED(hr)) - { - IUnknown *unk = (IUnknown *)*ppvObj; - SAFE_RELEASE(unk); - return hr; - } - - return OpenSharedHandleInternal(D3D12Chunk::Device_OpenSharedHandle, D3D12_HEAP_FLAG_NONE, riid, - ppvObj); -} - -HRESULT WrappedID3D12Device::OpenSharedHandleInternal(D3D12Chunk chunkType, - D3D12_HEAP_FLAGS HeapFlags, REFIID riid, - void **ppvObj) -{ - if(IsReplayMode(m_State)) - { - RDCERR("Don't support opening shared handle during replay."); - return E_NOTIMPL; - } - - bool isDXGIRes = riid == __uuidof(IDXGIResource) || riid == __uuidof(IDXGIResource1); - bool isRes = riid == __uuidof(ID3D12Resource) || riid == __uuidof(ID3D12Resource1) || - riid == __uuidof(ID3D12Resource2); - bool isFence = riid == __uuidof(ID3D12Fence) || riid == __uuidof(ID3D12Fence1); - bool isHeap = riid == __uuidof(ID3D12Heap) || riid == __uuidof(ID3D12Heap1); - bool isDeviceChild = riid == __uuidof(ID3D12DeviceChild); - bool isIUnknown = riid == __uuidof(IUnknown); - - IID riid_internal = riid; - void *ret = *ppvObj; - - if(isIUnknown) - { - // same as device child but we're even more in the dark. Hope against hope it's a - // ID3D12DeviceChild - IUnknown *real = (IUnknown *)ret; - - ID3D12DeviceChild *d3d12child = NULL; - isDeviceChild = - SUCCEEDED(real->QueryInterface(__uuidof(ID3D12DeviceChild), (void **)&d3d12child)) && - d3d12child; - SAFE_RELEASE(real); - - if(isDeviceChild) - { - riid_internal = __uuidof(ID3D12DeviceChild); - ret = (void *)d3d12child; - } - else - { - SAFE_RELEASE(d3d12child); - return E_NOINTERFACE; - } - } - - if(isDeviceChild) - { - // In this case we need to find out what the actual underlying type is - // Should be one of ID3D12Heap, ID3D12Resource, ID3D12Fence - ID3D12DeviceChild *real = (ID3D12DeviceChild *)ret; - - ID3D12Resource *d3d12Res = NULL; - ID3D12Fence *d3d12Fence = NULL; - ID3D12Heap *d3d12Heap = NULL; - isRes = SUCCEEDED(real->QueryInterface(__uuidof(ID3D12Resource), (void **)&d3d12Res)) && d3d12Res; - isFence = - SUCCEEDED(real->QueryInterface(__uuidof(ID3D12Fence), (void **)&d3d12Fence)) && d3d12Fence; - isHeap = SUCCEEDED(real->QueryInterface(__uuidof(ID3D12Heap), (void **)&d3d12Heap)) && d3d12Heap; - SAFE_RELEASE(real); - - if(isRes) - { - riid_internal = __uuidof(ID3D12Resource); - ret = (void *)d3d12Res; - } - else if(isFence) - { - riid_internal = __uuidof(ID3D12Fence); - ret = (void *)d3d12Fence; - } - else if(isHeap) - { - riid_internal = __uuidof(ID3D12Heap); - ret = (void *)d3d12Heap; - } - else - { - SAFE_RELEASE(d3d12Res); - SAFE_RELEASE(d3d12Fence); - SAFE_RELEASE(d3d12Heap); - return E_NOINTERFACE; - } - } - - if(isDXGIRes || isRes || isFence || isHeap) - { - HRESULT hr = S_OK; - - if(isDXGIRes) - { - IDXGIResource *dxgiRes = (IDXGIResource *)ret; - if(riid_internal == __uuidof(IDXGIResource1)) - dxgiRes = (IDXGIResource1 *)ret; - - ID3D12Resource *d3d12Res = NULL; - hr = dxgiRes->QueryInterface(__uuidof(ID3D12Resource), (void **)&d3d12Res); - - // if we can't get a d3d11Res then we can't properly wrap this resource, - // whatever it is. - if(FAILED(hr) || d3d12Res == NULL) - { - SAFE_RELEASE(d3d12Res); - SAFE_RELEASE(dxgiRes); - return E_NOINTERFACE; - } - - // release this interface - SAFE_RELEASE(dxgiRes); - - // and use this one, so it'll be casted back below - ret = (void *)d3d12Res; - isRes = true; - } - - ID3D12DeviceChild *wrappedDeviceChild = NULL; - D3D12ResourceRecord *record = NULL; - - if(isFence) - { - ID3D12Fence *real = (ID3D12Fence *)ret; - if(riid_internal == __uuidof(ID3D12Fence1)) - real = (ID3D12Fence1 *)ret; - - WrappedID3D12Fence *wrapped = new WrappedID3D12Fence(real, this); - - wrappedDeviceChild = wrapped; - - record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Fence; - record->Length = 0; - wrapped->SetResourceRecord(record); - } - else if(isRes) - { - ID3D12Resource *real = (ID3D12Resource *)ret; - if(riid_internal == __uuidof(ID3D12Resource1)) - real = (ID3D12Resource1 *)ret; - else if(riid_internal == __uuidof(ID3D12Resource2)) - real = (ID3D12Resource2 *)ret; - - WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(real, this); - - if(HeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT) - wrapped->Evict(); - - wrappedDeviceChild = wrapped; - - D3D12_RESOURCE_DESC desc = wrapped->GetDesc(); - D3D12_RESOURCE_STATES InitialResourceState = D3D12_RESOURCE_STATE_COMMON; - - record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Resource; - record->Length = 0; - wrapped->SetResourceRecord(record); - - record->m_MapsCount = GetNumSubresources(this, &desc); - record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; - - GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); - - { - SCOPED_LOCK(m_ResourceStatesLock); - SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - - states.fill(GetNumSubresources(m_pDevice, &desc), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); - } - - // while actively capturing we keep all buffers around to prevent the address lookup from - // losing addresses we might need (or the manageable but annoying problem of an address being - // re-used) - { - SCOPED_READLOCK(m_CapTransitionLock); - if(IsActiveCapturing(m_State)) - { - wrapped->AddRef(); - m_RefBuffers.push_back(wrapped); - if(m_BindlessResourceUseActive) - GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), - BindlessRefTypeForRes(wrapped)); - } - } - } - else if(isHeap) - { - ID3D12Heap *real = (ID3D12Heap *)ret; - if(riid_internal == __uuidof(ID3D12Heap1)) - real = (ID3D12Heap1 *)ret; - - WrappedID3D12Heap *wrapped = new WrappedID3D12Heap(real, this); - - if(HeapFlags & D3D12_HEAP_FLAG_CREATE_NOT_RESIDENT) - wrapped->Evict(); - - wrappedDeviceChild = wrapped; - - record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Heap; - record->Length = 0; - wrapped->SetResourceRecord(record); - } - - // use queryinterface to get the right interface into ppvObj, then release the reference - wrappedDeviceChild->QueryInterface(riid, ppvObj); - wrappedDeviceChild->Release(); - - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CHUNK(chunkType); - Serialise_OpenSharedHandle(ser, 0, riid_internal, (void **)&wrappedDeviceChild); - - record->AddChunk(scope.Get()); - - return S_OK; - } - - RDCERR("Unknown OpenSharedResourceInternal GUID: %s", ToStr(riid).c_str()); - - IUnknown *unk = (IUnknown *)*ppvObj; - SAFE_RELEASE(unk); - - return E_NOINTERFACE; -} - HRESULT WrappedID3D12Device::OpenSharedHandleByName(LPCWSTR Name, DWORD Access, HANDLE *pNTHandle) { return m_pDevice->OpenSharedHandleByName(Name, Access, pNTHandle); @@ -3531,23 +2379,8 @@ INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateRootSignature, REFIID riid, void **ppvRootSignature); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, DynamicDescriptorWrite, const DynamicDescriptorWrite *write); -INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommittedResource, - const D3D12_HEAP_PROPERTIES *pHeapProperties, - D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC *pDesc, - D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riidResource, - void **ppvResource); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateHeap, const D3D12_HEAP_DESC *pDesc, REFIID riid, void **ppvHeap); -INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreatePlacedResource, ID3D12Heap *pHeap, - UINT64 HeapOffset, const D3D12_RESOURCE_DESC *pDesc, - D3D12_RESOURCE_STATES InitialState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, - void **ppvResource); -INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateReservedResource, - const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, - void **ppvResource); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateFence, UINT64 InitialValue, D3D12_FENCE_FLAGS Flags, REFIID riid, void **ppFence); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateQueryHeap, @@ -3558,5 +2391,24 @@ INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommandSignatur void **ppvCommandSignature); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, DynamicDescriptorCopies, const rdcarray &DescriptorCopies); -INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, OpenSharedHandle, HANDLE NTHandle, - REFIID riid, void **ppvObj); + +#if ENABLED(ENABLE_UNIT_TESTS) + +#include "catch/catch.hpp" + +// ensure that we don't have to pay attention to the GUID requested and can return our +// WrappedID3D12Resource anywhere and know it satisfies all possibilities +TEST_CASE("Check ID3D12Resource inheritance chain", "[d3d]") +{ + // this should really be checkable at compile time + IUnknown *u = (IUnknown *)0x1000000; + ID3D12Resource *a = (ID3D12Resource *)u; + ID3D12Resource1 *b = (ID3D12Resource1 *)a; + ID3D12Resource2 *c = (ID3D12Resource2 *)b; + + CHECK((byte *)a == (byte *)u); + CHECK((byte *)b == (byte *)a); + CHECK((byte *)c == (byte *)b); +} + +#endif diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap10.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap10.cpp deleted file mode 100644 index 53c0e1f1a..000000000 --- a/renderdoc/driver/d3d12/d3d12_device_wrap10.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/****************************************************************************** - * The MIT License (MIT) - * - * Copyright (c) 2021-2023 Baldur Karlsson - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -#include "d3d12_device.h" -#include "driver/dxgi/dxgi_common.h" -#include "d3d12_command_queue.h" -#include "d3d12_resources.h" - -HRESULT WrappedID3D12Device::CreateCommittedResource3( - _In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, - _In_ const D3D12_RESOURCE_DESC1 *pDesc, D3D12_BARRIER_LAYOUT InitialLayout, - _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, - _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, UINT32 NumCastableFormats, - _In_opt_count_(NumCastableFormats) const DXGI_FORMAT *pCastableFormats, REFIID riidResource, - _COM_Outptr_opt_ void **ppvResource) -{ - return E_NOTIMPL; -} - -HRESULT WrappedID3D12Device::CreatePlacedResource2( - _In_ ID3D12Heap *pHeap, UINT64 HeapOffset, _In_ const D3D12_RESOURCE_DESC1 *pDesc, - D3D12_BARRIER_LAYOUT InitialLayout, _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, - UINT32 NumCastableFormats, _In_opt_count_(NumCastableFormats) const DXGI_FORMAT *pCastableFormats, - REFIID riid, _COM_Outptr_opt_ void **ppvResource) -{ - return E_NOTIMPL; -} - -HRESULT WrappedID3D12Device::CreateReservedResource2( - _In_ const D3D12_RESOURCE_DESC *pDesc, D3D12_BARRIER_LAYOUT InitialLayout, - _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, - _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, UINT32 NumCastableFormats, - _In_opt_count_(NumCastableFormats) const DXGI_FORMAT *pCastableFormats, REFIID riid, - _COM_Outptr_opt_ void **ppvResource) -{ - return E_NOTIMPL; -} diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp index 9d45af50d..62ef659ef 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap4.cpp @@ -228,250 +228,6 @@ HRESULT WrappedID3D12Device::CreateProtectedResourceSession( return ret; } -template -bool WrappedID3D12Device::Serialise_CreateCommittedResource1( - SerialiserType &ser, const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, - const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) -{ - SERIALISE_ELEMENT_LOCAL(props, *pHeapProperties).Named("pHeapProperties"_lit); - SERIALISE_ELEMENT(HeapFlags); - SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); - SERIALISE_ELEMENT(InitialResourceState); - SERIALISE_ELEMENT_OPT(pOptimizedClearValue); - // placeholder for future use if we properly capture & replay protected sessions - SERIALISE_ELEMENT_LOCAL(ProtectedSession, ResourceId()).Named("pProtectedSession"_lit); - SERIALISE_ELEMENT_LOCAL(guid, riidResource).Named("riidResource"_lit); - SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) - .TypedAs("ID3D12Resource *"_lit); - - SERIALISE_ELEMENT_LOCAL(gpuAddress, - ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) - .Hidden(); - - SERIALISE_CHECK_READ_ERRORS(); - - if(IsReplayingAndReading()) - { - if(props.Type == D3D12_HEAP_TYPE_UPLOAD && desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - // place large resources in local memory so that initial contents and maps can - // be cached and copied on the GPU instead of memcpy'd from the CPU every time. - // smaller resources it's better to just leave them as upload and map into them - if(desc.Width >= 1024 * 1024) - { - RDCLOG("Remapping committed resource %s from upload to default for efficient replay", - ToStr(pResource).c_str()); - props.Type = D3D12_HEAP_TYPE_DEFAULT; - m_UploadResourceIds.insert(pResource); - } - } - - APIProps.YUVTextures |= IsYUVFormat(desc.Format); - - // always allow SRVs on replay so we can inspect resources - desc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - GPUAddressRange range; - range.start = gpuAddress; - range.end = gpuAddress + desc.Width; - range.id = pResource; - - m_GPUAddresses.AddTo(range); - } - - ID3D12Resource *ret = NULL; - HRESULT hr = E_NOINTERFACE; - if(m_pDevice4) - { - hr = m_pDevice4->CreateCommittedResource1(&props, HeapFlags, &desc, InitialResourceState, - pOptimizedClearValue, NULL, guid, (void **)&ret); - } - else - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Capture requires ID3D12Device2 which isn't available"); - return false; - } - - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating committed resource, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - SetObjName(ret, StringFormat::Fmt("Committed Resource %s ID %s", - ToStr(desc.Dimension).c_str(), ToStr(pResource).c_str())); - - ret = new WrappedID3D12Resource(ret, this); - - GetResourceManager()->AddLiveResource(pResource, ret); - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - m_ModResources.insert(GetResID(ret)); - - SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - ResourceType type = ResourceType::Texture; - const char *prefix = "Texture"; - - if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - type = ResourceType::Buffer; - prefix = "Buffer"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - prefix = desc.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "1D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "1D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - prefix = desc.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "2D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "2D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - prefix = "3D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "3D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "3D Depth Target"; - } - - AddResource(pResource, type, prefix); - } - } - - return true; -} - -HRESULT WrappedID3D12Device::CreateCommittedResource1( - const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, - const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) -{ - if(ppvResource == NULL) - return m_pDevice4->CreateCommittedResource1(pHeapProperties, HeapFlags, pDesc, - InitialResourceState, pOptimizedClearValue, - Unwrap(pProtectedSession), riidResource, NULL); - - if(riidResource != __uuidof(ID3D12Resource) && riidResource != __uuidof(ID3D12Resource1) && - riidResource != __uuidof(ID3D12Resource2)) - return E_NOINTERFACE; - - const D3D12_RESOURCE_DESC *pCreateDesc = pDesc; - D3D12_RESOURCE_DESC localDesc; - - if(pDesc && pDesc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && pDesc->SampleDesc.Count > 1) - { - localDesc = *pDesc; - // need to be able to create SRVs of MSAA textures to copy out their contents - localDesc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - pCreateDesc = &localDesc; - } - - void *realptr = NULL; - HRESULT ret; - SERIALISE_TIME_CALL(ret = m_pDevice4->CreateCommittedResource1( - pHeapProperties, HeapFlags, pCreateDesc, InitialResourceState, - pOptimizedClearValue, Unwrap(pProtectedSession), riidResource, &realptr)); - - ID3D12Resource *real = NULL; - if(riidResource == __uuidof(ID3D12Resource)) - real = (ID3D12Resource *)realptr; - else if(riidResource == __uuidof(ID3D12Resource1)) - real = (ID3D12Resource1 *)realptr; - else if(riidResource == __uuidof(ID3D12Resource2)) - real = (ID3D12Resource2 *)realptr; - - if(SUCCEEDED(ret)) - { - WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(real, this); - - if(IsCaptureMode(m_State)) - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreateCommittedResource1); - Serialise_CreateCommittedResource1(ser, pHeapProperties, HeapFlags, pDesc, - InitialResourceState, pOptimizedClearValue, - pProtectedSession, riidResource, (void **)&wrapped); - - D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Resource; - record->Length = 0; - wrapped->SetResourceRecord(record); - - record->m_MapsCount = GetNumSubresources(this, pDesc); - record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; - - record->AddChunk(scope.Get()); - - GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); - } - else - { - GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped); - } - - { - SCOPED_LOCK(m_ResourceStatesLock); - SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - - states.fill(GetNumSubresources(m_pDevice, pDesc), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); - } - - if(riidResource == __uuidof(ID3D12Resource)) - *ppvResource = (ID3D12Resource *)wrapped; - else if(riidResource == __uuidof(ID3D12Resource1)) - *ppvResource = (ID3D12Resource1 *)wrapped; - else if(riidResource == __uuidof(ID3D12Resource2)) - *ppvResource = (ID3D12Resource2 *)wrapped; - - // while actively capturing we keep all buffers around to prevent the address lookup from - // losing addresses we might need (or the manageable but annoying problem of an address being - // re-used) - { - SCOPED_READLOCK(m_CapTransitionLock); - if(IsActiveCapturing(m_State)) - { - wrapped->AddRef(); - m_RefBuffers.push_back(wrapped); - if(m_BindlessResourceUseActive) - GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), - BindlessRefTypeForRes(wrapped)); - } - } - } - else - { - CheckHRESULT(ret); - } - - return ret; -} - template bool WrappedID3D12Device::Serialise_CreateHeap1(SerialiserType &ser, const D3D12_HEAP_DESC *pDesc, ID3D12ProtectedResourceSession *pProtectedSession, @@ -583,16 +339,6 @@ HRESULT WrappedID3D12Device::CreateHeap1(const D3D12_HEAP_DESC *pDesc, return ret; } -HRESULT WrappedID3D12Device::CreateReservedResource1( - _In_ const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialState, - _In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue, - _In_opt_ ID3D12ProtectedResourceSession *pProtectedSession, REFIID riid, - _COM_Outptr_opt_ void **ppvResource) -{ - RDCERR("Tiled Resources are not currently implemented on D3D12"); - return E_NOINTERFACE; -} - D3D12_RESOURCE_ALLOCATION_INFO WrappedID3D12Device::GetResourceAllocationInfo1( UINT visibleMask, UINT numResourceDescs, _In_reads_(numResourceDescs) const D3D12_RESOURCE_DESC *pResourceDescs, @@ -642,13 +388,6 @@ ID3D12Fence *WrappedID3D12Device::CreateProtectedSessionFence(ID3D12Fence *real) return wrapped; } -INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommittedResource1, - const D3D12_HEAP_PROPERTIES *pHeapProperties, - D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC *pDesc, - D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - ID3D12ProtectedResourceSession *pProtectedSession, - REFIID riidResource, void **ppvResource); INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateHeap1, const D3D12_HEAP_DESC *pDesc, ID3D12ProtectedResourceSession *pProtectedSession, REFIID riid, void **ppvHeap); diff --git a/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp b/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp index 1b006cb9b..7063f7024 100644 --- a/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp +++ b/renderdoc/driver/d3d12/d3d12_device_wrap8.cpp @@ -35,500 +35,6 @@ D3D12_RESOURCE_ALLOCATION_INFO STDMETHODCALLTYPE WrappedID3D12Device::GetResourc pResourceAllocationInfo1); } -template -bool WrappedID3D12Device::Serialise_CreateCommittedResource2( - SerialiserType &ser, const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, - const D3D12_RESOURCE_DESC1 *pDesc, D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) -{ - SERIALISE_ELEMENT_LOCAL(props, *pHeapProperties).Named("pHeapProperties"_lit); - SERIALISE_ELEMENT(HeapFlags); - SERIALISE_ELEMENT_LOCAL(desc, *pDesc).Named("pDesc"_lit).Important(); - SERIALISE_ELEMENT(InitialResourceState); - SERIALISE_ELEMENT_OPT(pOptimizedClearValue); - // placeholder for future use if we properly capture & replay protected sessions - SERIALISE_ELEMENT_LOCAL(ProtectedSession, ResourceId()).Named("pProtectedSession"_lit); - SERIALISE_ELEMENT_LOCAL(guid, riidResource).Named("riidResource"_lit); - SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) - .TypedAs("ID3D12Resource *"_lit); - - SERIALISE_ELEMENT_LOCAL(gpuAddress, - ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) - .Hidden(); - - SERIALISE_CHECK_READ_ERRORS(); - - if(IsReplayingAndReading()) - { - if(props.Type == D3D12_HEAP_TYPE_UPLOAD && desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - // place large resources in local memory so that initial contents and maps can - // be cached and copied on the GPU instead of memcpy'd from the CPU every time. - // smaller resources it's better to just leave them as upload and map into them - if(desc.Width >= 1024 * 1024) - { - RDCLOG("Remapping committed resource %s from upload to default for efficient replay", - ToStr(pResource).c_str()); - props.Type = D3D12_HEAP_TYPE_DEFAULT; - m_UploadResourceIds.insert(pResource); - } - } - - APIProps.YUVTextures |= IsYUVFormat(desc.Format); - - // always allow SRVs on replay so we can inspect resources - desc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - GPUAddressRange range; - range.start = gpuAddress; - range.end = gpuAddress + desc.Width; - range.id = pResource; - - m_GPUAddresses.AddTo(range); - } - - ID3D12Resource *ret = NULL; - HRESULT hr = E_NOINTERFACE; - if(m_pDevice8) - { - hr = m_pDevice8->CreateCommittedResource2(&props, HeapFlags, &desc, InitialResourceState, - pOptimizedClearValue, NULL, guid, (void **)&ret); - } - else - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Capture requires ID3D12Device8 which isn't available"); - return false; - } - - if(FAILED(hr)) - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating committed resource, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - SetObjName(ret, StringFormat::Fmt("Committed Resource %s ID %s", - ToStr(desc.Dimension).c_str(), ToStr(pResource).c_str())); - - ret = new WrappedID3D12Resource(ret, this); - - GetResourceManager()->AddLiveResource(pResource, ret); - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - m_ModResources.insert(GetResID(ret)); - - SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 - D3D12_RESOURCE_DESC desc0; - memcpy(&desc0, &desc, sizeof(desc0)); - states.fill(GetNumSubresources(m_pDevice, &desc0), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - ResourceType type = ResourceType::Texture; - const char *prefix = "Texture"; - - if(desc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - type = ResourceType::Buffer; - prefix = "Buffer"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - prefix = desc.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "1D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "1D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - prefix = desc.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "2D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "2D Depth Target"; - } - else if(desc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - prefix = "3D Texture"; - - if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "3D Render Target"; - else if(desc.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "3D Depth Target"; - } - - AddResource(pResource, type, prefix); - } - } - - return true; -} - -HRESULT WrappedID3D12Device::CreateCommittedResource2( - const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, - const D3D12_RESOURCE_DESC1 *pDesc, D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - ID3D12ProtectedResourceSession *pProtectedSession, REFIID riidResource, void **ppvResource) -{ - if(ppvResource == NULL) - return m_pDevice8->CreateCommittedResource2(pHeapProperties, HeapFlags, pDesc, - InitialResourceState, pOptimizedClearValue, - Unwrap(pProtectedSession), riidResource, NULL); - - if(riidResource != __uuidof(ID3D12Resource) && riidResource != __uuidof(ID3D12Resource1) && - riidResource != __uuidof(ID3D12Resource2)) - return E_NOINTERFACE; - - const D3D12_RESOURCE_DESC1 *pCreateDesc = pDesc; - D3D12_RESOURCE_DESC1 localDesc; - - if(pDesc && pDesc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && pDesc->SampleDesc.Count > 1) - { - localDesc = *pDesc; - // need to be able to create SRVs of MSAA textures to copy out their contents - localDesc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - pCreateDesc = &localDesc; - } - - void *realptr = NULL; - HRESULT ret; - SERIALISE_TIME_CALL(ret = m_pDevice8->CreateCommittedResource2( - pHeapProperties, HeapFlags, pCreateDesc, InitialResourceState, - pOptimizedClearValue, Unwrap(pProtectedSession), riidResource, &realptr)); - - ID3D12Resource *real = NULL; - if(riidResource == __uuidof(ID3D12Resource)) - real = (ID3D12Resource *)realptr; - else if(riidResource == __uuidof(ID3D12Resource1)) - real = (ID3D12Resource1 *)realptr; - else if(riidResource == __uuidof(ID3D12Resource2)) - real = (ID3D12Resource2 *)realptr; - - if(SUCCEEDED(ret)) - { - WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(real, this); - - if(IsCaptureMode(m_State)) - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreateCommittedResource2); - Serialise_CreateCommittedResource2(ser, pHeapProperties, HeapFlags, pDesc, - InitialResourceState, pOptimizedClearValue, - pProtectedSession, riidResource, (void **)&wrapped); - - D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Resource; - record->Length = 0; - wrapped->SetResourceRecord(record); - - // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 - D3D12_RESOURCE_DESC desc0; - memcpy(&desc0, pDesc, sizeof(desc0)); - record->m_MapsCount = GetNumSubresources(this, &desc0); - record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; - - record->AddChunk(scope.Get()); - - GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); - } - else - { - GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped); - } - - { - SCOPED_LOCK(m_ResourceStatesLock); - SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - - // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 - D3D12_RESOURCE_DESC desc0; - memcpy(&desc0, pDesc, sizeof(desc0)); - states.fill(GetNumSubresources(m_pDevice, &desc0), - D3D12ResourceLayout::FromStates(InitialResourceState)); - - m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); - } - - if(riidResource == __uuidof(ID3D12Resource)) - *ppvResource = (ID3D12Resource *)wrapped; - else if(riidResource == __uuidof(ID3D12Resource1)) - *ppvResource = (ID3D12Resource1 *)wrapped; - else if(riidResource == __uuidof(ID3D12Resource2)) - *ppvResource = (ID3D12Resource2 *)wrapped; - - // while actively capturing we keep all buffers around to prevent the address lookup from - // losing addresses we might need (or the manageable but annoying problem of an address being - // re-used) - { - SCOPED_READLOCK(m_CapTransitionLock); - if(IsActiveCapturing(m_State)) - { - wrapped->AddRef(); - m_RefBuffers.push_back(wrapped); - if(m_BindlessResourceUseActive) - GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), - BindlessRefTypeForRes(wrapped)); - } - } - } - else - { - CheckHRESULT(ret); - } - - return ret; -} - -template -bool WrappedID3D12Device::Serialise_CreatePlacedResource1( - SerialiserType &ser, ID3D12Heap *pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC1 *pDesc, - D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, - void **ppvResource) -{ - SERIALISE_ELEMENT(pHeap).Important(); - SERIALISE_ELEMENT(HeapOffset); - SERIALISE_ELEMENT_LOCAL(Descriptor, *pDesc).Named("pDesc"_lit).Important(); - SERIALISE_ELEMENT(InitialState); - SERIALISE_ELEMENT_OPT(pOptimizedClearValue); - SERIALISE_ELEMENT_LOCAL(guid, riid).Named("riid"_lit); - SERIALISE_ELEMENT_LOCAL(pResource, ((WrappedID3D12Resource *)*ppvResource)->GetResourceID()) - .TypedAs("ID3D12Resource *"_lit); - - SERIALISE_ELEMENT_LOCAL(gpuAddress, - ((WrappedID3D12Resource *)*ppvResource)->GetGPUVirtualAddressIfBuffer()) - .Hidden(); - - SERIALISE_CHECK_READ_ERRORS(); - - if(IsReplayingAndReading()) - { - if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - GPUAddressRange range; - range.start = gpuAddress; - range.end = gpuAddress + Descriptor.Width; - range.id = pResource; - - m_GPUAddresses.AddTo(range); - } - - APIProps.YUVTextures |= IsYUVFormat(Descriptor.Format); - - // always allow SRVs on replay so we can inspect resources - Descriptor.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - - D3D12_HEAP_DESC heapDesc = pHeap->GetDesc(); - - // if the heap was from OpenExistingHeap* then we will have removed the shared flags from it as - // it's CPU-visible and impossible to share. - // That means any resources placed to it would have had this flag that we then need to remove as - // well. - if((heapDesc.Flags & D3D12_HEAP_FLAG_SHARED_CROSS_ADAPTER) == 0) - Descriptor.Flags &= ~D3D12_RESOURCE_FLAG_ALLOW_CROSS_ADAPTER; - - ID3D12Resource *ret = NULL; - HRESULT hr = E_NOINTERFACE; - if(m_pDevice8) - { - hr = m_pDevice8->CreatePlacedResource1(Unwrap(pHeap), HeapOffset, &Descriptor, InitialState, - pOptimizedClearValue, guid, (void **)&ret); - } - else - { - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIHardwareUnsupported, - "Capture requires ID3D12Device8 which isn't available"); - return false; - } - - if(FAILED(hr)) - { - RDCERR("Failed on resource serialise-creation, HRESULT: %s", ToStr(hr).c_str()); - SET_ERROR_RESULT(m_FailedReplayResult, ResultCode::APIReplayFailed, - "Failed creating placed resource, HRESULT: %s", ToStr(hr).c_str()); - return false; - } - else - { - SetObjName(ret, StringFormat::Fmt("Placed Resource %s %s", ToStr(Descriptor.Dimension).c_str(), - ToStr(pResource).c_str())); - - ret = new WrappedID3D12Resource(ret, this); - - GetResourceManager()->AddLiveResource(pResource, ret); - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS) - m_ModResources.insert(GetResID(ret)); - - // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 - D3D12_RESOURCE_DESC desc0; - memcpy(&desc0, &Descriptor, sizeof(desc0)); - SubresourceStateVector &states = m_ResourceStates[GetResID(ret)]; - states.fill(GetNumSubresources(m_pDevice, &desc0), - D3D12ResourceLayout::FromStates(InitialState)); - } - - ResourceType type = ResourceType::Texture; - const char *prefix = "Texture"; - - if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) - { - type = ResourceType::Buffer; - prefix = "Buffer"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE1D) - { - prefix = Descriptor.DepthOrArraySize > 1 ? "1D TextureArray" : "1D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "1D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "1D Depth Target"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D) - { - prefix = Descriptor.DepthOrArraySize > 1 ? "2D TextureArray" : "2D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "2D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "2D Depth Target"; - } - else if(Descriptor.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D) - { - prefix = "3D Texture"; - - if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) - prefix = "3D Render Target"; - else if(Descriptor.Flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) - prefix = "3D Depth Target"; - } - - AddResource(pResource, type, prefix); - DerivedResource(pHeap, pResource); - } - - return true; -} - -HRESULT WrappedID3D12Device::CreatePlacedResource1(ID3D12Heap *pHeap, UINT64 HeapOffset, - const D3D12_RESOURCE_DESC1 *pDesc, - D3D12_RESOURCE_STATES InitialState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - REFIID riid, void **ppvResource) -{ - if(ppvResource == NULL) - return m_pDevice8->CreatePlacedResource1(Unwrap(pHeap), HeapOffset, pDesc, InitialState, - pOptimizedClearValue, riid, NULL); - - if(riid != __uuidof(ID3D12Resource)) - return E_NOINTERFACE; - - const D3D12_RESOURCE_DESC1 *pCreateDesc = pDesc; - D3D12_RESOURCE_DESC1 localDesc; - - if(pDesc && pDesc->Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE2D && pDesc->SampleDesc.Count > 1) - { - localDesc = *pDesc; - // need to be able to create SRVs of MSAA textures to copy out their contents - localDesc.Flags &= ~D3D12_RESOURCE_FLAG_DENY_SHADER_RESOURCE; - pCreateDesc = &localDesc; - } - - ID3D12Resource *real = NULL; - HRESULT ret; - SERIALISE_TIME_CALL(ret = m_pDevice8->CreatePlacedResource1(Unwrap(pHeap), HeapOffset, pCreateDesc, - InitialState, pOptimizedClearValue, - riid, (void **)&real)); - - if(SUCCEEDED(ret)) - { - WrappedID3D12Resource *wrapped = new WrappedID3D12Resource(real, this); - - wrapped->SetHeap(pHeap); - - if(IsCaptureMode(m_State)) - { - CACHE_THREAD_SERIALISER(); - - SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_CreatePlacedResource1); - Serialise_CreatePlacedResource1(ser, pHeap, HeapOffset, pDesc, InitialState, - pOptimizedClearValue, riid, (void **)&wrapped); - - D3D12ResourceRecord *record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID()); - record->type = Resource_Resource; - record->Length = 0; - wrapped->SetResourceRecord(record); - - // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 - D3D12_RESOURCE_DESC desc0; - memcpy(&desc0, pDesc, sizeof(desc0)); - record->m_MapsCount = GetNumSubresources(this, &desc0); - record->m_Maps = new D3D12ResourceRecord::MapData[record->m_MapsCount]; - - RDCASSERT(pHeap); - - record->AddParent(GetRecord(pHeap)); - record->AddChunk(scope.Get()); - - GetResourceManager()->MarkDirtyResource(wrapped->GetResourceID()); - } - else - { - GetResourceManager()->AddLiveResource(wrapped->GetResourceID(), wrapped); - } - - { - SCOPED_LOCK(m_ResourceStatesLock); - SubresourceStateVector &states = m_ResourceStates[wrapped->GetResourceID()]; - - // D3D12_RESOURCE_DESC is the same as the start of D3D12_RESOURCE_DESC1 - D3D12_RESOURCE_DESC desc0; - memcpy(&desc0, pDesc, sizeof(desc0)); - states.fill(GetNumSubresources(m_pDevice, &desc0), - D3D12ResourceLayout::FromStates(InitialState)); - - m_BindlessFrameRefs[wrapped->GetResourceID()] = BindlessRefTypeForRes(wrapped); - } - - if(riid == __uuidof(ID3D12Resource)) - *ppvResource = (ID3D12Resource *)wrapped; - else if(riid == __uuidof(ID3D12Resource1)) - *ppvResource = (ID3D12Resource1 *)wrapped; - else if(riid == __uuidof(ID3D12Resource2)) - *ppvResource = (ID3D12Resource2 *)wrapped; - - // while actively capturing we keep all buffers around to prevent the address lookup from - // losing addresses we might need (or the manageable but annoying problem of an address being - // re-used) - { - SCOPED_READLOCK(m_CapTransitionLock); - if(IsActiveCapturing(m_State)) - { - wrapped->AddRef(); - m_RefBuffers.push_back(wrapped); - if(m_BindlessResourceUseActive) - GetResourceManager()->MarkResourceFrameReferenced(wrapped->GetResourceID(), - BindlessRefTypeForRes(wrapped)); - } - } - } - else - { - CheckHRESULT(ret); - } - - return ret; -} - void STDMETHODCALLTYPE WrappedID3D12Device::CreateSamplerFeedbackUnorderedAccessView( _In_opt_ ID3D12Resource *pTargetedResource, _In_opt_ ID3D12Resource *pFeedbackResource, _In_ D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) @@ -548,16 +54,3 @@ void STDMETHODCALLTYPE WrappedID3D12Device::GetCopyableFootprints1( BaseOffset, pLayouts, pNumRows, pRowSizeInBytes, pTotalBytes); } - -INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreateCommittedResource2, - const D3D12_HEAP_PROPERTIES *pHeapProperties, - D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC1 *pDesc, - D3D12_RESOURCE_STATES InitialResourceState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, - ID3D12ProtectedResourceSession *pProtectedSession, - REFIID riidResource, void **ppvResource); -INSTANTIATE_FUNCTION_SERIALISED(void, WrappedID3D12Device, CreatePlacedResource1, ID3D12Heap *pHeap, - UINT64 HeapOffset, const D3D12_RESOURCE_DESC1 *pDesc, - D3D12_RESOURCE_STATES InitialState, - const D3D12_CLEAR_VALUE *pOptimizedClearValue, REFIID riid, - void **ppvResource); diff --git a/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj b/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj index c5d37ea3d..d4bf8c49d 100644 --- a/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj +++ b/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj @@ -117,9 +117,9 @@ + - diff --git a/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj.filters b/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj.filters index 7ec92b2b9..2bef07bde 100644 --- a/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj.filters +++ b/renderdoc/driver/d3d12/renderdoc_d3d12.vcxproj.filters @@ -215,9 +215,6 @@ Wrapped - - Wrapped - Wrapped @@ -227,5 +224,8 @@ Wrapped + + Wrapped + \ No newline at end of file