mirror of
https://github.com/optiscaler/OptiScaler.git
synced 2026-08-24 15:16:45 +00:00
wrapped swapchaing class for early hooking
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d12.h>
|
||||
|
||||
class WrappedID3D12CommandQueue : public ID3D12CommandQueue
|
||||
{
|
||||
ID3D12CommandQueue* m_pReal = nullptr;
|
||||
|
||||
unsigned int m_iRefcount;
|
||||
|
||||
public:
|
||||
WrappedID3D12CommandQueue(ID3D12CommandQueue* real) : m_pReal(real), m_iRefcount(1)
|
||||
{
|
||||
}
|
||||
|
||||
~WrappedID3D12CommandQueue()
|
||||
{
|
||||
if (m_pReal != nullptr)
|
||||
{
|
||||
m_pReal->Release();
|
||||
m_pReal = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// implement IUnknown
|
||||
|
||||
HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject)
|
||||
{
|
||||
if (riid == __uuidof(ID3D12CommandQueue))
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (ID3D12CommandQueue*)this;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE AddRef()
|
||||
{
|
||||
InterlockedIncrement(&m_iRefcount);
|
||||
m_pReal->AddRef();
|
||||
return m_iRefcount;
|
||||
}
|
||||
|
||||
ULONG STDMETHODCALLTYPE Release()
|
||||
{
|
||||
m_pReal->Release();
|
||||
|
||||
unsigned int ret = InterlockedDecrement(&m_iRefcount);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
//if (ClearTrig != nullptr)
|
||||
// ClearTrig();
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12Object
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid, UINT* pDataSize, void* pData)
|
||||
{
|
||||
return m_pReal->GetPrivateData(guid, pDataSize, pData);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void* pData)
|
||||
{
|
||||
return m_pReal->SetPrivateData(guid, DataSize, pData);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID guid, const IUnknown* pData)
|
||||
{
|
||||
return m_pReal->SetPrivateDataInterface(guid, pData);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE SetName(LPCWSTR Name)
|
||||
{
|
||||
return m_pReal->SetName(Name);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12DeviceChild
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, _COM_Outptr_opt_ void** ppvDevice)
|
||||
{
|
||||
return m_pReal->GetDevice(riid, ppvDevice);
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// implement ID3D12CommandQueue
|
||||
|
||||
void STDMETHODCALLTYPE UpdateTileMappings(
|
||||
ID3D12Resource* pResource, UINT NumResourceRegions,
|
||||
const D3D12_TILED_RESOURCE_COORDINATE* pResourceRegionStartCoordinates,
|
||||
const D3D12_TILE_REGION_SIZE* pResourceRegionSizes, ID3D12Heap* pHeap,
|
||||
UINT NumRanges, const D3D12_TILE_RANGE_FLAGS* pRangeFlags,
|
||||
const UINT* pHeapRangeStartOffsets, const UINT* pRangeTileCounts,
|
||||
D3D12_TILE_MAPPING_FLAGS Flags)
|
||||
{
|
||||
return m_pReal->UpdateTileMappings(pResource, NumResourceRegions, pResourceRegionStartCoordinates, pResourceRegionSizes, pHeap,
|
||||
NumRanges, pRangeFlags, pHeapRangeStartOffsets, pRangeTileCounts, Flags);
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE CopyTileMappings(
|
||||
ID3D12Resource* pDstResource,
|
||||
const D3D12_TILED_RESOURCE_COORDINATE* pDstRegionStartCoordinate,
|
||||
ID3D12Resource* pSrcResource,
|
||||
const D3D12_TILED_RESOURCE_COORDINATE* pSrcRegionStartCoordinate,
|
||||
const D3D12_TILE_REGION_SIZE* pRegionSize,
|
||||
D3D12_TILE_MAPPING_FLAGS Flags)
|
||||
{
|
||||
return m_pReal->CopyTileMappings(pDstResource, pDstRegionStartCoordinate, pSrcResource, pSrcRegionStartCoordinate, pRegionSize, Flags);
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE ExecuteCommandLists(
|
||||
UINT NumCommandLists, ID3D12CommandList* const* ppCommandLists)
|
||||
{
|
||||
return m_pReal->ExecuteCommandLists(NumCommandLists, ppCommandLists);
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE SetMarker(UINT Metadata,
|
||||
const void* pData, UINT Size)
|
||||
{
|
||||
return m_pReal->SetMarker(Metadata, pData, Size);
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE BeginEvent(UINT Metadata,
|
||||
const void* pData, UINT Size)
|
||||
{
|
||||
return m_pReal->BeginEvent(Metadata, pData, Size);
|
||||
}
|
||||
|
||||
void STDMETHODCALLTYPE EndEvent()
|
||||
{
|
||||
return m_pReal->EndEvent();
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Signal(ID3D12Fence* pFence,
|
||||
UINT64 Value)
|
||||
{
|
||||
return m_pReal->Signal(pFence, Value);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE Wait(ID3D12Fence* pFence,
|
||||
UINT64 Value)
|
||||
{
|
||||
return m_pReal->Wait(pFence, Value);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetTimestampFrequency(UINT64* pFrequency)
|
||||
{
|
||||
return m_pReal->GetTimestampFrequency(pFrequency);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE GetClockCalibration(UINT64* pGpuTimestamp, UINT64* pCpuTimestamp)
|
||||
{
|
||||
return m_pReal->GetClockCalibration(pGpuTimestamp, pCpuTimestamp);
|
||||
}
|
||||
|
||||
D3D12_COMMAND_QUEUE_DESC STDMETHODCALLTYPE GetDesc() { return m_pReal->GetDesc(); }
|
||||
|
||||
};
|
||||
@@ -0,0 +1,182 @@
|
||||
#include "wrapped_swapchain.h"
|
||||
|
||||
WrappedIDXGISwapChain4::WrappedIDXGISwapChain4(IDXGISwapChain* real,
|
||||
std::function<HRESULT(IDXGISwapChain3*, UINT, UINT)> renderTrig,
|
||||
std::function<HRESULT(IDXGISwapChain3*, UINT, UINT, const DXGI_PRESENT_PARAMETERS*)> renderTrig1,
|
||||
std::function<void(bool)> clearTrig) : m_pReal(real), RenderTrig(renderTrig), RenderTrig1(renderTrig1), ClearTrig(clearTrig), m_iRefcount(1)
|
||||
{
|
||||
real->QueryInterface(__uuidof(IDXGISwapChain1), (void**)&m_pReal1);
|
||||
real->QueryInterface(__uuidof(IDXGISwapChain2), (void**)&m_pReal2);
|
||||
real->QueryInterface(__uuidof(IDXGISwapChain3), (void**)&m_pReal3);
|
||||
real->QueryInterface(__uuidof(IDXGISwapChain4), (void**)&m_pReal4);
|
||||
}
|
||||
|
||||
WrappedIDXGISwapChain4::~WrappedIDXGISwapChain4()
|
||||
{
|
||||
if (m_pReal1 != nullptr)
|
||||
{
|
||||
m_pReal1->Release();
|
||||
m_pReal1 = nullptr;
|
||||
}
|
||||
|
||||
if (m_pReal2 != nullptr)
|
||||
{
|
||||
m_pReal2->Release();
|
||||
m_pReal2 = nullptr;
|
||||
}
|
||||
|
||||
if (m_pReal3 != nullptr)
|
||||
{
|
||||
m_pReal3->Release();
|
||||
m_pReal3 = nullptr;
|
||||
}
|
||||
|
||||
if (m_pReal4 != nullptr)
|
||||
{
|
||||
m_pReal4->Release();
|
||||
m_pReal4 = nullptr;
|
||||
}
|
||||
|
||||
if (m_pReal != nullptr)
|
||||
{
|
||||
m_pReal->Release();
|
||||
m_pReal = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::QueryInterface(REFIID riid, void** ppvObject)
|
||||
{
|
||||
if (riid == __uuidof(IDXGISwapChain))
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IDXGISwapChain*)this;
|
||||
return S_OK;
|
||||
}
|
||||
else if (riid == __uuidof(IDXGISwapChain1))
|
||||
{
|
||||
if (m_pReal1)
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IDXGISwapChain1*)this;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
else if (riid == __uuidof(IDXGISwapChain2))
|
||||
{
|
||||
if (m_pReal2)
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IDXGISwapChain2*)this;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
else if (riid == __uuidof(IDXGISwapChain3))
|
||||
{
|
||||
if (m_pReal3)
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IDXGISwapChain3*)this;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
else if (riid == __uuidof(IDXGISwapChain4))
|
||||
{
|
||||
if (m_pReal4)
|
||||
{
|
||||
AddRef();
|
||||
*ppvObject = (IDXGISwapChain4*)this;
|
||||
return S_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
}
|
||||
|
||||
return E_NOINTERFACE; // RefCountDXGIObject::QueryInterface("IDXGISwapChain", riid, ppvObject);
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags)
|
||||
{
|
||||
if (ClearTrig != nullptr)
|
||||
ClearTrig(false);
|
||||
|
||||
HRESULT ret = m_pReal->ResizeBuffers(BufferCount, Width, Height, NewFormat, SwapChainFlags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::GetContainingOutput(IDXGIOutput** ppOutput)
|
||||
{
|
||||
HRESULT ret = m_pReal->GetContainingOutput(ppOutput);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::ResizeBuffers1(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT Format, UINT SwapChainFlags,
|
||||
_In_reads_(BufferCount) const UINT* pCreationNodeMask, _In_reads_(BufferCount) IUnknown* const* ppPresentQueue)
|
||||
{
|
||||
if (ClearTrig != nullptr)
|
||||
ClearTrig(false);
|
||||
|
||||
HRESULT ret = m_pReal3->ResizeBuffers1(BufferCount, Width, Height, Format, SwapChainFlags, pCreationNodeMask, ppPresentQueue);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::SetFullscreenState(BOOL Fullscreen, IDXGIOutput* pTarget)
|
||||
{
|
||||
//if (ClearTrig != nullptr)
|
||||
// ClearTrig(true);
|
||||
|
||||
return m_pReal->SetFullscreenState(Fullscreen, pTarget);
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::GetFullscreenState(BOOL* pFullscreen, IDXGIOutput** ppTarget)
|
||||
{
|
||||
HRESULT ret = m_pReal->GetFullscreenState(pFullscreen, ppTarget);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::GetBuffer(UINT Buffer, REFIID riid, void** ppSurface)
|
||||
{
|
||||
HRESULT ret = m_pReal->GetBuffer(Buffer, riid, ppSurface);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::GetDevice(REFIID riid, void** ppDevice)
|
||||
{
|
||||
HRESULT ret = m_pReal->GetDevice(riid, ppDevice);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::Present(UINT SyncInterval, UINT Flags)
|
||||
{
|
||||
if (RenderTrig != nullptr && m_pReal3 != nullptr)
|
||||
RenderTrig(m_pReal3, SyncInterval, Flags);
|
||||
|
||||
return m_pReal->Present(SyncInterval, Flags);
|
||||
}
|
||||
|
||||
HRESULT WrappedIDXGISwapChain4::Present1(UINT SyncInterval, UINT Flags, const DXGI_PRESENT_PARAMETERS* pPresentParameters)
|
||||
{
|
||||
if (RenderTrig1 != nullptr && m_pReal3 != nullptr)
|
||||
RenderTrig1(m_pReal3, SyncInterval, Flags, pPresentParameters);
|
||||
|
||||
return m_pReal1->Present1(SyncInterval, Flags, pPresentParameters);
|
||||
}
|
||||
|
||||
HRESULT STDMETHODCALLTYPE WrappedIDXGISwapChain4::GetRestrictToOutput(IDXGIOutput** ppRestrictToOutput)
|
||||
{
|
||||
HRESULT ret = m_pReal1->GetRestrictToOutput(ppRestrictToOutput);
|
||||
return ret;
|
||||
}
|
||||
Reference in New Issue
Block a user