mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Add custom D3D12 interface for per-heap descriptor naming by index
This commit is contained in:
@@ -19,7 +19,23 @@ RenderDoc has initial support for D3D12, but it contains some caveats. In additi
|
||||
|
||||
* RenderDoc assumes that even if multiple GPUs are present, that only one will be used - i.e. NodeMask is always 0. Multiple queues are supported.
|
||||
* RenderDoc captures may not be portable between different systems, only currently supporting capture and replay on the same or similar enough machines.
|
||||
* Shader debugging is not supported for DXIL shaders.
|
||||
|
||||
RenderDoc extensions
|
||||
--------------------
|
||||
|
||||
On D3D12 there is a RenderDoc extension provided with this interface, queried from an ``ID3D12DescriptorHeap``:
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
MIDL_INTERFACE("52528c37-bfd9-4bbb-99ff-fdb7188619ce")
|
||||
IRenderDocDescriptorNamer : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetName(UINT DescriptorIndex, LPCSTR Name) = 0;
|
||||
};
|
||||
|
||||
This interface allows you to set a custom name for descriptors, if using SM6.6 style ``ResourceDescriptorHeap[]`` access for better debugging.
|
||||
|
||||
See Also
|
||||
--------
|
||||
|
||||
@@ -168,6 +168,22 @@ In Vulkan you can enable the ``VK_EXT_debug_utils`` extension, which is provided
|
||||
nameInfo.pObjectName = "Off-screen color framebuffer";
|
||||
vkSetDebugUtilsObjectNameEXT(device, &nameInfo);
|
||||
|
||||
On D3D12 there is a RenderDoc extension provided with this interface, queried from an ``ID3D12DescriptorHeap``:
|
||||
|
||||
.. highlight:: c++
|
||||
.. code:: c++
|
||||
|
||||
MIDL_INTERFACE("52528c37-bfd9-4bbb-99ff-fdb7188619ce")
|
||||
IRenderDocDescriptorNamer : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetName(UINT DescriptorIndex, LPCSTR Name) = 0;
|
||||
};
|
||||
|
||||
|
||||
This interface allows you to set a custom name for descriptors, if using SM6.6 style ``ResourceDescriptorHeap[]`` access for better debugging.
|
||||
|
||||
|
||||
Bookmarks
|
||||
---------
|
||||
|
||||
|
||||
@@ -506,6 +506,10 @@ bool D3D12InitParams::IsSupportedVersion(uint64_t ver)
|
||||
if(ver == 0x11)
|
||||
return true;
|
||||
|
||||
// 0x12 -> 0x13 - Descriptor heap initial states contain optional user names for descriptors
|
||||
if(ver == 0x12)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ struct D3D12InitParams
|
||||
UINT SDKVersion = 0;
|
||||
|
||||
// check if a frame capture section version is supported
|
||||
static const uint64_t CurrentVersion = 0x12;
|
||||
static const uint64_t CurrentVersion = 0x13;
|
||||
|
||||
static bool IsSupportedVersion(uint64_t ver);
|
||||
};
|
||||
|
||||
@@ -94,7 +94,12 @@ bool D3D12ResourceManager::Prepare_InitialState(ID3D12DeviceChild *res)
|
||||
D3D12Descriptor *descs = new D3D12Descriptor[numElems];
|
||||
memcpy(descs, heap->GetDescriptors(), sizeof(D3D12Descriptor) * numElems);
|
||||
|
||||
SetInitialContents(heap->GetResourceID(), D3D12InitialContents(descs, numElems));
|
||||
D3D12InitialContents initContents(descs, numElems);
|
||||
|
||||
if(heap->HasNames())
|
||||
initContents.descriptorNames = heap->GetNames();
|
||||
|
||||
SetInitialContents(heap->GetResourceID(), initContents);
|
||||
return true;
|
||||
}
|
||||
else if(type == Resource_Resource)
|
||||
@@ -768,6 +773,7 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
{
|
||||
D3D12Descriptor *Descriptors = initial ? initial->descriptors : NULL;
|
||||
uint32_t numElems = initial ? initial->numDescriptors : 0;
|
||||
rdcarray<rdcstr> names = initial ? initial->descriptorNames : rdcarray<rdcstr>();
|
||||
|
||||
// there's no point in setting up a lazy array when we're structured exporting because we KNOW
|
||||
// we're going to need all the data anyway.
|
||||
@@ -777,6 +783,11 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
SERIALISE_ELEMENT_ARRAY(Descriptors, numElems);
|
||||
SERIALISE_ELEMENT(numElems).Named("NumDescriptors"_lit).Important();
|
||||
|
||||
if(ser.VersionAtLeast(0x13))
|
||||
{
|
||||
SERIALISE_ELEMENT(names).Hidden();
|
||||
}
|
||||
|
||||
ser.SetLazyThreshold(0);
|
||||
|
||||
SERIALISE_CHECK_READ_ERRORS();
|
||||
@@ -785,6 +796,9 @@ bool D3D12ResourceManager::Serialise_InitialState(SerialiserType &ser, ResourceI
|
||||
{
|
||||
WrappedID3D12DescriptorHeap *heap = (WrappedID3D12DescriptorHeap *)GetLiveResource(id);
|
||||
|
||||
if(!names.empty())
|
||||
heap->GetNames() = names;
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC desc = heap->GetDesc();
|
||||
|
||||
// this heap doesn't have to be shader visible, we just use it to copy from
|
||||
|
||||
@@ -793,6 +793,7 @@ struct D3D12InitialContents
|
||||
ID3D12DeviceChild *resource;
|
||||
byte *srcData;
|
||||
size_t dataSize;
|
||||
rdcarray<rdcstr> descriptorNames;
|
||||
|
||||
rdcarray<uint32_t> subresources;
|
||||
|
||||
|
||||
@@ -2129,6 +2129,16 @@ rdcarray<DescriptorLogicalLocation> D3D12Replay::GetDescriptorLocations(
|
||||
{
|
||||
// can't set anything except the "bind number" which we just set as the offset.
|
||||
ret[dst].fixedBindNumber = descriptorId;
|
||||
if(heap->HasNames())
|
||||
{
|
||||
rdcstr name = heap->GetNames()[descriptorId];
|
||||
if(!name.empty())
|
||||
{
|
||||
ret[dst].logicalBindName = StringFormat::Fmt("%s[%u]", name.c_str(), descriptorId);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if(sampler)
|
||||
ret[dst].logicalBindName = StringFormat::Fmt("SamplerDescriptorHeap[%u]", descriptorId);
|
||||
else
|
||||
|
||||
@@ -469,7 +469,15 @@ public:
|
||||
|
||||
struct D3D12Descriptor;
|
||||
|
||||
class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12<ID3D12DescriptorHeap>
|
||||
MIDL_INTERFACE("52528c37-bfd9-4bbb-99ff-fdb7188619ce")
|
||||
IRenderDocDescriptorNamer : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetName(UINT DescriptorIndex, LPCSTR Name) = 0;
|
||||
};
|
||||
|
||||
class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12<ID3D12DescriptorHeap>,
|
||||
public IRenderDocDescriptorNamer
|
||||
{
|
||||
D3D12_CPU_DESCRIPTOR_HANDLE realCPUBase;
|
||||
D3D12_GPU_DESCRIPTOR_HANDLE realGPUBase;
|
||||
@@ -487,6 +495,9 @@ class WrappedID3D12DescriptorHeap : public WrappedDeviceChild12<ID3D12Descriptor
|
||||
// (which applications then queried and passed to the GPU) which is used for GPU-unwrapping handles
|
||||
uint64_t m_OriginalWrappedGPUBase;
|
||||
|
||||
Threading::CriticalSection namesLock;
|
||||
rdcarray<rdcstr> names;
|
||||
|
||||
public:
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D12DescriptorHeap);
|
||||
|
||||
@@ -499,6 +510,33 @@ public:
|
||||
const D3D12_DESCRIPTOR_HEAP_DESC &desc, UINT UnpatchedNumDescriptors);
|
||||
virtual ~WrappedID3D12DescriptorHeap();
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef() { return WrappedDeviceChild12::AddRef(); }
|
||||
ULONG STDMETHODCALLTYPE Release() { return WrappedDeviceChild12::Release(); }
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IRenderDocDescriptorNamer))
|
||||
{
|
||||
*ppvObject = (IRenderDocDescriptorNamer *)this;
|
||||
// allocate names array now
|
||||
GetNames();
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
return WrappedDeviceChild12::QueryInterface(riid, ppvObject);
|
||||
}
|
||||
|
||||
bool HasNames()
|
||||
{
|
||||
SCOPED_LOCK(namesLock);
|
||||
return !names.empty();
|
||||
}
|
||||
rdcarray<rdcstr> &GetNames()
|
||||
{
|
||||
SCOPED_LOCK(namesLock);
|
||||
names.resize(numDescriptors);
|
||||
return names;
|
||||
}
|
||||
|
||||
D3D12Descriptor *GetDescriptors() { return descriptors; }
|
||||
UINT GetNumDescriptors() { return numDescriptors; }
|
||||
|
||||
@@ -545,6 +583,23 @@ public:
|
||||
}
|
||||
|
||||
uint32_t GetUnwrappedIncrement() const { return increment; }
|
||||
|
||||
//////////////////////////////
|
||||
// implement IRenderDocDescriptorNamer
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE SetName(UINT DescriptorIndex, LPCSTR Name)
|
||||
{
|
||||
if(DescriptorIndex >= numDescriptors)
|
||||
return E_INVALIDARG;
|
||||
|
||||
SCOPED_LOCK(namesLock);
|
||||
if(!Name || !Name[0])
|
||||
names[DescriptorIndex].clear();
|
||||
else
|
||||
names[DescriptorIndex] = Name;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedID3D12Fence : public WrappedDeviceChild12<ID3D12Fence, ID3D12Fence1>
|
||||
|
||||
@@ -24,6 +24,15 @@
|
||||
|
||||
#include "d3d12_test.h"
|
||||
|
||||
MIDL_INTERFACE("52528c37-bfd9-4bbb-99ff-fdb7188619ce")
|
||||
IRenderDocDescriptorNamer : public IUnknown
|
||||
{
|
||||
public:
|
||||
virtual HRESULT STDMETHODCALLTYPE SetName(UINT DescriptorIndex, LPCSTR Name) = 0;
|
||||
};
|
||||
|
||||
COM_SMARTPTR(IRenderDocDescriptorNamer);
|
||||
|
||||
RD_TEST(D3D12_Descriptor_Indexing, D3D12GraphicsTest)
|
||||
{
|
||||
static constexpr const char *Description =
|
||||
@@ -464,9 +473,17 @@ float4 main(v2f IN) : SV_Target0
|
||||
MakeSRV(alias1Buf).StructureStride(3 * sizeof(Vec4f)).CreateGPU(150 + 6);
|
||||
MakeSRV(alias2Buf).StructureStride(3 * sizeof(Vec4f)).CreateGPU(150 + 12);
|
||||
|
||||
IRenderDocDescriptorNamerPtr namer = m_CBVUAVSRV;
|
||||
|
||||
MakeSRV(smiley).CreateGPU(12);
|
||||
if(namer)
|
||||
namer->SetName(12, "smiley");
|
||||
MakeSRV(smiley).CreateGPU(19);
|
||||
if(namer)
|
||||
namer->SetName(19, "another_smiley");
|
||||
MakeSRV(smiley).CreateGPU(20);
|
||||
if(namer)
|
||||
namer->SetName(20, "more_smileys???");
|
||||
MakeSRV(smiley).CreateGPU(21);
|
||||
MakeSRV(smiley).CreateGPU(49);
|
||||
MakeSRV(smiley).CreateGPU(59);
|
||||
@@ -474,7 +491,11 @@ float4 main(v2f IN) : SV_Target0
|
||||
MakeSRV(smiley).CreateGPU(99);
|
||||
MakeSRV(smiley).CreateGPU(103);
|
||||
MakeCBV(constBuf).SizeBytes(256).CreateGPU(9);
|
||||
if(namer)
|
||||
namer->SetName(9, "constBuf");
|
||||
MakeUAV(outUAV).Format(DXGI_FORMAT_R32_UINT).CreateGPU(10);
|
||||
if(namer)
|
||||
namer->SetName(10, "outUAV");
|
||||
|
||||
D3D12_SAMPLER_DESC samplerDesc = {};
|
||||
samplerDesc.Filter = D3D12_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
|
||||
Reference in New Issue
Block a user