mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-12 01:30:57 +00:00
Add support for DXGI desktop duplication API
* We treat it the same as OpenSharedResource/Handle, an opaque resource fetched from elsewhere and wrapped, instantly treated as dirty.
This commit is contained in:
@@ -421,6 +421,7 @@ enum class D3D11Chunk : uint32_t
|
||||
PostExecuteCommandList,
|
||||
PostFinishCommandListSet,
|
||||
SwapDeviceContextState,
|
||||
ExternalDXGIResource,
|
||||
Max,
|
||||
};
|
||||
|
||||
|
||||
@@ -993,6 +993,7 @@ bool WrappedID3D11Device::ProcessChunk(ReadSerialiser &ser, D3D11Chunk context)
|
||||
case D3D11Chunk::CreateDeferredContext: return Serialise_CreateDeferredContext(ser, 0, 0x0);
|
||||
|
||||
case D3D11Chunk::SetExceptionMode: return Serialise_SetExceptionMode(ser, 0);
|
||||
case D3D11Chunk::ExternalDXGIResource:
|
||||
case D3D11Chunk::OpenSharedResource:
|
||||
{
|
||||
IID nul;
|
||||
@@ -1468,6 +1469,24 @@ IUnknown *WrappedID3D11Device::WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_F
|
||||
return pTex;
|
||||
}
|
||||
|
||||
IDXGIResource *WrappedID3D11Device::WrapExternalDXGIResource(IDXGIResource *res)
|
||||
{
|
||||
ID3D11Resource *d3d11res;
|
||||
res->QueryInterface(__uuidof(ID3D11Resource), (void **)&d3d11res);
|
||||
if(GetResourceManager()->HasWrapper(d3d11res))
|
||||
{
|
||||
ID3D11DeviceChild *wrapper = GetResourceManager()->GetWrapper(d3d11res);
|
||||
IDXGIResource *ret = NULL;
|
||||
wrapper->QueryInterface(__uuidof(IDXGIResource), (void **)&ret);
|
||||
res->Release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *voidRes = (void *)res;
|
||||
OpenSharedResourceInternal(true, 0, __uuidof(IDXGIResource), &voidRes);
|
||||
return (IDXGIResource *)voidRes;
|
||||
}
|
||||
|
||||
void WrappedID3D11Device::SetMarker(uint32_t col, const wchar_t *name)
|
||||
{
|
||||
if(m_pCurrentWrappedDevice == NULL)
|
||||
|
||||
@@ -548,6 +548,8 @@ public:
|
||||
void ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue, IUnknown **unwrappedQueues);
|
||||
|
||||
virtual IDXGIResource *WrapExternalDXGIResource(IDXGIResource *res);
|
||||
|
||||
ResourceId GetBackbufferResourceID() { return m_BBID; }
|
||||
void InternalRef() { InterlockedIncrement(&m_InternalRefcount); }
|
||||
void InternalRelease() { InterlockedDecrement(&m_InternalRefcount); }
|
||||
@@ -607,6 +609,9 @@ public:
|
||||
SerialiserType &ser, ID3D11Resource *tex, ResourceId id, const D3D11_SUBRESOURCE_DATA *data,
|
||||
UINT w, UINT h, UINT d, DXGI_FORMAT fmt, UINT mips, UINT arr, bool HasData);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE OpenSharedResourceInternal(bool externalResource, HANDLE hResource,
|
||||
REFIID ReturnedInterface, void **ppResource);
|
||||
|
||||
// this is defined as a macro so that we can re-use it to explicitly instantiate these functions as
|
||||
// templates in the wrapper definition file.
|
||||
#define SERIALISED_ID3D11DEVICE_FUNCTIONS() \
|
||||
|
||||
@@ -3273,6 +3273,12 @@ bool WrappedID3D11Device::Serialise_OpenSharedResource(SerialiserType &ser, HAND
|
||||
|
||||
HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID ReturnedInterface,
|
||||
void **ppResource)
|
||||
{
|
||||
return OpenSharedResourceInternal(false, hResource, ReturnedInterface, ppResource);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D11Device::OpenSharedResourceInternal(bool externalResource, HANDLE hResource,
|
||||
REFIID ReturnedInterface, void **ppResource)
|
||||
{
|
||||
if(IsReplayMode(m_State))
|
||||
{
|
||||
@@ -3294,7 +3300,16 @@ HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID Returne
|
||||
{
|
||||
void *res = NULL;
|
||||
HRESULT hr;
|
||||
SERIALISE_TIME_CALL(hr = m_pDevice->OpenSharedResource(hResource, ReturnedInterface, &res));
|
||||
|
||||
if(externalResource)
|
||||
{
|
||||
res = *ppResource;
|
||||
SERIALISE_TIME_CALL(hr = S_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
SERIALISE_TIME_CALL(hr = m_pDevice->OpenSharedResource(hResource, ReturnedInterface, &res));
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -3362,6 +3377,8 @@ HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID Returne
|
||||
|
||||
ID3D11Resource *realRes = NULL;
|
||||
|
||||
void *ppvWrapped = NULL;
|
||||
|
||||
if(isBuf)
|
||||
{
|
||||
WrappedID3D11Buffer *w = new WrappedID3D11Buffer((ID3D11Buffer *)res, 0, this);
|
||||
@@ -3369,7 +3386,21 @@ HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID Returne
|
||||
|
||||
realRes = w->GetReal();
|
||||
|
||||
*ppResource = (ID3D11Buffer *)w;
|
||||
ppvWrapped = (ID3D11Buffer *)w;
|
||||
|
||||
if(isDXGIRes)
|
||||
{
|
||||
w->QueryInterface(__uuidof(IDXGIResource), ppResource);
|
||||
w->Release();
|
||||
}
|
||||
else if(isRes)
|
||||
{
|
||||
*ppResource = (ID3D11Resource *)w;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppResource = (ID3D11Buffer *)w;
|
||||
}
|
||||
}
|
||||
else if(isTex1D)
|
||||
{
|
||||
@@ -3378,7 +3409,21 @@ HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID Returne
|
||||
|
||||
realRes = w->GetReal();
|
||||
|
||||
*ppResource = (ID3D11Texture1D *)w;
|
||||
ppvWrapped = (ID3D11Texture1D *)w;
|
||||
|
||||
if(isDXGIRes)
|
||||
{
|
||||
w->QueryInterface(__uuidof(IDXGIResource), ppResource);
|
||||
w->Release();
|
||||
}
|
||||
else if(isRes)
|
||||
{
|
||||
*ppResource = (ID3D11Resource *)w;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppResource = (ID3D11Texture1D *)w;
|
||||
}
|
||||
}
|
||||
else if(isTex2D)
|
||||
{
|
||||
@@ -3387,7 +3432,21 @@ HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID Returne
|
||||
|
||||
realRes = w->GetReal();
|
||||
|
||||
*ppResource = (ID3D11Texture2D *)w;
|
||||
ppvWrapped = (ID3D11Texture2D *)w;
|
||||
|
||||
if(isDXGIRes)
|
||||
{
|
||||
w->QueryInterface(__uuidof(IDXGIResource), ppResource);
|
||||
w->Release();
|
||||
}
|
||||
else if(isRes)
|
||||
{
|
||||
*ppResource = (ID3D11Resource *)w;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppResource = (ID3D11Texture2D *)w;
|
||||
}
|
||||
}
|
||||
else if(isTex3D)
|
||||
{
|
||||
@@ -3396,15 +3455,30 @@ HRESULT WrappedID3D11Device::OpenSharedResource(HANDLE hResource, REFIID Returne
|
||||
|
||||
realRes = w->GetReal();
|
||||
|
||||
*ppResource = (ID3D11Texture3D *)w;
|
||||
ppvWrapped = (ID3D11Texture3D *)w;
|
||||
|
||||
if(isDXGIRes)
|
||||
{
|
||||
w->QueryInterface(__uuidof(IDXGIResource), ppResource);
|
||||
w->Release();
|
||||
}
|
||||
else if(isRes)
|
||||
{
|
||||
*ppResource = (ID3D11Resource *)w;
|
||||
}
|
||||
else
|
||||
{
|
||||
*ppResource = (ID3D11Texture3D *)w;
|
||||
}
|
||||
}
|
||||
|
||||
Chunk *chunk = NULL;
|
||||
|
||||
{
|
||||
USE_SCRATCH_SERIALISER();
|
||||
SCOPED_SERIALISE_CHUNK(D3D11Chunk::OpenSharedResource);
|
||||
Serialise_OpenSharedResource(GET_SERIALISER, hResource, ReturnedInterface, ppResource);
|
||||
SCOPED_SERIALISE_CHUNK(externalResource ? D3D11Chunk::ExternalDXGIResource
|
||||
: D3D11Chunk::OpenSharedResource);
|
||||
Serialise_OpenSharedResource(GET_SERIALISER, hResource, ReturnedInterface, &ppvWrapped);
|
||||
|
||||
chunk = scope.Get();
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ rdcstr DoStringise(const D3D11ResourceType &el)
|
||||
template <>
|
||||
rdcstr DoStringise(const D3D11Chunk &el)
|
||||
{
|
||||
RDCCOMPILE_ASSERT((uint32_t)D3D11Chunk::Max == 1127, "Chunks changed without updating names");
|
||||
RDCCOMPILE_ASSERT((uint32_t)D3D11Chunk::Max == 1128, "Chunks changed without updating names");
|
||||
|
||||
BEGIN_ENUM_STRINGISE(D3D11Chunk)
|
||||
{
|
||||
@@ -209,6 +209,7 @@ rdcstr DoStringise(const D3D11Chunk &el)
|
||||
STRINGISE_ENUM_CLASS_NAMED(PostFinishCommandListSet, "ID3D11DeviceContext::FinishCommandList");
|
||||
STRINGISE_ENUM_CLASS_NAMED(SwapDeviceContextState,
|
||||
"ID3D11DeviceContext1::SwapDeviceContextState");
|
||||
STRINGISE_ENUM_CLASS_NAMED(ExternalDXGIResource, "External DXGI Resource import");
|
||||
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
|
||||
}
|
||||
END_ENUM_STRINGISE()
|
||||
|
||||
@@ -195,6 +195,10 @@ public:
|
||||
{
|
||||
return m_pDevice->WrapSwapchainBuffer(swapper, bufferFormat, buffer, realSurface);
|
||||
}
|
||||
virtual IDXGIResource *WrapExternalDXGIResource(IDXGIResource *res)
|
||||
{
|
||||
return m_pDevice->WrapExternalDXGIResource(res);
|
||||
}
|
||||
|
||||
virtual HRESULT Present(IDXGISwapper *swapper, UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
|
||||
@@ -826,5 +826,6 @@ enum class D3D12Chunk : uint32_t
|
||||
List_EndRenderPass,
|
||||
List_RSSetShadingRate,
|
||||
List_RSSetShadingRateImage,
|
||||
Device_ExternalDXGIResource,
|
||||
Max,
|
||||
};
|
||||
|
||||
@@ -1135,6 +1135,24 @@ IUnknown *WrappedID3D12Device::WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_F
|
||||
return pRes;
|
||||
}
|
||||
|
||||
IDXGIResource *WrappedID3D12Device::WrapExternalDXGIResource(IDXGIResource *res)
|
||||
{
|
||||
ID3D12Resource *d3d12res;
|
||||
res->QueryInterface(__uuidof(ID3D12Resource), (void **)&d3d12res);
|
||||
if(GetResourceManager()->HasWrapper(d3d12res))
|
||||
{
|
||||
ID3D12DeviceChild *wrapper = GetResourceManager()->GetWrapper(d3d12res);
|
||||
IDXGIResource *ret = NULL;
|
||||
wrapper->QueryInterface(__uuidof(IDXGIResource), (void **)&ret);
|
||||
res->Release();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void *voidRes = (void *)res;
|
||||
OpenSharedHandleInternal(true, 0, __uuidof(IDXGIResource), &voidRes);
|
||||
return (IDXGIResource *)voidRes;
|
||||
}
|
||||
|
||||
void WrappedID3D12Device::Map(ID3D12Resource *Resource, UINT Subresource)
|
||||
{
|
||||
MapState map;
|
||||
@@ -2896,6 +2914,9 @@ bool WrappedID3D12Device::ProcessChunk(ReadSerialiser &ser, D3D12Chunk context)
|
||||
return Serialise_CreateCommittedResource1(ser, NULL, D3D12_HEAP_FLAG_NONE, NULL,
|
||||
D3D12_RESOURCE_STATE_COMMON, NULL, NULL, IID(), NULL);
|
||||
case D3D12Chunk::Device_CreateHeap1: return Serialise_CreateHeap1(ser, NULL, NULL, IID(), NULL);
|
||||
case D3D12Chunk::Device_ExternalDXGIResource:
|
||||
return Serialise_OpenSharedHandle(ser, NULL, IID(), NULL);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
SystemChunk system = (SystemChunk)context;
|
||||
|
||||
@@ -713,6 +713,8 @@ public:
|
||||
void ReleaseSwapchainResources(IDXGISwapper *swapper, UINT QueueCount,
|
||||
IUnknown *const *ppPresentQueue, IUnknown **unwrappedQueues);
|
||||
|
||||
IDXGIResource *WrapExternalDXGIResource(IDXGIResource *res);
|
||||
|
||||
void Map(ID3D12Resource *Resource, UINT Subresource);
|
||||
void Unmap(ID3D12Resource *Resource, UINT Subresource, byte *mapPtr,
|
||||
const D3D12_RANGE *pWrittenRange);
|
||||
@@ -954,6 +956,9 @@ public:
|
||||
const SECURITY_ATTRIBUTES *pAttributes, DWORD Access,
|
||||
LPCWSTR Name, HANDLE *pHandle);
|
||||
|
||||
HRESULT STDMETHODCALLTYPE OpenSharedHandleInternal(bool externalResource, HANDLE NTHandle,
|
||||
REFIID riid, void **ppvObj);
|
||||
|
||||
IMPLEMENT_FUNCTION_THREAD_SERIALISED(virtual HRESULT STDMETHODCALLTYPE, OpenSharedHandle,
|
||||
HANDLE NTHandle, REFIID riid, void **ppvObj);
|
||||
|
||||
|
||||
@@ -2284,7 +2284,7 @@ bool WrappedID3D12Device::Serialise_OpenSharedHandle(SerialiserType &ser, HANDLE
|
||||
D3D12_HEAP_PROPERTIES heapProperties;
|
||||
D3D12_HEAP_FLAGS heapFlags;
|
||||
|
||||
ID3D12Resource *res{};
|
||||
ID3D12Resource *res = NULL;
|
||||
if(ser.IsWriting())
|
||||
{
|
||||
res = (ID3D12Resource *)*ppvObj;
|
||||
@@ -2375,6 +2375,12 @@ bool WrappedID3D12Device::Serialise_OpenSharedHandle(SerialiserType &ser, HANDLE
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void **ppvObj)
|
||||
{
|
||||
return OpenSharedHandleInternal(false, NTHandle, riid, ppvObj);
|
||||
}
|
||||
|
||||
HRESULT WrappedID3D12Device::OpenSharedHandleInternal(bool externalResource, HANDLE NTHandle,
|
||||
REFIID riid, void **ppvObj)
|
||||
{
|
||||
if(IsReplayMode(m_State))
|
||||
{
|
||||
@@ -2385,12 +2391,22 @@ HRESULT WrappedID3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void
|
||||
if(ppvObj == NULL)
|
||||
return E_INVALIDARG;
|
||||
|
||||
bool isDXGIRes = (riid == __uuidof(IDXGIResource) ? true : false);
|
||||
bool isRes = (riid == __uuidof(ID3D12Resource) ? true : false);
|
||||
if(isRes)
|
||||
if(isDXGIRes || isRes)
|
||||
{
|
||||
void *ret = NULL;
|
||||
HRESULT hr;
|
||||
SERIALISE_TIME_CALL(hr = m_pDevice->OpenSharedHandle(NTHandle, riid, &ret));
|
||||
|
||||
if(externalResource)
|
||||
{
|
||||
ret = *ppvObj;
|
||||
SERIALISE_TIME_CALL(hr = S_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
SERIALISE_TIME_CALL(hr = m_pDevice->OpenSharedHandle(NTHandle, riid, &ret));
|
||||
}
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -2400,15 +2416,44 @@ HRESULT WrappedID3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void
|
||||
}
|
||||
else
|
||||
{
|
||||
if(isDXGIRes)
|
||||
{
|
||||
IDXGIResource *dxgiRes = (IDXGIResource *)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;
|
||||
}
|
||||
|
||||
ID3D12Resource *real = (ID3D12Resource *)ret;
|
||||
|
||||
WrappedID3D12Resource1 *wrapped = new WrappedID3D12Resource1(real, this);
|
||||
*ppvObj = (ID3D12Resource *)wrapped;
|
||||
|
||||
if(isDXGIRes)
|
||||
wrapped->QueryInterface(__uuidof(IDXGIResource), ppvObj);
|
||||
else
|
||||
*ppvObj = (ID3D12Resource *)wrapped;
|
||||
|
||||
CACHE_THREAD_SERIALISER();
|
||||
|
||||
SCOPED_SERIALISE_CHUNK(D3D12Chunk::Device_OpenSharedHandle);
|
||||
Serialise_OpenSharedHandle(ser, NTHandle, riid, ppvObj);
|
||||
SCOPED_SERIALISE_CHUNK(externalResource ? D3D12Chunk::Device_ExternalDXGIResource
|
||||
: D3D12Chunk::Device_OpenSharedHandle);
|
||||
Serialise_OpenSharedHandle(ser, NTHandle, __uuidof(ID3D12Resource), (void **)&wrapped);
|
||||
|
||||
D3D12_RESOURCE_DESC desc = wrapped->GetDesc();
|
||||
D3D12_RESOURCE_STATES InitialResourceState = D3D12_RESOURCE_STATE_COMMON;
|
||||
|
||||
@@ -51,6 +51,9 @@ ID3DDevice *GetD3D12DeviceIfAlloc(IUnknown *dev)
|
||||
if(WrappedID3D12CommandQueue::IsAlloc(dev))
|
||||
return (WrappedID3D12CommandQueue *)dev;
|
||||
|
||||
if(WrappedID3D12Device::IsAlloc(dev))
|
||||
return (WrappedID3D12Device *)dev;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
template <>
|
||||
rdcstr DoStringise(const D3D12Chunk &el)
|
||||
{
|
||||
RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1104, "Chunks changed without updating names");
|
||||
RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::List_RSSetShadingRateImage == 1103,
|
||||
"New chunks must be appended otherwise it breaks old captures");
|
||||
RDCCOMPILE_ASSERT((uint32_t)D3D12Chunk::Max == 1105, "Chunks changed without updating names");
|
||||
|
||||
BEGIN_ENUM_STRINGISE(D3D12Chunk)
|
||||
{
|
||||
@@ -192,6 +190,7 @@ rdcstr DoStringise(const D3D12Chunk &el)
|
||||
"ID3D12GraphicsCommandList5::RSSetShadingRate");
|
||||
STRINGISE_ENUM_CLASS_NAMED(List_RSSetShadingRateImage,
|
||||
"ID3D12GraphicsCommandList5::RSSetShadingRateImage");
|
||||
STRINGISE_ENUM_CLASS_NAMED(Device_ExternalDXGIResource, "External DXGI Resource import");
|
||||
STRINGISE_ENUM_CLASS_NAMED(Max, "Max Chunk");
|
||||
}
|
||||
END_ENUM_STRINGISE()
|
||||
|
||||
@@ -605,6 +605,125 @@ WrappedIDXGIOutput6::~WrappedIDXGIOutput6()
|
||||
SAFE_RELEASE(m_Owner);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput6::FindClosestMatchingMode(
|
||||
const DXGI_MODE_DESC *pModeToMatch, DXGI_MODE_DESC *pClosestMatch, IUnknown *pConcernedDevice)
|
||||
{
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pConcernedDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
return m_pReal->FindClosestMatchingMode(pModeToMatch, pClosestMatch,
|
||||
wrapDevice->GetRealIUnknown());
|
||||
|
||||
if(pConcernedDevice)
|
||||
RDCERR("Unrecognised device in FindClosestMatchingMode()");
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput6::TakeOwnership(IUnknown *pDevice, BOOL Exclusive)
|
||||
{
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
return m_pReal->TakeOwnership(wrapDevice->GetRealIUnknown(), Exclusive);
|
||||
|
||||
// since this is supposed to be an internal function, allow passing through the pointer directly
|
||||
// just in case
|
||||
return m_pReal->TakeOwnership(pDevice, Exclusive);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput6::FindClosestMatchingMode1(
|
||||
const DXGI_MODE_DESC1 *pModeToMatch, DXGI_MODE_DESC1 *pClosestMatch, IUnknown *pConcernedDevice)
|
||||
{
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pConcernedDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
return m_pReal1->FindClosestMatchingMode1(pModeToMatch, pClosestMatch,
|
||||
wrapDevice->GetRealIUnknown());
|
||||
|
||||
if(pConcernedDevice)
|
||||
RDCERR("Unrecognised device in FindClosestMatchingMode1()");
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput6::GetDisplaySurfaceData1(IDXGIResource *pDestination)
|
||||
{
|
||||
return m_pReal1->GetDisplaySurfaceData1(UnwrapDXGIResource(pDestination));
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE
|
||||
WrappedIDXGIOutput6::DuplicateOutput(IUnknown *pDevice, IDXGIOutputDuplication **ppOutputDuplication)
|
||||
{
|
||||
if(!ppOutputDuplication)
|
||||
return E_INVALIDARG;
|
||||
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
{
|
||||
IDXGIOutputDuplication *dup = NULL;
|
||||
HRESULT ret = m_pReal1->DuplicateOutput(wrapDevice->GetRealIUnknown(), &dup);
|
||||
|
||||
if(SUCCEEDED(ret) && dup)
|
||||
dup = new WrappedIDXGIOutputDuplication(wrapDevice, dup);
|
||||
|
||||
*ppOutputDuplication = dup;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(pDevice)
|
||||
RDCERR("Unrecognised device in DuplicateOutput()");
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput6::CheckOverlaySupport(DXGI_FORMAT EnumFormat,
|
||||
IUnknown *pConcernedDevice,
|
||||
UINT *pFlags)
|
||||
{
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pConcernedDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
return m_pReal3->CheckOverlaySupport(EnumFormat, wrapDevice->GetRealIUnknown(), pFlags);
|
||||
|
||||
if(pConcernedDevice)
|
||||
RDCERR("Unrecognised device in CheckOverlaySupport()");
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput6::DuplicateOutput1(
|
||||
IUnknown *pDevice, UINT Flags, UINT SupportedFormatsCount, const DXGI_FORMAT *pSupportedFormats,
|
||||
IDXGIOutputDuplication **ppOutputDuplication)
|
||||
{
|
||||
if(!ppOutputDuplication)
|
||||
return E_INVALIDARG;
|
||||
|
||||
ID3DDevice *wrapDevice = GetD3DDevice(pDevice);
|
||||
|
||||
if(wrapDevice)
|
||||
{
|
||||
IDXGIOutputDuplication *dup = NULL;
|
||||
HRESULT ret =
|
||||
m_pReal5->DuplicateOutput1(wrapDevice->GetRealIUnknown(), Flags, SupportedFormatsCount,
|
||||
pSupportedFormats, ppOutputDuplication);
|
||||
|
||||
if(SUCCEEDED(ret) && dup)
|
||||
dup = new WrappedIDXGIOutputDuplication(wrapDevice, dup);
|
||||
|
||||
*ppOutputDuplication = dup;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
if(pDevice)
|
||||
RDCERR("Unrecognised device in DuplicateOutput()");
|
||||
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutput6::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IDXGIOutput))
|
||||
@@ -1272,3 +1391,47 @@ HRESULT WrappedIDXGIFactory::CreateSwapChainForComposition(IUnknown *pDevice,
|
||||
|
||||
return m_pReal2->CreateSwapChainForComposition(pDevice, pDesc, unwrappedOutput, ppSwapChain);
|
||||
}
|
||||
|
||||
WrappedIDXGIOutputDuplication::WrappedIDXGIOutputDuplication(ID3DDevice *device,
|
||||
IDXGIOutputDuplication *real)
|
||||
: RefCountDXGIObject(real), m_Device(device), m_pReal(real)
|
||||
{
|
||||
}
|
||||
|
||||
WrappedIDXGIOutputDuplication::~WrappedIDXGIOutputDuplication()
|
||||
{
|
||||
SAFE_RELEASE(m_pReal);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutputDuplication::AcquireNextFrame(
|
||||
UINT TimeoutInMilliseconds, DXGI_OUTDUPL_FRAME_INFO *pFrameInfo, IDXGIResource **ppDesktopResource)
|
||||
{
|
||||
if(!ppDesktopResource)
|
||||
return E_INVALIDARG;
|
||||
|
||||
IDXGIResource *desktop = NULL;
|
||||
HRESULT ret = m_pReal->AcquireNextFrame(TimeoutInMilliseconds, pFrameInfo, &desktop);
|
||||
|
||||
if(SUCCEEDED(ret) && desktop)
|
||||
desktop = m_Device->WrapExternalDXGIResource(desktop);
|
||||
|
||||
*ppDesktopResource = desktop;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGIOutputDuplication::QueryInterface(REFIID riid, void **ppvObject)
|
||||
{
|
||||
if(riid == __uuidof(IDXGIOutputDuplication))
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IDXGIOutputDuplication *)this;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
WarnUnknownGUID("IDXGIOutputDuplication", riid);
|
||||
}
|
||||
|
||||
return RefCountDXGIObject::QueryInterface(riid, ppvObject);
|
||||
}
|
||||
@@ -192,6 +192,8 @@ struct ID3DDevice
|
||||
virtual IUnknown *WrapSwapchainBuffer(IDXGISwapper *swapper, DXGI_FORMAT bufferFormat,
|
||||
UINT buffer, IUnknown *realSurface) = 0;
|
||||
|
||||
virtual IDXGIResource *WrapExternalDXGIResource(IDXGIResource *res) = 0;
|
||||
|
||||
virtual HRESULT Present(IDXGISwapper *swapper, UINT SyncInterval, UINT Flags) = 0;
|
||||
};
|
||||
|
||||
@@ -903,6 +905,93 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class WrappedIDXGIOutputDuplication : public IDXGIOutputDuplication, public RefCountDXGIObject
|
||||
{
|
||||
ID3DDevice *m_Device;
|
||||
IDXGIOutputDuplication *m_pReal;
|
||||
|
||||
public:
|
||||
IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY;
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject);
|
||||
|
||||
WrappedIDXGIOutputDuplication(ID3DDevice *device, IDXGIOutputDuplication *real);
|
||||
~WrappedIDXGIOutputDuplication();
|
||||
|
||||
IDXGIOutputDuplication *GetReal() { return m_pReal; }
|
||||
//////////////////////////////
|
||||
// implement IDXGIOutputDuplication
|
||||
|
||||
virtual void STDMETHODCALLTYPE GetDesc(
|
||||
/* [annotation][out] */
|
||||
_Out_ DXGI_OUTDUPL_DESC *pDesc)
|
||||
{
|
||||
return m_pReal->GetDesc(pDesc);
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE AcquireNextFrame(
|
||||
/* [annotation][in] */
|
||||
_In_ UINT TimeoutInMilliseconds,
|
||||
/* [annotation][out] */
|
||||
_Out_ DXGI_OUTDUPL_FRAME_INFO *pFrameInfo,
|
||||
/* [annotation][out] */
|
||||
_COM_Outptr_ IDXGIResource **ppDesktopResource);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFrameDirtyRects(
|
||||
/* [annotation][in] */
|
||||
_In_ UINT DirtyRectsBufferSize,
|
||||
/* [annotation][out] */
|
||||
_Out_writes_bytes_to_(DirtyRectsBufferSize, *pDirtyRectsBufferSizeRequired)
|
||||
RECT *pDirtyRectsBuffer,
|
||||
/* [annotation][out] */
|
||||
_Out_ UINT *pDirtyRectsBufferSizeRequired)
|
||||
{
|
||||
return m_pReal->GetFrameDirtyRects(DirtyRectsBufferSize, pDirtyRectsBuffer,
|
||||
pDirtyRectsBufferSizeRequired);
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFrameMoveRects(
|
||||
/* [annotation][in] */
|
||||
_In_ UINT MoveRectsBufferSize,
|
||||
/* [annotation][out] */
|
||||
_Out_writes_bytes_to_(MoveRectsBufferSize, *pMoveRectsBufferSizeRequired)
|
||||
DXGI_OUTDUPL_MOVE_RECT *pMoveRectBuffer,
|
||||
/* [annotation][out] */
|
||||
_Out_ UINT *pMoveRectsBufferSizeRequired)
|
||||
{
|
||||
return m_pReal->GetFrameMoveRects(MoveRectsBufferSize, pMoveRectBuffer,
|
||||
pMoveRectsBufferSizeRequired);
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetFramePointerShape(
|
||||
/* [annotation][in] */
|
||||
_In_ UINT PointerShapeBufferSize,
|
||||
/* [annotation][out] */
|
||||
_Out_writes_bytes_to_(PointerShapeBufferSize,
|
||||
*pPointerShapeBufferSizeRequired) void *pPointerShapeBuffer,
|
||||
/* [annotation][out] */
|
||||
_Out_ UINT *pPointerShapeBufferSizeRequired,
|
||||
/* [annotation][out] */
|
||||
_Out_ DXGI_OUTDUPL_POINTER_SHAPE_INFO *pPointerShapeInfo)
|
||||
{
|
||||
return m_pReal->GetFramePointerShape(PointerShapeBufferSize, pPointerShapeBuffer,
|
||||
pPointerShapeBufferSizeRequired, pPointerShapeInfo);
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE MapDesktopSurface(
|
||||
/* [annotation][out] */
|
||||
_Out_ DXGI_MAPPED_RECT *pLockedRect)
|
||||
{
|
||||
return m_pReal->MapDesktopSurface(pLockedRect);
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE UnMapDesktopSurface(void)
|
||||
{
|
||||
return m_pReal->UnMapDesktopSurface();
|
||||
}
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE ReleaseFrame(void) { return m_pReal->ReleaseFrame(); }
|
||||
};
|
||||
|
||||
class WrappedIDXGIOutput6 : public IDXGIOutput6, public RefCountDXGIObject
|
||||
{
|
||||
RefCountDXGIObject *m_Owner;
|
||||
@@ -949,18 +1038,12 @@ public:
|
||||
/* [annotation][out] */
|
||||
_Out_ DXGI_MODE_DESC *pClosestMatch,
|
||||
/* [annotation][in] */
|
||||
_In_opt_ IUnknown *pConcernedDevice)
|
||||
{
|
||||
return m_pReal->FindClosestMatchingMode(pModeToMatch, pClosestMatch, pConcernedDevice);
|
||||
}
|
||||
_In_opt_ IUnknown *pConcernedDevice);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE WaitForVBlank(void) { return m_pReal->WaitForVBlank(); }
|
||||
virtual HRESULT STDMETHODCALLTYPE TakeOwnership(
|
||||
/* [annotation][in] */
|
||||
_In_ IUnknown *pDevice, BOOL Exclusive)
|
||||
{
|
||||
return m_pReal->TakeOwnership(pDevice, Exclusive);
|
||||
}
|
||||
_In_ IUnknown *pDevice, BOOL Exclusive);
|
||||
|
||||
virtual void STDMETHODCALLTYPE ReleaseOwnership(void) { return m_pReal->ReleaseOwnership(); }
|
||||
virtual HRESULT STDMETHODCALLTYPE GetGammaControlCapabilities(
|
||||
@@ -1025,26 +1108,17 @@ public:
|
||||
/* [annotation][out] */
|
||||
_Out_ DXGI_MODE_DESC1 *pClosestMatch,
|
||||
/* [annotation][in] */
|
||||
_In_opt_ IUnknown *pConcernedDevice)
|
||||
{
|
||||
return m_pReal1->FindClosestMatchingMode1(pModeToMatch, pClosestMatch, pConcernedDevice);
|
||||
}
|
||||
_In_opt_ IUnknown *pConcernedDevice);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE GetDisplaySurfaceData1(
|
||||
/* [annotation][in] */
|
||||
_In_ IDXGIResource *pDestination)
|
||||
{
|
||||
return m_pReal1->GetDisplaySurfaceData1(pDestination);
|
||||
}
|
||||
_In_ IDXGIResource *pDestination);
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE DuplicateOutput(
|
||||
/* [annotation][in] */
|
||||
_In_ IUnknown *pDevice,
|
||||
/* [annotation][out] */
|
||||
_COM_Outptr_ IDXGIOutputDuplication **ppOutputDuplication)
|
||||
{
|
||||
return m_pReal1->DuplicateOutput(pDevice, ppOutputDuplication);
|
||||
}
|
||||
_COM_Outptr_ IDXGIOutputDuplication **ppOutputDuplication);
|
||||
|
||||
//////////////////////////////
|
||||
// implement IDXGIOutput2
|
||||
@@ -1059,10 +1133,7 @@ public:
|
||||
/* [annotation][out] */
|
||||
_In_ IUnknown *pConcernedDevice,
|
||||
/* [annotation][out] */
|
||||
_Out_ UINT *pFlags)
|
||||
{
|
||||
return m_pReal3->CheckOverlaySupport(EnumFormat, pConcernedDevice, pFlags);
|
||||
}
|
||||
_Out_ UINT *pFlags);
|
||||
|
||||
//////////////////////////////
|
||||
// implement IDXGIOutput4
|
||||
@@ -1092,11 +1163,7 @@ public:
|
||||
/* [annotation][in] */
|
||||
_In_reads_(SupportedFormatsCount) const DXGI_FORMAT *pSupportedFormats,
|
||||
/* [annotation][out] */
|
||||
_COM_Outptr_ IDXGIOutputDuplication **ppOutputDuplication)
|
||||
{
|
||||
return m_pReal5->DuplicateOutput1(pDevice, Flags, SupportedFormatsCount, pSupportedFormats,
|
||||
ppOutputDuplication);
|
||||
}
|
||||
_COM_Outptr_ IDXGIOutputDuplication **ppOutputDuplication);
|
||||
|
||||
//////////////////////////////
|
||||
// implement IDXGIOutput6
|
||||
|
||||
Reference in New Issue
Block a user