Wrap and serialise calls through ID3D12CompatibilityDevice

This commit is contained in:
baldurk
2020-08-31 10:51:32 +01:00
parent 052cd255e8
commit 8b935a1c11
7 changed files with 250 additions and 30 deletions
@@ -757,6 +757,8 @@ bool WrappedID3D12CommandQueue::ProcessChunk(ReadSerialiser &ser, D3D12Chunk chu
case D3D12Chunk::Device_CreateCommittedResource1:
case D3D12Chunk::Device_CreateHeap1:
case D3D12Chunk::Device_ExternalDXGIResource:
case D3D12Chunk::CompatDevice_CreateSharedResource:
case D3D12Chunk::CompatDevice_CreateSharedHeap:
RDCERR("Unexpected chunk while processing frame: %s", ToStr(chunk).c_str());
return false;
+2
View File
@@ -854,5 +854,7 @@ enum class D3D12Chunk : uint32_t
Device_ExternalDXGIResource,
Swapchain_Present,
List_ClearState,
CompatDevice_CreateSharedResource,
CompatDevice_CreateSharedHeap,
Max,
};
+106 -10
View File
@@ -195,6 +195,89 @@ ULONG STDMETHODCALLTYPE WrappedDREDSettings::Release()
return m_pDevice.Release();
}
HRESULT STDMETHODCALLTYPE WrappedCompatibilityDevice::QueryInterface(REFIID riid, void **ppvObject)
{
return m_pDevice.QueryInterface(riid, ppvObject);
}
ULONG STDMETHODCALLTYPE WrappedCompatibilityDevice::AddRef()
{
return m_pDevice.AddRef();
}
ULONG STDMETHODCALLTYPE WrappedCompatibilityDevice::Release()
{
return m_pDevice.Release();
}
WriteSerialiser &WrappedCompatibilityDevice::GetThreadSerialiser()
{
return m_pDevice.GetThreadSerialiser();
}
HRESULT STDMETHODCALLTYPE WrappedCompatibilityDevice::CreateSharedResource(
_In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags,
_In_ const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState,
_In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
_In_opt_ const D3D11_RESOURCE_FLAGS *pFlags11,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
_In_opt_ ID3D12LifetimeTracker *pLifetimeTracker,
_In_opt_ ID3D12SwapChainAssistant *pOwningSwapchain, REFIID riid,
_COM_Outptr_opt_ void **ppResource)
{
if(ppResource == NULL)
return E_INVALIDARG;
HRESULT hr;
// not exactly sure what to do with these...
RDCASSERT(pLifetimeTracker == NULL);
RDCASSERT(pOwningSwapchain == NULL);
SERIALISE_TIME_CALL(
hr = m_pReal->CreateSharedResource(pHeapProperties, HeapFlags, pDesc, InitialResourceState,
pOptimizedClearValue, pFlags11, CompatibilityFlags,
pLifetimeTracker, pOwningSwapchain, riid, ppResource));
if(FAILED(hr))
{
IUnknown *unk = (IUnknown *)*ppResource;
SAFE_RELEASE(unk);
return hr;
}
return m_pDevice.OpenSharedHandleInternal(D3D12Chunk::CompatDevice_CreateSharedResource, riid,
ppResource);
}
HRESULT STDMETHODCALLTYPE WrappedCompatibilityDevice::CreateSharedHeap(
_In_ const D3D12_HEAP_DESC *pHeapDesc, D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
REFIID riid, _COM_Outptr_opt_ void **ppHeap)
{
if(ppHeap == NULL)
return E_INVALIDARG;
HRESULT hr;
SERIALISE_TIME_CALL(hr = m_pReal->CreateSharedHeap(pHeapDesc, CompatibilityFlags, riid, ppHeap));
if(FAILED(hr))
{
IUnknown *unk = (IUnknown *)*ppHeap;
SAFE_RELEASE(unk);
return hr;
}
return m_pDevice.OpenSharedHandleInternal(D3D12Chunk::CompatDevice_CreateSharedHeap, riid, ppHeap);
}
HRESULT STDMETHODCALLTYPE WrappedCompatibilityDevice::ReflectSharedProperties(
_In_ ID3D12Object *pHeapOrResource, D3D12_REFLECT_SHARED_PROPERTY ReflectType,
_Out_writes_bytes_(DataSize) void *pData, UINT DataSize)
{
return m_pReal->ReflectSharedProperties(Unwrap(pHeapOrResource), ReflectType, pData, DataSize);
}
WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitParams params,
bool enabledDebugLayer)
: m_RefCounter(realDevice, false),
@@ -203,7 +286,8 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
m_debugLayerEnabled(enabledDebugLayer),
m_WrappedDownlevel(*this),
m_DRED(*this),
m_DREDSettings(*this)
m_DREDSettings(*this),
m_CompatDevice(*this)
{
if(RenderDoc::Inst().GetCrashHandler())
RenderDoc::Inst().GetCrashHandler()->RegisterMemoryRegion(this, sizeof(WrappedID3D12Device));
@@ -238,6 +322,7 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
m_pDevice->QueryInterface(__uuidof(ID3D12DeviceRemovedExtendedDataSettings),
(void **)&m_DREDSettings.m_pReal);
m_pDevice->QueryInterface(__uuidof(ID3D12DeviceDownlevel), (void **)&m_pDownlevel);
m_pDevice->QueryInterface(__uuidof(ID3D12CompatibilityDevice), (void **)&m_CompatDevice.m_pReal);
for(size_t i = 0; i < ARRAY_COUNT(m_DescriptorIncrements); i++)
m_DescriptorIncrements[i] =
@@ -513,6 +598,7 @@ WrappedID3D12Device::~WrappedID3D12Device()
SAFE_RELEASE(m_DRED.m_pReal);
SAFE_RELEASE(m_DREDSettings.m_pReal);
SAFE_RELEASE(m_CompatDevice.m_pReal);
SAFE_RELEASE(m_pDownlevel);
SAFE_RELEASE(m_pDevice6);
SAFE_RELEASE(m_pDevice5);
@@ -564,19 +650,13 @@ WrappedID3D12Device *WrappedID3D12Device::Create(ID3D12Device *realDevice, D3D12
HRESULT WrappedID3D12Device::QueryInterface(REFIID riid, void **ppvObject)
{
// DEFINE_GUID(IID_IDirect3DDevice9, 0xd0223b96, 0xbf7a, 0x43fd, 0x92, 0xbd, 0xa4, 0x3b, 0xd,
// 0x82, 0xb9, 0xeb);
static const GUID IDirect3DDevice9_uuid = {
0xd0223b96, 0xbf7a, 0x43fd, {0x92, 0xbd, 0xa4, 0x3b, 0xd, 0x82, 0xb9, 0xeb}};
// ID3D10Device UUID {9B7E4C0F-342C-4106-A19F-4F2704F689F0}
static const GUID ID3D10Device_uuid = {
0x9b7e4c0f, 0x342c, 0x4106, {0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0}};
// RenderDoc UUID {A7AA6116-9C8D-4BBA-9083-B4D816B71B78}
static const GUID IRenderDoc_uuid = {
0xa7aa6116, 0x9c8d, 0x4bba, {0x90, 0x83, 0xb4, 0xd8, 0x16, 0xb7, 0x1b, 0x78}};
static const GUID ID3D12CompatibilityDevice_uuid = {
0x8f1c0e3c, 0xfae3, 0x4a82, {0xb0, 0x98, 0xbf, 0xe1, 0x70, 0x82, 0x07, 0xff}};
HRESULT hr = S_OK;
if(riid == __uuidof(IUnknown))
@@ -856,6 +936,19 @@ HRESULT WrappedID3D12Device::QueryInterface(REFIID riid, void **ppvObject)
*ppvObject = (IUnknown *)this;
return S_OK;
}
else if(riid == __uuidof(ID3D12CompatibilityDevice))
{
if(m_CompatDevice.m_pReal)
{
AddRef();
*ppvObject = (ID3D12CompatibilityDevice *)&m_CompatDevice;
return S_OK;
}
else
{
return E_NOINTERFACE;
}
}
else
{
WarnUnknownGUID("ID3D12Device", riid);
@@ -3006,6 +3099,9 @@ bool WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context)
case D3D12Chunk::Device_CreateHeap1: return Serialise_CreateHeap1(ser, NULL, NULL, IID(), NULL);
case D3D12Chunk::Device_ExternalDXGIResource:
return Serialise_OpenSharedHandle(ser, NULL, IID(), NULL);
case D3D12Chunk::CompatDevice_CreateSharedResource:
case D3D12Chunk::CompatDevice_CreateSharedHeap:
return Serialise_OpenSharedHandle(ser, NULL, IID(), NULL);
// in order to get a warning if we miss a case, we explicitly handle the list/queue chunks here.
// If we actually encounter one it's an error (we should hit CaptureBegin first and switch to
+84
View File
@@ -340,6 +340,89 @@ struct WrappedDREDSettings : public ID3D12DeviceRemovedExtendedDataSettings
}
};
// these aren't documented, they're defined in D3D12TranslationLayer in the d3d11on12 codebase
typedef enum D3D12_COMPATIBILITY_SHARED_FLAGS {
D3D12_COMPATIBILITY_SHARED_FLAG_NONE = 0,
D3D12_COMPATIBILITY_SHARED_FLAG_NON_NT_HANDLE = 0x1,
D3D12_COMPATIBILITY_SHARED_FLAG_KEYED_MUTEX = 0x2,
D3D12_COMPATIBILITY_SHARED_FLAG_9_ON_12 = 0x4
} D3D12_COMPATIBILITY_SHARED_FLAGS;
typedef enum D3D12_REFLECT_SHARED_PROPERTY {
D3D12_REFLECT_SHARED_PROPERTY_D3D11_RESOURCE_FLAGS = 0,
D3D12_REFELCT_SHARED_PROPERTY_COMPATIBILITY_SHARED_FLAGS =
(D3D12_REFLECT_SHARED_PROPERTY_D3D11_RESOURCE_FLAGS + 1),
D3D12_REFLECT_SHARED_PROPERTY_NON_NT_SHARED_HANDLE =
(D3D12_REFELCT_SHARED_PROPERTY_COMPATIBILITY_SHARED_FLAGS + 1)
} D3D12_REFLECT_SHARED_PROPERTY;
typedef struct D3D11_RESOURCE_FLAGS
{
UINT BindFlags;
UINT MiscFlags;
UINT CPUAccessFlags;
UINT StructureByteStride;
} D3D11_RESOURCE_FLAGS;
MIDL_INTERFACE("8f1c0e3c-fae3-4a82-b098-bfe1708207ff")
ID3D12CompatibilityDevice : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE CreateSharedResource(
_In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags,
_In_ const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState,
_In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
_In_opt_ const D3D11_RESOURCE_FLAGS *pFlags11,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
_In_opt_ ID3D12LifetimeTracker *pLifetimeTracker,
_In_opt_ ID3D12SwapChainAssistant *pOwningSwapchain, REFIID riid,
_COM_Outptr_opt_ void **ppResource) = 0;
virtual HRESULT STDMETHODCALLTYPE CreateSharedHeap(
_In_ const D3D12_HEAP_DESC *pHeapDesc, D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
REFIID riid, _COM_Outptr_opt_ void **ppHeap) = 0;
virtual HRESULT STDMETHODCALLTYPE ReflectSharedProperties(
_In_ ID3D12Object * pHeapOrResource, D3D12_REFLECT_SHARED_PROPERTY ReflectType,
_Out_writes_bytes_(DataSize) void *pData, UINT DataSize) = 0;
};
struct WrappedCompatibilityDevice : public ID3D12CompatibilityDevice
{
WrappedID3D12Device &m_pDevice;
ID3D12CompatibilityDevice *m_pReal = NULL;
WrappedCompatibilityDevice(WrappedID3D12Device &dev) : m_pDevice(dev) {}
//////////////////////////////
// implement IUnknown
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
ULONG STDMETHODCALLTYPE AddRef();
ULONG STDMETHODCALLTYPE Release();
WriteSerialiser &GetThreadSerialiser();
//////////////////////////////
// implement ID3D12CompatibilityDevice
virtual HRESULT STDMETHODCALLTYPE CreateSharedResource(
_In_ const D3D12_HEAP_PROPERTIES *pHeapProperties, D3D12_HEAP_FLAGS HeapFlags,
_In_ const D3D12_RESOURCE_DESC *pDesc, D3D12_RESOURCE_STATES InitialResourceState,
_In_opt_ const D3D12_CLEAR_VALUE *pOptimizedClearValue,
_In_opt_ const D3D11_RESOURCE_FLAGS *pFlags11,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
_In_opt_ ID3D12LifetimeTracker *pLifetimeTracker,
_In_opt_ ID3D12SwapChainAssistant *pOwningSwapchain, REFIID riid,
_COM_Outptr_opt_ void **ppResource);
virtual HRESULT STDMETHODCALLTYPE CreateSharedHeap(_In_ const D3D12_HEAP_DESC *pHeapDesc,
D3D12_COMPATIBILITY_SHARED_FLAGS CompatibilityFlags,
REFIID riid, _COM_Outptr_opt_ void **ppHeap);
virtual HRESULT STDMETHODCALLTYPE ReflectSharedProperties(_In_ ID3D12Object *pHeapOrResource,
D3D12_REFLECT_SHARED_PROPERTY ReflectType,
_Out_writes_bytes_(DataSize) void *pData,
UINT DataSize);
};
class WrappedID3D12CommandQueue;
#define IMPLEMENT_FUNCTION_THREAD_SERIALISED(ret, func, ...) \
@@ -383,6 +466,7 @@ private:
WrappedDownlevelDevice m_WrappedDownlevel;
WrappedDRED m_DRED;
WrappedDREDSettings m_DREDSettings;
WrappedCompatibilityDevice m_CompatDevice;
rdcarray<ID3D12CommandAllocator *> m_CommandAllocators;
+34 -19
View File
@@ -2316,6 +2316,10 @@ bool WrappedID3D12Device::Serialise_OpenSharedHandle(SerialiserType &ser, HANDLE
// 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);
HRESULT hr;
ID3D12Resource *ret;
hr = m_pDevice->CreateCommittedResource(&heapProperties, heapFlags, &desc,
@@ -2454,15 +2458,40 @@ HRESULT WrappedID3D12Device::OpenSharedHandleInternal(D3D12Chunk chunkType, REFI
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 *)(*ppvObj);
ID3D12DeviceChild *real = (ID3D12DeviceChild *)ret;
ID3D12Resource *d3d12Res = NULL;
ID3D12Fence *d3d12Fence = NULL;
@@ -2540,10 +2569,6 @@ HRESULT WrappedID3D12Device::OpenSharedHandleInternal(D3D12Chunk chunkType, REFI
wrappedDeviceChild = wrapped;
*ppvObj = (ID3D12Fence *)wrapped;
if(riid_internal == __uuidof(ID3D12Fence1))
*ppvObj = (ID3D12Fence1 *)wrapped;
record = GetResourceManager()->AddResourceRecord(wrapped->GetResourceID());
record->type = Resource_Fence;
record->Length = 0;
@@ -2559,18 +2584,6 @@ HRESULT WrappedID3D12Device::OpenSharedHandleInternal(D3D12Chunk chunkType, REFI
wrappedDeviceChild = wrapped;
if(isDXGIRes)
{
wrapped->QueryInterface(riid_internal, ppvObj);
wrapped->Release();
}
else
{
*ppvObj = (ID3D12Resource *)wrapped;
if(riid_internal == __uuidof(ID3D12Resource1))
*ppvObj = (ID3D12Resource1 *)wrapped;
}
D3D12_RESOURCE_DESC desc = wrapped->GetDesc();
D3D12_RESOURCE_STATES InitialResourceState = D3D12_RESOURCE_STATE_COMMON;
@@ -2613,14 +2626,16 @@ HRESULT WrappedID3D12Device::OpenSharedHandleInternal(D3D12Chunk chunkType, REFI
wrappedDeviceChild = wrapped;
*ppvObj = wrappedDeviceChild;
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);
+5 -1
View File
@@ -28,7 +28,7 @@
template <>
rdcstr DoStringise(const D3D12Chunk &el)
{
RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1107, "Chunks changed without updating names");
RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1109, "Chunks changed without updating names");
BEGIN_ENUM_STRINGISE(D3D12Chunk)
{
@@ -193,6 +193,10 @@ rdcstr DoStringise(const D3D12Chunk &el)
STRINGISE_ENUM_CLASS_NAMED(Device_ExternalDXGIResource, "External DXGI Resource import");
STRINGISE_ENUM_CLASS_NAMED(Swapchain_Present, "IDXGISwapChain::Present");
STRINGISE_ENUM_CLASS_NAMED(List_ClearState, "ID3D12GraphicsCommandList::ClearState");
STRINGISE_ENUM_CLASS_NAMED(CompatDevice_CreateSharedResource,
"ID3D12CompatibilityDevice::CreateSharedResource");
STRINGISE_ENUM_CLASS_NAMED(CompatDevice_CreateSharedHeap,
"ID3D12CompatibilityDevice::CreateSharedHeap");
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
}
END_ENUM_STRINGISE()
+17
View File
@@ -66,6 +66,11 @@ bool RefCountDXGIObject::HandleWrap(REFIID riid, void **ppvObject)
static const GUID ID3D10Texture2D_uuid = {
0x9b7e4c04, 0x342c, 0x4106, {0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0}};
// unknown/undocumented internal interface
// {7abb6563-02bc-47c4-8ef9-acc4795edbcf}
static const GUID IDXGIAdapterInternal2_uuid = {
0x7abb6563, 0x02bc, 0x47c4, {0x8e, 0xf9, 0xac, 0xc4, 0x79, 0x5e, 0xdb, 0xcf}};
if(riid == __uuidof(IDXGIDevice))
{
// should have been handled elsewhere, so we can properly create this device
@@ -172,6 +177,18 @@ bool RefCountDXGIObject::HandleWrap(REFIID riid, void **ppvObject)
}
return false;
}
else if(riid == IDXGIAdapterInternal2_uuid)
{
static bool printed = false;
if(!printed)
{
printed = true;
RDCWARN(
"Querying IDXGIObject for unsupported/undocumented IDXGIAdapterInternal2 interface: %s",
ToStr(riid).c_str());
}
return false;
}
else if(riid == Unknown_uuid)
{
static bool printed = false;