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:
baldurk
2019-10-22 13:13:36 +01:00
parent ba3df46052
commit 92e2899ca3
14 changed files with 454 additions and 46 deletions
+1
View File
@@ -421,6 +421,7 @@ enum class D3D11Chunk : uint32_t
PostExecuteCommandList,
PostFinishCommandListSet,
SwapDeviceContextState,
ExternalDXGIResource,
Max,
};
+19
View File
@@ -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)
+5
View File
@@ -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() \
+81 -7
View File
@@ -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();
}
+2 -1
View File
@@ -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)
{
+1
View File
@@ -826,5 +826,6 @@ enum class D3D12Chunk : uint32_t
List_EndRenderPass,
List_RSSetShadingRate,
List_RSSetShadingRateImage,
Device_ExternalDXGIResource,
Max,
};
+21
View File
@@ -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;
+5
View File
@@ -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);
+51 -6
View File
@@ -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;
+3
View File
@@ -51,6 +51,9 @@ ID3DDevice *GetD3D12DeviceIfAlloc(IUnknown *dev)
if(WrappedID3D12CommandQueue::IsAlloc(dev))
return (WrappedID3D12CommandQueue *)dev;
if(WrappedID3D12Device::IsAlloc(dev))
return (WrappedID3D12Device *)dev;
return NULL;
}
+2 -3
View File
@@ -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()
+163
View File
@@ -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);
}
+96 -29
View File
@@ -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