1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-24 13:54:17 +01:00
dxvk/src/dxgi/dxgi_swapchain_dispatcher.h
2023-03-01 13:25:56 +01:00

312 lines
9.8 KiB
C++

#pragma once
#include "dxgi_swapchain.h"
namespace dxvk {
class DxgiSwapChainDispatcher : public IDXGISwapChain4 {
public:
DxgiSwapChainDispatcher(IDXGISwapChain4* dispatch, IUnknown* device)
: m_device(device),
m_dispatch(dispatch) {
}
virtual ~DxgiSwapChainDispatcher() {
}
ULONG STDMETHODCALLTYPE AddRef() {
if (likely(m_dispatch != nullptr))
return m_dispatch->AddRef();
return 0;
}
ULONG STDMETHODCALLTYPE Release() {
if (likely(m_dispatch != nullptr)) {
ULONG refCount = m_dispatch->Release();
if (unlikely(!refCount)) {
// Clear the underlying swap chain pointer. Helps in
// use-after-free situations encountered in Divinity
// Original Sin Enhanced Edition.
m_dispatch = nullptr;
delete this;
}
return refCount;
}
return ~0u;
}
HRESULT STDMETHODCALLTYPE QueryInterface(
REFIID riid,
void** ppvObject) final {
if (ppvObject == nullptr)
return E_POINTER;
*ppvObject = nullptr;
if (riid == __uuidof(IUnknown)
|| riid == __uuidof(IDXGIObject)
|| riid == __uuidof(IDXGIDeviceSubObject)
|| riid == __uuidof(IDXGISwapChain)
|| riid == __uuidof(IDXGISwapChain1)
|| riid == __uuidof(IDXGISwapChain2)
|| riid == __uuidof(IDXGISwapChain3)
|| riid == __uuidof(IDXGISwapChain4)) {
*ppvObject = ref(this);
return S_OK;
}
if (logQueryInterfaceError(__uuidof(IDXGISwapChain), riid)) {
Logger::warn("DxgiSwapChainDispatcher::QueryInterface: Unknown interface query");
Logger::warn(str::format(riid));
}
return m_dispatch->QueryInterface(riid, ppvObject);
}
HRESULT STDMETHODCALLTYPE GetPrivateData(
REFGUID Name,
UINT* pDataSize,
void* pData) final {
return m_dispatch->GetPrivateData(Name, pDataSize, pData);
}
HRESULT STDMETHODCALLTYPE SetPrivateData(
REFGUID Name,
UINT DataSize,
const void* pData) final {
return m_dispatch->SetPrivateData(Name, DataSize, pData);
}
HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(
REFGUID Name,
const IUnknown* pUnknown) final {
return m_dispatch->SetPrivateDataInterface(Name, pUnknown);
}
HRESULT STDMETHODCALLTYPE GetParent(
REFIID riid,
void** ppParent) final {
return m_dispatch->GetParent(riid, ppParent);
}
HRESULT STDMETHODCALLTYPE GetDevice(
REFIID riid,
void** ppDevice) final {
return m_dispatch->GetDevice(riid, ppDevice);
}
HRESULT STDMETHODCALLTYPE GetBuffer(
UINT Buffer,
REFIID riid,
void** ppSurface) final {
return m_dispatch->GetBuffer(Buffer, riid, ppSurface);
}
UINT STDMETHODCALLTYPE GetCurrentBackBufferIndex() final {
return m_dispatch->GetCurrentBackBufferIndex();
}
HRESULT STDMETHODCALLTYPE GetContainingOutput(
IDXGIOutput** ppOutput) final {
return m_dispatch->GetContainingOutput(ppOutput);
}
HRESULT STDMETHODCALLTYPE GetDesc(
DXGI_SWAP_CHAIN_DESC* pDesc) final {
return m_dispatch->GetDesc(pDesc);
}
HRESULT STDMETHODCALLTYPE GetDesc1(
DXGI_SWAP_CHAIN_DESC1* pDesc) final {
return m_dispatch->GetDesc1(pDesc);
}
HRESULT STDMETHODCALLTYPE GetFullscreenState(
BOOL* pFullscreen,
IDXGIOutput** ppTarget) final {
if (likely(m_dispatch != nullptr))
return m_dispatch->GetFullscreenState(pFullscreen, ppTarget);
if (pFullscreen)
*pFullscreen = FALSE;
if (ppTarget)
*ppTarget = nullptr;
return S_OK;
}
HRESULT STDMETHODCALLTYPE GetFullscreenDesc(
DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pDesc) final {
return m_dispatch->GetFullscreenDesc(pDesc);
}
HRESULT STDMETHODCALLTYPE GetHwnd(
HWND* pHwnd) final {
return m_dispatch->GetHwnd(pHwnd);
}
HRESULT STDMETHODCALLTYPE GetCoreWindow(
REFIID refiid,
void** ppUnk) final {
return m_dispatch->GetCoreWindow(refiid, ppUnk);
}
HRESULT STDMETHODCALLTYPE GetBackgroundColor(
DXGI_RGBA* pColor) final {
return m_dispatch->GetBackgroundColor(pColor);
}
HRESULT STDMETHODCALLTYPE GetRotation(
DXGI_MODE_ROTATION* pRotation) final {
return m_dispatch->GetRotation(pRotation);
}
HRESULT STDMETHODCALLTYPE GetRestrictToOutput(
IDXGIOutput** ppRestrictToOutput) final {
return m_dispatch->GetRestrictToOutput(ppRestrictToOutput);
}
HRESULT STDMETHODCALLTYPE GetFrameStatistics(
DXGI_FRAME_STATISTICS* pStats) final {
return m_dispatch->GetFrameStatistics(pStats);
}
HRESULT STDMETHODCALLTYPE GetLastPresentCount(
UINT* pLastPresentCount) final {
return m_dispatch->GetLastPresentCount(pLastPresentCount);
}
BOOL STDMETHODCALLTYPE IsTemporaryMonoSupported() final {
return m_dispatch->IsTemporaryMonoSupported();
}
HRESULT STDMETHODCALLTYPE Present(
UINT SyncInterval,
UINT Flags) final {
return m_dispatch->Present(SyncInterval, Flags);
}
HRESULT STDMETHODCALLTYPE Present1(
UINT SyncInterval,
UINT PresentFlags,
const DXGI_PRESENT_PARAMETERS* pPresentParameters) final {
return m_dispatch->Present1(SyncInterval, PresentFlags, pPresentParameters);
}
HRESULT STDMETHODCALLTYPE ResizeBuffers(
UINT BufferCount,
UINT Width,
UINT Height,
DXGI_FORMAT NewFormat,
UINT SwapChainFlags) final {
return m_dispatch->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags);
}
HRESULT STDMETHODCALLTYPE ResizeBuffers1(
UINT BufferCount,
UINT Width,
UINT Height,
DXGI_FORMAT Format,
UINT SwapChainFlags,
const UINT* pCreationNodeMask,
IUnknown* const* ppPresentQueue) final {
return m_dispatch->ResizeBuffers1(BufferCount, Width, Height, Format, SwapChainFlags, pCreationNodeMask, ppPresentQueue);
}
HRESULT STDMETHODCALLTYPE ResizeTarget(
const DXGI_MODE_DESC* pNewTargetParameters) final {
return m_dispatch->ResizeTarget(pNewTargetParameters);
}
HRESULT STDMETHODCALLTYPE SetFullscreenState(
BOOL Fullscreen,
IDXGIOutput* pTarget) final {
if (likely(m_dispatch != nullptr))
return m_dispatch->SetFullscreenState(Fullscreen, pTarget);
return S_OK;
}
HRESULT STDMETHODCALLTYPE SetBackgroundColor(
const DXGI_RGBA* pColor) final {
return m_dispatch->SetBackgroundColor(pColor);
}
HRESULT STDMETHODCALLTYPE SetRotation(
DXGI_MODE_ROTATION Rotation) final {
return m_dispatch->SetRotation(Rotation);
}
HANDLE STDMETHODCALLTYPE GetFrameLatencyWaitableObject() final {
return m_dispatch->GetFrameLatencyWaitableObject();
}
HRESULT STDMETHODCALLTYPE GetMatrixTransform(
DXGI_MATRIX_3X2_F* pMatrix) final {
return m_dispatch->GetMatrixTransform(pMatrix);
}
HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency(
UINT* pMaxLatency) final {
return m_dispatch->GetMaximumFrameLatency(pMaxLatency);
}
HRESULT STDMETHODCALLTYPE GetSourceSize(
UINT* pWidth,
UINT* pHeight) final {
return m_dispatch->GetSourceSize(pWidth, pHeight);
}
HRESULT STDMETHODCALLTYPE SetMatrixTransform(
const DXGI_MATRIX_3X2_F* pMatrix) final {
return m_dispatch->SetMatrixTransform(pMatrix);
}
HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency(
UINT MaxLatency) final {
return m_dispatch->SetMaximumFrameLatency(MaxLatency);
}
HRESULT STDMETHODCALLTYPE SetSourceSize(
UINT Width,
UINT Height) final {
return m_dispatch->SetSourceSize(Width, Height);
}
HRESULT STDMETHODCALLTYPE CheckColorSpaceSupport(
DXGI_COLOR_SPACE_TYPE ColorSpace,
UINT* pColorSpaceSupport) final {
return m_dispatch->CheckColorSpaceSupport(ColorSpace, pColorSpaceSupport);
}
HRESULT STDMETHODCALLTYPE SetColorSpace1(
DXGI_COLOR_SPACE_TYPE ColorSpace) final {
return m_dispatch->SetColorSpace1(ColorSpace);
}
HRESULT STDMETHODCALLTYPE SetHDRMetaData(
DXGI_HDR_METADATA_TYPE Type,
UINT Size,
void* pMetaData) final {
return m_dispatch->SetHDRMetaData(Type, Size, pMetaData);
}
private:
// m_device is not used or reference counted, provided for compatibility with mod engines
// which expect to find device pointer in the memory after swapchain interface.
IUnknown* m_device;
IDXGISwapChain4* m_dispatch;
};
}