From f4f57537c6b77ef133447f2bf27cbfc86665aadd Mon Sep 17 00:00:00 2001 From: cdozdil Date: Mon, 27 May 2024 17:59:47 +0300 Subject: [PATCH] wrapped swapchaing class for early hooking --- OptiScaler/imgui/wrapped_command_queue.h | 168 +++++++++++++++++++++ OptiScaler/imgui/wrapped_swapchain.cpp | 182 +++++++++++++++++++++++ 2 files changed, 350 insertions(+) create mode 100644 OptiScaler/imgui/wrapped_command_queue.h create mode 100644 OptiScaler/imgui/wrapped_swapchain.cpp diff --git a/OptiScaler/imgui/wrapped_command_queue.h b/OptiScaler/imgui/wrapped_command_queue.h new file mode 100644 index 00000000..4267e002 --- /dev/null +++ b/OptiScaler/imgui/wrapped_command_queue.h @@ -0,0 +1,168 @@ +#pragma once + +#include + +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(); } + +}; diff --git a/OptiScaler/imgui/wrapped_swapchain.cpp b/OptiScaler/imgui/wrapped_swapchain.cpp new file mode 100644 index 00000000..90cf3be2 --- /dev/null +++ b/OptiScaler/imgui/wrapped_swapchain.cpp @@ -0,0 +1,182 @@ +#include "wrapped_swapchain.h" + +WrappedIDXGISwapChain4::WrappedIDXGISwapChain4(IDXGISwapChain* real, + std::function renderTrig, + std::function renderTrig1, + std::function 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; +} \ No newline at end of file