wrapped swapchaing class for early hooking

This commit is contained in:
cdozdil
2024-05-27 17:59:47 +03:00
parent 06765b7d15
commit f4f57537c6
2 changed files with 350 additions and 0 deletions
+168
View File
@@ -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(); }
};
+182
View File
@@ -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;
}