diff --git a/CyberXeSS.vcxproj b/CyberXeSS.vcxproj new file mode 100644 index 00000000..25d2f199 --- /dev/null +++ b/CyberXeSS.vcxproj @@ -0,0 +1,197 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {8d2b73fb-eecd-45ce-b8e5-335610462f58} + CyberXeSS + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)external\simpleini;$(SolutionDir)\external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(VULKAN_SDK)\include;$(XESS_SDK)\inc\xess;$(IncludePath) + $(XESS_SDK)\lib;$(LibraryPath) + + + $(SolutionDir)external\simpleini;$(SolutionDir)\external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(VULKAN_SDK)\include;$(XESS_SDK)\inc\xess;$(IncludePath) + $(XESS_SDK)\lib;$(LibraryPath) + + + $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\vulkan\include;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) + $(ProjectDir)external\minhook\build\VC17\bin\Debug;$(SolutionDir)external\xess\lib;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) + nvngx + ..\..\God of War + + + $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\vulkan\include;$(IncludePath) + nvngx + $(SolutionDir)external\xess\lib;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpplatest + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpplatest + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + true + false + stdcpp20 + + + Windows + true + false + d3d11.lib;dxgi.lib;d3d12.lib;dxguid.lib;libxess.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + NDEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + Fast + true + stdcpp20 + + + Windows + true + true + true + false + d3d11.lib;d3dx11.lib;dxgi.lib;d3d12.lib;dxguid.lib;libxess.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + \ No newline at end of file diff --git a/CyberXeSS.vcxproj.filters b/CyberXeSS.vcxproj.filters new file mode 100644 index 00000000..1d56f95e --- /dev/null +++ b/CyberXeSS.vcxproj.filters @@ -0,0 +1,66 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/CyberXeSS/CyberXeSS.vcxproj b/CyberXeSS/CyberXeSS.vcxproj index 79b0a96f..1c487f6e 100644 --- a/CyberXeSS/CyberXeSS.vcxproj +++ b/CyberXeSS/CyberXeSS.vcxproj @@ -79,14 +79,15 @@ $(XESS_SDK)\lib;$(LibraryPath) - $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\vulkan\include;$(IncludePath) - $(SolutionDir)external\xess\lib;$(LibraryPath) + $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\vulkan\include;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) + $(ProjectDir)external\minhook\build\VC17\bin\Debug;$(SolutionDir)external\xess\lib;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) nvngx + ..\..\..\Games\God of War $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\vulkan\include;$(IncludePath) nvngx - $(SolutionDir)external\xess\lib;$(LibraryPath) + $(SolutionDir)external\xess\lib;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) @@ -140,7 +141,7 @@ Windows true false - dxguid.lib;libxess.lib;%(AdditionalDependencies) + d3d11.lib;dxgi.lib;d3d12.lib;dxguid.lib;libxess.lib;%(AdditionalDependencies) @@ -162,7 +163,7 @@ true true false - libxess.lib;dxguid.lib;%(AdditionalDependencies) + d3d11.lib;dxgi.lib;d3d12.lib;dxguid.lib;libxess.lib;%(AdditionalDependencies) UseLinkTimeCodeGeneration diff --git a/CyberXeSS/CyberXess.cpp b/CyberXeSS/CyberXess.cpp index d4def042..548754b3 100644 --- a/CyberXeSS/CyberXess.cpp +++ b/CyberXeSS/CyberXess.cpp @@ -5,7 +5,7 @@ FeatureContext* CyberXessContext::CreateContext() { - auto handleId = rand(); + auto handleId = handleCounter++; Contexts[handleId] = std::make_unique(); Contexts[handleId]->Handle.Id = handleId; return Contexts[handleId].get(); @@ -24,3 +24,4 @@ CyberXessContext::CyberXessContext() { MyConfig = std::make_unique(L"nvngx.ini"); } + diff --git a/CyberXeSS/CyberXess.h b/CyberXeSS/CyberXess.h index ed89fd09..cc4d99e0 100644 --- a/CyberXeSS/CyberXess.h +++ b/CyberXeSS/CyberXess.h @@ -3,6 +3,9 @@ #include "NvParameter.h" #include "xess_d3d12.h" #include "xess_debug.h" +#include "dxgi1_6.h" + +static unsigned int handleCounter = 1000; class FeatureContext; @@ -11,17 +14,98 @@ class CyberXessContext { CyberXessContext(); + void GetHardwareAdapter(IDXGIFactory1* pFactory, IDXGIAdapter** ppAdapter, D3D_FEATURE_LEVEL featureLevel, bool requestHighPerformanceAdapter) const + { + *ppAdapter = nullptr; + + IDXGIAdapter1* adapter; + + IDXGIFactory6* factory6; + if (SUCCEEDED(pFactory->QueryInterface(IID_PPV_ARGS(&factory6)))) + { + for ( + UINT adapterIndex = 0; + DXGI_ERROR_NOT_FOUND != factory6->EnumAdapterByGpuPreference( + adapterIndex, + requestHighPerformanceAdapter == true ? DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE : DXGI_GPU_PREFERENCE_UNSPECIFIED, + IID_PPV_ARGS(&adapter)); + ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see whether the adapter supports Direct3D 12, but don't create the + // actual device yet. + + auto result = D3D12CreateDevice(adapter, featureLevel, _uuidof(ID3D12Device), nullptr); + + if (result == S_FALSE) + { + *ppAdapter = adapter; + break; + } + } + } + else + { + for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see whether the adapter supports Direct3D 12, but don't create the + // actual device yet. + + auto result = D3D12CreateDevice(adapter, featureLevel, _uuidof(ID3D12Device), nullptr); + + if (result == S_FALSE) + { + *ppAdapter = adapter; + break; + } + } + } + + } + public: std::shared_ptr MyConfig; bool init = false; const NvParameter* CreateFeatureParams; - ID3D12Device* Dx12Device = nullptr; - ID3D11Device* Dx11Device = nullptr; + + // D3D12 stuff + ID3D12Device* Dx12Device = nullptr; + + // D3D11 stuff + ID3D11Device5* Dx11Device = nullptr; + ID3D11DeviceContext4* Dx11DeviceContext = nullptr; + + // D3D11on12 stuff + ID3D12CommandQueue* Dx12CommandQueue = nullptr; + ID3D12CommandAllocator* Dx12CommandAllocator[2] = { nullptr, nullptr }; + ID3D12GraphicsCommandList* Dx12CommandList[2] = { nullptr, nullptr }; + ID3D12Fence* Dx12Fence = nullptr; + + // Vulkan stuff VkDevice VulkanDevice = nullptr; VkInstance VulkanInstance = nullptr; VkPhysicalDevice VulkanPhysicalDevice = nullptr; - + std::shared_ptr NvParameterInstance = NvParameter::instance(); ankerl::unordered_dense::map > Contexts; @@ -33,13 +117,145 @@ public: static std::shared_ptr INSTANCE{ std::make_shared(CyberXessContext()) }; return INSTANCE; } + + void Shutdown(bool fromDx11 = false, bool shutdownEvent = false) const + { + if (CyberXessContext::instance()->Dx12Fence != nullptr && fromDx11 && shutdownEvent) + { + CyberXessContext::instance()->Dx12Fence->Release(); + CyberXessContext::instance()->Dx12Fence = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandList[0] != nullptr && fromDx11 && shutdownEvent) + { + CyberXessContext::instance()->Dx12CommandList[0]->Release(); + CyberXessContext::instance()->Dx12CommandList[0] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandList[1] != nullptr && fromDx11 && shutdownEvent) + { + CyberXessContext::instance()->Dx12CommandList[1]->Release(); + CyberXessContext::instance()->Dx12CommandList[1] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandQueue != nullptr && fromDx11 && shutdownEvent) + { + CyberXessContext::instance()->Dx12CommandQueue->Release(); + CyberXessContext::instance()->Dx12CommandQueue = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandAllocator[0] != nullptr && fromDx11 && shutdownEvent) + { + CyberXessContext::instance()->Dx12CommandAllocator[0]->Release(); + CyberXessContext::instance()->Dx12CommandAllocator[0] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandAllocator[1] != nullptr && fromDx11 && shutdownEvent) + { + CyberXessContext::instance()->Dx12CommandAllocator[1]->Release(); + CyberXessContext::instance()->Dx12CommandAllocator[1] = nullptr; + } + + if (CyberXessContext::instance()->Dx12Device != nullptr && fromDx11 && shutdownEvent) + { + CyberXessContext::instance()->Dx12Device->Release(); + CyberXessContext::instance()->Dx12Device = nullptr; + } + + if (CyberXessContext::instance()->VulkanInstance != nullptr) + CyberXessContext::instance()->VulkanInstance = nullptr; + + if (CyberXessContext::instance()->VulkanDevice != nullptr) + CyberXessContext::instance()->VulkanDevice = nullptr; + + if (CyberXessContext::instance()->VulkanPhysicalDevice != nullptr) + CyberXessContext::instance()->VulkanPhysicalDevice = nullptr; + + } + + HRESULT CreateDx12Device(D3D_FEATURE_LEVEL featureLevel) + { + if (Dx12Device != nullptr) + return S_OK; + + HRESULT result; + + IDXGIFactory4* factory; + result = CreateDXGIFactory2(0, IID_PPV_ARGS(&factory)); + + if (result != S_OK) + { + LOG("CreateDx12Device Can't create factory: " + int_to_hex(result), LEVEL_ERROR); + return result; + } + + IDXGIAdapter* hardwareAdapter = nullptr; + GetHardwareAdapter(factory, &hardwareAdapter, featureLevel, true); + + if (hardwareAdapter == nullptr) + { + LOG("CreateDx12Device Can't get hardwareAdapter!", LEVEL_ERROR); + return E_NOINTERFACE; + } + + result = D3D12CreateDevice(hardwareAdapter, featureLevel, IID_PPV_ARGS(&Dx12Device)); + + if (result != S_OK) + { + LOG("CreateDx12Device Can't create device: " + int_to_hex(result), LEVEL_ERROR); + return result; + } + + if (CyberXessContext::instance()->Dx12CommandList[0] != nullptr) + { + CyberXessContext::instance()->Dx12CommandList[0]->Release(); + CyberXessContext::instance()->Dx12CommandList[0] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandList[1] != nullptr) + { + CyberXessContext::instance()->Dx12CommandList[1]->Release(); + CyberXessContext::instance()->Dx12CommandList[1] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandQueue != nullptr) + { + CyberXessContext::instance()->Dx12CommandQueue->Release(); + CyberXessContext::instance()->Dx12CommandQueue = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandAllocator[0] != nullptr) + { + CyberXessContext::instance()->Dx12CommandAllocator[0]->Release(); + CyberXessContext::instance()->Dx12CommandAllocator[0] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandAllocator[1] != nullptr) + { + CyberXessContext::instance()->Dx12CommandAllocator[1]->Release(); + CyberXessContext::instance()->Dx12CommandAllocator[1] = nullptr; + } + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH; + + // CreateCommandQueue + result = Dx12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&Dx12CommandQueue)); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandQueue result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK || Dx12CommandQueue == nullptr) + return NVSDK_NGX_Result_FAIL_PlatformError; + + return S_OK; + } }; class FeatureContext { public: NVSDK_NGX_Handle Handle; - xess_context_handle_t XessContext = nullptr; unsigned int Width{}, Height{}, RenderWidth{}, RenderHeight{}; @@ -48,3 +264,27 @@ public: float MVScaleX{}, MVScaleY{}; float JitterOffsetX{}, JitterOffsetY{}; }; + +static std::string ResultToString(xess_result_t result) +{ + switch (result) + { + case XESS_RESULT_WARNING_NONEXISTING_FOLDER: return "Warning Nonexistent Folder"; + case XESS_RESULT_WARNING_OLD_DRIVER: return "Warning Old Driver"; + case XESS_RESULT_SUCCESS: return "Success"; + case XESS_RESULT_ERROR_UNSUPPORTED_DEVICE: return "Unsupported Device"; + case XESS_RESULT_ERROR_UNSUPPORTED_DRIVER: return "Unsupported Driver"; + case XESS_RESULT_ERROR_UNINITIALIZED: return "Uninitialized"; + case XESS_RESULT_ERROR_INVALID_ARGUMENT: return "Invalid Argument"; + case XESS_RESULT_ERROR_DEVICE_OUT_OF_MEMORY: return "Device Out of Memory"; + case XESS_RESULT_ERROR_DEVICE: return "Device Error"; + case XESS_RESULT_ERROR_NOT_IMPLEMENTED: return "Not Implemented"; + case XESS_RESULT_ERROR_INVALID_CONTEXT: return "Invalid Context"; + case XESS_RESULT_ERROR_OPERATION_IN_PROGRESS: return "Operation in Progress"; + case XESS_RESULT_ERROR_UNSUPPORTED: return "Unsupported"; + case XESS_RESULT_ERROR_CANT_LOAD_LIBRARY: return "Cannot Load Library"; + case XESS_RESULT_ERROR_UNKNOWN: + default: return "Unknown"; + } +} + diff --git a/CyberXeSS/CyberXessDx11.cpp b/CyberXeSS/CyberXessDx11.cpp index 6d5a6008..3b703346 100644 --- a/CyberXeSS/CyberXessDx11.cpp +++ b/CyberXeSS/CyberXessDx11.cpp @@ -2,15 +2,828 @@ #include "Config.h" #include "CyberXess.h" #include "Util.h" +#include "detours.h" -NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_Ext(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, - ID3D11Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion, - unsigned long long unknown0) +#ifdef _DEBUG +#pragma comment(lib, "detours.d.lib") +#else +#pragma comment(lib, "detours.r.lib") +#endif // DEBUG + +//#define ALWAYS_COPY_OUTPUT + +static volatile int listCount = 0; +decltype(&ID3D11Device::CreateTexture2D) ptrCreateTexture2D = nullptr; +decltype(&ID3D11Device3::CreateTexture2D1) ptrCreateTexture2D1 = nullptr; + +typedef enum _texture_type_t +{ + COLOR, + MOTIONV, + DEPTH, + TMASK, + EXPOSURE, + OUTPUT +} texture_type_t; + +typedef struct D3D11_TEXTURE2D_DESC_C +{ + UINT Width; + UINT Height; + DXGI_FORMAT Format; + UINT BindFlags; + void* pointer; +} D3D11_TEXTURE2D_DESC_C; + +//static D3D11_TEXTURE2D_DESC_C colorDesc = {}; +//static D3D11_TEXTURE2D_DESC_C mvDesc = {}; +//static D3D11_TEXTURE2D_DESC_C depthDesc = {}; +//static D3D11_TEXTURE2D_DESC_C tmDesc = {}; +//static D3D11_TEXTURE2D_DESC_C expDesc = {}; +//static D3D11_TEXTURE2D_DESC_C outDesc = {}; + +#define ASSIGN_DESC(dest, src) dest.Width = src.Width; \ +dest.Height = src.Height; \ +dest.Format = src.Format; \ +dest.BindFlags = src.BindFlags; \ + +static HANDLE colorHandle = NULL; +static HANDLE mvHandle = NULL; +static HANDLE depthHandle = NULL; +static HANDLE outHandle = NULL; +static HANDLE tmHandle = NULL; +static HANDLE expHandle = NULL; +static ID3D11Resource* colorShared = nullptr; +static ID3D11Resource* mvShared = nullptr; +static ID3D11Resource* depthShared = nullptr; +static ID3D11Resource* outShared = nullptr; +static ID3D11Resource* tmShared = nullptr; +static ID3D11Resource* expShared = nullptr; + +static ID3D12Fence* d3d12Fence = nullptr; +static ID3D11Fence* d3d11Fence = nullptr; +static HANDLE fenceHandle = NULL; + +xess_d3d12_execute_params_t params{}; + +static int inWidth = 0; +static int outWidth = 0; + +std::atomic isDeviceBusy(false); +std::atomic xessActive(false); + +// xess log callback +inline void LogCallback(const char* Message, xess_logging_level_t Level) +{ + std::string s = Message; + LOG("XeSS Runtime (" + std::to_string(Level) + ") : " + s, LEVEL_DEBUG); +} + +#pragma region D3D11 hooks + +HRESULT WINAPI hk_ID3D11Device_CreateTexture2D(ID3D11Device* This, const D3D11_TEXTURE2D_DESC* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture2D** ppTexture2D) +{ + if (ptrCreateTexture2D == nullptr) + return E_INVALIDARG; + + //if (xessActive.load() && pDesc->MipLevels == 1 && (pDesc->MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0 && + // (pDesc->Width == 1 || (pDesc->Width != pDesc->Height && pDesc->Width > 580)) && + // ( + // (pDesc->Width == 1 && pDesc->Height == 1) || + // ( + // (pDesc->BindFlags == colorDesc.BindFlags && pDesc->Format == colorDesc.Format) || + // (pDesc->BindFlags == depthDesc.BindFlags && pDesc->Format == depthDesc.Format) || + // (pDesc->BindFlags == outDesc.BindFlags && pDesc->Format == outDesc.Format) || + // (pDesc->BindFlags == mvDesc.BindFlags && pDesc->Format == mvDesc.Format) || + // (pDesc->BindFlags == tmDesc.BindFlags && pDesc->Format == tmDesc.Format) || + // (pDesc->BindFlags == expDesc.BindFlags && pDesc->Format == expDesc.Format) + // ) + // ) + // ) + //{ + // LOG("hk_ID3D11Device_CreateTexture2D marked D3D11_RESOURCE_MISC_SHARED", LEVEL_DEBUG); + + // auto makeShared = false; + + // if ((pDesc->Width == 1 && pDesc->Height == 1) || (pDesc->BindFlags == expDesc.BindFlags && pDesc->Format == expDesc.Format)) + // makeShared = true; + + // D3D11_TEXTURE2D_DESC desc = *pDesc; + // desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; + // auto hr = (This->*ptrCreateTexture2D)(&desc, pInitialData, ppTexture2D); + // return hr; + //} + + return (This->*ptrCreateTexture2D)(pDesc, pInitialData, ppTexture2D); +} + +HRESULT WINAPI hk_ID3D11Device_CreateTexture2D1(ID3D11Device3* This, const D3D11_TEXTURE2D_DESC1* pDesc, const D3D11_SUBRESOURCE_DATA* pInitialData, ID3D11Texture2D1** ppTexture2D) +{ + if (ptrCreateTexture2D1 == nullptr) + return E_INVALIDARG; + + //if (xessActive.load() && pDesc->MipLevels == 1 && (pDesc->MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0 && + // (pDesc->Width == 1 || (pDesc->Width != pDesc->Height && pDesc->Width > 580)) && + // ( + // (pDesc->Width == 1 && pDesc->Height == 1) || + // ( + // (pDesc->BindFlags == colorDesc.BindFlags && pDesc->Format == colorDesc.Format) || + // (pDesc->BindFlags == depthDesc.BindFlags && pDesc->Format == depthDesc.Format) || + // (pDesc->BindFlags == outDesc.BindFlags && pDesc->Format == outDesc.Format) || + // (pDesc->BindFlags == mvDesc.BindFlags && pDesc->Format == mvDesc.Format) || + // (pDesc->BindFlags == tmDesc.BindFlags && pDesc->Format == tmDesc.Format) || + // (pDesc->BindFlags == expDesc.BindFlags && pDesc->Format == expDesc.Format) + // ) + // ) + // ) + //{ + // LOG("hk_ID3D11Device_CreateTexture2D1 marked D3D11_RESOURCE_MISC_SHARED", LEVEL_DEBUG); + // D3D11_TEXTURE2D_DESC1 desc = *pDesc; + // desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; + // auto hr = (This->*ptrCreateTexture2D1)(&desc, pInitialData, ppTexture2D); + // return hr; + //} + + return (This->*ptrCreateTexture2D1)(pDesc, pInitialData, ppTexture2D); +} + +void AttachToD3D11() +{ + return; + + if (ptrCreateTexture2D == nullptr) + { + LOG("Attach to CreateTexture2D", LEVEL_INFO); + *(uintptr_t*)&ptrCreateTexture2D = Detours::X64::DetourClassVTable(*(uintptr_t*)CyberXessContext::instance()->Dx11Device, &hk_ID3D11Device_CreateTexture2D, 5); + } + + if (ptrCreateTexture2D1 == nullptr) + { + LOG("Attach to CreateTexture2D1", LEVEL_INFO); + *(uintptr_t*)&ptrCreateTexture2D1 = Detours::X64::DetourClassVTable(*(uintptr_t*)CyberXessContext::instance()->Dx11Device, &hk_ID3D11Device_CreateTexture2D1, 5); + } +} + +#pragma endregion + +#pragma region Texture copy&share methods + +void ReleaseSharedResources() +{ + LOG("ReleaseSharedResources!", LEVEL_INFO); + + if (colorShared != nullptr) + { + colorShared->Release(); + colorShared = nullptr; + } + + if (mvShared != nullptr) + { + mvShared->Release(); + mvShared = nullptr; + } + + if (depthShared != nullptr) + { + depthShared->Release(); + depthShared = nullptr; + } + + if (outShared != nullptr) + { + outShared->Release(); + outShared = nullptr; + } + + if (tmShared != nullptr) + { + tmShared->Release(); + tmShared = nullptr; + } + + if (expShared != nullptr) + { + expShared->Release(); + expShared = nullptr; + } +} + +static bool CreateFeature11(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* handle) +{ + while (isDeviceBusy.load()) + { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + isDeviceBusy.store(true); + + LOG("CreateFeature11 Start!", LEVEL_INFO); + + +#pragma region Read XeSS Version + + xess_version_t ver; + xess_result_t ret = xessGetVersion(&ver); + LOG("CreateFeature11 xessGetVersion result: " + ResultToString(ret), LEVEL_ERROR); + + if (ret == XESS_RESULT_SUCCESS) + { + char buf[128]; + sprintf_s(buf, "%u.%u.%u", ver.major, ver.minor, ver.patch); + + std::string m_VersionStr = buf; + + LOG("CreateFeature11 XeSS Version - " + m_VersionStr, LEVEL_WARNING); + } + +#pragma endregion + +#pragma region Check for Dx12Device Device + + if (CyberXessContext::instance()->Dx12Device == nullptr) + { + if (InCmdList == nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature InCmdList is null!!!", LEVEL_ERROR); + isDeviceBusy.store(false); + return false; + } + + LOG("NVSDK_NGX_D3D11_CreateFeature CyberXessContext::instance()->Dx12Device is null trying to get from InCmdList!", LEVEL_WARNING); + InCmdList->GetDevice(IID_PPV_ARGS(&CyberXessContext::instance()->Dx12Device)); + + if (CyberXessContext::instance()->Dx12Device == nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature CyberXessContext::instance()->Dx12Device can't receive from InCmdList!", LEVEL_ERROR); + isDeviceBusy.store(false); + return false; + } + } + else + LOG("NVSDK_NGX_D3D11_CreateFeature CyberXessContext::instance()->Dx12Device is OK!", LEVEL_DEBUG); + +#pragma endregion + + auto inParams = CyberXessContext::instance()->CreateFeatureParams; + auto deviceContext = CyberXessContext::instance()->Contexts[handle->Id].get(); + + if (deviceContext == nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature deviceContext is null!", LEVEL_ERROR); + isDeviceBusy.store(false); + return false; + } + + LOG("NVSDK_NGX_D3D11_CreateFeature deviceContext ok, xessD3D12CreateContext start", LEVEL_DEBUG); + + if (deviceContext->XessContext != nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature Destrying old XeSSContext", LEVEL_WARNING); + ret = xessDestroyContext(deviceContext->XessContext); + LOG("NVSDK_NGX_D3D11_CreateFeature xessDestroyContext result -> " + ResultToString(ret), LEVEL_WARNING); + } + + ret = xessD3D12CreateContext(CyberXessContext::instance()->Dx12Device, &deviceContext->XessContext); + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12CreateContext result -> " + ResultToString(ret), LEVEL_INFO); + + ret = xessSetLoggingCallback(deviceContext->XessContext, XESS_LOGGING_LEVEL_DEBUG, LogCallback); + LOG("NVSDK_NGX_D3D11_CreateFeature xessSetLoggingCallback : " + ResultToString(ret), LEVEL_DEBUG); + + ret = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + LOG("NVSDK_NGX_D3D11_CreateFeature xessSetVelocityScale : " + ResultToString(ret), LEVEL_DEBUG); + +#pragma region Create Parameters for XeSS + + xess_d3d12_init_params_t initParams{}; + + LOG("NVSDK_NGX_D3D11_CreateFeature Params Init!", LEVEL_DEBUG); + initParams.outputResolution.x = inParams->OutWidth; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.outputResolution.x : " + std::to_string(initParams.outputResolution.x), LEVEL_DEBUG); + initParams.outputResolution.y = inParams->OutHeight; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.outputResolution.y : " + std::to_string(initParams.outputResolution.y), LEVEL_DEBUG); + + switch (inParams->PerfQualityValue) + { + case NVSDK_NGX_PerfQuality_Value_UltraPerformance: + initParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_MaxPerf: + initParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_Balanced: + initParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED; + break; + case NVSDK_NGX_PerfQuality_Value_MaxQuality: + initParams.qualitySetting = XESS_QUALITY_SETTING_QUALITY; + break; + case NVSDK_NGX_PerfQuality_Value_UltraQuality: + initParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_QUALITY; + break; + default: + initParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED; //Set out-of-range value for non-existing fsr ultra quality mode + break; + } + + initParams.initFlags = XESS_INIT_FLAG_NONE; + + if (CyberXessContext::instance()->MyConfig->DepthInverted.value_or(inParams->DepthInverted)) + { + initParams.initFlags |= XESS_INIT_FLAG_INVERTED_DEPTH; + CyberXessContext::instance()->MyConfig->DepthInverted = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (DepthInverted) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->AutoExposure.value_or(inParams->AutoExposure)) + { + initParams.initFlags |= XESS_INIT_FLAG_ENABLE_AUTOEXPOSURE; + CyberXessContext::instance()->MyConfig->AutoExposure = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (AutoExposure) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + else + { + initParams.initFlags |= XESS_INIT_FLAG_EXPOSURE_SCALE_TEXTURE; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (!AutoExposure) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + if (!CyberXessContext::instance()->MyConfig->HDR.value_or(!inParams->Hdr)) + { + initParams.initFlags |= XESS_INIT_FLAG_LDR_INPUT_COLOR; + CyberXessContext::instance()->MyConfig->HDR = false; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (HDR) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->JitterCancellation.value_or(inParams->JitterMotion)) + { + initParams.initFlags |= XESS_INIT_FLAG_JITTERED_MV; + CyberXessContext::instance()->MyConfig->JitterCancellation = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (JitterCancellation) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->DisplayResolution.value_or(!inParams->LowRes)) + { + initParams.initFlags |= XESS_INIT_FLAG_HIGH_RES_MV; + CyberXessContext::instance()->MyConfig->DisplayResolution = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (LowRes) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + if (!CyberXessContext::instance()->MyConfig->DisableReactiveMask.value_or(true)) + { + initParams.initFlags |= XESS_INIT_FLAG_RESPONSIVE_PIXEL_MASK; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (DisableReactiveMask) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + LOG("NVSDK_NGX_D3D11_CreateFeature Params done!", LEVEL_DEBUG); + +#pragma endregion + +#pragma region Build Pipelines + + if (CyberXessContext::instance()->MyConfig->BuildPipelines.value_or(true)) + { + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12BuildPipelines start!", LEVEL_DEBUG); + + ret = xessD3D12BuildPipelines(deviceContext->XessContext, NULL, false, initParams.initFlags); + + if (ret != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12BuildPipelines error : -> " + ResultToString(ret), LEVEL_ERROR); + isDeviceBusy.store(false); + return false; + } + } + else + { + LOG("NVSDK_NGX_D3D11_CreateFeature skipping xessD3D12BuildPipelines!", LEVEL_DEBUG); + } + +#pragma endregion + +#pragma region Select Network Model + + auto model = static_cast(CyberXessContext::instance()->MyConfig->NetworkModel.value_or(0)); + + LOG("NVSDK_NGX_D3D11_CreateFeature xessSelectNetworkModel trying to set value to " + std::to_string(model), LEVEL_DEBUG); + + ret = xessSelectNetworkModel(deviceContext->XessContext, model); + + if (ret == XESS_RESULT_SUCCESS) + LOG("NVSDK_NGX_D3D11_CreateFeature xessSelectNetworkModel set to " + std::to_string(model), LEVEL_DEBUG); + else + LOG("NVSDK_NGX_D3D11_CreateFeature xessSelectNetworkModel(" + std::to_string(model) + ") error : " + ResultToString(ret), LEVEL_ERROR); + +#pragma endregion + + + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12Init start!", LEVEL_DEBUG); + + ret = xessD3D12Init(deviceContext->XessContext, &initParams); + + if (ret != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12Init error: " + ResultToString(ret), LEVEL_ERROR); + CyberXessContext::instance()->init = false; + isDeviceBusy.store(false); + return false; + } + + LOG("NVSDK_NGX_D3D11_CreateFeature End!", LEVEL_DEBUG); + + CyberXessContext::instance()->init = true; + isDeviceBusy.store(false); + return true; +} + +FeatureContext* CreateContext11(NVSDK_NGX_Handle** OutHandle) +{ + auto deviceContext = CyberXessContext::instance()->CreateContext(); + *OutHandle = &deviceContext->Handle; + return deviceContext; +} + +HANDLE CopyTexture(ID3D11Texture2D* originalTexture, ID3D11Texture2D** pSharedTexture, bool copy = true) +{ + HANDLE handle; + ID3D11Texture2D* sharedTexture = *pSharedTexture; + D3D11_TEXTURE2D_DESC desc; + HRESULT result; + + LOG("CopyTexture slow path :/", LEVEL_WARNING); + + originalTexture->GetDesc(&desc); + + // ok then lets kill the perf, we need shared version of this texture + // so first create a 2d texture with same properties and shared flag + //desc.CPUAccessFlags = 0; + desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; + + // if it's output texture add UNORDERED ACCESS + if (!copy) + desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; + + // Create shared texture + if (sharedTexture != nullptr) + { + D3D11_TEXTURE2D_DESC sDesc; + sharedTexture->GetDesc(&sDesc); + + if (sDesc.BindFlags != desc.BindFlags || sDesc.Format != desc.Format || + sDesc.Width != desc.Width || sDesc.Height != desc.Height) + { + sharedTexture->Release(); + result = CyberXessContext::instance()->Dx11Device->CreateTexture2D(&desc, nullptr, &sharedTexture); + LOG("CopyTexture CreateTexture2D result: " + int_to_hex(result), LEVEL_DEBUG); + } + else + { + LOG("CopyTexture desc matches, skipping CreateTexture2D", LEVEL_DEBUG); + result = S_OK; + } + } + else + { + result = CyberXessContext::instance()->Dx11Device->CreateTexture2D(&desc, nullptr, &sharedTexture); + LOG("CopyTexture CreateTexture2D result: " + int_to_hex(result), LEVEL_DEBUG); + } + + if (result != S_OK) + return NULL; + + // if it's not output texture copy it to use it with xess + if (copy) + { + CyberXessContext::instance()->Dx11DeviceContext->CopyResource(sharedTexture, originalTexture); + LOG("CopyTexture CreateTexture2D CopyResource!", LEVEL_DEBUG); + } + + // Query resource + IDXGIResource1* resource; + result = sharedTexture->QueryInterface(IID_PPV_ARGS(&resource)); + LOG("CopyTexture QueryInterface(resource) result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + // Get shared handle + result = resource->GetSharedHandle(&handle); + LOG("CopyTexture CreateSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + resource->Release(); + + *pSharedTexture = sharedTexture; + + return handle; +} + +HANDLE CopyTexture1(ID3D11Texture2D1* originalTexture, ID3D11Texture2D1** pSharedTexture, bool copy = true) +{ + HANDLE handle; + ID3D11Texture2D1* sharedTexture = *pSharedTexture; + D3D11_TEXTURE2D_DESC1 desc; + HRESULT result; + + LOG("CopyTexture1 slow path :/", LEVEL_WARNING); + + originalTexture->GetDesc1(&desc); + + // ok then lets kill the perf, we need shared version of this texture + // so first create a 2d texture with same properties and shared flag + //desc.CPUAccessFlags = 0; + desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; + + // if it's output texture add UNORDERED ACCESS + if (!copy) + desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; + + // Create shared texture + if (sharedTexture != nullptr) + { + D3D11_TEXTURE2D_DESC sDesc; + sharedTexture->GetDesc(&sDesc); + + if (sDesc.BindFlags != desc.BindFlags || sDesc.Format != desc.Format || + sDesc.Width != desc.Width || sDesc.Height != desc.Height) + { + sharedTexture->Release(); + result = CyberXessContext::instance()->Dx11Device->CreateTexture2D1(&desc, nullptr, &sharedTexture); + LOG("CopyTexture1 CreateTexture2D result: " + int_to_hex(result), LEVEL_DEBUG); + } + else + { + LOG("CopyTexture1 desc matches, skipping CreateTexture2D", LEVEL_DEBUG); + result = S_OK; + } + } + else + { + result = CyberXessContext::instance()->Dx11Device->CreateTexture2D1(&desc, nullptr, &sharedTexture); + LOG("CopyTexture1 CreateTexture2D result: " + int_to_hex(result), LEVEL_DEBUG); + } + + if (result != S_OK) + return NULL; + + // if it's not output texture copy it to use it with xess + if (copy) + { + CyberXessContext::instance()->Dx11DeviceContext->CopyResource(sharedTexture, originalTexture); + LOG("CopyTexture1 CreateTexture2D CopyResource!", LEVEL_DEBUG); + } + + // Query resource + IDXGIResource1* resource; + result = sharedTexture->QueryInterface(IID_PPV_ARGS(&resource)); + LOG("CopyTexture1 QueryInterface(resource) result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + // Get shared handle + result = resource->GetSharedHandle(&handle); + LOG("CopyTexture1 CreateSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + resource->Release(); + + *pSharedTexture = sharedTexture; + + return handle; +} + +HANDLE ShareTexture(ID3D11Texture2D* originalTexture, ID3D11Texture2D** pSharedTexture) +{ + HANDLE handle; + + // Query resource + IDXGIResource1* resource; + + auto result = originalTexture->QueryInterface(IID_PPV_ARGS(&resource)); + LOG("ShareTexture QueryInterface(resource) result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + // Get shared handle + result = resource->GetSharedHandle(&handle); + LOG("ShareTexture CreateSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + resource->Release(); + + // to release at end of frame + *pSharedTexture = originalTexture; + + return handle; +} + +HANDLE ShareTexture1(ID3D11Texture2D1* originalTexture, ID3D11Texture2D1** pSharedTexture) +{ + HANDLE handle; + + // Query resource + IDXGIResource1* resource; + + auto result = originalTexture->QueryInterface(IID_PPV_ARGS(&resource)); + LOG("ShareTexture1 QueryInterface(resource) result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + // Get shared handle + result = resource->GetSharedHandle(&handle); + LOG("ShareTexture1 CreateSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + return NULL; + + resource->Release(); + + // to release at end of frame + *pSharedTexture = originalTexture; + + return handle; +} + +HANDLE CopyTextureFrom11To12(ID3D11Resource* d3d11texture, ID3D11Resource** pSharedTexture, texture_type_t texType) +{ + ID3D11Texture2D* originalTexture = nullptr; + ID3D11Texture2D1* originalTexture1 = nullptr; + ID3D11Texture2D* sharedTexture = nullptr; + ID3D11Texture2D1* sharedTexture1 = nullptr; + D3D11_TEXTURE2D_DESC desc; + D3D11_TEXTURE2D_DESC1 desc1; + HANDLE handle; + HRESULT result; + bool copy = true; + + // Get texture + result = d3d11texture->QueryInterface(IID_PPV_ARGS(&originalTexture1)); + LOG("CopyTextureFrom11To12 QueryInterface(texture2d) result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + { + result = d3d11texture->QueryInterface(IID_PPV_ARGS(&originalTexture)); + + if (result != S_OK) + return NULL; + + if (*pSharedTexture != nullptr) + { + result = (*pSharedTexture)->QueryInterface(IID_PPV_ARGS(&sharedTexture)); + + if (result != S_OK) + return NULL; + } + + originalTexture->GetDesc(&desc); + + if ((desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0) + LOG("texture is shared!", LEVEL_DEBUG); + + handle = CopyTexture(originalTexture, &sharedTexture, texType != OUTPUT); + originalTexture = reinterpret_cast(sharedTexture); + +// +//#ifdef ALWAYS_COPY_OUTPUT +// if ((desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0 || texType == OUTPUT) +//#else +// if ((desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0) +//#endif // ALWAYS_COPY_OUTPUT +// { +// switch (texType) +// { +// case COLOR: +// ASSIGN_DESC(colorDesc, desc) +// colorDesc.pointer = d3d11texture; +// break; +// +// case MOTIONV: +// ASSIGN_DESC(mvDesc, desc) +// mvDesc.pointer = d3d11texture; +// break; +// +// case DEPTH: +// ASSIGN_DESC(depthDesc, desc) +// depthDesc.pointer = d3d11texture; +// break; +// +// case TMASK: +// ASSIGN_DESC(tmDesc, desc) +// tmDesc.pointer = d3d11texture; +// break; +// +// case EXPOSURE: +// ASSIGN_DESC(expDesc, desc) +// expDesc.pointer = d3d11texture; +// break; +// +// case OUTPUT: +// ASSIGN_DESC(outDesc, desc) +// outDesc.pointer = d3d11texture; +// copy = false; +// break; +// +// } +// +// handle = CopyTexture(originalTexture, &sharedTexture, copy); +// } +// else +// handle = ShareTexture(originalTexture, &sharedTexture); + + if (handle != NULL) + *pSharedTexture = sharedTexture; + + return handle; + } + else + { + if (*pSharedTexture != nullptr) + { + result = (*pSharedTexture)->QueryInterface(IID_PPV_ARGS(&sharedTexture1)); + + if (result != S_OK) + return NULL; + } + + originalTexture1->GetDesc1(&desc1); + if ((desc1.MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0) + LOG("texture1 is shared!", LEVEL_DEBUG); + + handle = CopyTexture1(originalTexture1, &sharedTexture1, texType != OUTPUT); + originalTexture1 = reinterpret_cast(sharedTexture1); + + + // Get desc of original texture and create shared desc +// +//#ifdef ALWAYS_COPY_OUTPUT +// if ((desc1.MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0 || texType == OUTPUT) +//#else +// if ((desc1.MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0) +//#endif // ALWAYS_COPY_OUTPUT +// { +// switch (texType) +// { +// case COLOR: +// ASSIGN_DESC(colorDesc, desc1) +// colorDesc.pointer = d3d11texture; +// break; +// +// case MOTIONV: +// ASSIGN_DESC(mvDesc, desc1) +// mvDesc.pointer = d3d11texture; +// break; +// +// case DEPTH: +// ASSIGN_DESC(depthDesc, desc1) +// depthDesc.pointer = d3d11texture; +// break; +// +// case TMASK: +// ASSIGN_DESC(tmDesc, desc1) +// tmDesc.pointer = d3d11texture; +// break; +// +// case EXPOSURE: +// ASSIGN_DESC(expDesc, desc1) +// expDesc.pointer = d3d11texture; +// break; +// +// case OUTPUT: +// ASSIGN_DESC(outDesc, desc1) +// outDesc.pointer = d3d11texture; +// copy = false; +// break; +// +// } +// +// handle = CopyTexture1(originalTexture1, &sharedTexture1, copy); +// } +// else +// handle = ShareTexture1(originalTexture1, &sharedTexture1); + + if (handle != NULL) + *pSharedTexture = sharedTexture1; + + return handle; + } +} + +#pragma endregion + +#pragma region NVSDK_NGX_D3D11_Init + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_Ext(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, ID3D11Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion, unsigned long long unknown0) { LOG("NVSDK_NGX_D3D11_Init_Ext AppId:" + std::to_string(InApplicationId), LEVEL_INFO); LOG("NVSDK_NGX_D3D11_Init_Ext SDK:" + std::to_string(InSDKVersion), LEVEL_INFO); - CyberXessContext::instance()->Dx11Device = InDevice; + ReleaseSharedResources(); + CyberXessContext::instance()->init = false; + CyberXessContext::instance()->Shutdown(true, true); return NVSDK_NGX_Result_Success; } @@ -20,7 +833,7 @@ NVSDK_NGX_Result NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const LOG("NVSDK_NGX_D3D11_Init AppId:" + std::to_string(InApplicationId), LEVEL_DEBUG); LOG("NVSDK_NGX_D3D11_Init SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); - return NVSDK_NGX_D3D11_Init_Ext(0x1337, InApplicationDataPath, nullptr, InFeatureInfo, InSDKVersion, 0); + return NVSDK_NGX_D3D11_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); } NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, ID3D11Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) @@ -42,13 +855,55 @@ NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_with_ProjectID(const char* InProjectId, NV return NVSDK_NGX_D3D11_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); } +#pragma endregion + +#pragma region NVSDK_NGX_D3D11_Shutdown + NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown(void) { LOG("NVSDK_NGX_D3D11_Shutdown", LEVEL_INFO); - CyberXessContext::instance()->Dx11Device = nullptr; + while (isDeviceBusy.load()) + { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + // Close D3D12 device + if (CyberXessContext::instance()->Dx12Device != nullptr && CyberXessContext::instance()->Dx12CommandQueue != nullptr && + CyberXessContext::instance()->Dx12CommandList[0] != nullptr && CyberXessContext::instance()->Dx12CommandList[1] != nullptr) + { + LOG("NVSDK_NGX_D3D11_Shutdown: releasing d3d12 resources", LEVEL_DEBUG); + ID3D12Fence* d3d12Fence; + CyberXessContext::instance()->Dx12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&d3d12Fence)); + CyberXessContext::instance()->Dx12CommandQueue->Signal(d3d12Fence, 999); + LOG("NVSDK_NGX_D3D11_Shutdown: releasing d3d12 fence created and signalled", LEVEL_DEBUG); + + CyberXessContext::instance()->Dx12CommandList[0]->Close(); + CyberXessContext::instance()->Dx12CommandList[1]->Close(); + ID3D12CommandList* ppCommandLists[] = { CyberXessContext::instance()->Dx12CommandList[0], CyberXessContext::instance()->Dx12CommandList[1] }; + LOG("NVSDK_NGX_D3D11_Shutdown: releasing d3d12 command list executing", LEVEL_DEBUG); + CyberXessContext::instance()->Dx12CommandQueue->ExecuteCommandLists(2, ppCommandLists); + + LOG("NVSDK_NGX_D3D11_Shutdown: releasing d3d12 waiting signal", LEVEL_DEBUG); + auto fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + d3d12Fence->SetEventOnCompletion(999, fenceEvent); + WaitForSingleObject(fenceEvent, INFINITE); + CloseHandle(fenceEvent); + d3d12Fence->Release(); + LOG("NVSDK_NGX_D3D11_Shutdown: releasing d3d12 release done", LEVEL_DEBUG); + } + + ReleaseSharedResources(); + CyberXessContext::instance()->Shutdown(true, true); CyberXessContext::instance()->NvParameterInstance->Params.clear(); + + // close all xess contexts + for (auto const& [key, val] : CyberXessContext::instance()->Contexts) { + NVSDK_NGX_D3D11_ReleaseFeature(&val->Handle); + } + CyberXessContext::instance()->Contexts.clear(); + xessActive.store(false); return NVSDK_NGX_Result_Success; } @@ -57,13 +912,55 @@ NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown1(ID3D11Device* InDevice) { LOG("NVSDK_NGX_D3D11_Shutdown1", LEVEL_INFO); - CyberXessContext::instance()->Dx11Device = nullptr; + while (isDeviceBusy.load()) + { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + // Close D3D12 device + if (CyberXessContext::instance()->Dx12Device != nullptr && CyberXessContext::instance()->Dx12CommandQueue != nullptr && + CyberXessContext::instance()->Dx12CommandList[0] != nullptr && CyberXessContext::instance()->Dx12CommandList[1] != nullptr) + { + LOG("NVSDK_NGX_D3D11_Shutdown1: releasing d3d12 resources", LEVEL_DEBUG); + ID3D12Fence* d3d12Fence; + CyberXessContext::instance()->Dx12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&d3d12Fence)); + CyberXessContext::instance()->Dx12CommandQueue->Signal(d3d12Fence, 999); + LOG("NVSDK_NGX_D3D11_Shutdown1: releasing d3d12 fence created and signalled", LEVEL_DEBUG); + + CyberXessContext::instance()->Dx12CommandList[0]->Close(); + CyberXessContext::instance()->Dx12CommandList[1]->Close(); + ID3D12CommandList* ppCommandLists[] = { CyberXessContext::instance()->Dx12CommandList[0], CyberXessContext::instance()->Dx12CommandList[1] }; + LOG("NVSDK_NGX_D3D11_Shutdown1: releasing d3d12 command list executing", LEVEL_DEBUG); + CyberXessContext::instance()->Dx12CommandQueue->ExecuteCommandLists(2, ppCommandLists); + + LOG("NVSDK_NGX_D3D11_Shutdown1: releasing d3d12 waiting signal", LEVEL_DEBUG); + auto fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + d3d12Fence->SetEventOnCompletion(999, fenceEvent); + WaitForSingleObject(fenceEvent, INFINITE); + CloseHandle(fenceEvent); + d3d12Fence->Release(); + LOG("NVSDK_NGX_D3D11_Shutdown1: releasing d3d12 release done", LEVEL_DEBUG); + } + + ReleaseSharedResources(); + CyberXessContext::instance()->Shutdown(true, true); CyberXessContext::instance()->NvParameterInstance->Params.clear(); + + // close all xess contexts + for (auto const& [key, val] : CyberXessContext::instance()->Contexts) { + NVSDK_NGX_D3D11_ReleaseFeature(&val->Handle); + } + CyberXessContext::instance()->Contexts.clear(); + xessActive.store(false); return NVSDK_NGX_Result_Success; } +#pragma endregion + +#pragma region NVSDK_NGX_D3D11 Parameters + NVSDK_NGX_Result NVSDK_NGX_D3D11_GetParameters(NVSDK_NGX_Parameter** OutParameters) { LOG("NVSDK_NGX_D3D11_GetParameters", LEVEL_DEBUG); @@ -99,8 +996,7 @@ NVSDK_NGX_Result NVSDK_NGX_D3D11_DestroyParameters(NVSDK_NGX_Parameter* InParame return NVSDK_NGX_Result_Success; } -NVSDK_NGX_Result NVSDK_NGX_D3D11_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, - const NVSDK_NGX_Parameter* InParameters, size_t* OutSizeInBytes) +NVSDK_NGX_Result NVSDK_NGX_D3D11_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter* InParameters, size_t* OutSizeInBytes) { LOG("NVSDK_NGX_D3D11_GetScratchBufferSize -> 52428800", LEVEL_WARNING); @@ -108,19 +1004,87 @@ NVSDK_NGX_Result NVSDK_NGX_D3D11_GetScratchBufferSize(NVSDK_NGX_Feature InFeatur return NVSDK_NGX_Result_Success; } +#pragma endregion + +#pragma region NVSDK_NGX_D3D11 Feature + NVSDK_NGX_Result NVSDK_NGX_D3D11_CreateFeature(ID3D11DeviceContext* InDevCtx, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) { - LOG("NVSDK_NGX_D3D11_CreateFeature Fail!", LEVEL_ERROR); + LOG("NVSDK_NGX_D3D11_CreateFeature", LEVEL_DEBUG); - return NVSDK_NGX_Result_FAIL_PlatformError; + while (isDeviceBusy.load()) + { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + isDeviceBusy.store(true); + + HRESULT result; + + ID3D11Device* device; + InDevCtx->GetDevice(&device); + + result = device->QueryInterface(IID_PPV_ARGS(&CyberXessContext::instance()->Dx11Device)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_CreateFeature QueryInterface ID3D11Device5 result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_FeatureNotFound; + } + + ReleaseSharedResources(); + AttachToD3D11(); + + // create d3d12 device + auto fl = CyberXessContext::instance()->Dx11Device->GetFeatureLevel(); + result = CyberXessContext::instance()->CreateDx12Device(fl); + + if (result != S_OK || CyberXessContext::instance()->Dx12Device == nullptr) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_NotInitialized; + } + + auto cfResult = NVSDK_NGX_D3D12_CreateFeature(nullptr, InFeatureID, InParameters, OutHandle); + LOG("NVSDK_NGX_D3D11_CreateFeature Handle: " + std::to_string((*OutHandle)->Id) + ", result: " + int_to_hex(cfResult), LEVEL_DEBUG); + + isDeviceBusy.store(false); + return cfResult; } NVSDK_NGX_Result NVSDK_NGX_D3D11_ReleaseFeature(NVSDK_NGX_Handle* InHandle) { - LOG("NVSDK_NGX_D3D11_ReleaseFeature", LEVEL_DEBUG); + if (InHandle == nullptr) + return NVSDK_NGX_Result_Success; + + LOG("NVSDK_NGX_D3D11_ReleaseFeature Handle: " + std::to_string(InHandle->Id), LEVEL_DEBUG); + + while (isDeviceBusy.load()) + { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + isDeviceBusy.store(true); + + if (auto deviceContext = CyberXessContext::instance()->Contexts[InHandle->Id].get(); deviceContext->XessContext != nullptr) + { + auto result = xessDestroyContext(deviceContext->XessContext); + deviceContext->XessContext = nullptr; + LOG("NVSDK_NGX_D3D11_ReleaseFeature: xessDestroyContext result: " + ResultToString(result), LEVEL_DEBUG); + } - auto deviceContext = CyberXessContext::instance()->Contexts[InHandle->Id].get(); CyberXessContext::instance()->DeleteContext(InHandle); + + if (CyberXessContext::instance()->Contexts.empty()) + { + ReleaseSharedResources(); + CyberXessContext::instance()->Shutdown(true, false); + + } + + isDeviceBusy.store(false); + return NVSDK_NGX_Result_Success; } @@ -138,6 +1102,530 @@ NVSDK_NGX_Result NVSDK_NGX_D3D11_GetFeatureRequirements(IDXGIAdapter* Adapter, c NVSDK_NGX_Result NVSDK_NGX_D3D11_EvaluateFeature(ID3D11DeviceContext* InDevCtx, const NVSDK_NGX_Handle* InFeatureHandle, const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) { - LOG("NVSDK_NGX_D3D11_EvaluateFeature Fail!", LEVEL_DEBUG); - return NVSDK_NGX_Result_FAIL_PlatformError; -} \ No newline at end of file + LOG("NVSDK_NGX_D3D11_EvaluateFeature Handle: " + std::to_string(InFeatureHandle->Id), LEVEL_DEBUG); + + if (!xessActive.load()) + { + ReleaseSharedResources(); + xessActive.store(true); + } + + auto instance = CyberXessContext::instance(); + auto deviceContext = instance->Contexts[InFeatureHandle->Id].get(); + + if (deviceContext == nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature trying to use released handle, returning NVSDK_NGX_Result_Success", LEVEL_DEBUG); + return NVSDK_NGX_Result_Success; + } + + while (isDeviceBusy.load()) + { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + HRESULT result; + + isDeviceBusy.store(true); + + if (instance->Dx11Device == nullptr) + { + InDevCtx->GetDevice((ID3D11Device**)&instance->Dx11Device); + + // No D3D12 device! + if (instance->Dx12Device == nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature no Dx12Device device!", LEVEL_DEBUG); + ReleaseSharedResources(); + + auto fl = CyberXessContext::instance()->Dx11Device->GetFeatureLevel(); + result = CyberXessContext::instance()->CreateDx12Device(fl); + + if (result != S_OK || CyberXessContext::instance()->Dx12Device == nullptr) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_NotInitialized; + } + + LOG("NVSDK_NGX_D3D11_EvaluateFeature no Dx12Device created!", LEVEL_DEBUG); + + } + } + + if (instance->Dx11DeviceContext == nullptr) + { + result = InDevCtx->QueryInterface(IID_PPV_ARGS(&instance->Dx11DeviceContext)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature no ID3D11DeviceContext4 interface!", LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_FeatureNotSupported; + } + } + + auto listIndex = listCount % 2; + + // Command allocator & command list + if (instance->Dx12CommandAllocator[listIndex] == nullptr) + { + // CreateCommandAllocator + result = instance->Dx12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&instance->Dx12CommandAllocator[listIndex])); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandAllocator result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_UnableToInitializeFeature; + } + + // CreateCommandList + result = instance->Dx12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, instance->Dx12CommandAllocator[listIndex], nullptr, IID_PPV_ARGS(&instance->Dx12CommandList[listIndex])); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandList result: " + int_to_hex(result), LEVEL_DEBUG); + + if (result != S_OK) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_UnableToInitializeFeature; + } + } + + // get params from dlss + const auto inParams = static_cast(InParameters); + + // init check + if (!instance->init) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature init is false, calling CreateFeature!", LEVEL_WARNING); + instance->init = CreateFeature11(nullptr, InFeatureHandle); + } + + if (!instance->init) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature init still is null CreateFeature failed!", LEVEL_ERROR); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_UnableToInitializeFeature; + } + + AttachToD3D11(); + + // Fence for syncing + if (d3d12Fence == nullptr) + { + result = instance->Dx12Device->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&d3d12Fence)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateFence d3d12fence result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (fenceHandle == NULL) + { + result = instance->Dx12Device->CreateSharedHandle(d3d12Fence, NULL, GENERIC_ALL, nullptr, &fenceHandle); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateFence fenceHandle result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (d3d11Fence == nullptr) + { + result = instance->Dx11Device->OpenSharedFence(fenceHandle, IID_PPV_ARGS(&d3d11Fence)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateFence d3d11fence result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + // creatimg params for XeSS + xess_result_t xessResult; + + params.jitterOffsetX = inParams->JitterOffsetX; + params.jitterOffsetY = inParams->JitterOffsetY; + + params.exposureScale = inParams->ExposureScale; + params.resetHistory = inParams->ResetRender; + + params.inputWidth = inParams->Width; + params.inputHeight = inParams->Height; + LOG("NVSDK_NGX_D3D11_EvaluateFeature inp width: " + std::to_string(inParams->Width) + " height: " + std::to_string(inParams->Height), LEVEL_DEBUG); + +#pragma region Texture copies + + if (listIndex > 0) + { + auto oldIndex = (listIndex + 1) % 2; + + if (params.pColorTexture != nullptr && params.pColorTexture != NULL) + { + //CloseHandle(colorHandle); + colorHandle = NULL; + } + + if (params.pVelocityTexture != nullptr && params.pVelocityTexture != NULL) + { + //CloseHandle(mvHandle); + mvHandle = NULL; + } + + if (params.pExposureScaleTexture != nullptr && params.pExposureScaleTexture != NULL) + { + //CloseHandle(expHandle); + expHandle = NULL; + } + + if (params.pDepthTexture != nullptr && params.pDepthTexture != NULL) + { + //CloseHandle(depthHandle); + depthHandle = NULL; + } + + if (params.pResponsivePixelMaskTexture != nullptr && params.pResponsivePixelMaskTexture != NULL) + { + //CloseHandle(tmHandle); + tmHandle = NULL; + } + + if (params.pOutputTexture != nullptr && params.pOutputTexture != NULL) + { + //CloseHandle(outHandle); + outHandle = NULL; + } + } + + if (params.pColorTexture != nullptr && params.pColorTexture != NULL) + params.pColorTexture->Release(); + + if (params.pVelocityTexture != nullptr && params.pVelocityTexture != NULL) + params.pVelocityTexture->Release(); + + if (params.pExposureScaleTexture != nullptr && params.pExposureScaleTexture != NULL) + params.pExposureScaleTexture->Release(); + + if (params.pDepthTexture != nullptr && params.pDepthTexture != NULL) + params.pDepthTexture->Release(); + + if (params.pResponsivePixelMaskTexture != nullptr && params.pResponsivePixelMaskTexture != NULL) + params.pResponsivePixelMaskTexture->Release(); + + if (params.pOutputTexture != nullptr && params.pOutputTexture != NULL) + params.pOutputTexture->Release(); + + ID3D11Query* query1; + D3D11_QUERY_DESC pQueryDesc; + pQueryDesc.Query = D3D11_QUERY_EVENT; + pQueryDesc.MiscFlags = 0; + instance->Dx11Device->CreateQuery(&pQueryDesc, &query1); + + // Associate the query with the copy operation + instance->Dx11DeviceContext->Begin(query1); + + if (inParams->Color != nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Color exist..", LEVEL_DEBUG); + colorHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->Color, &colorShared, COLOR); + + if (colorHandle == NULL) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Color not exist!!", LEVEL_ERROR); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->MotionVectors) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature MotionVectors exist..", LEVEL_DEBUG); + mvHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->MotionVectors, &mvShared, MOTIONV); + + if (mvHandle == NULL) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature MotionVectors not exist!!", LEVEL_ERROR); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->Output) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Output exist..", LEVEL_DEBUG); + outHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->Output, &outShared, OUTPUT); + + if (outHandle == NULL) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Output not exist!!", LEVEL_ERROR); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->Depth) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Depth exist..", LEVEL_DEBUG); + depthHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->Depth, &depthShared, DEPTH); + + if (depthHandle == NULL) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Depth not exist!!", LEVEL_ERROR); + params.pDepthTexture = nullptr; + } + + if (!instance->MyConfig->AutoExposure.value_or(false)) + { + if (inParams->ExposureTexture == nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature AutoExposure disabled but ExposureTexture is not exist, it may cause problems!!", LEVEL_WARNING); + params.pExposureScaleTexture = nullptr; + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature ExposureTexture exist..", LEVEL_DEBUG); + expHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->ExposureTexture, &expShared, EXPOSURE); + + if (expHandle == NULL) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature AutoExposure enabled!", LEVEL_WARNING); + params.pExposureScaleTexture = nullptr; + } + + if (!instance->MyConfig->DisableReactiveMask.value_or(true)) + { + if (inParams->TransparencyMask != nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature TransparencyMask exist..", LEVEL_INFO); + + tmHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->TransparencyMask, &tmShared, TMASK); + + if (tmHandle == NULL) + { + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature TransparencyMask not exist and its enabled in config, it may cause problems!!", LEVEL_WARNING); + params.pResponsivePixelMaskTexture = nullptr; + } + } + else + { + params.pResponsivePixelMaskTexture = nullptr; + } + + // Execute dx11 commands + instance->Dx11DeviceContext->End(query1); + + // Wait for the query to be ready + while (instance->Dx11DeviceContext->GetData(query1, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH) == S_FALSE) { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + // Release the query + query1->Release(); + + // Signal for copy & share complete + instance->Dx11DeviceContext->Signal(d3d11Fence, 10); + + if (instance->Dx12CommandQueue == nullptr) + LOG("NVSDK_NGX_D3D11_EvaluateFeature where is Dx12CommandQueue!!", LEVEL_WARNING); + + if (inParams->Color) + { + result = instance->Dx12Device->OpenSharedHandle(colorHandle, IID_PPV_ARGS(¶ms.pColorTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Color OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (inParams->MotionVectors) + { + result = instance->Dx12Device->OpenSharedHandle(mvHandle, IID_PPV_ARGS(¶ms.pVelocityTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature MotionVectors OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (inParams->Output) + { + result = instance->Dx12Device->OpenSharedHandle(outHandle, IID_PPV_ARGS(¶ms.pOutputTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Output OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (inParams->Depth && !instance->MyConfig->DisplayResolution.value_or(false)) + { + result = instance->Dx12Device->OpenSharedHandle(depthHandle, IID_PPV_ARGS(¶ms.pDepthTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Depth OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (!instance->MyConfig->AutoExposure.value_or(false) && inParams->ExposureTexture != nullptr) + { + result = instance->Dx12Device->OpenSharedHandle(expHandle, IID_PPV_ARGS(¶ms.pExposureScaleTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature ExposureTexture OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (!instance->MyConfig->DisableReactiveMask.value_or(true) && inParams->TransparencyMask != nullptr) + { + result = instance->Dx12Device->OpenSharedHandle(tmHandle, IID_PPV_ARGS(¶ms.pResponsivePixelMaskTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature TransparencyMask OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + +#pragma endregion + + LOG("NVSDK_NGX_D3D11_EvaluateFeature mvscale x: " + std::to_string(inParams->MVScaleX) + " y: " + std::to_string(inParams->MVScaleY), LEVEL_DEBUG); + xessResult = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + + if (xessResult != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature xessSetVelocityScale : " + ResultToString(xessResult), LEVEL_ERROR); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_Fail; + } + + // wait for copy + instance->Dx12CommandQueue->Wait(d3d12Fence, 10); + + // Execute xess + LOG("NVSDK_NGX_D3D11_EvaluateFeature Executing!!", LEVEL_INFO); + xessResult = xessD3D12Execute(deviceContext->XessContext, instance->Dx12CommandList[listIndex], ¶ms); + + if (xessResult != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature xessD3D12Execute result: " + ResultToString(xessResult), LEVEL_INFO); + ReleaseSharedResources(); + isDeviceBusy.store(false); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + + } + + // Execute dx12 commands to process xess + instance->Dx12CommandList[listIndex]->Close(); + ID3D12CommandList* ppCommandLists[] = { instance->Dx12CommandList[listIndex] }; + instance->Dx12CommandQueue->ExecuteCommandLists(1, ppCommandLists); + + // xess done + instance->Dx12CommandQueue->Signal(d3d12Fence, 20); + + //// wait for end of copy + auto fenceEvent12 = CreateEvent(nullptr, FALSE, FALSE, nullptr); + d3d11Fence->SetEventOnCompletion(20, fenceEvent12); + WaitForSingleObject(fenceEvent12, INFINITE); + CloseHandle(fenceEvent12); + + //copy output back + if (outShared != inParams->Output) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Copy back!", LEVEL_DEBUG); + ID3D11Query* query; + D3D11_QUERY_DESC pQueryDesc; + pQueryDesc.Query = D3D11_QUERY_EVENT; + pQueryDesc.MiscFlags = 0; + instance->Dx11Device->CreateQuery(&pQueryDesc, &query); + + // Associate the query with the copy operation + instance->Dx11DeviceContext->Begin(query); + instance->Dx11DeviceContext->CopyResource((ID3D11Resource*)inParams->Output, outShared); + instance->Dx11DeviceContext->End(query); + + // Wait for the query to be ready + while (instance->Dx11DeviceContext->GetData(query, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH) == S_FALSE) { + std::this_thread::yield(); // Yield to reduce CPU usage + } + + // Release the query + query->Release(); + + //instance->Dx11DeviceContext->CopyResource((ID3D11Resource*)inParams->Output, outShared); + //instance->Dx11DeviceContext->Flush(); + //instance->Dx11DeviceContext->Signal(d3d11Fence, 30); + + ////// wait for end of copy + //auto fenceEvent11 = CreateEvent(nullptr, FALSE, FALSE, nullptr); + //d3d12Fence->SetEventOnCompletion(30, fenceEvent11); + //WaitForSingleObject(fenceEvent11, INFINITE); + //CloseHandle(fenceEvent11); + } + + LOG("NVSDK_NGX_D3D11_EvaluateFeature Frame Ready: " + std::to_string(listCount), LEVEL_DEBUG); + + instance->Dx12CommandAllocator[listIndex]->Reset(); + instance->Dx12CommandList[listIndex]->Reset(instance->Dx12CommandAllocator[listIndex], nullptr); + + listCount++; + + isDeviceBusy.store(false); + + return NVSDK_NGX_Result_Success; +} + +#pragma endregion + diff --git a/CyberXeSS/CyberXessDx12.cpp b/CyberXeSS/CyberXessDx12.cpp index c1ecb6f7..785cf3d8 100644 --- a/CyberXeSS/CyberXessDx12.cpp +++ b/CyberXeSS/CyberXessDx12.cpp @@ -3,48 +3,13 @@ #include "CyberXess.h" #include "Util.h" -static int cnt = 0; -xess_dump_parameters_t dumpParams = {}; - inline void LogCallback(const char* Message, xess_logging_level_t Level) { std::string s = Message; LOG("XeSS Runtime (" + std::to_string(Level) + ") : " + s, LEVEL_DEBUG); } -const std::string ResultToString(xess_result_t result) -{ - switch (result) - { - case XESS_RESULT_WARNING_NONEXISTING_FOLDER: return "Warning Nonexistent Folder"; - case XESS_RESULT_WARNING_OLD_DRIVER: return "Warning Old Driver"; - case XESS_RESULT_SUCCESS: return "Success"; - case XESS_RESULT_ERROR_UNSUPPORTED_DEVICE: return "Unsupported Device"; - case XESS_RESULT_ERROR_UNSUPPORTED_DRIVER: return "Unsupported Driver"; - case XESS_RESULT_ERROR_UNINITIALIZED: return "Uninitialized"; - case XESS_RESULT_ERROR_INVALID_ARGUMENT: return "Invalid Argument"; - case XESS_RESULT_ERROR_DEVICE_OUT_OF_MEMORY: return "Device Out of Memory"; - case XESS_RESULT_ERROR_DEVICE: return "Device Error"; - case XESS_RESULT_ERROR_NOT_IMPLEMENTED: return "Not Implemented"; - case XESS_RESULT_ERROR_INVALID_CONTEXT: return "Invalid Context"; - case XESS_RESULT_ERROR_OPERATION_IN_PROGRESS: return "Operation in Progress"; - case XESS_RESULT_ERROR_UNSUPPORTED: return "Unsupported"; - case XESS_RESULT_ERROR_CANT_LOAD_LIBRARY: return "Cannot Load Library"; - case XESS_RESULT_ERROR_UNKNOWN: - default: return "Unknown"; - } -} - -FeatureContext* CreateContext(NVSDK_NGX_Handle** OutHandle) -{ - auto instance = CyberXessContext::instance(); - auto deviceContext = instance->CreateContext(); - *OutHandle = &deviceContext->Handle; - - return deviceContext; -} - -bool CreateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* handle) +static bool CreateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* handle) { LOG("NVSDK_NGX_D3D12_CreateFeature Start!", LEVEL_INFO); @@ -65,26 +30,27 @@ bool CreateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* #pragma endregion - if (InCmdList == nullptr) - { - LOG("NVSDK_NGX_D3D12_CreateFeature InCmdList is null!!!", LEVEL_ERROR); - return false; - } - #pragma region Check for Dx12Device Device if (CyberXessContext::instance()->Dx12Device == nullptr) { - LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device is null trying to get from InCmdList!", LEVEL_WARNING); - InCmdList->GetDevice(IID_PPV_ARGS(&CyberXessContext::instance()->Dx12Device)); + if (InCmdList == nullptr && CyberXessContext::instance()->Dx11Device != nullptr) + { + LOG("NVSDK_NGX_D3D12_CreateFeature InCmdList is null!!!", LEVEL_ERROR); + auto fl = CyberXessContext::instance()->Dx11Device->GetFeatureLevel(); + CyberXessContext::instance()->CreateDx12Device(fl); + } + else + { + LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device is null trying to get from InCmdList!", LEVEL_WARNING); + InCmdList->GetDevice(IID_PPV_ARGS(&CyberXessContext::instance()->Dx12Device)); + } if (CyberXessContext::instance()->Dx12Device == nullptr) { LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device can't receive from InCmdList!", LEVEL_ERROR); return false; } - else - LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device received from InCmdList!", LEVEL_WARNING); } else LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device is OK!", LEVEL_DEBUG); @@ -105,18 +71,25 @@ bool CreateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* if (deviceContext->XessContext != nullptr) { LOG("NVSDK_NGX_D3D12_CreateFeature Destrying old XeSSContext", LEVEL_WARNING); - auto dStatus = xessDestroyContext(deviceContext->XessContext); - LOG("NVSDK_NGX_D3D12_CreateFeature xessDestroyContext result -> " + ResultToString(dStatus), LEVEL_WARNING); + ret = xessDestroyContext(deviceContext->XessContext); + LOG("NVSDK_NGX_D3D12_CreateFeature xessDestroyContext result -> " + ResultToString(ret), LEVEL_WARNING); } - auto status = xessD3D12CreateContext(CyberXessContext::instance()->Dx12Device, &deviceContext->XessContext); - LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12CreateContext result -> " + ResultToString(status), LEVEL_INFO); + if (CyberXessContext::instance()->Dx12Device == nullptr && CyberXessContext::instance()->Dx11Device != nullptr) + { + LOG("NVSDK_NGX_D3D12_CreateFeature InCmdList is null!!!", LEVEL_ERROR); + auto fl = CyberXessContext::instance()->Dx11Device->GetFeatureLevel(); + CyberXessContext::instance()->CreateDx12Device(fl); + } - status = xessSetLoggingCallback(deviceContext->XessContext, XESS_LOGGING_LEVEL_DEBUG, LogCallback); - LOG("NVSDK_NGX_D3D12_CreateFeature xessSetLoggingCallback : " + ResultToString(status), LEVEL_DEBUG); + ret = xessD3D12CreateContext(CyberXessContext::instance()->Dx12Device, &deviceContext->XessContext); + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12CreateContext result -> " + ResultToString(ret), LEVEL_INFO); - status = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); - LOG("NVSDK_NGX_D3D12_CreateFeature xessSetVelocityScale : " + ResultToString(status), LEVEL_DEBUG); + ret = xessSetLoggingCallback(deviceContext->XessContext, XESS_LOGGING_LEVEL_DEBUG, LogCallback); + LOG("NVSDK_NGX_D3D12_CreateFeature xessSetLoggingCallback : " + ResultToString(ret), LEVEL_DEBUG); + + ret = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + LOG("NVSDK_NGX_D3D12_CreateFeature xessSetVelocityScale : " + ResultToString(ret), LEVEL_DEBUG); #pragma region Create Parameters for XeSS @@ -205,11 +178,11 @@ bool CreateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* { LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12BuildPipelines start!", LEVEL_DEBUG); - status = xessD3D12BuildPipelines(deviceContext->XessContext, NULL, false, initParams.initFlags); + ret = xessD3D12BuildPipelines(deviceContext->XessContext, NULL, false, initParams.initFlags); - if (status != XESS_RESULT_SUCCESS) + if (ret != XESS_RESULT_SUCCESS) { - LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12BuildPipelines error : -> " + ResultToString(status), LEVEL_ERROR); + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12BuildPipelines error : -> " + ResultToString(ret), LEVEL_ERROR); return false; } } @@ -226,50 +199,58 @@ bool CreateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* LOG("NVSDK_NGX_D3D12_CreateFeature xessSelectNetworkModel trying to set value to " + std::to_string(model), LEVEL_DEBUG); - status = xessSelectNetworkModel(deviceContext->XessContext, model); + ret = xessSelectNetworkModel(deviceContext->XessContext, model); - if (status == XESS_RESULT_SUCCESS) + if (ret == XESS_RESULT_SUCCESS) LOG("NVSDK_NGX_D3D12_CreateFeature xessSelectNetworkModel set to " + std::to_string(model), LEVEL_DEBUG); else - LOG("NVSDK_NGX_D3D12_CreateFeature xessSelectNetworkModel(" + std::to_string(model) + ") error : " + ResultToString(status), LEVEL_ERROR); + LOG("NVSDK_NGX_D3D12_CreateFeature xessSelectNetworkModel(" + std::to_string(model) + ") error : " + ResultToString(ret), LEVEL_ERROR); #pragma endregion - LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12Init start!", LEVEL_DEBUG); - status = xessD3D12Init(deviceContext->XessContext, &initParams); + ret = xessD3D12Init(deviceContext->XessContext, &initParams); - if (status != XESS_RESULT_SUCCESS) + if (ret != XESS_RESULT_SUCCESS) { - LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12Init error : -> " + ResultToString(status), LEVEL_ERROR); + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12Init error: " + ResultToString(ret), LEVEL_ERROR); + CyberXessContext::instance()->init = false; return false; } LOG("NVSDK_NGX_D3D12_CreateFeature End!", LEVEL_DEBUG); + CyberXessContext::instance()->init = true; + return true; } +FeatureContext* CreateContext(NVSDK_NGX_Handle** OutHandle) +{ + auto deviceContext = CyberXessContext::instance()->CreateContext(); + *OutHandle = &deviceContext->Handle; + return deviceContext; +} + #pragma region DLSS Init Calls NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, - ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion, - unsigned long long unknown0) + ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion, unsigned long long unknown0) { + LOG("XeSS DelayedInit : " + std::to_string(CyberXessContext::instance()->MyConfig->DelayedInit.value_or(false)), LEVEL_INFO); + LOG("XeSS BuildPipelines : " + std::to_string(CyberXessContext::instance()->MyConfig->BuildPipelines.value_or(true)), LEVEL_INFO); + LOG("XeSS NetworkModel : " + std::to_string(CyberXessContext::instance()->MyConfig->NetworkModel.value_or(0)), LEVEL_INFO); + LOG("XeSS LogFile : " + CyberXessContext::instance()->MyConfig->LogFile.value_or(""), LEVEL_INFO); + LOG("XeSS LogLevel : " + std::to_string(CyberXessContext::instance()->MyConfig->LogLevel.value_or(1)), LEVEL_INFO); + LOG("XeSS XeSSLogging : " + std::to_string(CyberXessContext::instance()->MyConfig->XeSSLogging.value_or(true)), LEVEL_INFO); + LOG("NVSDK_NGX_D3D12_Init_Ext AppId:" + std::to_string(InApplicationId), LEVEL_DEBUG); LOG("NVSDK_NGX_D3D12_Init_Ext SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); - LOG("Logger DelayedInit : " + std::to_string(CyberXessContext::instance()->MyConfig->DelayedInit.value_or(false)), LEVEL_INFO); - LOG("Logger BuildPipelines : " + std::to_string(CyberXessContext::instance()->MyConfig->BuildPipelines.value_or(true)), LEVEL_INFO); - LOG("Logger NetworkModel : " + std::to_string(CyberXessContext::instance()->MyConfig->NetworkModel.value_or(0)), LEVEL_INFO); - LOG("Logger LogFile : " + CyberXessContext::instance()->MyConfig->LogFile.value_or(""), LEVEL_INFO); - LOG("Logger LogLevel : " + std::to_string(CyberXessContext::instance()->MyConfig->LogLevel.value_or(1)), LEVEL_INFO); - LOG("Logger XeSSLogging : " + std::to_string(CyberXessContext::instance()->MyConfig->XeSSLogging.value_or(true)), LEVEL_INFO); - CyberXessContext::instance()->init = false; - CyberXessContext::instance()->Dx12Device = nullptr; + CyberXessContext::instance()->Shutdown(true, true); if (InDevice) { @@ -277,7 +258,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApp LOG("NVSDK_NGX_D3D12_Init_Ext Dx12Device assigned...", LEVEL_DEBUG); } else - LOG("NVSDK_NGX_D3D12_Init_Ext Dx12Device is already assigned or InDevice is null!!!!", LEVEL_ERROR); + LOG("NVSDK_NGX_D3D12_Init_Ext InDevice is null!!!!", LEVEL_ERROR); return NVSDK_NGX_Result_Success; } @@ -319,8 +300,13 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void) { LOG("NVSDK_NGX_D3D12_Shutdown", LEVEL_DEBUG); - CyberXessContext::instance()->Dx12Device = nullptr; + CyberXessContext::instance()->Shutdown(false, true); CyberXessContext::instance()->NvParameterInstance->Params.clear(); + + for (auto const& [key, val] : CyberXessContext::instance()->Contexts) { + NVSDK_NGX_D3D12_ReleaseFeature(&val->Handle); + } + CyberXessContext::instance()->Contexts.clear(); return NVSDK_NGX_Result_Success; @@ -330,10 +316,14 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown1(ID3D12Device* InDevice) { LOG("NVSDK_NGX_D3D12_Shutdown1", LEVEL_DEBUG); - CyberXessContext::instance()->Dx12Device = nullptr; + CyberXessContext::instance()->Shutdown(false, true); CyberXessContext::instance()->NvParameterInstance->Params.clear(); CyberXessContext::instance()->Contexts.clear(); + for (auto const& [key, val] : CyberXessContext::instance()->Contexts) { + NVSDK_NGX_D3D12_ReleaseFeature(&val->Handle); + } + return NVSDK_NGX_Result_Success; } @@ -381,8 +371,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_DestroyParameters(NVSDK_NGX_Param #pragma region DLSS Feature Calls -NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList* InCmdList, NVSDK_NGX_Feature InFeatureID, - NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList* InCmdList, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) { auto context = CreateContext(OutHandle); CyberXessContext::instance()->CreateFeatureParams = static_cast(InParameters); @@ -390,9 +379,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsComma if (CyberXessContext::instance()->MyConfig->DelayedInit.value_or(false)) return NVSDK_NGX_Result_Success; - auto result = CreateFeature(InCmdList, &context->Handle); - - if (result) + if (CreateFeature(InCmdList, &context->Handle)) return NVSDK_NGX_Result_Success; LOG("NVSDK_NGX_D3D12_CreateFeature: CreateFeature failed", LEVEL_ERROR); @@ -404,9 +391,18 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_ReleaseFeature(NVSDK_NGX_Handle* { LOG("NVSDK_NGX_D3D12_ReleaseFeature!", LEVEL_DEBUG); - auto deviceContext = CyberXessContext::instance()->Contexts[InHandle->Id].get(); - auto result = xessDestroyContext(deviceContext->XessContext); + if (auto deviceContext = CyberXessContext::instance()->Contexts[InHandle->Id].get(); deviceContext->XessContext != nullptr) + { + auto result = xessDestroyContext(deviceContext->XessContext); + deviceContext->XessContext = nullptr; + LOG("NVSDK_NGX_D3D11_ReleaseFeature: xessDestroyContext result: " + ResultToString(result), LEVEL_DEBUG); + } + CyberXessContext::instance()->DeleteContext(InHandle); + + if (CyberXessContext::instance()->Contexts.empty()) + CyberXessContext::instance()->Shutdown(false, true); + return NVSDK_NGX_Result_Success; } @@ -423,8 +419,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_GetFeatureRequirements(IDXGIAdapt return NVSDK_NGX_Result_Success; } -NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* InFeatureHandle, - const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* InFeatureHandle, const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) { LOG("NVSDK_NGX_D3D12_EvaluateFeature init!", LEVEL_DEBUG); @@ -438,16 +433,15 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom LOG("NVSDK_NGX_D3D12_EvaluateFeature callback exist", LEVEL_WARNING); const auto inParams = static_cast(InParameters); + const auto instance = CyberXessContext::instance(); - auto instance = CyberXessContext::instance(); - - if (!CyberXessContext::instance()->init) + if (!instance->init) { LOG("NVSDK_NGX_D3D12_EvaluateFeature init is false, calling CreateFeature!", LEVEL_WARNING); - CyberXessContext::instance()->init = CreateFeature(InCmdList, InFeatureHandle); + instance->init = CreateFeature(InCmdList, InFeatureHandle); } - if (!CyberXessContext::instance()->init) + if (!instance->init) { LOG("NVSDK_NGX_D3D12_EvaluateFeature init still is null CreateFeature failed!", LEVEL_ERROR); return NVSDK_NGX_Result_Fail; @@ -461,6 +455,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom //xessStartDump(deviceContext->XessContext, &dumpParams); // creatimg params for XeSS + xess_result_t xessResult; xess_d3d12_execute_params_t params{}; params.jitterOffsetX = inParams->JitterOffsetX; @@ -474,7 +469,8 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom LOG("NVSDK_NGX_D3D12_EvaluateFeature inp width: " + std::to_string(inParams->Width) + " height: " + std::to_string(inParams->Height), LEVEL_DEBUG); - if (inParams->Color) + + if (inParams->Color != nullptr) { LOG("NVSDK_NGX_D3D12_EvaluateFeature Color exist..", LEVEL_DEBUG); params.pColorTexture = (ID3D12Resource*)inParams->Color; @@ -507,14 +503,14 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom return NVSDK_NGX_Result_FAIL_InvalidParameter; } - if (inParams->Depth && !CyberXessContext::instance()->MyConfig->DisplayResolution.value_or(false)) + if (inParams->Depth) { LOG("NVSDK_NGX_D3D12_EvaluateFeature Depth exist..", LEVEL_INFO); params.pDepthTexture = (ID3D12Resource*)inParams->Depth; } else { - if (!CyberXessContext::instance()->MyConfig->DisplayResolution.value_or(false)) + if (!instance->MyConfig->DisplayResolution.value_or(false)) LOG("NVSDK_NGX_D3D12_EvaluateFeature Depth not exist!!", LEVEL_ERROR); else LOG("NVSDK_NGX_D3D12_EvaluateFeature Using high res motion vectors, depth is not needed!!", LEVEL_INFO); @@ -522,7 +518,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom params.pDepthTexture = nullptr; } - if (!CyberXessContext::instance()->MyConfig->AutoExposure.value_or(false)) + if (!instance->MyConfig->AutoExposure.value_or(false)) { if (inParams->ExposureTexture == nullptr) { @@ -533,7 +529,6 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom { LOG("NVSDK_NGX_D3D12_EvaluateFeature ExposureTexture exist..", LEVEL_INFO); params.pExposureScaleTexture = (ID3D12Resource*)inParams->ExposureTexture; - } } else @@ -542,7 +537,7 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom params.pExposureScaleTexture = nullptr; } - if (!CyberXessContext::instance()->MyConfig->DisableReactiveMask.value_or(true)) + if (!instance->MyConfig->DisableReactiveMask.value_or(true)) { if (inParams->TransparencyMask != nullptr) { @@ -561,20 +556,20 @@ NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCom } LOG("NVSDK_NGX_D3D12_EvaluateFeature mvscale x: " + std::to_string(inParams->MVScaleX) + " y: " + std::to_string(inParams->MVScaleY), LEVEL_DEBUG); - auto vResult = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + xessResult = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); - if (vResult != XESS_RESULT_SUCCESS) + if (xessResult != XESS_RESULT_SUCCESS) { - LOG("NVSDK_NGX_D3D12_EvaluateFeature xessSetVelocityScale : " + ResultToString(vResult), LEVEL_ERROR); + LOG("NVSDK_NGX_D3D12_EvaluateFeature xessSetVelocityScale : " + ResultToString(xessResult), LEVEL_ERROR); return NVSDK_NGX_Result_Fail; } LOG("NVSDK_NGX_D3D12_EvaluateFeature Executing!!", LEVEL_INFO); - vResult = xessD3D12Execute(deviceContext->XessContext, InCmdList, ¶ms); + xessResult = xessD3D12Execute(deviceContext->XessContext, InCmdList, ¶ms); - if (vResult != XESS_RESULT_SUCCESS) + if (xessResult != XESS_RESULT_SUCCESS) { - LOG("xessD3D12Execute error : -> " + ResultToString(vResult), LEVEL_ERROR); + LOG("xessD3D12Execute error : -> " + ResultToString(xessResult), LEVEL_ERROR); return NVSDK_NGX_Result_Fail; } diff --git a/CyberXeSS/Detours.h b/CyberXeSS/Detours.h new file mode 100644 index 00000000..f6eac645 --- /dev/null +++ b/CyberXeSS/Detours.h @@ -0,0 +1,134 @@ +#pragma once + +#include + +namespace Detours +{ + static_assert(sizeof(uintptr_t) == sizeof(void *)); + + const static uint32_t DISASM_MAX_INSTRUCTIONS = 50; // Maximum number of instructions to decode at once + + const static uint32_t OPT_MASK = 0xFFF; // Mask for all options + const static uint32_t OPT_NONE = 0x000; // No options + const static uint32_t OPT_BREAK_ON_FAIL = 0x001; // Throw INT3 on failure + const static uint32_t OPT_DO_NOT_PAD_NOPS = 0x002; // Don't pad replaced instructions with NOPs + + struct JumpTrampolineHeader + { + uint32_t Magic; // Used to verify the header + uint32_t Random; // Variable to change the code/data hash + + uintptr_t CodeOffset; // Offset, in code, that was hooked: "target" + uintptr_t DetourOffset; // User function that is called: "destination" + + uintptr_t InstructionLength;// Length of the instructions that were replaced + uintptr_t InstructionOffset;// Where the backed-up instructions are + + uintptr_t TrampolineLength; // Length of the trampoline + uintptr_t TrampolineOffset; // Code offset where 'jmp (q/d)word ptr ' occurs + + // Anything after this struct is null data or pure code (instructions/trampoline) + }; + + void SetGlobalOptions(uint32_t Options); + uint32_t GetGlobalOptions(); + + uint64_t DetourAlignAddress(uint64_t Address, uint8_t Align); + + bool DetourCopyMemory(uintptr_t Target, uintptr_t Memory, size_t Length); + bool DetourFlushCache(uintptr_t Target, size_t Length); + uintptr_t IATHook(uintptr_t Module, const char *ImportModule, const char *API, uintptr_t Detour); + uintptr_t IATDelayedHook(uintptr_t Module, const char *ImportModule, const char *API, uintptr_t Detour); + +#ifdef _M_IX86 + enum class X86Option + { + USE_JUMP, // jmp
; + USE_CALL, // call
; + USE_PUSH_RET, // push
; retn; + }; + + namespace X86 + { + // Redirects a single static function to another + uintptr_t DetourFunction(uintptr_t Target, uintptr_t Detour, X86Option Options = X86Option::USE_JUMP); + + // Redirects a class member function (__thiscall) to another + template + uintptr_t DetourFunctionClass(uintptr_t Target, T Detour, X86Option Options = X86Option::USE_JUMP) + { + return DetourFunction(Target, *(uintptr_t *)&Detour, Options); + } + + // Removes a detoured function (Static or class member) + bool DetourRemove(uintptr_t Trampoline); + + // Redirects an index in a virtual table + uintptr_t DetourVTable(uintptr_t Target, uintptr_t Detour, uint32_t TableIndex); + + // Redirects a class member virtual function (__thiscall) to another + template + uintptr_t DetourClassVTable(uintptr_t Target, T Detour, uint32_t TableIndex) + { + return DetourVTable(Target, *(uintptr_t *)&Detour, TableIndex); + } + + // Removes a detoured virtual table index + bool VTableRemove(uintptr_t Target, uintptr_t Function, uint32_t TableIndex); + + void DetourWriteStub(JumpTrampolineHeader *Header); + bool DetourWriteJump(JumpTrampolineHeader *Header); + bool DetourWriteCall(JumpTrampolineHeader *Header); + bool DetourWritePushRet(JumpTrampolineHeader *Header); + + uint32_t DetourGetHookLength(X86Option Options); + } +#endif // _M_IX86 + +#ifdef _M_AMD64 + enum class X64Option + { + USE_PUSH_RET, // push ; [rsp+4h] = ; retn; + USE_RAX_JUMP, // mov rax,
; jmp rax; + USE_REL32_JUMP, // jmp
+ USE_REL32_CALL, // call
+ }; + + namespace X64 + { + // Redirects a single static function to another + uintptr_t DetourFunction(uintptr_t Target, uintptr_t Detour, X64Option Options = X64Option::USE_REL32_JUMP); + + // Redirects a class member function (__thiscall) to another + template + uintptr_t DetourFunctionClass(uintptr_t Target, T Detour, X64Option Options = X64Option::USE_REL32_JUMP) + { + return DetourFunction(Target, *(uintptr_t *)&Detour, Options); + } + + // Removes a detoured function (Static or class member) + bool DetourRemove(uintptr_t Trampoline); + + // Redirects an index in a virtual table + uintptr_t DetourVTable(uintptr_t Target, uintptr_t Detour, uint32_t TableIndex); + + // Redirects a class member virtual function (__thiscall) to another + template + uintptr_t DetourClassVTable(uintptr_t Target, T Detour, uint32_t TableIndex) + { + return DetourVTable(Target, *(uintptr_t *)&Detour, TableIndex); + } + + // Removes a detoured virtual table index + bool VTableRemove(uintptr_t Target, uintptr_t Function, uint32_t TableIndex); + + void DetourWriteStub(JumpTrampolineHeader *Header); + bool DetourWritePushRet(JumpTrampolineHeader *Header); + bool DetourWriteRaxJump(JumpTrampolineHeader *Header); + bool DetourWriteRel32Jump(JumpTrampolineHeader *Header); + bool DetourWriteRel32Call(JumpTrampolineHeader *Header); + + uint32_t DetourGetHookLength(X64Option Options); + } +#endif // _M_AMD64 +} \ No newline at end of file diff --git a/CyberXeSS/NvParameter.cpp b/CyberXeSS/NvParameter.cpp index b9510e87..511660f6 100644 --- a/CyberXeSS/NvParameter.cpp +++ b/CyberXeSS/NvParameter.cpp @@ -231,6 +231,7 @@ NVSDK_NGX_Result NvParameter::Get_Internal(const char* InName, unsigned long lon auto outValueULL = (unsigned long long*)OutValue; //Includes DirectX Resources auto outValuePtr = (void**)OutValue; + const auto params = CyberXessContext::instance()->NvParameterInstance; std::string s; s = InName; @@ -284,7 +285,7 @@ NVSDK_NGX_Result NvParameter::Get_Internal(const char* InName, unsigned long lon *outValuePtr = NVSDK_NGX_DLSS_GetStatsCallback; break; case Util::NvParameter::SizeInBytes: - *outValueULL = 0x1337; //Dummy value + *outValueULL = params->OutHeight * params->OutWidth * 31; //Dummy value break; case Util::NvParameter::OptLevel: *outValueInt = 0; //Dummy value @@ -397,31 +398,32 @@ void NvParameter::EvaluateRenderScale() LOG("EvaluateRenderScale Quality : " + std::to_string(PerfQualityValue), LEVEL_DEBUG); - switch (xessQualityMode) + switch (PerfQualityValue) { - case XESS_QUALITY_SETTING_PERFORMANCE: + case NVSDK_NGX_PerfQuality_Value_UltraPerformance: + OutHeight = (unsigned int)((float)Height / 3.0); + OutWidth = (unsigned int)((float)Width / 3.0); + break; + case NVSDK_NGX_PerfQuality_Value_MaxPerf: OutHeight = (unsigned int)((float)Height / 2.0); OutWidth = (unsigned int)((float)Width / 2.0); break; - - case XESS_QUALITY_SETTING_BALANCED: + case NVSDK_NGX_PerfQuality_Value_Balanced: OutHeight = (unsigned int)((float)Height / 1.699115044247788); OutWidth = (unsigned int)((float)Width / 1.699115044247788); break; - - case XESS_QUALITY_SETTING_QUALITY: + case NVSDK_NGX_PerfQuality_Value_MaxQuality: OutHeight = (unsigned int)((float)Height / 1.5); OutWidth = (unsigned int)((float)Width / 1.5); break; - - case XESS_QUALITY_SETTING_ULTRA_QUALITY: + case NVSDK_NGX_PerfQuality_Value_UltraQuality: OutHeight = (unsigned int)((float)Height / 1.299932295192959); OutWidth = (unsigned int)((float)Width / 1.299932295192959); break; - default: - OutHeight = Height; - OutWidth = Width; + OutHeight = (unsigned int)((float)Height / 1.699115044247788); + OutWidth = (unsigned int)((float)Width / 1.699115044247788); + break; } } diff --git a/CyberXeSS/dllmain.cpp b/CyberXeSS/dllmain.cpp index 19c37623..9ff3c2d8 100644 --- a/CyberXeSS/dllmain.cpp +++ b/CyberXeSS/dllmain.cpp @@ -1,5 +1,6 @@ #include "pch.h" + HMODULE dllModule; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) diff --git a/CyberXeSS/framework.h b/CyberXeSS/framework.h index 22d4b9ae..0aab8481 100644 --- a/CyberXeSS/framework.h +++ b/CyberXeSS/framework.h @@ -4,6 +4,7 @@ #define NOMINMAX #define WIN32_NO_STATUS #include +#include #include #include #include @@ -30,3 +31,4 @@ + diff --git a/CyberXeSS/pch.h b/CyberXeSS/pch.h index 54bfb67a..890b9074 100644 --- a/CyberXeSS/pch.h +++ b/CyberXeSS/pch.h @@ -1,7 +1,7 @@ #pragma once #include "framework.h" -//#define LOGGING_ACTIVE +#define LOGGING_ACTIVE typedef enum _log_level_t { @@ -12,6 +12,15 @@ typedef enum _log_level_t LEVEL_ERROR = 3 } log_level_t; +#define SAFE_RELEASE(p) \ + do \ + { \ + if(p) \ + { \ + (p)->Release(); \ + (p) = NULL; \ + } \ + } while((void)0, 0) #ifdef LOGGING_ACTIVE #define LOG(string, level) logprintf(string, level) @@ -25,7 +34,7 @@ typedef enum _log_level_t #include #include "Config.h" -void logprintf(std::string logMsg, log_level_t level); +void logprintf(std::string logMsg, log_level_t level = LEVEL_DEBUG); void prepareOfs(std::string fileName, log_level_t level); @@ -40,4 +49,30 @@ static inline int64_t GetTicks() return ticks.QuadPart; } +template< typename T > +static inline std::string int_to_hex(T i) +{ + std::stringstream stream; + stream << "0x" + << std::setfill('0') + << std::setw(sizeof(T) * 2) + << std::hex << i; + return stream.str(); +} + +static inline std::string ToString(REFIID guid) +{ + char guid_string[37]; // 32 hex chars + 4 hyphens + null terminator + + snprintf( + guid_string, sizeof(guid_string), + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], + guid.Data4[3], guid.Data4[4], guid.Data4[5], + guid.Data4[6], guid.Data4[7]); + + return guid_string; +} + #endif \ No newline at end of file diff --git a/CyberXeSS_YEDEK/Config.cpp b/CyberXeSS_YEDEK/Config.cpp new file mode 100644 index 00000000..9f996ce2 --- /dev/null +++ b/CyberXeSS_YEDEK/Config.cpp @@ -0,0 +1,153 @@ +#include "pch.h" +#include "Config.h" +#include "Util.h" + +Config::Config(std::wstring fileName) +{ + absoluteFileName = Util::DllPath().parent_path() / fileName; + Reload(); +} + +void Config::Reload() +{ +#ifdef LOGGING_ACTIVE + const auto now = std::chrono::system_clock::now(); + auto str = std::format("{:%d%m%Y_%H%M%OS}", now); + + auto logFile = "./log_xess_" + str + ".log"; + LogLevel = 1; + XeSSLogging = false; +#endif + + NetworkModel = 0; + BuildPipelines = true; + DelayedInit = false; + + if (ini.LoadFile(absoluteFileName.c_str()) == SI_OK) + { + DelayedInit = readBool("XeSS", "DelayedInit"); + BuildPipelines = readBool("XeSS", "BuildPipelines"); + NetworkModel = readInt("XeSS", "NetworkModel"); + +#ifdef LOGGING_ACTIVE + LogFile = readString("XeSS", "LogFile"); + + if (!LogFile.has_value()) + LogFile = logFile; + + XeSSLogging = readBool("XeSS", "XeSSLogging"); + LogLevel = readInt("XeSS", "LogLevel"); + + if (XeSSLogging.value_or(false)) + LogLevel = -1; + + prepareOfs(LogFile.value(), (log_level_t)LogLevel.value()); +#endif + + // Depth + DepthInverted = readBool("Depth", "DepthInverted"); + + // Color + AutoExposure = readBool("Color", "AutoExposure"); + HDR = readBool("Color", "HDR"); + + // MotionVectors + JitterCancellation = readBool("MotionVectors", "JitterCancellation"); + DisplayResolution = readBool("MotionVectors", "DisplayResolution"); + + //Upscale Ratio Override + UpscaleRatioOverrideEnabled = readBool("UpscaleRatio", "UpscaleRatioOverrideEnabled"); + UpscaleRatioOverrideValue = readFloat("UpscaleRatio", "UpscaleRatioOverrideValue"); + + // Quality Overrides + QualityRatioOverrideEnabled = readBool("QualityOverrides", "QualityRatioOverrideEnabled"); + if (QualityRatioOverrideEnabled) { + QualityRatio_UltraQuality = readFloat("QualityOverrides", "QualityRatioUltraQuality"); + QualityRatio_Quality = readFloat("QualityOverrides", "QualityRatioQuality"); + QualityRatio_Balanced = readFloat("QualityOverrides", "QualityRatioBalanced"); + QualityRatio_Performance = readFloat("QualityOverrides", "QualityRatioPerformance"); + QualityRatio_UltraPerformance = readFloat("QualityOverrides", "QualityRatioUltraPerformance"); + } + + DisableReactiveMask = readBool("Hotfix", "DisableReactiveMask"); + } +} + +std::optional Config::readString(std::string section, std::string key, bool lowercase) +{ + std::string value = ini.GetValue(section.c_str(), key.c_str(), "auto"); + + std::string lower = value; + std::transform( + lower.begin(), lower.end(), + lower.begin(), + [](unsigned char c) + { + return std::tolower(c); + } + ); + + if (lower == "auto") + { + return std::nullopt; + } + return lowercase ? lower : value; +} + +std::optional Config::readFloat(std::string section, std::string key) +{ + auto value = readString(section, key); + try + { + return std::stof(value.value()); + } + catch (const std::bad_optional_access&) // missing or auto value + { + return std::nullopt; + } + catch (const std::invalid_argument&) // invalid float string for std::stof + { + return std::nullopt; + } + catch (const std::out_of_range&) // out of range for 32 bit float + { + return std::nullopt; + } +} + +std::optional Config::readInt(std::string section, std::string key) +{ + auto value = readString(section, key); + try + { + return std::stoi(value.value()); + } + catch (const std::bad_optional_access&) // missing or auto value + { + return std::nullopt; + } + catch (const std::invalid_argument&) // invalid float string for std::stof + { + return std::nullopt; + } + catch (const std::out_of_range&) // out of range for 32 bit float + { + return std::nullopt; + } +} + +std::optional Config::readBool(std::string section, std::string key) +{ + auto value = readString(section, key, true); + if (value == "true") + { + return true; + } + else if (value == "false") + { + return false; + } + + return std::nullopt; +} + diff --git a/CyberXeSS_YEDEK/Config.h b/CyberXeSS_YEDEK/Config.h new file mode 100644 index 00000000..ef825540 --- /dev/null +++ b/CyberXeSS_YEDEK/Config.h @@ -0,0 +1,54 @@ +#pragma once +#include "pch.h" + +class Config +{ +public: + Config(std::wstring fileName); + + // Depth + std::optional DepthInverted; + + // Color + std::optional AutoExposure; + std::optional HDR; + + // Motion + std::optional JitterCancellation; + std::optional DisplayResolution; + + // XeSS + std::optional DelayedInit; + std::optional BuildPipelines; + std::optional XeSSLogging; + std::optional LogFile; + std::optional NetworkModel; + std::optional LogLevel; + + // Upscale Ratio Override + std::optional UpscaleRatioOverrideEnabled; + std::optional UpscaleRatioOverrideValue; + + // Quality Overrides + std::optional QualityRatioOverrideEnabled; + std::optional QualityRatio_UltraQuality; + std::optional QualityRatio_Quality; + std::optional QualityRatio_Balanced; + std::optional QualityRatio_Performance; + std::optional QualityRatio_UltraPerformance; + + //Hotfix for Steam Deck + std::optional DisableReactiveMask; + + void Reload(); + +private: + CSimpleIniA ini; + + std::filesystem::path absoluteFileName; + + std::optional readString(std::string section, std::string key, bool lowercase = false); + std::optional readFloat(std::string section, std::string key); + std::optional readInt(std::string section, std::string key); + std::optional readBool(std::string section, std::string key); +}; diff --git a/CyberXeSS_YEDEK/CyberXeSS.vcxproj b/CyberXeSS_YEDEK/CyberXeSS.vcxproj new file mode 100644 index 00000000..bf73ba5e --- /dev/null +++ b/CyberXeSS_YEDEK/CyberXeSS.vcxproj @@ -0,0 +1,202 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {8d2b73fb-eecd-45ce-b8e5-335610462f58} + CyberXeSS + 10.0 + + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + DynamicLibrary + true + v143 + Unicode + + + DynamicLibrary + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + $(SolutionDir)external\simpleini;$(SolutionDir)\external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(VULKAN_SDK)\include;$(XESS_SDK)\inc\xess;$(IncludePath) + $(XESS_SDK)\lib;$(LibraryPath) + + + $(SolutionDir)external\simpleini;$(SolutionDir)\external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(VULKAN_SDK)\include;$(XESS_SDK)\inc\xess;$(IncludePath) + $(XESS_SDK)\lib;$(LibraryPath) + + + $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\vulkan\include;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) + $(SolutionDir)external\xess\lib;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) + nvngx + F:\Games\God of War + + + $(SolutionDir)external\simpleini;$(SolutionDir)external\nvngx_dlss_sdk;$(SolutionDir)external\unordered_dense\include;$(SolutionDir)external\xess\inc\xess;$(SolutionDir)external\vulkan\include;$(IncludePath) + nvngx + $(SolutionDir)external\xess\lib;C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) + + + + Level3 + true + WIN32;_DEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpplatest + + + Windows + true + false + + + + + Level3 + true + true + true + WIN32;NDEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + stdcpplatest + + + Windows + true + true + true + false + + + + + Level3 + true + _DEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + NotUsing + pch.h + true + false + stdcpp20 + + + Windows + true + false + d3d11.lib;dxgi.lib;d3d12.lib;dxguid.lib;libxess.lib;%(AdditionalDependencies) + + + + + Level3 + true + true + NDEBUG;CYBERXESS_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) + true + Use + pch.h + Fast + true + stdcpp20 + + + Windows + true + true + true + false + d3d11.lib;dxgi.lib;d3d12.lib;dxguid.lib;libxess.lib;%(AdditionalDependencies) + UseLinkTimeCodeGeneration + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + \ No newline at end of file diff --git a/CyberXeSS_YEDEK/CyberXeSS.vcxproj.filters b/CyberXeSS_YEDEK/CyberXeSS.vcxproj.filters new file mode 100644 index 00000000..35e23bc2 --- /dev/null +++ b/CyberXeSS_YEDEK/CyberXeSS.vcxproj.filters @@ -0,0 +1,81 @@ + + + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/CyberXeSS_YEDEK/CyberXess.cpp b/CyberXeSS_YEDEK/CyberXess.cpp new file mode 100644 index 00000000..d4def042 --- /dev/null +++ b/CyberXeSS_YEDEK/CyberXess.cpp @@ -0,0 +1,26 @@ +#include "pch.h" +#include "Config.h" +#include "CyberXess.h" +#include "Util.h" + +FeatureContext* CyberXessContext::CreateContext() +{ + auto handleId = rand(); + Contexts[handleId] = std::make_unique(); + Contexts[handleId]->Handle.Id = handleId; + return Contexts[handleId].get(); +} + +void CyberXessContext::DeleteContext(NVSDK_NGX_Handle* handle) +{ + auto handleId = handle->Id; + + auto it = std::find_if(Contexts.begin(), Contexts.end(), + [&handleId](const auto& p) { return p.first == handleId; }); + Contexts.erase(it); +} + +CyberXessContext::CyberXessContext() +{ + MyConfig = std::make_unique(L"nvngx.ini"); +} diff --git a/CyberXeSS_YEDEK/CyberXess.h b/CyberXeSS_YEDEK/CyberXess.h new file mode 100644 index 00000000..839ed406 --- /dev/null +++ b/CyberXeSS_YEDEK/CyberXess.h @@ -0,0 +1,282 @@ +#pragma once +#include "pch.h" +#include "NvParameter.h" +#include "xess_d3d12.h" +#include "xess_debug.h" +#include "WrappedD3D12Device.h" +#include "d3d11on12.h" +#include "d3dx12.h" + +class FeatureContext; + +//Global Context +class CyberXessContext +{ + CyberXessContext(); + + void GetHardwareAdapter(IDXGIFactory1* pFactory, IDXGIAdapter1** ppAdapter, D3D_FEATURE_LEVEL featureLevel, bool requestHighPerformanceAdapter) const + { + *ppAdapter = nullptr; + + IDXGIAdapter1* adapter; + + IDXGIFactory6* factory6; + if (SUCCEEDED(pFactory->QueryInterface(IID_PPV_ARGS(&factory6)))) + { + for ( + UINT adapterIndex = 0; + DXGI_ERROR_NOT_FOUND != factory6->EnumAdapterByGpuPreference( + adapterIndex, + requestHighPerformanceAdapter == true ? DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE : DXGI_GPU_PREFERENCE_UNSPECIFIED, + IID_PPV_ARGS(&adapter)); + ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see whether the adapter supports Direct3D 12, but don't create the + // actual device yet. + + + auto result = D3D12CreateDevice(adapter, featureLevel, _uuidof(ID3D12Device), nullptr); + + if (result == S_FALSE) + break; + } + } + else + { + for (UINT adapterIndex = 0; DXGI_ERROR_NOT_FOUND != pFactory->EnumAdapters1(adapterIndex, &adapter); ++adapterIndex) + { + DXGI_ADAPTER_DESC1 desc; + adapter->GetDesc1(&desc); + + if (desc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't select the Basic Render Driver adapter. + // If you want a software adapter, pass in "/warp" on the command line. + continue; + } + + // Check to see whether the adapter supports Direct3D 12, but don't create the + // actual device yet. + auto result = D3D12CreateDevice(adapter, featureLevel, _uuidof(ID3D12Device), nullptr); + + if (result == S_FALSE) + break; + } + } + + *ppAdapter = adapter; + } + + +public: + std::shared_ptr MyConfig; + + bool init = false; + const NvParameter* CreateFeatureParams; + + // D3D12 stuff + ID3D12Device* Dx12Device = nullptr; + WrappedD3D12Device* Dx12ProxyDevice = nullptr; + + // D3D11 stuff + ID3D11Device5* Dx11Device = nullptr; + ID3D11DeviceContext4* Dx11DeviceContext = nullptr; + + // D3D11on12 stuff + ID3D11On12Device2* Dx11on12Device = nullptr; + ID3D12CommandQueue* Dx12CommandQueue = nullptr; + ID3D12CommandAllocator* Dx12CommandAllocator[2] = { nullptr, nullptr }; + ID3D12GraphicsCommandList* Dx12CommandList[2] = { nullptr, nullptr }; + ID3D12Fence* Dx12Fence = nullptr; + volatile UINT64 Dx12FenceValueCounter = 0; + + // Vulkan stuff + VkDevice VulkanDevice = nullptr; + VkInstance VulkanInstance = nullptr; + VkPhysicalDevice VulkanPhysicalDevice = nullptr; + + std::shared_ptr NvParameterInstance = NvParameter::instance(); + + ankerl::unordered_dense::map > Contexts; + FeatureContext* CreateContext(); + void DeleteContext(NVSDK_NGX_Handle* handle); + + static std::shared_ptr instance() + { + static std::shared_ptr INSTANCE{ std::make_shared(CyberXessContext()) }; + return INSTANCE; + } + + void Shutdown() const + { + CyberXessContext::instance()->Dx12FenceValueCounter = 0; + + if (CyberXessContext::instance()->Dx12Fence != nullptr) + { + CyberXessContext::instance()->Dx12Fence->Release(); + CyberXessContext::instance()->Dx12Fence = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandList[0] != nullptr) + { + CyberXessContext::instance()->Dx12CommandList[0]->Release(); + CyberXessContext::instance()->Dx12CommandList[0] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandList[1] != nullptr) + { + CyberXessContext::instance()->Dx12CommandList[1]->Release(); + CyberXessContext::instance()->Dx12CommandList[1] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandQueue != nullptr) + { + CyberXessContext::instance()->Dx12CommandQueue->Release(); + CyberXessContext::instance()->Dx12CommandQueue = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandAllocator[0] != nullptr) + { + CyberXessContext::instance()->Dx12CommandAllocator[0]->Release(); + CyberXessContext::instance()->Dx12CommandAllocator[0] = nullptr; + } + + if (CyberXessContext::instance()->Dx12CommandAllocator[1] != nullptr) + { + CyberXessContext::instance()->Dx12CommandAllocator[1]->Release(); + CyberXessContext::instance()->Dx12CommandAllocator[1] = nullptr; + } + + if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + { + CyberXessContext::instance()->Dx12ProxyDevice->Release(); + CyberXessContext::instance()->Dx12ProxyDevice = nullptr; + } + + if (CyberXessContext::instance()->Dx12Device != nullptr) + { + CyberXessContext::instance()->Dx12Device->Release(); + CyberXessContext::instance()->Dx12Device = nullptr; + } + + if (CyberXessContext::instance()->Dx11on12Device != nullptr) + { + CyberXessContext::instance()->Dx11on12Device->Release(); + CyberXessContext::instance()->Dx11on12Device = nullptr; + } + + if (CyberXessContext::instance()->Dx11Device != nullptr) + { + CyberXessContext::instance()->Dx11Device->Release(); + CyberXessContext::instance()->Dx11Device = nullptr; + } + + if (CyberXessContext::instance()->Dx11DeviceContext != nullptr) + { + CyberXessContext::instance()->Dx11DeviceContext->Release(); + CyberXessContext::instance()->Dx11DeviceContext = nullptr; + } + + if (CyberXessContext::instance()->VulkanInstance != nullptr) + CyberXessContext::instance()->VulkanInstance = nullptr; + + if (CyberXessContext::instance()->VulkanDevice != nullptr) + CyberXessContext::instance()->VulkanDevice = nullptr; + + if (CyberXessContext::instance()->VulkanPhysicalDevice != nullptr) + CyberXessContext::instance()->VulkanPhysicalDevice = nullptr; + } + + HRESULT CreateDx12Device(D3D_FEATURE_LEVEL featureLevel) + { + HRESULT result; + + IDXGIFactory4* factory; + result = CreateDXGIFactory2(0, IID_PPV_ARGS(&factory)); + + if (result != S_OK) + { + LOG("CreateDx12Device Can't create factory: " + int_to_hex(result)); + return result; + } + + IDXGIAdapter1* hardwareAdapter = nullptr; + GetHardwareAdapter(factory, &hardwareAdapter, featureLevel, true); + + if (hardwareAdapter == nullptr) + { + LOG("CreateDx12Device Can't get hardwareAdapter!"); + return E_NOINTERFACE; + } + + result = D3D12CreateDevice(hardwareAdapter, featureLevel, IID_PPV_ARGS(&Dx12Device)); + + if (result != S_OK) + { + LOG("CreateDx12Device Can't create device: " + int_to_hex(result)); + return result; + } + + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; + queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH; + + // CreateCommandQueue + result = Dx12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&Dx12CommandQueue)); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandQueue result: " + int_to_hex(result)); + + if (result != S_OK || Dx12CommandQueue == nullptr) + return NVSDK_NGX_Result_FAIL_PlatformError; + + + return S_OK; + } +}; + +class FeatureContext +{ +public: + NVSDK_NGX_Handle Handle; + + xess_context_handle_t XessContext = nullptr; + + unsigned int Width{}, Height{}, RenderWidth{}, RenderHeight{}; + NVSDK_NGX_PerfQuality_Value PerfQualityValue = NVSDK_NGX_PerfQuality_Value_Balanced; + float Sharpness = 1.0f; + float MVScaleX{}, MVScaleY{}; + float JitterOffsetX{}, JitterOffsetY{}; +}; + +static std::string ResultToString(xess_result_t result) +{ + switch (result) + { + case XESS_RESULT_WARNING_NONEXISTING_FOLDER: return "Warning Nonexistent Folder"; + case XESS_RESULT_WARNING_OLD_DRIVER: return "Warning Old Driver"; + case XESS_RESULT_SUCCESS: return "Success"; + case XESS_RESULT_ERROR_UNSUPPORTED_DEVICE: return "Unsupported Device"; + case XESS_RESULT_ERROR_UNSUPPORTED_DRIVER: return "Unsupported Driver"; + case XESS_RESULT_ERROR_UNINITIALIZED: return "Uninitialized"; + case XESS_RESULT_ERROR_INVALID_ARGUMENT: return "Invalid Argument"; + case XESS_RESULT_ERROR_DEVICE_OUT_OF_MEMORY: return "Device Out of Memory"; + case XESS_RESULT_ERROR_DEVICE: return "Device Error"; + case XESS_RESULT_ERROR_NOT_IMPLEMENTED: return "Not Implemented"; + case XESS_RESULT_ERROR_INVALID_CONTEXT: return "Invalid Context"; + case XESS_RESULT_ERROR_OPERATION_IN_PROGRESS: return "Operation in Progress"; + case XESS_RESULT_ERROR_UNSUPPORTED: return "Unsupported"; + case XESS_RESULT_ERROR_CANT_LOAD_LIBRARY: return "Cannot Load Library"; + case XESS_RESULT_ERROR_UNKNOWN: + default: return "Unknown"; + } +} \ No newline at end of file diff --git a/CyberXeSS_YEDEK/CyberXessDx11.cpp b/CyberXeSS_YEDEK/CyberXessDx11.cpp new file mode 100644 index 00000000..ce3f6e80 --- /dev/null +++ b/CyberXeSS_YEDEK/CyberXessDx11.cpp @@ -0,0 +1,1054 @@ +#include "pch.h" +#include "Config.h" +#include "CyberXess.h" +#include "Util.h" +//#include "d3dx11tex.h" + +static volatile int listCount = 0; + + + +inline void LogCallback(const char* Message, xess_logging_level_t Level) +{ + std::string s = Message; + LOG("XeSS Runtime (" + std::to_string(Level) + ") : " + s, LEVEL_DEBUG); +} + +static bool CreateFeature11(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* handle) +{ + LOG("NVSDK_NGX_D3D11_CreateFeature Start!", LEVEL_INFO); + +#pragma region Read XeSS Version + + xess_version_t ver; + xess_result_t ret = xessGetVersion(&ver); + + if (ret != XESS_RESULT_SUCCESS) + LOG("NVSDK_NGX_D3D11_CreateFeature error : " + ResultToString(ret), LEVEL_ERROR); + + char buf[128]; + sprintf_s(buf, "%u.%u.%u", ver.major, ver.minor, ver.patch); + + std::string m_VersionStr = buf; + + LOG("NVSDK_NGX_D3D11_CreateFeature XeSS Version - " + m_VersionStr, LEVEL_WARNING); + +#pragma endregion + +#pragma region Check for Dx12Device Device + + if (CyberXessContext::instance()->Dx12Device == nullptr) + { + if (InCmdList == nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature InCmdList is null!!!", LEVEL_ERROR); + return false; + } + + LOG("NVSDK_NGX_D3D11_CreateFeature CyberXessContext::instance()->Dx12Device is null trying to get from InCmdList!", LEVEL_WARNING); + InCmdList->GetDevice(IID_PPV_ARGS(&CyberXessContext::instance()->Dx12Device)); + + if (CyberXessContext::instance()->Dx12Device == nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature CyberXessContext::instance()->Dx12Device can't receive from InCmdList!", LEVEL_ERROR); + return false; + } + else + { + LOG("NVSDK_NGX_D3D11_CreateFeature CyberXessContext::instance()->Dx12Device received from InCmdList!", LEVEL_WARNING); + + CyberXessContext::instance()->Dx12Device->QueryInterface(__uuidof(ID3D12ProxyDevice), (void**)&CyberXessContext::instance()->Dx12ProxyDevice); + + if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + LOG("NVSDK_NGX_D3D11_CreateFeature Dx12ProxyDevice assigned...", LEVEL_DEBUG); + else + LOG("NVSDK_NGX_D3D11_CreateFeature Dx12ProxyDevice not assigned...", LEVEL_DEBUG); + } + } + else + LOG("NVSDK_NGX_D3D11_CreateFeature CyberXessContext::instance()->Dx12Device is OK!", LEVEL_DEBUG); + +#pragma endregion + +#pragma region Check for Dx12ProxyDevice Device + //if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + //{ + // LOG("NVSDK_NGX_D3D11_CreateFeature Dx12ProxyDevice proxy adapter disabling spoofing...", LEVEL_DEBUG); + // IDXGIProxyAdapter* pAdapter = nullptr; + + // if (SUCCEEDED(CyberXessContext::instance()->Dx12ProxyDevice->GetProxyAdapter(&pAdapter)) && pAdapter != nullptr) + // { + // LOG("NVSDK_NGX_D3D11_CreateFeature Dx12ProxyDevice proxy adapter accuired...", LEVEL_DEBUG); + // pAdapter->Spoofing(false); + // LOG("NVSDK_NGX_D3D11_CreateFeature Dx12ProxyDevice proxy adapter spoofing disabled...", LEVEL_DEBUG); + // } + // else + // LOG("NVSDK_NGX_D3D11_CreateFeature Dx12ProxyDevice proxy adapter is null!!!", LEVEL_DEBUG); + //} +#pragma endregion + + auto inParams = CyberXessContext::instance()->CreateFeatureParams; + auto deviceContext = CyberXessContext::instance()->Contexts[handle->Id].get(); + + if (deviceContext == nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature deviceContext is null!", LEVEL_ERROR); + return false; + } + + LOG("NVSDK_NGX_D3D11_CreateFeature deviceContext ok, xessD3D12CreateContext start", LEVEL_DEBUG); + + if (deviceContext->XessContext != nullptr) + { + LOG("NVSDK_NGX_D3D11_CreateFeature Destrying old XeSSContext", LEVEL_WARNING); + ret = xessDestroyContext(deviceContext->XessContext); + LOG("NVSDK_NGX_D3D11_CreateFeature xessDestroyContext result -> " + ResultToString(ret), LEVEL_WARNING); + } + + ret = xessD3D12CreateContext(CyberXessContext::instance()->Dx12Device, &deviceContext->XessContext); + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12CreateContext result -> " + ResultToString(ret), LEVEL_INFO); + + ret = xessSetLoggingCallback(deviceContext->XessContext, XESS_LOGGING_LEVEL_DEBUG, LogCallback); + LOG("NVSDK_NGX_D3D11_CreateFeature xessSetLoggingCallback : " + ResultToString(ret), LEVEL_DEBUG); + + ret = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + LOG("NVSDK_NGX_D3D11_CreateFeature xessSetVelocityScale : " + ResultToString(ret), LEVEL_DEBUG); + +#pragma region Create Parameters for XeSS + + xess_d3d12_init_params_t initParams{}; + + LOG("NVSDK_NGX_D3D11_CreateFeature Params Init!", LEVEL_DEBUG); + initParams.outputResolution.x = inParams->OutWidth; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.outputResolution.x : " + std::to_string(initParams.outputResolution.x), LEVEL_DEBUG); + initParams.outputResolution.y = inParams->OutHeight; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.outputResolution.y : " + std::to_string(initParams.outputResolution.y), LEVEL_DEBUG); + + switch (inParams->PerfQualityValue) + { + case NVSDK_NGX_PerfQuality_Value_UltraPerformance: + initParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_MaxPerf: + initParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_Balanced: + initParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED; + break; + case NVSDK_NGX_PerfQuality_Value_MaxQuality: + initParams.qualitySetting = XESS_QUALITY_SETTING_QUALITY; + break; + case NVSDK_NGX_PerfQuality_Value_UltraQuality: + initParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_QUALITY; + break; + default: + initParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED; //Set out-of-range value for non-existing fsr ultra quality mode + break; + } + + initParams.initFlags = XESS_INIT_FLAG_NONE; + + if (CyberXessContext::instance()->MyConfig->DepthInverted.value_or(inParams->DepthInverted)) + { + initParams.initFlags |= XESS_INIT_FLAG_INVERTED_DEPTH; + CyberXessContext::instance()->MyConfig->DepthInverted = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (DepthInverted) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->AutoExposure.value_or(inParams->AutoExposure)) + { + initParams.initFlags |= XESS_INIT_FLAG_ENABLE_AUTOEXPOSURE; + CyberXessContext::instance()->MyConfig->AutoExposure = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (AutoExposure) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + else + { + initParams.initFlags |= XESS_INIT_FLAG_EXPOSURE_SCALE_TEXTURE; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (!AutoExposure) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + if (!CyberXessContext::instance()->MyConfig->HDR.value_or(!inParams->Hdr)) + { + initParams.initFlags |= XESS_INIT_FLAG_LDR_INPUT_COLOR; + CyberXessContext::instance()->MyConfig->HDR = false; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (HDR) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->JitterCancellation.value_or(inParams->JitterMotion)) + { + initParams.initFlags |= XESS_INIT_FLAG_JITTERED_MV; + CyberXessContext::instance()->MyConfig->JitterCancellation = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (JitterCancellation) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->DisplayResolution.value_or(!inParams->LowRes)) + { + initParams.initFlags |= XESS_INIT_FLAG_HIGH_RES_MV; + CyberXessContext::instance()->MyConfig->DisplayResolution = true; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (LowRes) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + if (!CyberXessContext::instance()->MyConfig->DisableReactiveMask.value_or(true)) + { + initParams.initFlags |= XESS_INIT_FLAG_RESPONSIVE_PIXEL_MASK; + LOG("NVSDK_NGX_D3D11_CreateFeature initParams.initFlags (DisableReactiveMask) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + LOG("NVSDK_NGX_D3D11_CreateFeature Params done!", LEVEL_DEBUG); + +#pragma endregion + +#pragma region Build Pipelines + + if (CyberXessContext::instance()->MyConfig->BuildPipelines.value_or(true)) + { + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12BuildPipelines start!", LEVEL_DEBUG); + + ret = xessD3D12BuildPipelines(deviceContext->XessContext, NULL, false, initParams.initFlags); + + if (ret != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12BuildPipelines error : -> " + ResultToString(ret), LEVEL_ERROR); + return false; + } + } + else + { + LOG("NVSDK_NGX_D3D11_CreateFeature skipping xessD3D12BuildPipelines!", LEVEL_DEBUG); + } + +#pragma endregion + +#pragma region Select Network Model + + auto model = static_cast(CyberXessContext::instance()->MyConfig->NetworkModel.value_or(0)); + + LOG("NVSDK_NGX_D3D11_CreateFeature xessSelectNetworkModel trying to set value to " + std::to_string(model), LEVEL_DEBUG); + + ret = xessSelectNetworkModel(deviceContext->XessContext, model); + + if (ret == XESS_RESULT_SUCCESS) + LOG("NVSDK_NGX_D3D11_CreateFeature xessSelectNetworkModel set to " + std::to_string(model), LEVEL_DEBUG); + else + LOG("NVSDK_NGX_D3D11_CreateFeature xessSelectNetworkModel(" + std::to_string(model) + ") error : " + ResultToString(ret), LEVEL_ERROR); + +#pragma endregion + + + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12Init start!", LEVEL_DEBUG); + + ret = xessD3D12Init(deviceContext->XessContext, &initParams); + + if (ret != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D11_CreateFeature xessD3D12Init error: " + ResultToString(ret), LEVEL_ERROR); + CyberXessContext::instance()->init = false; + return false; + } + + LOG("NVSDK_NGX_D3D11_CreateFeature End!", LEVEL_DEBUG); + + CyberXessContext::instance()->init = true; + return true; +} + +HANDLE CopyTextureFrom11To12(ID3D11Resource* d3d11texture, ID3D11Texture2D** pSharedTexture, bool copyTexture = true, bool save = false) +{ + ID3D11Texture2D* originalTexture = nullptr; + ID3D11Texture2D* sharedTexture = nullptr; + HANDLE handle; + HRESULT result; + + // Get texture + result = d3d11texture->QueryInterface(IID_PPV_ARGS(&originalTexture)); + + if (result != S_OK) + { + LOG("CopyTextureFrom11To12 QueryInterface(texture2d) result: " + int_to_hex(result), LEVEL_DEBUG); + return NULL; + } + + // Get desc of original texture and create shared desc + D3D11_TEXTURE2D_DESC desc; + originalTexture->GetDesc(&desc); + + // if we are lucky maybe it's a shared texture + if ((desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED) == 0) + { + desc.CPUAccessFlags = 0; + desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED; + + if (!copyTexture) + desc.BindFlags |= D3D11_BIND_UNORDERED_ACCESS; + + // Create shared texture + result = CyberXessContext::instance()->Dx11Device->CreateTexture2D(&desc, nullptr, &sharedTexture); + + if (result != S_OK) + { + LOG("CopyTextureFrom11To12 CreateTexture2D result: " + int_to_hex(result), LEVEL_DEBUG); + return NULL; + } + + if (copyTexture) + CyberXessContext::instance()->Dx11DeviceContext->CopyResource(sharedTexture, originalTexture); + + // Query resource + IDXGIResource1* resource; + result = sharedTexture->QueryInterface(IID_PPV_ARGS(&resource)); + + if (result != S_OK) + { + LOG("CopyTextureFrom11To12 QueryInterface(resource) result: " + int_to_hex(result), LEVEL_DEBUG); + return NULL; + } + + // Get shared handle + result = resource->GetSharedHandle(&handle); + + if (result != S_OK) + { + LOG("CopyTextureFrom11To12 GetSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NULL; + } + + resource->Release(); + + *pSharedTexture = sharedTexture; + return handle; + } + else + { + *pSharedTexture = originalTexture; + return nullptr; + } +} + +FeatureContext* CreateContext11(NVSDK_NGX_Handle** OutHandle) +{ + auto deviceContext = CyberXessContext::instance()->CreateContext(); + *OutHandle = &deviceContext->Handle; + return deviceContext; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_Ext(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, ID3D11Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion, unsigned long long unknown0) +{ + LOG("NVSDK_NGX_D3D11_Init_Ext AppId:" + std::to_string(InApplicationId), LEVEL_INFO); + LOG("NVSDK_NGX_D3D11_Init_Ext SDK:" + std::to_string(InSDKVersion), LEVEL_INFO); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_Init(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, ID3D11Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + LOG("NVSDK_NGX_D3D11_Init AppId:" + std::to_string(InApplicationId), LEVEL_DEBUG); + LOG("NVSDK_NGX_D3D11_Init SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_D3D11_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, ID3D11Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + LOG("NVSDK_NGX_D3D11_Init_ProjectID Init!", LEVEL_DEBUG); + std::string pId = InProjectId; + LOG("NVSDK_NGX_D3D11_Init_ProjectID : " + pId, LEVEL_DEBUG); + LOG("NVSDK_NGX_D3D11_Init_ProjectID SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_D3D11_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_Init_with_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, ID3D11Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + std::string pId = InProjectId; + LOG("NVSDK_NGX_D3D11_Init_with_ProjectID : " + pId, LEVEL_DEBUG); + LOG("NVSDK_NGX_D3D11_Init_with_ProjectID SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_D3D11_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); +} + +NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown(void) +{ + LOG("NVSDK_NGX_D3D11_Shutdown", LEVEL_INFO); + + CyberXessContext::instance()->Shutdown(); + + CyberXessContext::instance()->NvParameterInstance->Params.clear(); + CyberXessContext::instance()->Contexts.clear(); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_D3D11_Shutdown1(ID3D11Device* InDevice) +{ + LOG("NVSDK_NGX_D3D11_Shutdown1", LEVEL_INFO); + + CyberXessContext::instance()->Shutdown(); + + CyberXessContext::instance()->NvParameterInstance->Params.clear(); + CyberXessContext::instance()->Contexts.clear(); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_GetParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_D3D11_GetParameters", LEVEL_DEBUG); + + *OutParameters = CyberXessContext::instance()->NvParameterInstance->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +//currently it's kind of hack still needs a proper implementation +NVSDK_NGX_Result NVSDK_NGX_D3D11_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_D3D11_GetCapabilityParameters", LEVEL_DEBUG); + + *OutParameters = NvParameter::instance()->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +//currently it's kind of hack still needs a proper implementation +NVSDK_NGX_Result NVSDK_NGX_D3D11_AllocateParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_D3D11_AllocateParameters", LEVEL_DEBUG); + + *OutParameters = NvParameter::instance()->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +//currently it's kind of hack still needs a proper implementation +NVSDK_NGX_Result NVSDK_NGX_D3D11_DestroyParameters(NVSDK_NGX_Parameter* InParameters) +{ + LOG("NVSDK_NGX_D3D11_DestroyParameters", LEVEL_DEBUG); + + NvParameter::instance()->DeleteParameters((NvParameter*)InParameters); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter* InParameters, size_t* OutSizeInBytes) +{ + LOG("NVSDK_NGX_D3D11_GetScratchBufferSize -> 52428800", LEVEL_WARNING); + + *OutSizeInBytes = 52428800; + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_CreateFeature(ID3D11DeviceContext* InDevCtx, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) +{ + LOG("NVSDK_NGX_D3D11_CreateFeature"); + + HRESULT result; + + ID3D11Device* device; + InDevCtx->GetDevice(&device); + + result = device->QueryInterface(IID_PPV_ARGS(&CyberXessContext::instance()->Dx11Device)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_CreateFeature QueryInterface ID3D11Device5 result: " + int_to_hex(result)); + return NVSDK_NGX_Result_FAIL_PlatformError; + } + +#ifdef D3D11on12 + // D3D11on12 Device + result = CyberXessContext::instance()->Dx11Device->QueryInterface(IID_PPV_ARGS(&CyberXessContext::instance()->Dx11on12Device)); + LOG("NVSDK_NGX_D3D11_CreateFeature query d3d11on12 result: " + int_to_hex(result)); + + if (result != S_OK || CyberXessContext::instance()->Dx11on12Device == nullptr) + return NVSDK_NGX_Result_FAIL_PlatformError; + + // D3D12 Device + result = CyberXessContext::instance()->Dx11on12Device->GetD3D12Device(IID_PPV_ARGS(&CyberXessContext::instance()->Dx12Device)); + LOG("NVSDK_NGX_D3D11_CreateFeature query device12 result: " + int_to_hex(result)); +#else + auto fl = CyberXessContext::instance()->Dx11Device->GetFeatureLevel(); + + result = CyberXessContext::instance()->CreateDx12Device(fl); +#endif // D3D11on12 + + if (result != S_OK || CyberXessContext::instance()->Dx12Device == nullptr) + return NVSDK_NGX_Result_FAIL_PlatformError; + + auto cfResult = NVSDK_NGX_D3D12_CreateFeature(nullptr, InFeatureID, InParameters, OutHandle); + LOG("NVSDK_NGX_D3D11_CreateFeature result: " + int_to_hex(cfResult)); + + return cfResult; +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_ReleaseFeature(NVSDK_NGX_Handle* InHandle) +{ + LOG("NVSDK_NGX_D3D11_ReleaseFeature", LEVEL_DEBUG); + + + auto cfResult = NVSDK_NGX_D3D12_ReleaseFeature(InHandle); + LOG("NVSDK_NGX_D3D11_ReleaseFeature result: " + int_to_hex(cfResult)); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_GetFeatureRequirements(IDXGIAdapter* Adapter, const NVSDK_NGX_FeatureDiscoveryInfo* FeatureDiscoveryInfo, NVSDK_NGX_FeatureRequirement* OutSupported) +{ + LOG("NVSDK_NGX_D3D11_GetFeatureRequirements", LEVEL_DEBUG); + + *OutSupported = NVSDK_NGX_FeatureRequirement(); + OutSupported->FeatureSupported = NVSDK_NGX_FeatureSupportResult_Supported; + OutSupported->MinHWArchitecture = 0; + //Some windows 10 os version + strcpy_s(OutSupported->MinOSVersion, "10.0.19045.2728"); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_NGX_D3D11_EvaluateFeature(ID3D11DeviceContext* InDevCtx, const NVSDK_NGX_Handle* InFeatureHandle, const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) +{ + auto instance = CyberXessContext::instance(); + + // No D3D12 device! + if (instance->Dx12Device == nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature no Dx12Device device!", LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_PlatformError; + } + + HRESULT result; + + InDevCtx->GetDevice((ID3D11Device**)&instance->Dx11Device); + + result = InDevCtx->QueryInterface(IID_PPV_ARGS(&instance->Dx11DeviceContext)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature no ID3D11DeviceContext4 interface!", LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_PlatformError; + } + +#ifdef D3D11on12 + if (instance->Dx12CommandQueue == nullptr) + { + D3D12_COMMAND_QUEUE_DESC queueDesc = {}; + queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_DISABLE_GPU_TIMEOUT; + queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE; + //queueDesc.Priority = D3D12_COMMAND_QUEUE_PRIORITY_HIGH; + + // CreateCommandQueue + result = instance->Dx12Device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&instance->Dx12CommandQueue)); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandQueue result: " + int_to_hex(result)); + + if (result != S_OK || instance->Dx12CommandQueue == nullptr) + return NVSDK_NGX_Result_FAIL_PlatformError; + + // CreateCommandAllocator + result = instance->Dx12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_COMPUTE, IID_PPV_ARGS(&instance->Dx12CommandAllocator)); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandAllocator result: " + int_to_hex(result)); + + if (result != S_OK) + return NVSDK_NGX_Result_FAIL_PlatformError; + + // CreateCommandList + result = instance->Dx12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_COMPUTE, instance->Dx12CommandAllocator, nullptr, IID_PPV_ARGS(&instance->Dx12CommandList)); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandList result: " + int_to_hex(result)); + + if (result != S_OK) + return NVSDK_NGX_Result_FAIL_PlatformError; + } + else + { + instance->Dx12CommandAllocator->Reset(); + instance->Dx12CommandList->Reset(instance->Dx12CommandAllocator, nullptr); + } + + auto eResult = NVSDK_NGX_D3D11_EvaluateFeature(instance->Dx12CommandList, InFeatureHandle, InParameters, InCallback); + LOG("NVSDK_NGX_D3D11_EvaluateFeature result: " + int_to_hex(eResult)); + + instance->Dx12CommandList->Close(); + ID3D12CommandList* ppCommandLists[] = { instance->Dx12CommandList }; + instance->Dx12CommandQueue->ExecuteCommandLists(1, ppCommandLists); + + instance->Dx12FenceValueCounter++; + instance->Dx12Fence->Release(); + + return NVSDK_NGX_Result_Success; +#else + auto listIndex = listCount % 2; + + // Command allocator & command list + if (instance->Dx12CommandAllocator[listIndex] == nullptr) + { + // CreateCommandAllocator + result = instance->Dx12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&instance->Dx12CommandAllocator[listIndex])); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandAllocator result: " + int_to_hex(result)); + + if (result != S_OK) + return NVSDK_NGX_Result_FAIL_PlatformError; + + // CreateCommandList + result = instance->Dx12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, instance->Dx12CommandAllocator[listIndex], nullptr, IID_PPV_ARGS(&instance->Dx12CommandList[listIndex])); + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateCommandList result: " + int_to_hex(result)); + } + + // get params from dlss + const auto inParams = static_cast(InParameters); + + // init check + if (!instance->init) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature init is false, calling CreateFeature!", LEVEL_WARNING); + instance->init = CreateFeature11(nullptr, InFeatureHandle); + } + + if (!instance->init) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature init still is null CreateFeature failed!", LEVEL_ERROR); + return NVSDK_NGX_Result_Fail; + } + + // Get device context + auto deviceContext = instance->Contexts[InFeatureHandle->Id].get(); + + //if (listCount == 1150) + //{ + // xess_dump_parameters_t dumpParams = {}; + // dumpParams.frame_count = 20; + // dumpParams.frame_idx = 1; + // dumpParams.path = "D:\\dmp\\"; + // xessStartDump(deviceContext->XessContext, &dumpParams); + //} + + // Fence for syncing + ID3D12Fence* d3d12Fence; + result = instance->Dx12Device->CreateFence(0, D3D12_FENCE_FLAG_SHARED, IID_PPV_ARGS(&d3d12Fence)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateFence d3d12fence result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + HANDLE fenceHandle = NULL; + result = instance->Dx12Device->CreateSharedHandle(d3d12Fence, NULL, GENERIC_ALL, nullptr, &fenceHandle); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateFence fenceHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + ID3D11Fence* d3d11Fence; + result = instance->Dx11Device->OpenSharedFence(fenceHandle, IID_PPV_ARGS(&d3d11Fence)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature CreateFence d3d11fence result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + instance->Dx12FenceValueCounter++; + + // creatimg params for XeSS + xess_result_t xessResult; + xess_d3d12_execute_params_t params{}; + + params.jitterOffsetX = inParams->JitterOffsetX; + params.jitterOffsetY = inParams->JitterOffsetY; + + params.exposureScale = inParams->ExposureScale; + params.resetHistory = inParams->ResetRender; + + params.inputWidth = inParams->Width; + params.inputHeight = inParams->Height; + LOG("NVSDK_NGX_D3D11_EvaluateFeature inp width: " + std::to_string(inParams->Width) + " height: " + std::to_string(inParams->Height), LEVEL_DEBUG); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Dx11Device CreateQuery result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + +#pragma region Texture copies + + HANDLE colorHandle = NULL; + HANDLE mvHandle = NULL; + HANDLE depthHandle = NULL; + HANDLE outHandle = NULL; + HANDLE tmHandle = NULL; + HANDLE expHandle = NULL; + ID3D11Texture2D* colorShared = nullptr; + ID3D11Texture2D* mvShared = nullptr; + ID3D11Texture2D* depthShared = nullptr; + ID3D11Texture2D* outShared = nullptr; + ID3D11Texture2D* tmShared = nullptr; + ID3D11Texture2D* expShared = nullptr; + + if (inParams->Color != nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Color exist..", LEVEL_DEBUG); + colorHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->Color, &colorShared, true, true); + + if (colorHandle == NULL) + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Color not exist!!", LEVEL_ERROR); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->MotionVectors) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature MotionVectors exist..", LEVEL_DEBUG); + mvHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->MotionVectors, &mvShared); + + if (colorHandle == NULL) + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature MotionVectors not exist!!", LEVEL_ERROR); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->Output) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Output exist..", LEVEL_DEBUG); + outHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->Output, &outShared, false); + + if (outHandle == NULL) + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Output not exist!!", LEVEL_ERROR); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->Depth && !instance->MyConfig->DisplayResolution.value_or(false)) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Depth exist..", LEVEL_DEBUG); + depthHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->Depth, &depthShared); + + if (depthHandle == NULL) + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + else + { + if (!instance->MyConfig->DisplayResolution.value_or(false)) + LOG("NVSDK_NGX_D3D11_EvaluateFeature Depth not exist!!", LEVEL_ERROR); + else + LOG("NVSDK_NGX_D3D11_EvaluateFeature Using high res motion vectors, depth is not needed!!", LEVEL_INFO); + + params.pDepthTexture = nullptr; + } + + if (!instance->MyConfig->AutoExposure.value_or(false)) + { + if (inParams->ExposureTexture == nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature AutoExposure disabled but ExposureTexture is not exist, it may cause problems!!", LEVEL_WARNING); + params.pExposureScaleTexture = nullptr; + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature ExposureTexture exist..", LEVEL_DEBUG); + expHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->ExposureTexture, &expShared, ¶ms.pExposureScaleTexture); + + if (expHandle == NULL) + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature AutoExposure enabled!", LEVEL_WARNING); + params.pExposureScaleTexture = nullptr; + } + + if (!instance->MyConfig->DisableReactiveMask.value_or(true)) + { + if (inParams->TransparencyMask != nullptr) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature TransparencyMask exist..", LEVEL_INFO); + + tmHandle = CopyTextureFrom11To12((ID3D11Resource*)inParams->TransparencyMask, &tmShared); + + if (tmHandle == NULL) + return NVSDK_NGX_Result_FAIL_InvalidParameter; + + } + else + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature TransparencyMask not exist and its enabled in config, it may cause problems!!", LEVEL_WARNING); + params.pResponsivePixelMaskTexture = nullptr; + } + } + else + { + params.pResponsivePixelMaskTexture = nullptr; + } + + // Signal #1 + instance->Dx11DeviceContext->Signal(d3d11Fence, instance->Dx12FenceValueCounter); + + // for fences + + // Wait for Signal #1 + instance->Dx12CommandQueue->Wait(d3d12Fence, instance->Dx12FenceValueCounter); + instance->Dx12FenceValueCounter++; + + if (inParams->Color) + { + result = instance->Dx12Device->OpenSharedHandle(colorHandle, IID_PPV_ARGS(¶ms.pColorTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Color OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (inParams->MotionVectors) + { + result = instance->Dx12Device->OpenSharedHandle(mvHandle, IID_PPV_ARGS(¶ms.pVelocityTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature MotionVectors OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + + if (inParams->Output) + { + result = instance->Dx12Device->OpenSharedHandle(outHandle, IID_PPV_ARGS(¶ms.pOutputTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Output OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (inParams->Depth && !instance->MyConfig->DisplayResolution.value_or(false)) + { + result = instance->Dx12Device->OpenSharedHandle(depthHandle, IID_PPV_ARGS(¶ms.pDepthTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature Depth OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (!instance->MyConfig->AutoExposure.value_or(false) && inParams->ExposureTexture != nullptr) + { + result = instance->Dx12Device->OpenSharedHandle(expHandle, IID_PPV_ARGS(¶ms.pExposureScaleTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature ExposureTexture OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + + if (!instance->MyConfig->DisableReactiveMask.value_or(true) && inParams->TransparencyMask != nullptr) + { + result = instance->Dx12Device->OpenSharedHandle(tmHandle, IID_PPV_ARGS(¶ms.pResponsivePixelMaskTexture)); + + if (result != S_OK) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature TransparencyMask OpenSharedHandle result: " + int_to_hex(result), LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + } + +#pragma endregion + + LOG("NVSDK_NGX_D3D11_EvaluateFeature mvscale x: " + std::to_string(inParams->MVScaleX) + " y: " + std::to_string(inParams->MVScaleY), LEVEL_DEBUG); + xessResult = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + + if (xessResult != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D11_EvaluateFeature xessSetVelocityScale : " + ResultToString(xessResult), LEVEL_ERROR); + return NVSDK_NGX_Result_Fail; + } + + // Transition render targets D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE for XeSS + std::vector transitions = {}; + + if (params.pColorTexture != nullptr) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = params.pColorTexture; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + transitions.push_back(barrier); + } + + if (params.pVelocityTexture != nullptr) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = params.pVelocityTexture; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + transitions.push_back(barrier); + } + + if (params.pDepthTexture != nullptr) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = params.pDepthTexture; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + transitions.push_back(barrier); + } + + if (params.pExposureScaleTexture != nullptr) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = params.pExposureScaleTexture; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + transitions.push_back(barrier); + } + + if (params.pResponsivePixelMaskTexture != nullptr) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = params.pResponsivePixelMaskTexture; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + transitions.push_back(barrier); + } + + if (params.pOutputTexture != nullptr) + { + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = params.pOutputTexture; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_COPY_DEST; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + + transitions.push_back(barrier); + } + + instance->Dx12CommandList[listIndex]->ResourceBarrier((UINT)transitions.size(), transitions.data()); + + // Execute xess + LOG("NVSDK_NGX_D3D11_EvaluateFeature Executing!!", LEVEL_INFO); + xessResult = xessD3D12Execute(deviceContext->XessContext, instance->Dx12CommandList[listIndex], ¶ms); + + NVSDK_NGX_Result evaluateResult = NVSDK_NGX_Result_FAIL_InvalidParameter; + + if (xessResult != XESS_RESULT_SUCCESS) + LOG("NVSDK_NGX_D3D11_EvaluateFeature xessD3D12Execute result: " + ResultToString(xessResult), LEVEL_INFO); + else + { + evaluateResult = NVSDK_NGX_Result_Success; + + // switch back to common + D3D12_RESOURCE_BARRIER barrier = {}; + barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + barrier.Transition.pResource = params.pOutputTexture; + barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_UNORDERED_ACCESS; + barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_COMMON; + barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; + instance->Dx12CommandList[listIndex]->ResourceBarrier(1, &barrier); + + // signal for xess complete to d3d11 for copy back - Signal #2 + instance->Dx12CommandQueue->Signal(d3d12Fence, instance->Dx12FenceValueCounter); + + // Execute dx12 commands to process xess + instance->Dx12CommandList[listIndex]->Close(); + ID3D12CommandList* ppCommandLists[] = { instance->Dx12CommandList[listIndex] }; + instance->Dx12CommandQueue->ExecuteCommandLists(1, ppCommandLists); + + // copy back output texture - Signal #2 + instance->Dx11DeviceContext->Wait(d3d11Fence, instance->Dx12FenceValueCounter); + + // copy output back + instance->Dx11DeviceContext->CopyResource((ID3D11Resource*)inParams->Output, outShared); + + instance->Dx12FenceValueCounter++; + + // Signal #3 + instance->Dx11DeviceContext->Signal(d3d11Fence, instance->Dx12FenceValueCounter); + + // Execute dx11 commands + instance->Dx11DeviceContext->Flush(); + + // Wait for Signal #3 + auto fenceEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); + d3d11Fence->SetEventOnCompletion(instance->Dx12FenceValueCounter, fenceEvent); + WaitForSingleObject(fenceEvent, INFINITE); + CloseHandle(fenceEvent); + } + + + if (colorShared != nullptr) + { + params.pColorTexture->Release(); + colorShared->Release(); + colorShared = nullptr; + } + + if (mvShared != nullptr) + { + params.pVelocityTexture->Release(); + mvShared->Release(); + mvShared = nullptr; + } + + if (expShared != nullptr) + { + params.pExposureScaleTexture->Release(); + expShared->Release(); + expShared = nullptr; + } + + if (depthShared != nullptr) + { + params.pDepthTexture->Release(); + depthShared->Release(); + depthShared = nullptr; + } + + if (tmShared != nullptr) + { + params.pResponsivePixelMaskTexture->Release(); + tmShared->Release(); + tmShared = nullptr; + } + + if (outShared != nullptr) + { + params.pOutputTexture->Release(); + outShared->Release(); + outShared = nullptr; + } + + d3d12Fence->Release(); + d3d11Fence->Release(); + CloseHandle(fenceHandle); + + instance->Dx12CommandAllocator[listIndex]->Reset(); + instance->Dx12CommandList[listIndex]->Reset(instance->Dx12CommandAllocator[listIndex], nullptr); + + listCount++; + + return evaluateResult; +#endif +} + diff --git a/CyberXeSS_YEDEK/CyberXessDx12.cpp b/CyberXeSS_YEDEK/CyberXessDx12.cpp new file mode 100644 index 00000000..4b0b964c --- /dev/null +++ b/CyberXeSS_YEDEK/CyberXessDx12.cpp @@ -0,0 +1,827 @@ +#include "pch.h" +#include "Config.h" +#include "CyberXess.h" +#include "Util.h" + +//static int cnt = 0; + +inline void LogCallback(const char* Message, xess_logging_level_t Level) +{ + std::string s = Message; + LOG("XeSS Runtime (" + std::to_string(Level) + ") : " + s, LEVEL_DEBUG); +} + +static bool CreateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* handle) +{ + LOG("NVSDK_NGX_D3D12_CreateFeature Start!", LEVEL_INFO); + +#pragma region Read XeSS Version + + xess_version_t ver; + xess_result_t ret = xessGetVersion(&ver); + + if (ret != XESS_RESULT_SUCCESS) + LOG("NVSDK_NGX_D3D12_CreateFeature error : " + ResultToString(ret), LEVEL_ERROR); + + char buf[128]; + sprintf_s(buf, "%u.%u.%u", ver.major, ver.minor, ver.patch); + + std::string m_VersionStr = buf; + + LOG("NVSDK_NGX_D3D12_CreateFeature XeSS Version - " + m_VersionStr, LEVEL_WARNING); + +#pragma endregion + +#pragma region Check for Dx12Device Device + + if (CyberXessContext::instance()->Dx12Device == nullptr) + { + if (InCmdList == nullptr) + { + LOG("NVSDK_NGX_D3D12_CreateFeature InCmdList is null!!!", LEVEL_ERROR); + return false; + } + + LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device is null trying to get from InCmdList!", LEVEL_WARNING); + InCmdList->GetDevice(IID_PPV_ARGS(&CyberXessContext::instance()->Dx12Device)); + + if (CyberXessContext::instance()->Dx12Device == nullptr) + { + LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device can't receive from InCmdList!", LEVEL_ERROR); + return false; + } + else + { + LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device received from InCmdList!", LEVEL_WARNING); + + CyberXessContext::instance()->Dx12Device->QueryInterface(__uuidof(ID3D12ProxyDevice), (void**)&CyberXessContext::instance()->Dx12ProxyDevice); + + if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + LOG("NVSDK_NGX_D3D12_CreateFeature Dx12ProxyDevice assigned...", LEVEL_DEBUG); + else + LOG("NVSDK_NGX_D3D12_CreateFeature Dx12ProxyDevice not assigned...", LEVEL_DEBUG); + } + } + else + LOG("NVSDK_NGX_D3D12_CreateFeature CyberXessContext::instance()->Dx12Device is OK!", LEVEL_DEBUG); + +#pragma endregion + +#pragma region Check for Dx12ProxyDevice Device + //if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + //{ + // LOG("NVSDK_NGX_D3D12_CreateFeature Dx12ProxyDevice proxy adapter disabling spoofing...", LEVEL_DEBUG); + // IDXGIProxyAdapter* pAdapter = nullptr; + + // if (SUCCEEDED(CyberXessContext::instance()->Dx12ProxyDevice->GetProxyAdapter(&pAdapter)) && pAdapter != nullptr) + // { + // LOG("NVSDK_NGX_D3D12_CreateFeature Dx12ProxyDevice proxy adapter accuired...", LEVEL_DEBUG); + // pAdapter->Spoofing(false); + // LOG("NVSDK_NGX_D3D12_CreateFeature Dx12ProxyDevice proxy adapter spoofing disabled...", LEVEL_DEBUG); + // } + // else + // LOG("NVSDK_NGX_D3D12_CreateFeature Dx12ProxyDevice proxy adapter is null!!!", LEVEL_DEBUG); + //} +#pragma endregion + + auto inParams = CyberXessContext::instance()->CreateFeatureParams; + auto deviceContext = CyberXessContext::instance()->Contexts[handle->Id].get(); + + if (deviceContext == nullptr) + { + LOG("NVSDK_NGX_D3D12_CreateFeature deviceContext is null!", LEVEL_ERROR); + return false; + } + + LOG("NVSDK_NGX_D3D12_CreateFeature deviceContext ok, xessD3D12CreateContext start", LEVEL_DEBUG); + + if (deviceContext->XessContext != nullptr) + { + LOG("NVSDK_NGX_D3D12_CreateFeature Destrying old XeSSContext", LEVEL_WARNING); + ret = xessDestroyContext(deviceContext->XessContext); + LOG("NVSDK_NGX_D3D12_CreateFeature xessDestroyContext result -> " + ResultToString(ret), LEVEL_WARNING); + } + + ret = xessD3D12CreateContext(CyberXessContext::instance()->Dx12Device, &deviceContext->XessContext); + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12CreateContext result -> " + ResultToString(ret), LEVEL_INFO); + + ret = xessSetLoggingCallback(deviceContext->XessContext, XESS_LOGGING_LEVEL_DEBUG, LogCallback); + LOG("NVSDK_NGX_D3D12_CreateFeature xessSetLoggingCallback : " + ResultToString(ret), LEVEL_DEBUG); + + ret = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + LOG("NVSDK_NGX_D3D12_CreateFeature xessSetVelocityScale : " + ResultToString(ret), LEVEL_DEBUG); + +#pragma region Create Parameters for XeSS + + xess_d3d12_init_params_t initParams{}; + + LOG("NVSDK_NGX_D3D12_CreateFeature Params Init!", LEVEL_DEBUG); + initParams.outputResolution.x = inParams->OutWidth; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.outputResolution.x : " + std::to_string(initParams.outputResolution.x), LEVEL_DEBUG); + initParams.outputResolution.y = inParams->OutHeight; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.outputResolution.y : " + std::to_string(initParams.outputResolution.y), LEVEL_DEBUG); + + switch (inParams->PerfQualityValue) + { + case NVSDK_NGX_PerfQuality_Value_UltraPerformance: + initParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_MaxPerf: + initParams.qualitySetting = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_Balanced: + initParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED; + break; + case NVSDK_NGX_PerfQuality_Value_MaxQuality: + initParams.qualitySetting = XESS_QUALITY_SETTING_QUALITY; + break; + case NVSDK_NGX_PerfQuality_Value_UltraQuality: + initParams.qualitySetting = XESS_QUALITY_SETTING_ULTRA_QUALITY; + break; + default: + initParams.qualitySetting = XESS_QUALITY_SETTING_BALANCED; //Set out-of-range value for non-existing fsr ultra quality mode + break; + } + + initParams.initFlags = XESS_INIT_FLAG_NONE; + + if (CyberXessContext::instance()->MyConfig->DepthInverted.value_or(inParams->DepthInverted)) + { + initParams.initFlags |= XESS_INIT_FLAG_INVERTED_DEPTH; + CyberXessContext::instance()->MyConfig->DepthInverted = true; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.initFlags (DepthInverted) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->AutoExposure.value_or(inParams->AutoExposure)) + { + initParams.initFlags |= XESS_INIT_FLAG_ENABLE_AUTOEXPOSURE; + CyberXessContext::instance()->MyConfig->AutoExposure = true; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.initFlags (AutoExposure) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + else + { + initParams.initFlags |= XESS_INIT_FLAG_EXPOSURE_SCALE_TEXTURE; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.initFlags (!AutoExposure) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + if (!CyberXessContext::instance()->MyConfig->HDR.value_or(!inParams->Hdr)) + { + initParams.initFlags |= XESS_INIT_FLAG_LDR_INPUT_COLOR; + CyberXessContext::instance()->MyConfig->HDR = false; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.initFlags (HDR) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->JitterCancellation.value_or(inParams->JitterMotion)) + { + initParams.initFlags |= XESS_INIT_FLAG_JITTERED_MV; + CyberXessContext::instance()->MyConfig->JitterCancellation = true; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.initFlags (JitterCancellation) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + if (CyberXessContext::instance()->MyConfig->DisplayResolution.value_or(!inParams->LowRes)) + { + initParams.initFlags |= XESS_INIT_FLAG_HIGH_RES_MV; + CyberXessContext::instance()->MyConfig->DisplayResolution = true; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.initFlags (LowRes) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + if (!CyberXessContext::instance()->MyConfig->DisableReactiveMask.value_or(true)) + { + initParams.initFlags |= XESS_INIT_FLAG_RESPONSIVE_PIXEL_MASK; + LOG("NVSDK_NGX_D3D12_CreateFeature initParams.initFlags (DisableReactiveMask) " + std::to_string(initParams.initFlags), LEVEL_INFO); + } + + LOG("NVSDK_NGX_D3D12_CreateFeature Params done!", LEVEL_DEBUG); + +#pragma endregion + +#pragma region Build Pipelines + + if (CyberXessContext::instance()->MyConfig->BuildPipelines.value_or(true)) + { + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12BuildPipelines start!", LEVEL_DEBUG); + + ret = xessD3D12BuildPipelines(deviceContext->XessContext, NULL, false, initParams.initFlags); + + if (ret != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12BuildPipelines error : -> " + ResultToString(ret), LEVEL_ERROR); + return false; + } + } + else + { + LOG("NVSDK_NGX_D3D12_CreateFeature skipping xessD3D12BuildPipelines!", LEVEL_DEBUG); + } + +#pragma endregion + +#pragma region Select Network Model + + auto model = static_cast(CyberXessContext::instance()->MyConfig->NetworkModel.value_or(0)); + + LOG("NVSDK_NGX_D3D12_CreateFeature xessSelectNetworkModel trying to set value to " + std::to_string(model), LEVEL_DEBUG); + + ret = xessSelectNetworkModel(deviceContext->XessContext, model); + + if (ret == XESS_RESULT_SUCCESS) + LOG("NVSDK_NGX_D3D12_CreateFeature xessSelectNetworkModel set to " + std::to_string(model), LEVEL_DEBUG); + else + LOG("NVSDK_NGX_D3D12_CreateFeature xessSelectNetworkModel(" + std::to_string(model) + ") error : " + ResultToString(ret), LEVEL_ERROR); + +#pragma endregion + + + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12Init start!", LEVEL_DEBUG); + + ret = xessD3D12Init(deviceContext->XessContext, &initParams); + + if (ret != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D12_CreateFeature xessD3D12Init error: " + ResultToString(ret), LEVEL_ERROR); + CyberXessContext::instance()->init = false; + return false; + } + + LOG("NVSDK_NGX_D3D12_CreateFeature End!", LEVEL_DEBUG); + + CyberXessContext::instance()->init = true; + + return true; +} + +FeatureContext* CreateContext(NVSDK_NGX_Handle** OutHandle) +{ + auto deviceContext = CyberXessContext::instance()->CreateContext(); + *OutHandle = &deviceContext->Handle; + return deviceContext; +} + +#pragma region DLSS Init Calls + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_Ext(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, + ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion, + unsigned long long unknown0) +{ + + LOG("NVSDK_NGX_D3D12_Init_Ext AppId:" + std::to_string(InApplicationId), LEVEL_DEBUG); + LOG("NVSDK_NGX_D3D12_Init_Ext SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + LOG("Logger DelayedInit : " + std::to_string(CyberXessContext::instance()->MyConfig->DelayedInit.value_or(false)), LEVEL_INFO); + LOG("Logger BuildPipelines : " + std::to_string(CyberXessContext::instance()->MyConfig->BuildPipelines.value_or(true)), LEVEL_INFO); + LOG("Logger NetworkModel : " + std::to_string(CyberXessContext::instance()->MyConfig->NetworkModel.value_or(0)), LEVEL_INFO); + LOG("Logger LogFile : " + CyberXessContext::instance()->MyConfig->LogFile.value_or(""), LEVEL_INFO); + LOG("Logger LogLevel : " + std::to_string(CyberXessContext::instance()->MyConfig->LogLevel.value_or(1)), LEVEL_INFO); + LOG("Logger XeSSLogging : " + std::to_string(CyberXessContext::instance()->MyConfig->XeSSLogging.value_or(true)), LEVEL_INFO); + + CyberXessContext::instance()->init = false; + CyberXessContext::instance()->Dx12Device = nullptr; + CyberXessContext::instance()->Dx12ProxyDevice = nullptr; + + if (InDevice) + { + WrappedD3D12Device* proxyDevice = nullptr; + if (InDevice->QueryInterface(__uuidof(ID3D12ProxyDevice), (void**)&proxyDevice) == S_OK && proxyDevice != nullptr) + { + CyberXessContext::instance()->Dx12Device = proxyDevice->m_device; + LOG("NVSDK_NGX_D3D12_Init_Ext Proxy Dx12Device assigned...", LEVEL_DEBUG); + } + else + { + CyberXessContext::instance()->Dx12Device = InDevice; + LOG("NVSDK_NGX_D3D12_Init_Ext Dx12Device assigned...", LEVEL_DEBUG); + } + + + InDevice->QueryInterface(__uuidof(ID3D12ProxyDevice), (void**)&CyberXessContext::instance()->Dx12ProxyDevice); + + if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + LOG("NVSDK_NGX_D3D12_Init_Ext Dx12ProxyDevice assigned...", LEVEL_DEBUG); + else + LOG("NVSDK_NGX_D3D12_Init_Ext Dx12ProxyDevice not assigned...", LEVEL_DEBUG); + } + else + LOG("NVSDK_NGX_D3D12_Init_Ext Dx12Device is already assigned or InDevice is null!!!!", LEVEL_ERROR); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, + ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + LOG("NVSDK_NGX_D3D12_Init AppId:" + std::to_string(InApplicationId), LEVEL_DEBUG); + LOG("NVSDK_NGX_D3D12_Init SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_D3D12_Init_Ext(InApplicationId, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, + const char* InEngineVersion, const wchar_t* InApplicationDataPath, ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + std::string pId = InProjectId; + LOG("NVSDK_NGX_D3D12_Init_ProjectID : " + pId, LEVEL_DEBUG); + LOG("NVSDK_NGX_D3D12_Init_ProjectID SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_D3D12_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Init_with_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, + const wchar_t* InApplicationDataPath, ID3D12Device* InDevice, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + std::string pId = InProjectId; + LOG("NVSDK_NGX_D3D12_Init_with_ProjectID : " + pId, LEVEL_DEBUG); + LOG("NVSDK_NGX_D3D12_Init_with_ProjectID SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_D3D12_Init_Ext(0x1337, InApplicationDataPath, InDevice, InFeatureInfo, InSDKVersion, 0); +} + +#pragma endregion + +#pragma region DLSS Shutdown Calls + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown(void) +{ + LOG("NVSDK_NGX_D3D12_Shutdown", LEVEL_DEBUG); + + //if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + //{ + // LOG("NVSDK_NGX_D3D12_Shutdown Dx12ProxyDevice proxy adapter spoofing enabling...", LEVEL_DEBUG); + // IDXGIProxyAdapter* pAdapter = nullptr; + // CyberXessContext::instance()->Dx12ProxyDevice->GetProxyAdapter(&pAdapter); + // LOG("NVSDK_NGX_D3D12_Shutdown Dx12ProxyDevice proxy adapter accuired...", LEVEL_DEBUG); + + // if (pAdapter != nullptr) + // { + // pAdapter->Spoofing(true); + // LOG("NVSDK_NGX_D3D12_Shutdown Dx12ProxyDevice proxy adapter spoofing enabled...", LEVEL_DEBUG); + // } + // else + // LOG("NVSDK_NGX_D3D12_Shutdown Dx12ProxyDevice proxy adapter is null!!!", LEVEL_DEBUG); + //} + + CyberXessContext::instance()->Shutdown(); + + CyberXessContext::instance()->NvParameterInstance->Params.clear(); + CyberXessContext::instance()->Contexts.clear(); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_Shutdown1(ID3D12Device* InDevice) +{ + LOG("NVSDK_NGX_D3D12_Shutdown1", LEVEL_DEBUG); + + //if (CyberXessContext::instance()->Dx12ProxyDevice != nullptr) + //{ + // LOG("NVSDK_NGX_D3D12_Shutdown1 Dx12ProxyDevice proxy adapter spoofing enabling...", LEVEL_DEBUG); + + // IDXGIProxyAdapter* pAdapter = nullptr; + // CyberXessContext::instance()->Dx12ProxyDevice->GetProxyAdapter(&pAdapter); + // LOG("NVSDK_NGX_D3D12_Shutdown1 Dx12ProxyDevice proxy adapter accuired...", LEVEL_DEBUG); + + // if (pAdapter != nullptr) + // { + // pAdapter->Spoofing(true); + // LOG("NVSDK_NGX_D3D12_Shutdown1 Dx12ProxyDevice proxy adapter spoofing enabled...", LEVEL_DEBUG); + // } + // else + // LOG("NVSDK_NGX_D3D12_Shutdown1 Dx12ProxyDevice proxy adapter is null!!!", LEVEL_DEBUG); + //} + + CyberXessContext::instance()->Shutdown(); + + CyberXessContext::instance()->NvParameterInstance->Params.clear(); + CyberXessContext::instance()->Contexts.clear(); + + return NVSDK_NGX_Result_Success; +} + +#pragma endregion + +#pragma region DLSS Parameter Calls + +//currently it's kind of hack but better than what it was previously -- External Memory Tracking +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_GetParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_D3D12_GetParameters", LEVEL_DEBUG); + + *OutParameters = CyberXessContext::instance()->NvParameterInstance->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +//currently it's kind of hack still needs a proper implementation +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_D3D12_GetCapabilityParameters", LEVEL_DEBUG); + + *OutParameters = NvParameter::instance()->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +//currently it's kind of hack still needs a proper implementation +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_AllocateParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_D3D12_AllocateParameters", LEVEL_DEBUG); + + *OutParameters = NvParameter::instance()->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +//currently it's kind of hack still needs a proper implementation +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_DestroyParameters(NVSDK_NGX_Parameter* InParameters) +{ + LOG("NVSDK_NGX_D3D12_DestroyParameters", LEVEL_DEBUG); + + NvParameter::instance()->DeleteParameters((NvParameter*)InParameters); + return NVSDK_NGX_Result_Success; +} + +#pragma endregion + +#pragma region DLSS Feature Calls + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_CreateFeature(ID3D12GraphicsCommandList* InCmdList, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) +{ + auto context = CreateContext(OutHandle); + CyberXessContext::instance()->CreateFeatureParams = static_cast(InParameters); + + if (CyberXessContext::instance()->MyConfig->DelayedInit.value_or(false)) + return NVSDK_NGX_Result_Success; + + if (CreateFeature(InCmdList, &context->Handle)) + return NVSDK_NGX_Result_Success; + + LOG("NVSDK_NGX_D3D12_CreateFeature: CreateFeature failed", LEVEL_ERROR); + + return NVSDK_NGX_Result_Fail; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_ReleaseFeature(NVSDK_NGX_Handle* InHandle) +{ + LOG("NVSDK_NGX_D3D12_ReleaseFeature!", LEVEL_DEBUG); + + auto deviceContext = CyberXessContext::instance()->Contexts[InHandle->Id].get(); + auto result = xessDestroyContext(deviceContext->XessContext); + LOG("NVSDK_NGX_D3D12_ReleaseFeature: xessDestroyContext result: " + ResultToString(result), LEVEL_DEBUG); + CyberXessContext::instance()->DeleteContext(InHandle); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_GetFeatureRequirements(IDXGIAdapter* Adapter, const NVSDK_NGX_FeatureDiscoveryInfo* FeatureDiscoveryInfo, + NVSDK_NGX_FeatureRequirement* OutSupported) +{ + LOG("NVSDK_NGX_D3D12_GetFeatureRequirements!", LEVEL_DEBUG); + + *OutSupported = NVSDK_NGX_FeatureRequirement(); + OutSupported->FeatureSupported = NVSDK_NGX_FeatureSupportResult_Supported; + OutSupported->MinHWArchitecture = 0; + //Some windows 10 os version + strcpy_s(OutSupported->MinOSVersion, "10.0.19045.2728"); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_EvaluateFeature(ID3D12GraphicsCommandList* InCmdList, const NVSDK_NGX_Handle* InFeatureHandle, const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) +{ + LOG("NVSDK_NGX_D3D12_EvaluateFeature init!", LEVEL_DEBUG); + + if (!InCmdList) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature InCmdList is null!!!", LEVEL_ERROR); + return NVSDK_NGX_Result_Fail; + } + + if (InCallback) + LOG("NVSDK_NGX_D3D12_EvaluateFeature callback exist", LEVEL_WARNING); + + const auto inParams = static_cast(InParameters); + const auto instance = CyberXessContext::instance(); + + if (!instance->init) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature init is false, calling CreateFeature!", LEVEL_WARNING); + instance->init = CreateFeature(InCmdList, InFeatureHandle); + } + + if (!instance->init) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature init still is null CreateFeature failed!", LEVEL_ERROR); + return NVSDK_NGX_Result_Fail; + } + + auto deviceContext = instance->Contexts[InFeatureHandle->Id].get(); + + //dumpParams.frame_count = 1; + //dumpParams.frame_idx = cnt++; + //dumpParams.path = "D:\\dmp\\"; + //xessStartDump(deviceContext->XessContext, &dumpParams); + + // creatimg params for XeSS + xess_result_t xessResult; + xess_d3d12_execute_params_t params{}; + + params.jitterOffsetX = inParams->JitterOffsetX; + params.jitterOffsetY = inParams->JitterOffsetY; + + params.exposureScale = inParams->ExposureScale; + params.resetHistory = inParams->ResetRender; + + params.inputWidth = inParams->Width; + params.inputHeight = inParams->Height; + + LOG("NVSDK_NGX_D3D12_EvaluateFeature inp width: " + std::to_string(inParams->Width) + " height: " + std::to_string(inParams->Height), LEVEL_DEBUG); + + + HRESULT d3d11on11Result; + + if (inParams->Color != nullptr) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature Color exist..", LEVEL_DEBUG); + + if (instance->Dx11on12Device != nullptr) + { + params.pColorTexture = nullptr; + + d3d11on11Result = instance->Dx11on12Device->UnwrapUnderlyingResource( + (ID3D11Resource*)inParams->Color, + instance->Dx12CommandQueue, + IID_PPV_ARGS(¶ms.pColorTexture) + ); + + LOG("NVSDK_NGX_D3D12_EvaluateFeature Color UnwrapUnderlyingResource result: " + int_to_hex(d3d11on11Result), LEVEL_DEBUG); + } + else + params.pColorTexture = (ID3D12Resource*)inParams->Color; + } + else + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature Color not exist!!", LEVEL_ERROR); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->MotionVectors) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature MotionVectors exist..", LEVEL_DEBUG); + + if (instance->Dx11on12Device != nullptr) + { + params.pVelocityTexture = nullptr; + + d3d11on11Result = instance->Dx11on12Device->UnwrapUnderlyingResource( + (ID3D11Resource*)inParams->MotionVectors, + instance->Dx12CommandQueue, + IID_PPV_ARGS(¶ms.pVelocityTexture) + ); + + LOG("NVSDK_NGX_D3D12_EvaluateFeature MotionVectors UnwrapUnderlyingResource result: " + int_to_hex(d3d11on11Result), LEVEL_DEBUG); + } + else + params.pVelocityTexture = (ID3D12Resource*)inParams->MotionVectors; + } + else + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature MotionVectors not exist!!", LEVEL_ERROR); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->Output) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature Output exist..", LEVEL_DEBUG); + + if (instance->Dx11on12Device != nullptr) + { + params.pOutputTexture = nullptr; + + d3d11on11Result = instance->Dx11on12Device->UnwrapUnderlyingResource( + (ID3D11Resource*)inParams->Output, + instance->Dx12CommandQueue, + IID_PPV_ARGS(¶ms.pOutputTexture) + ); + + LOG("NVSDK_NGX_D3D12_EvaluateFeature Output UnwrapUnderlyingResource result: " + int_to_hex(d3d11on11Result), LEVEL_DEBUG); + } + else + params.pOutputTexture = (ID3D12Resource*)inParams->Output; + } + else + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature Output not exist!!", LEVEL_ERROR); + return NVSDK_NGX_Result_FAIL_InvalidParameter; + } + + if (inParams->Depth && !instance->MyConfig->DisplayResolution.value_or(false)) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature Depth exist..", LEVEL_INFO); + + if (instance->Dx11on12Device != nullptr) + { + params.pDepthTexture = nullptr; + + d3d11on11Result = instance->Dx11on12Device->UnwrapUnderlyingResource( + (ID3D11Resource*)inParams->Depth, + instance->Dx12CommandQueue, + IID_PPV_ARGS(¶ms.pDepthTexture) + ); + + LOG("NVSDK_NGX_D3D12_EvaluateFeature Depth UnwrapUnderlyingResource result: " + int_to_hex(d3d11on11Result), LEVEL_DEBUG); + } + else + params.pDepthTexture = (ID3D12Resource*)inParams->Depth; + } + else + { + if (!instance->MyConfig->DisplayResolution.value_or(false)) + LOG("NVSDK_NGX_D3D12_EvaluateFeature Depth not exist!!", LEVEL_ERROR); + else + LOG("NVSDK_NGX_D3D12_EvaluateFeature Using high res motion vectors, depth is not needed!!", LEVEL_INFO); + + params.pDepthTexture = nullptr; + } + + if (!instance->MyConfig->AutoExposure.value_or(false)) + { + if (inParams->ExposureTexture == nullptr) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature AutoExposure disabled but ExposureTexture is not exist, it may cause problems!!", LEVEL_WARNING); + params.pExposureScaleTexture = nullptr; + } + else + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature ExposureTexture exist..", LEVEL_INFO); + + if (instance->Dx11on12Device != nullptr) + { + params.pExposureScaleTexture = nullptr; + + d3d11on11Result = instance->Dx11on12Device->UnwrapUnderlyingResource( + (ID3D11Resource*)inParams->ExposureTexture, + instance->Dx12CommandQueue, + IID_PPV_ARGS(¶ms.pExposureScaleTexture) + ); + + LOG("NVSDK_NGX_D3D12_EvaluateFeature ExposureTexture UnwrapUnderlyingResource result: " + int_to_hex(d3d11on11Result), LEVEL_DEBUG); + } + else + params.pExposureScaleTexture = (ID3D12Resource*)inParams->ExposureTexture; + } + } + else + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature AutoExposure enabled!", LEVEL_WARNING); + params.pExposureScaleTexture = nullptr; + } + + if (!instance->MyConfig->DisableReactiveMask.value_or(true)) + { + if (inParams->TransparencyMask != nullptr) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature TransparencyMask exist..", LEVEL_INFO); + + if (instance->Dx11on12Device != nullptr) + { + params.pResponsivePixelMaskTexture = nullptr; + + d3d11on11Result = instance->Dx11on12Device->UnwrapUnderlyingResource( + (ID3D11Resource*)inParams->TransparencyMask, + instance->Dx12CommandQueue, + IID_PPV_ARGS(¶ms.pResponsivePixelMaskTexture) + ); + + LOG("NVSDK_NGX_D3D12_EvaluateFeature TransparencyMask UnwrapUnderlyingResource result: " + int_to_hex(d3d11on11Result), LEVEL_DEBUG); + } + else + params.pResponsivePixelMaskTexture = (ID3D12Resource*)inParams->TransparencyMask; + } + else + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature TransparencyMask not exist and its enabled in config, it may cause problems!!", LEVEL_WARNING); + params.pResponsivePixelMaskTexture = nullptr; + } + } + else + { + params.pResponsivePixelMaskTexture = nullptr; + } + + LOG("NVSDK_NGX_D3D12_EvaluateFeature mvscale x: " + std::to_string(inParams->MVScaleX) + " y: " + std::to_string(inParams->MVScaleY), LEVEL_DEBUG); + xessResult = xessSetVelocityScale(deviceContext->XessContext, inParams->MVScaleX, inParams->MVScaleY); + + if (xessResult != XESS_RESULT_SUCCESS) + { + LOG("NVSDK_NGX_D3D12_EvaluateFeature xessSetVelocityScale : " + ResultToString(xessResult), LEVEL_ERROR); + return NVSDK_NGX_Result_Fail; + } + + const UINT64 fence = instance->Dx12FenceValueCounter; + + if (instance->Dx11on12Device != nullptr) + { + // Transition render targets D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE for XeSS + std::vector transitions = {}; + + if (params.pColorTexture != nullptr) + transitions.push_back(CD3DX12_RESOURCE_BARRIER::Transition(params.pColorTexture, + D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE)); + if (params.pVelocityTexture != nullptr) + CD3DX12_RESOURCE_BARRIER::Transition(params.pVelocityTexture, + D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + if (params.pDepthTexture != nullptr) + CD3DX12_RESOURCE_BARRIER::Transition(params.pDepthTexture, + D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + if (params.pExposureScaleTexture != nullptr) + CD3DX12_RESOURCE_BARRIER::Transition(params.pExposureScaleTexture, + D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + if (params.pResponsivePixelMaskTexture != nullptr) + CD3DX12_RESOURCE_BARRIER::Transition(params.pResponsivePixelMaskTexture, + D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE); + + // Transition output D3D12_RESOURCE_STATE_UNORDERED_ACCESS for XeSS + if (params.pOutputTexture != nullptr) + CD3DX12_RESOURCE_BARRIER::Transition(params.pResponsivePixelMaskTexture, + D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); + + InCmdList->ResourceBarrier((UINT)transitions.size(), transitions.data()); + } + + LOG("NVSDK_NGX_D3D12_EvaluateFeature Executing!!", LEVEL_INFO); + xessResult = xessD3D12Execute(deviceContext->XessContext, InCmdList, ¶ms); + + if (instance->Dx11on12Device != nullptr) + { + auto bResult = instance->Dx12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&instance->Dx12Fence)); + LOG("NVSDK_NGX_D3D12_EvaluateFeature CreateFence result: " + int_to_hex(bResult), LEVEL_DEBUG); + + // Signal the command queue and wait for the fence + bResult = instance->Dx12CommandQueue->Signal(instance->Dx12Fence, fence); + LOG("NVSDK_NGX_D3D12_EvaluateFeature Signal result: " + int_to_hex(bResult), LEVEL_DEBUG); + } + + if (xessResult != XESS_RESULT_SUCCESS) + { + LOG("xessD3D12Execute error : -> " + ResultToString(xessResult), LEVEL_ERROR); + return NVSDK_NGX_Result_Fail; + } + + if (instance->Dx11DeviceContext != nullptr && params.pOutputTexture) + { + UINT64 signals[1] = { fence }; + ID3D12Fence* fences[1] = { CyberXessContext::instance()->Dx12Fence }; + HRESULT bResult; + + if (params.pOutputTexture != nullptr) + { + bResult = CyberXessContext::instance()->Dx11on12Device->ReturnUnderlyingResource((ID3D11Resource*)inParams->Output, 1, signals, fences); + LOG("NVSDK_NGX_D3D12_EvaluateFeature pOutputTexture ReturnUnderlyingResource Output result: " + int_to_hex(bResult), LEVEL_DEBUG); + } + + if (params.pColorTexture != nullptr) + { + bResult = CyberXessContext::instance()->Dx11on12Device->ReturnUnderlyingResource((ID3D11Resource*)inParams->Color, 1, signals, fences); + LOG("NVSDK_NGX_D3D12_EvaluateFeature pOutputTexture ReturnUnderlyingResource Color result: " + int_to_hex(bResult), LEVEL_DEBUG); + } + + if (params.pDepthTexture != nullptr) + { + bResult = CyberXessContext::instance()->Dx11on12Device->ReturnUnderlyingResource((ID3D11Resource*)inParams->Depth, 1, signals, fences); + LOG("NVSDK_NGX_D3D12_EvaluateFeature pOutputTexture ReturnUnderlyingResource Depth result: " + int_to_hex(bResult), LEVEL_DEBUG); + } + + if (params.pVelocityTexture != nullptr) + { + bResult = CyberXessContext::instance()->Dx11on12Device->ReturnUnderlyingResource((ID3D11Resource*)inParams->MotionVectors, 1, signals, fences); + LOG("NVSDK_NGX_D3D12_EvaluateFeature pOutputTexture ReturnUnderlyingResource MotionVectors result: " + int_to_hex(bResult), LEVEL_DEBUG); + } + + if (params.pExposureScaleTexture != nullptr) + { + bResult = CyberXessContext::instance()->Dx11on12Device->ReturnUnderlyingResource((ID3D11Resource*)inParams->ExposureTexture, 1, signals, fences); + LOG("NVSDK_NGX_D3D12_EvaluateFeature pOutputTexture ReturnUnderlyingResource MotionVectors result: " + int_to_hex(bResult), LEVEL_DEBUG); + } + + if (params.pResponsivePixelMaskTexture != nullptr) + { + bResult = CyberXessContext::instance()->Dx11on12Device->ReturnUnderlyingResource((ID3D11Resource*)inParams->TransparencyMask, 1, signals, fences); + LOG("NVSDK_NGX_D3D12_EvaluateFeature pOutputTexture ReturnUnderlyingResource MotionVectors result: " + int_to_hex(bResult), LEVEL_DEBUG); + } + } + + LOG("NVSDK_NGX_D3D12_EvaluateFeature End!", LEVEL_DEBUG); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_UpdateFeature(const NVSDK_NGX_Application_Identifier* ApplicationId, const NVSDK_NGX_Feature FeatureID) +{ + LOG("NVSDK_NGX_UpdateFeature -> " + std::to_string(FeatureID), LEVEL_DEBUG); + return NVSDK_NGX_Result_Success; +} + +#pragma endregion + +#pragma region DLSS Buffer Size Call + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_D3D12_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter* InParameters, size_t* OutSizeInBytes) +{ + LOG("NVSDK_NGX_D3D12_GetScratchBufferSize -> 52428800", LEVEL_WARNING); + + *OutSizeInBytes = 52428800; + return NVSDK_NGX_Result_Success; +} + +#pragma endregion + diff --git a/CyberXeSS_YEDEK/CyberXessVk.cpp b/CyberXeSS_YEDEK/CyberXessVk.cpp new file mode 100644 index 00000000..77d3a78a --- /dev/null +++ b/CyberXeSS_YEDEK/CyberXessVk.cpp @@ -0,0 +1,129 @@ +#include "pch.h" +#include "Config.h" +#include "CyberXess.h" +#include "Util.h" + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init(unsigned long long InApplicationId, const wchar_t* InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA, PFN_vkGetDeviceProcAddr InGDPA, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + LOG("NVSDK_NGX_VULKAN_Init Init!", LEVEL_DEBUG); + LOG("NVSDK_NGX_VULKAN_Init AppId:" + std::to_string(InApplicationId), LEVEL_DEBUG); + LOG("NVSDK_NGX_VULKAN_Init SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + CyberXessContext::instance()->VulkanInstance = InInstance; + CyberXessContext::instance()->VulkanPhysicalDevice = InPD; + CyberXessContext::instance()->VulkanDevice = InDevice; + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA, PFN_vkGetDeviceProcAddr InGDPA, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + LOG("NVSDK_NGX_VULKAN_Init_ProjectID Init!", LEVEL_DEBUG); + std::string pId = InProjectId; + LOG("NVSDK_NGX_VULKAN_Init_ProjectID : " + pId, LEVEL_DEBUG); + LOG("NVSDK_NGX_VULKAN_Init_ProjectID SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_VULKAN_Init(0x1337, InApplicationDataPath, InInstance, InPD, InDevice, InGIPA, InGDPA, InFeatureInfo, InSDKVersion); +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_NGX_VULKAN_Init_with_ProjectID(const char* InProjectId, NVSDK_NGX_EngineType InEngineType, const char* InEngineVersion, const wchar_t* InApplicationDataPath, VkInstance InInstance, VkPhysicalDevice InPD, VkDevice InDevice, PFN_vkGetInstanceProcAddr InGIPA, PFN_vkGetDeviceProcAddr InGDPA, const NVSDK_NGX_FeatureCommonInfo* InFeatureInfo, NVSDK_NGX_Version InSDKVersion) +{ + std::string pId = InProjectId; + LOG("NVSDK_NGX_VULKAN_Init_with_ProjectID : " + pId, LEVEL_DEBUG); + LOG("NVSDK_NGX_VULKAN_Init_with_ProjectID SDK:" + std::to_string(InSDKVersion), LEVEL_DEBUG); + + return NVSDK_NGX_VULKAN_Init(0x1337, InApplicationDataPath, InInstance, InPD, InDevice, InGIPA, InGDPA, InFeatureInfo, InSDKVersion); +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown(void) +{ + LOG("NVSDK_NGX_VULKAN_Shutdown", LEVEL_DEBUG); + + CyberXessContext::instance()->VulkanDevice = nullptr; + CyberXessContext::instance()->VulkanInstance = nullptr; + CyberXessContext::instance()->VulkanPhysicalDevice = nullptr; + CyberXessContext::instance()->NvParameterInstance->Params.clear(); + CyberXessContext::instance()->Contexts.clear(); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_Shutdown1(VkDevice InDevice) +{ + LOG("NVSDK_NGX_VULKAN_Shutdown1", LEVEL_DEBUG); + + CyberXessContext::instance()->VulkanDevice = nullptr; + CyberXessContext::instance()->VulkanInstance = nullptr; + CyberXessContext::instance()->VulkanPhysicalDevice = nullptr; + CyberXessContext::instance()->NvParameterInstance->Params.clear(); + CyberXessContext::instance()->Contexts.clear(); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_NGX_VULKAN_GetParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_VULKAN_GetParameters", LEVEL_DEBUG); + + *OutParameters = CyberXessContext::instance()->NvParameterInstance->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_AllocateParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_VULKAN_AllocateParameters", LEVEL_DEBUG); + + *OutParameters = NvParameter::instance()->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetCapabilityParameters(NVSDK_NGX_Parameter** OutParameters) +{ + LOG("NVSDK_NGX_VULKAN_GetCapabilityParameters", LEVEL_DEBUG); + + *OutParameters = NvParameter::instance()->AllocateParameters(); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_DestroyParameters(NVSDK_NGX_Parameter* InParameters) +{ + LOG("NVSDK_NGX_VULKAN_DestroyParameters", LEVEL_DEBUG); + + NvParameter::instance()->DeleteParameters((NvParameter*)InParameters); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_GetScratchBufferSize(NVSDK_NGX_Feature InFeatureId, const NVSDK_NGX_Parameter* InParameters, size_t* OutSizeInBytes) +{ + LOG("NVSDK_NGX_VULKAN_GetScratchBufferSize -> 52428800", LEVEL_DEBUG); + + *OutSizeInBytes = 52428800; + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature(VkCommandBuffer InCmdBuffer, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) +{ + return NVSDK_NGX_VULKAN_CreateFeature1(CyberXessContext::instance()->VulkanDevice, InCmdBuffer, InFeatureID, InParameters, OutHandle); +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_CreateFeature1(VkDevice InDevice, VkCommandBuffer InCmdList, NVSDK_NGX_Feature InFeatureID, NVSDK_NGX_Parameter* InParameters, NVSDK_NGX_Handle** OutHandle) +{ + LOG("NVSDK_NGX_VULKAN_CreateFeature1 Fail!", LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_PlatformError; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_ReleaseFeature(NVSDK_NGX_Handle* InHandle) +{ + LOG("NVSDK_NGX_VULKAN_ReleaseFeature", LEVEL_DEBUG); + + auto deviceContext = CyberXessContext::instance()->Contexts[InHandle->Id].get(); + CyberXessContext::instance()->DeleteContext(InHandle); + + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_VULKAN_EvaluateFeature(VkCommandBuffer InCmdList, const NVSDK_NGX_Handle* InFeatureHandle, const NVSDK_NGX_Parameter* InParameters, PFN_NVSDK_NGX_ProgressCallback InCallback) +{ + LOG("NVSDK_NGX_VULKAN_EvaluateFeature", LEVEL_DEBUG); + return NVSDK_NGX_Result_FAIL_PlatformError; +} \ No newline at end of file diff --git a/CyberXeSS_YEDEK/NvParameter.cpp b/CyberXeSS_YEDEK/NvParameter.cpp new file mode 100644 index 00000000..2a70cc53 --- /dev/null +++ b/CyberXeSS_YEDEK/NvParameter.cpp @@ -0,0 +1,444 @@ +#include "pch.h" +#include "Config.h" +#include "Util.h" +#include "NvParameter.h" +#include "CyberXess.h" + +void NvParameter::Set(const char* InName, unsigned long long InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvULL); +} + +void NvParameter::Set(const char* InName, float InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvFloat); +} + +void NvParameter::Set(const char* InName, double InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvDouble); +} + +void NvParameter::Set(const char* InName, unsigned int InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvUInt); +} + +void NvParameter::Set(const char* InName, int InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvInt); +} + +void NvParameter::Set(const char* InName, ID3D11Resource* InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvD3D11Resource); +} + +void NvParameter::Set(const char* InName, ID3D12Resource* InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvD3D12Resource); +} + +void NvParameter::Set(const char* InName, void* InValue) +{ + auto value = (unsigned long long*) & InValue; + Set_Internal(InName, *value, NvVoidPtr); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, unsigned long long* OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvULL); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, float* OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvFloat); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, double* OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvDouble); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, unsigned int* OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvUInt); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, int* OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvInt); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, ID3D11Resource** OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvD3D11Resource); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, ID3D12Resource** OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvD3D12Resource); +} + +NVSDK_NGX_Result NvParameter::Get(const char* InName, void** OutValue) const +{ + return Get_Internal(InName, (unsigned long long*)OutValue, NvVoidPtr); +} + +void NvParameter::Reset() +{ +} + +void NvParameter::Set_Internal(const char* InName, unsigned long long InValue, NvParameterType ParameterType) +{ + auto inValueFloat = (float*)&InValue; + auto inValueInt = (int*)&InValue; + auto inValueDouble = (double*)&InValue; + auto inValueUInt = (unsigned int*)&InValue; + //Includes DirectX Resources + auto inValuePtr = (void*)InValue; + + std::string s; + s = InName; + + LOG("Set_Internal : " + s + " - f:" + std::to_string(*inValueFloat) + " - d:" + std::to_string(*inValueDouble) + " - i:" + std::to_string(*inValueInt) + " - u:" + std::to_string(*inValueUInt), LEVEL_DEBUG); + + switch (Util::NvParameterToEnum(InName)) + { + case Util::NvParameter::MV_Scale_X: + MVScaleX = *inValueFloat; + break; + case Util::NvParameter::MV_Scale_Y: + MVScaleY = *inValueFloat; + break; + case Util::NvParameter::Jitter_Offset_X: + JitterOffsetX = *inValueFloat; + break; + case Util::NvParameter::Jitter_Offset_Y: + JitterOffsetY = *inValueFloat; + break; + case Util::NvParameter::Sharpness: + Sharpness = *inValueFloat; + break; + case Util::NvParameter::Width: + Width = *inValueInt; + break; + case Util::NvParameter::Height: + Height = *inValueInt; + break; + case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Width: + Width = *inValueInt; + break; + case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Height: + Height = *inValueInt; + break; + case Util::NvParameter::PerfQualityValue: + PerfQualityValue = static_cast(*inValueInt); + break; + case Util::NvParameter::RTXValue: + RTXValue = *inValueInt; + break; + case Util::NvParameter::FreeMemOnReleaseFeature: + FreeMemOnReleaseFeature = *inValueInt; + break; + case Util::NvParameter::CreationNodeMask: + CreationNodeMask = *inValueInt; + break; + case Util::NvParameter::VisibilityNodeMask: + VisibilityNodeMask = *inValueInt; + break; + case Util::NvParameter::Reset: + ResetRender = *inValueInt; + break; + case Util::NvParameter::OutWidth: + OutWidth = *inValueInt; + break; + case Util::NvParameter::OutHeight: + OutHeight = *inValueInt; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_Balanced: + BalancedPreset = *inValueInt; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_DLAA: + DLAAPreset = *inValueInt; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_Performance: + PerfPreset = *inValueInt; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_Quality: + QualityPreset = *inValueInt; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_UltraQuality: + UltraQualityPreset = *inValueInt; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_UltraPerformance: + UltraPerfPreset = *inValueInt; + break; + case Util::NvParameter::DLSS_Feature_Create_Flags: + Hdr = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_IsHDR; + EnableSharpening = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_DoSharpening; + DepthInverted = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_DepthInverted; + JitterMotion = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_MVJittered; + LowRes = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_MVLowRes; + AutoExposure = *inValueInt & NVSDK_NGX_DLSS_Feature_Flags_AutoExposure; + break; + case Util::NvParameter::DLSS_Input_Bias_Current_Color_Mask: + InputBiasCurrentColorMask = inValuePtr; + break; + case Util::NvParameter::Color: + Color = inValuePtr; + break; + case Util::NvParameter::Depth: + Depth = inValuePtr; + break; + case Util::NvParameter::MotionVectors: + MotionVectors = inValuePtr; + break; + case Util::NvParameter::Output: + Output = inValuePtr; + break; + case Util::NvParameter::TransparencyMask: + TransparencyMask = inValuePtr; + break; + case Util::NvParameter::ExposureTexture: + ExposureTexture = inValuePtr; + break; + case Util::NvParameter::Exposure_Scale: + ExposureScale = *inValueFloat; + break; + default: + LOG("Set_Internal Not Implemented : " + s, LEVEL_DEBUG); + + } +} + +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetOptimalSettingsCallback(NVSDK_NGX_Parameter* InParams); +NVSDK_NGX_API NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetStatsCallback(NVSDK_NGX_Parameter* InParams); + +NVSDK_NGX_Result NvParameter::Get_Internal(const char* InName, unsigned long long* OutValue, NvParameterType ParameterType) const +{ + auto outValueFloat = (float*)OutValue; + auto outValueInt = (int*)OutValue; + auto outValueDouble = (double*)OutValue; + auto outValueUInt = (unsigned int*)OutValue; + auto outValueULL = (unsigned long long*)OutValue; + //Includes DirectX Resources + auto outValuePtr = (void**)OutValue; + + std::string s; + s = InName; + + switch (Util::NvParameterToEnum(InName)) + { + case Util::NvParameter::Sharpness: + *outValueFloat = Sharpness; + break; + case Util::NvParameter::SuperSampling_Available: + *outValueInt = true; + break; + case Util::NvParameter::SuperSampling_FeatureInitResult: + *outValueInt = NVSDK_NGX_Result_Success; + break; + case Util::NvParameter::SuperSampling_NeedsUpdatedDriver: + *outValueInt = 0; + break; + case Util::NvParameter::SuperSampling_MinDriverVersionMinor: + case Util::NvParameter::SuperSampling_MinDriverVersionMajor: + *outValueInt = 0; + break; + case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Width: + *outValueInt = Width; + break; + case Util::NvParameter::DLSS_Render_Subrect_Dimensions_Height: + *outValueInt = Height; + break; + case Util::NvParameter::OutWidth: + *outValueInt = OutWidth; + break; + case Util::NvParameter::OutHeight: + *outValueInt = OutHeight; + break; + case Util::NvParameter::DLSS_Get_Dynamic_Max_Render_Width: + *outValueInt = Width; + break; + case Util::NvParameter::DLSS_Get_Dynamic_Max_Render_Height: + *outValueInt = Height; + break; + case Util::NvParameter::DLSS_Get_Dynamic_Min_Render_Width: + *outValueInt = OutWidth; + break; + case Util::NvParameter::DLSS_Get_Dynamic_Min_Render_Height: + *outValueInt = OutHeight; + break; + case Util::NvParameter::DLSSOptimalSettingsCallback: + *outValuePtr = NVSDK_NGX_DLSS_GetOptimalSettingsCallback; + break; + case Util::NvParameter::DLSSGetStatsCallback: + *outValuePtr = NVSDK_NGX_DLSS_GetStatsCallback; + break; + case Util::NvParameter::SizeInBytes: + *outValueULL = 0x1337; //Dummy value + break; + case Util::NvParameter::OptLevel: + *outValueInt = 0; //Dummy value + break; + case Util::NvParameter::IsDevSnippetBranch: + *outValueInt = 0; //Dummy value + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_Balanced: + *outValueInt = BalancedPreset; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_DLAA: + *outValueInt = DLAAPreset; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_Performance: + *outValueInt = PerfPreset; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_Quality: + *outValueInt = QualityPreset; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_UltraQuality: + *outValueInt = UltraQualityPreset; + break; + case Util::NvParameter::DLSS_Hint_Render_Preset_UltraPerformance: + *outValueInt = UltraPerfPreset; + break; + default: + LOG("Get_Internal Not Implemented : " + s, LEVEL_DEBUG); + return NVSDK_NGX_Result_Fail; + } + + LOG("Get_Internal : " + s + " - f:" + std::to_string(*outValueFloat) + " - d:" + std::to_string(*outValueDouble) + " - i:" + std::to_string(*outValueInt) + " - u:" + std::to_string(*outValueUInt) + " - ul:" + std::to_string(*outValueULL), LEVEL_DEBUG); + return NVSDK_NGX_Result_Success; +} + +// EvaluateRenderScale helper +inline xess_quality_settings_t DLSS2XeSSQualityTable(const NVSDK_NGX_PerfQuality_Value input) +{ + xess_quality_settings_t output; + + switch (input) + { + case NVSDK_NGX_PerfQuality_Value_UltraPerformance: + output = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_MaxPerf: + output = XESS_QUALITY_SETTING_PERFORMANCE; + break; + case NVSDK_NGX_PerfQuality_Value_Balanced: + output = XESS_QUALITY_SETTING_BALANCED; + break; + case NVSDK_NGX_PerfQuality_Value_MaxQuality: + output = XESS_QUALITY_SETTING_QUALITY; + break; + case NVSDK_NGX_PerfQuality_Value_UltraQuality: + output = XESS_QUALITY_SETTING_ULTRA_QUALITY; + break; + default: + output = XESS_QUALITY_SETTING_BALANCED; //Set out-of-range value for non-existing fsr ultra quality mode + break; + } + + return output; +} + +// EvaluateRenderScale helper +inline std::optional GetQualityOverrideRatio(const NVSDK_NGX_PerfQuality_Value input) +{ + std::optional output; + + if (!(CyberXessContext::instance()->MyConfig->QualityRatioOverrideEnabled.has_value() && CyberXessContext::instance()->MyConfig->QualityRatioOverrideEnabled)) + return output; // override not enabled + + switch (input) + { + case NVSDK_NGX_PerfQuality_Value_UltraPerformance: + output = CyberXessContext::instance()->MyConfig->QualityRatio_UltraPerformance; + break; + case NVSDK_NGX_PerfQuality_Value_MaxPerf: + output = CyberXessContext::instance()->MyConfig->QualityRatio_Performance; + break; + case NVSDK_NGX_PerfQuality_Value_Balanced: + output = CyberXessContext::instance()->MyConfig->QualityRatio_Balanced; + break; + case NVSDK_NGX_PerfQuality_Value_MaxQuality: + output = CyberXessContext::instance()->MyConfig->QualityRatio_Quality; + break; + case NVSDK_NGX_PerfQuality_Value_UltraQuality: + output = CyberXessContext::instance()->MyConfig->QualityRatio_UltraQuality; + break; + default: + LOG("GetQualityOverrideRatio: Unknown quality : " + std::to_string(input), LEVEL_WARNING); + output = CyberXessContext::instance()->MyConfig->QualityRatio_Balanced; + break; + } + return output; +} + +void NvParameter::EvaluateRenderScale() +{ + LOG("EvaluateRenderScale start :" + std::to_string(Width) + "x" + std::to_string(Height) + " o:" + std::to_string(OutWidth) + "x" + std::to_string(OutHeight), LEVEL_DEBUG); + + const std::optional QualityRatio = GetQualityOverrideRatio(PerfQualityValue); + + if (QualityRatio.has_value()) { + OutHeight = (unsigned int)((float)Height / QualityRatio.value()); + OutWidth = (unsigned int)((float)Width / QualityRatio.value()); + } + else { + const xess_quality_settings_t xessQualityMode = DLSS2XeSSQualityTable(PerfQualityValue); + + LOG("EvaluateRenderScale Quality : " + std::to_string(PerfQualityValue), LEVEL_DEBUG); + + switch (PerfQualityValue) + { + case NVSDK_NGX_PerfQuality_Value_UltraPerformance: + OutHeight = (unsigned int)((float)Height / 3.0); + OutWidth = (unsigned int)((float)Width / 3.0); + break; + case NVSDK_NGX_PerfQuality_Value_MaxPerf: + OutHeight = (unsigned int)((float)Height / 2.0); + OutWidth = (unsigned int)((float)Width / 2.0); + break; + case NVSDK_NGX_PerfQuality_Value_Balanced: + OutHeight = (unsigned int)((float)Height / 1.699115044247788); + OutWidth = (unsigned int)((float)Width / 1.699115044247788); + break; + case NVSDK_NGX_PerfQuality_Value_MaxQuality: + OutHeight = (unsigned int)((float)Height / 1.5); + OutWidth = (unsigned int)((float)Width / 1.5); + break; + case NVSDK_NGX_PerfQuality_Value_UltraQuality: + OutHeight = (unsigned int)((float)Height / 1.299932295192959); + OutWidth = (unsigned int)((float)Width / 1.299932295192959); + break; + default: + OutHeight = (unsigned int)((float)Height / 1.699115044247788); + OutWidth = (unsigned int)((float)Width / 1.699115044247788); + break; + } + } + + LOG("EvaluateRenderScale end :" + std::to_string(Width) + "x" + std::to_string(Height) + " o:" + std::to_string(OutWidth) + "x" + std::to_string(OutHeight), LEVEL_DEBUG); +} + +NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetOptimalSettingsCallback(NVSDK_NGX_Parameter* InParams) +{ + auto params = static_cast(InParams); + params->EvaluateRenderScale(); + return NVSDK_NGX_Result_Success; +} + +NVSDK_NGX_Result NVSDK_CONV NVSDK_NGX_DLSS_GetStatsCallback(NVSDK_NGX_Parameter* InParams) +{ + //TODO: Somehow check for allocated memory + //Then set values: SizeInBytes, OptLevel, IsDevSnippetBranch + return NVSDK_NGX_Result_Success; +} \ No newline at end of file diff --git a/CyberXeSS_YEDEK/NvParameter.h b/CyberXeSS_YEDEK/NvParameter.h new file mode 100644 index 00000000..10bc7267 --- /dev/null +++ b/CyberXeSS_YEDEK/NvParameter.h @@ -0,0 +1,84 @@ +#pragma once +#include "pch.h" + +enum NvParameterType { + NvInt, + NvFloat, + NvDouble, + NvUInt, + NvULL, + NvD3D11Resource, + NvD3D12Resource, + NvVoidPtr +}; + +struct NvParameter : NVSDK_NGX_Parameter +{ + unsigned int Width{}, Height{}, OutWidth{}, OutHeight{}; + NVSDK_NGX_PerfQuality_Value PerfQualityValue = NVSDK_NGX_PerfQuality_Value_Balanced; + bool RTXValue{}, FreeMemOnReleaseFeature{}; + int CreationNodeMask{}, VisibilityNodeMask{}, OptLevel{}, IsDevSnippetBranch{}; + int DLAAPreset{}, UltraQualityPreset{}, QualityPreset{}, BalancedPreset{}, PerfPreset{}, UltraPerfPreset{}; + float Sharpness = 1.0f; + float ExposureScale = 1.0f; + int ResetRender = 0; + float MVScaleX = 1.0, MVScaleY = 1.0; + float JitterOffsetX{}, JitterOffsetY{}; + + long long SizeInBytes{}; + + bool DepthInverted{}, AutoExposure{}, Hdr{}, EnableSharpening{}, JitterMotion{}, LowRes{}; + + //external Resources + void* InputBiasCurrentColorMask{}; + void* Color{}; + void* Depth{}; + void* MotionVectors{}; + void* Output{}; + void* TransparencyMask{}; + void* ExposureTexture{}; + + virtual void Set(const char* InName, unsigned long long InValue) override; + virtual void Set(const char* InName, float InValue) override; + virtual void Set(const char* InName, double InValue) override; + virtual void Set(const char* InName, unsigned int InValue) override; + virtual void Set(const char* InName, int InValue) override; + virtual void Set(const char* InName, ID3D11Resource* InValue) override; + virtual void Set(const char* InName, ID3D12Resource* InValue) override; + virtual void Set(const char* InName, void* InValue) override; + virtual NVSDK_NGX_Result Get(const char* InName, unsigned long long* OutValue) const override; + virtual NVSDK_NGX_Result Get(const char* InName, float* OutValue) const override; + virtual NVSDK_NGX_Result Get(const char* InName, double* OutValue) const override; + virtual NVSDK_NGX_Result Get(const char* InName, unsigned int* OutValue) const override; + virtual NVSDK_NGX_Result Get(const char* InName, int* OutValue) const override; + virtual NVSDK_NGX_Result Get(const char* InName, ID3D11Resource** OutValue) const override; + virtual NVSDK_NGX_Result Get(const char* InName, ID3D12Resource** OutValue) const override; + virtual NVSDK_NGX_Result Get(const char* InName, void** OutValue) const override; + virtual void Reset() override; + + void Set_Internal(const char* InName, unsigned long long InValue, NvParameterType ParameterType); + NVSDK_NGX_Result Get_Internal(const char* InName, unsigned long long* OutValue, NvParameterType ParameterType) const; + + void EvaluateRenderScale(); + + std::vector> Params; + + __declspec(noinline) NvParameter* AllocateParameters() + { + Params.push_back(std::make_shared()); + return Params.back().get(); + } + + __declspec(noinline) void DeleteParameters(NvParameter* param) + { + auto it = std::find_if(Params.begin(), Params.end(), + [param](const auto& p) { return p.get() == param; }); + Params.erase(it); + } + + static std::shared_ptr instance() + { + static std::shared_ptr INSTANCE { std::make_shared() }; + return INSTANCE; + } +}; diff --git a/CyberXeSS_YEDEK/Util.cpp b/CyberXeSS_YEDEK/Util.cpp new file mode 100644 index 00000000..0fc1d2b8 --- /dev/null +++ b/CyberXeSS_YEDEK/Util.cpp @@ -0,0 +1,100 @@ +#include "pch.h" +#include "Config.h" +#include "Util.h" + +namespace fs = std::filesystem; + +extern HMODULE dllModule; + +fs::path Util::DllPath() +{ + static fs::path dll; + if (dll.empty()) + { + wchar_t dllPath[MAX_PATH]; + GetModuleFileNameW(dllModule, dllPath, MAX_PATH); + dll = fs::path(dllPath); + } + return dll; +} + +fs::path Util::ExePath() +{ + static fs::path exe; + if (exe.empty()) + { + wchar_t exePath[MAX_PATH]; + GetModuleFileNameW(nullptr, exePath, MAX_PATH); + exe = fs::path(exePath); + } + return exe; +} + +Util::NvParameter Util::NvParameterToEnum(const char* name) +{ + static ankerl::unordered_dense::map NvParamTranslation = { + {"SuperSampling.ScaleFactor", NvParameter::SuperSampling_ScaleFactor}, + {"SuperSampling.Available", NvParameter::SuperSampling_Available}, + {"SuperSampling.MinDriverVersionMajor", NvParameter::SuperSampling_MinDriverVersionMajor}, + {"SuperSampling.MinDriverVersionMinor", NvParameter::SuperSampling_MinDriverVersionMinor}, + {"SuperSampling.FeatureInitResult", NvParameter::SuperSampling_FeatureInitResult}, + {"SuperSampling.NeedsUpdatedDriver", NvParameter::SuperSampling_NeedsUpdatedDriver}, + {"#\x01", NvParameter::SuperSampling_Available}, + + {"Width", NvParameter::Width}, + {"Height", NvParameter::Height}, + {"PerfQualityValue", NvParameter::PerfQualityValue}, + {"RTXValue", NvParameter::RTXValue}, + {"NVSDK_NGX_Parameter_FreeMemOnReleaseFeature", NvParameter::FreeMemOnReleaseFeature}, + + {"OutWidth", NvParameter::OutWidth}, + {"OutHeight", NvParameter::OutHeight}, + + {"DLSS.Render.Subrect.Dimensions.Width", NvParameter::DLSS_Render_Subrect_Dimensions_Width}, + {"DLSS.Render.Subrect.Dimensions.Height", NvParameter::DLSS_Render_Subrect_Dimensions_Height}, + {"DLSS.Get.Dynamic.Max.Render.Width", NvParameter::DLSS_Get_Dynamic_Max_Render_Width}, + {"DLSS.Get.Dynamic.Max.Render.Height", NvParameter::DLSS_Get_Dynamic_Max_Render_Height}, + {"DLSS.Get.Dynamic.Min.Render.Width", NvParameter::DLSS_Get_Dynamic_Min_Render_Width}, + {"DLSS.Get.Dynamic.Min.Render.Height", NvParameter::DLSS_Get_Dynamic_Min_Render_Height}, + {"Sharpness", NvParameter::Sharpness}, + + {"DLSSOptimalSettingsCallback", NvParameter::DLSSOptimalSettingsCallback}, + {"DLSSGetStatsCallback", NvParameter::DLSSGetStatsCallback}, + + {"CreationNodeMask", NvParameter::CreationNodeMask}, + {"VisibilityNodeMask", NvParameter::VisibilityNodeMask}, + {"DLSS.Feature.Create.Flags", NvParameter::DLSS_Feature_Create_Flags}, + {"DLSS.Enable.Output.Subrects", NvParameter::DLSS_Enable_Output_Subrects}, + + {"Color", NvParameter::Color}, + {"MotionVectors", NvParameter::MotionVectors}, + {"Depth", NvParameter::Depth}, + {"Output", NvParameter::Output}, + {"TransparencyMask", NvParameter::TransparencyMask}, + {"ExposureTexture", NvParameter::ExposureTexture}, + {"DLSS.Input.Bias.Current.Color.Mask", NvParameter::DLSS_Input_Bias_Current_Color_Mask}, + + {"DLSS.Pre.Exposure", NvParameter::Pre_Exposure}, + {"DLSS.Exposure.Scale", NvParameter::Exposure_Scale}, + + {"Reset", NvParameter::Reset}, + {"MV.Scale.X", NvParameter::MV_Scale_X}, + {"MV.Scale.Y", NvParameter::MV_Scale_Y}, + {"Jitter.Offset.X", NvParameter::Jitter_Offset_X}, + {"Jitter.Offset.Y", NvParameter::Jitter_Offset_Y}, + + {"SizeInBytes", NvParameter::SizeInBytes}, + {"Snippet.OptLevel", NvParameter::OptLevel}, + {"#\x44", NvParameter::OptLevel}, + {"Snippet.IsDevBranch", NvParameter::IsDevSnippetBranch}, + {"#\x45", NvParameter::IsDevSnippetBranch}, + {"DLSS.Hint.Render.Preset.DLAA", NvParameter::DLSS_Hint_Render_Preset_DLAA}, + {"DLSS.Hint.Render.Preset.UltraQuality", NvParameter::DLSS_Hint_Render_Preset_UltraQuality}, + {"DLSS.Hint.Render.Preset.Quality", NvParameter::DLSS_Hint_Render_Preset_Quality}, + {"DLSS.Hint.Render.Preset.Balanced", NvParameter::DLSS_Hint_Render_Preset_Balanced}, + {"DLSS.Hint.Render.Preset.Performance", NvParameter::DLSS_Hint_Render_Preset_Performance}, + {"DLSS.Hint.Render.Preset.UltraPerformance", NvParameter::DLSS_Hint_Render_Preset_UltraPerformance}, + }; + + return NvParamTranslation[std::string(name)]; +} diff --git a/CyberXeSS_YEDEK/Util.h b/CyberXeSS_YEDEK/Util.h new file mode 100644 index 00000000..2d9186f8 --- /dev/null +++ b/CyberXeSS_YEDEK/Util.h @@ -0,0 +1,91 @@ +#pragma once +#include "Config.h" + +namespace Util +{ + std::filesystem::path ExePath(); + + std::filesystem::path DllPath(); + + enum class NvParameter + { + Invalid, + + //SuperSampling + SuperSampling_ScaleFactor, + SuperSampling_Available, + SuperSampling_MinDriverVersionMajor, + SuperSampling_MinDriverVersionMinor, + SuperSampling_FeatureInitResult, + SuperSampling_NeedsUpdatedDriver, + + //User settings stuff + Width, + Height, + PerfQualityValue, + RTXValue, + FreeMemOnReleaseFeature, + + //Resolution stuff + OutWidth, + OutHeight, + + DLSS_Render_Subrect_Dimensions_Width, + DLSS_Render_Subrect_Dimensions_Height, + DLSS_Get_Dynamic_Max_Render_Width, + DLSS_Get_Dynamic_Max_Render_Height, + DLSS_Get_Dynamic_Min_Render_Width, + DLSS_Get_Dynamic_Min_Render_Height, + Sharpness, + + //Callbacks + DLSSGetStatsCallback, + DLSSOptimalSettingsCallback, + + //Render stuff + CreationNodeMask, + VisibilityNodeMask, + DLSS_Feature_Create_Flags, + DLSS_Enable_Output_Subrects, + + //D3D12 Buffers + Color, + MotionVectors, + Depth, + Output, + TransparencyMask, + ExposureTexture, + DLSS_Input_Bias_Current_Color_Mask, + Pre_Exposure, + Exposure_Scale, + + Reset, + MV_Scale_X, + MV_Scale_Y, + Jitter_Offset_X, + Jitter_Offset_Y, + + //Dev Stuff + SizeInBytes, + OptLevel, + IsDevSnippetBranch, + + DLSS_Hint_Render_Preset_DLAA, + DLSS_Hint_Render_Preset_UltraQuality, + DLSS_Hint_Render_Preset_Quality, + DLSS_Hint_Render_Preset_Balanced, + DLSS_Hint_Render_Preset_Performance, + DLSS_Hint_Render_Preset_UltraPerformance + }; + + NvParameter NvParameterToEnum(const char* name); +}; + +inline void ThrowIfFailed(HRESULT hr) +{ + if (FAILED(hr)) + { + // Set a breakpoint on this line to catch DirectX API errors + throw std::exception(); + } +} \ No newline at end of file diff --git a/CyberXeSS_YEDEK/WrappedD3D12Device.cpp b/CyberXeSS_YEDEK/WrappedD3D12Device.cpp new file mode 100644 index 00000000..142dd840 --- /dev/null +++ b/CyberXeSS_YEDEK/WrappedD3D12Device.cpp @@ -0,0 +1,702 @@ +#include "pch.h" +#include "WrappedD3D12Device.h" + +bool RefCountD3D12Object::HandleWrap(const char* ifaceName, REFIID riid, void** ppvObject) +{ + LOG("RefCountD3D12Object.HandleWrap"); + + if (ppvObject == NULL || *ppvObject == NULL) + { + std::string str(ifaceName); + LOG("RefCountD3D12Object.HandleWrap called with NULL ppvObject querying " + str); + return false; + } + + // unknown GUID that we only want to print once to avoid log spam + // {79D2046C-22EF-451B-9E74-2245D9C760EA} + static const GUID Unknown_uuid = { + 0x79d2046c, 0x22ef, 0x451b, {0x9e, 0x74, 0x22, 0x45, 0xd9, 0xc7, 0x60, 0xea} }; + + // unknown/undocumented internal interface + // {7abb6563-02bc-47c4-8ef9-acc4795edbcf} + static const GUID ID3D12DeviceInternal2_uuid = { + 0x7abb6563, 0x02bc, 0x47c4, {0x8e, 0xf9, 0xac, 0xc4, 0x79, 0x5e, 0xdb, 0xcf} }; + + if (riid == __uuidof(ID3D12Device)) + { + ID3D12Device* real = (ID3D12Device*)(*ppvObject); + *ppvObject = (ID3D12Device*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device1)) + { + ID3D12Device1* real = (ID3D12Device1*)(*ppvObject); + *ppvObject = (ID3D12Device1*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device2)) + { + ID3D12Device2* real = (ID3D12Device2*)(*ppvObject); + *ppvObject = (ID3D12Device2*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device3)) + { + ID3D12Device3* real = (ID3D12Device3*)(*ppvObject); + *ppvObject = (ID3D12Device3*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device4)) + { + ID3D12Device4* real = (ID3D12Device4*)(*ppvObject); + *ppvObject = (ID3D12Device4*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device5)) + { + ID3D12Device5* real = (ID3D12Device5*)(*ppvObject); + *ppvObject = (ID3D12Device5*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device6)) + { + ID3D12Device6* real = (ID3D12Device6*)(*ppvObject); + *ppvObject = (ID3D12Device6*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device7)) + { + ID3D12Device7* real = (ID3D12Device7*)(*ppvObject); + *ppvObject = (ID3D12Device7*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device8)) + { + ID3D12Device8* real = (ID3D12Device8*)(*ppvObject); + *ppvObject = (ID3D12Device8*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device9)) + { + ID3D12Device9* real = (ID3D12Device9*)(*ppvObject); + *ppvObject = (ID3D12Device9*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == __uuidof(ID3D12Device10)) + { + ID3D12Device10* real = (ID3D12Device10*)(*ppvObject); + *ppvObject = (ID3D12Device10*)(new WrappedD3D12Device(real)); + return true; + } + else if (riid == Unknown_uuid) + { + LOG("RefCountDXGIObject.HandleWrap Querying Unknown_uuid, returning false"); + } + else if (riid == ID3D12DeviceInternal2_uuid) + { + LOG("RefCountDXGIObject.HandleWrap Querying ID3D12DeviceInternal2_uuid, returning false"); + } + else + { + std::string str(ifaceName); + LOG("RefCountDXGIObject.HandleWrap Querying " + str + " for unrecognized GUID: " + ToString(riid)); + } + + return false; +} + +HRESULT RefCountD3D12Object::WrapQueryInterface(IUnknown* real, const char* ifaceName, REFIID riid, void** ppvObject) +{ + LOG("RefCountD3D12Object.WrapQueryInterface"); + + HRESULT ret = real->QueryInterface(riid, ppvObject); + + if (ret == S_OK && HandleWrap(ifaceName, riid, ppvObject)) + return ret; + + *ppvObject = NULL; + return E_NOINTERFACE; +} + +WrappedD3D12Device::WrappedD3D12Device(ID3D12Device* device) : RefCountD3D12Object(device), m_device(device) +{ + m_device1 = NULL; + device->QueryInterface(__uuidof(ID3D12Device1), (void**)&m_device1); + m_device2 = NULL; + device->QueryInterface(__uuidof(ID3D12Device2), (void**)&m_device2); + m_device3 = NULL; + device->QueryInterface(__uuidof(ID3D12Device3), (void**)&m_device3); + m_device4 = NULL; + device->QueryInterface(__uuidof(ID3D12Device4), (void**)&m_device4); + m_device5 = NULL; + device->QueryInterface(__uuidof(ID3D12Device5), (void**)&m_device5); + m_device6 = NULL; + device->QueryInterface(__uuidof(ID3D12Device6), (void**)&m_device6); + m_device7 = NULL; + device->QueryInterface(__uuidof(ID3D12Device7), (void**)&m_device7); + m_device8 = NULL; + device->QueryInterface(__uuidof(ID3D12Device8), (void**)&m_device8); + m_device9 = NULL; + device->QueryInterface(__uuidof(ID3D12Device9), (void**)&m_device9); + m_device10 = NULL; + device->QueryInterface(__uuidof(ID3D12Device10), (void**)&m_device10); +} + +WrappedD3D12Device::~WrappedD3D12Device() +{ + SAFE_RELEASE(m_device); + SAFE_RELEASE(m_device1); + SAFE_RELEASE(m_device2); + SAFE_RELEASE(m_device3); + SAFE_RELEASE(m_device4); + SAFE_RELEASE(m_device5); + SAFE_RELEASE(m_device6); + SAFE_RELEASE(m_device7); + SAFE_RELEASE(m_device8); + SAFE_RELEASE(m_device9); + SAFE_RELEASE(m_device10); +} + + +HRESULT __stdcall WrappedD3D12Device::QueryInterface(REFIID riid, void** ppvObject) +{ + LOG("D3D12Device.QueryInterface: " + ToString(riid)); + + if (ppvObject == nullptr) + return E_POINTER; + + if (riid == __uuidof(ID3D12Device)) + { + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + if (riid == __uuidof(ID3D12ProxyDevice)) + { + LOG("D3D12Device.QueryInterface: Looking for ID3D12ProxyDevice, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device1)) + { + if (m_device1 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device1 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device1, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device2)) + { + if (m_device2 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device2 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device2, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device3)) + { + if (m_device == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device3 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device3, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device4)) + { + if (m_device4 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device4 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device4, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device5)) + { + if (m_device5 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device5 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device5, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device6)) + { + if (m_device6 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device6 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device6, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device7)) + { + if (m_device7 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device7 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device7, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device8)) + { + if (m_device8 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device8 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device8, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device9)) + { + if (m_device9 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device9 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device9, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Device10)) + { + if (m_device10 == nullptr) + { + LOG("D3D12Device.QueryInterface: m_device10 is not available, returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + + LOG("D3D12Device.QueryInterface: Looking for ID3D12Device10, returning this"); + AddRef(); + *ppvObject = this; + return S_OK; + } + else if (riid == __uuidof(ID3D12DeviceRemovedExtendedData) || + riid == __uuidof(ID3D12DeviceRemovedExtendedData1) || + riid == __uuidof(ID3D12DeviceRemovedExtendedData2)) + { + LOG("D3D12Device.QueryInterface: Looking for ID3D12DeviceRemovedExtendedData"); + auto ret = m_device->QueryInterface(riid, ppvObject); + LOG("D3D12Device.QueryInterface: Looking for ID3D12DeviceRemovedExtendedData result: " + int_to_hex(ret)); + return ret; + } + + auto hr = m_device->QueryInterface(riid, ppvObject); + + if (hr == S_OK && *ppvObject != nullptr) + { + auto wrapResult = RefCountD3D12Object::HandleWrap("ID3DDevice", riid, ppvObject); + + if (!wrapResult) + { + LOG("D3D12Device.QueryInterface: returning E_NOINTERFACE"); + return E_NOINTERFACE; + } + } + + LOG("D3D12Device.QueryInterface Unknown interface result: " + int_to_hex(hr)); + return hr; +} + +HRESULT STDMETHODCALLTYPE RefCountD3D12Object::SetName(_In_z_ LPCWSTR Name) +{ + return m_pReal->SetName(Name); +} + +UINT __stdcall WrappedD3D12Device::GetNodeCount(void) +{ + return m_device->GetNodeCount(); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC* pDesc, REFIID riid, void** ppCommandQueue) +{ + return m_device->CreateCommandQueue(pDesc, riid, ppCommandQueue); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type, REFIID riid, void** ppCommandAllocator) +{ + return m_device->CreateCommandAllocator(type, riid, ppCommandAllocator); +} + +HRESULT __stdcall WrappedD3D12Device::CreateGraphicsPipelineState(const D3D12_GRAPHICS_PIPELINE_STATE_DESC* pDesc, REFIID riid, void** ppPipelineState) +{ + return m_device->CreateGraphicsPipelineState(pDesc, riid, ppPipelineState); +} + +HRESULT __stdcall WrappedD3D12Device::CreateComputePipelineState(const D3D12_COMPUTE_PIPELINE_STATE_DESC* pDesc, REFIID riid, void** ppPipelineState) +{ + return m_device->CreateComputePipelineState(pDesc, riid, ppPipelineState); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator* pCommandAllocator, ID3D12PipelineState* pInitialState, REFIID riid, void** ppCommandList) +{ + return m_device->CreateCommandList(nodeMask, type, pCommandAllocator, pInitialState, riid, ppCommandList); +} + +HRESULT __stdcall WrappedD3D12Device::CheckFeatureSupport(D3D12_FEATURE Feature, void* pFeatureSupportData, UINT FeatureSupportDataSize) +{ + return m_device->CheckFeatureSupport(Feature, pFeatureSupportData, FeatureSupportDataSize); +} + +HRESULT __stdcall WrappedD3D12Device::CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DESC* pDescriptorHeapDesc, REFIID riid, void** ppvHeap) +{ + return m_device->CreateDescriptorHeap(pDescriptorHeapDesc, riid, ppvHeap); +} + +UINT __stdcall WrappedD3D12Device::GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType) +{ + return m_device->GetDescriptorHandleIncrementSize(DescriptorHeapType); +} + +HRESULT __stdcall WrappedD3D12Device::CreateRootSignature(UINT nodeMask, const void* pBlobWithRootSignature, SIZE_T blobLengthInBytes, REFIID riid, void** ppvRootSignature) +{ + return m_device->CreateRootSignature(nodeMask, pBlobWithRootSignature, blobLengthInBytes, riid, ppvRootSignature); +} + +void __stdcall WrappedD3D12Device::CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + return m_device->CreateConstantBufferView(pDesc, DestDescriptor); +} + +void __stdcall WrappedD3D12Device::CreateShaderResourceView(ID3D12Resource* pResource, const D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + return m_device->CreateShaderResourceView(pResource, pDesc, DestDescriptor); +} + +void __stdcall WrappedD3D12Device::CreateUnorderedAccessView(ID3D12Resource* pResource, ID3D12Resource* pCounterResource, const D3D12_UNORDERED_ACCESS_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + return m_device->CreateUnorderedAccessView(pResource, pCounterResource, pDesc, DestDescriptor); +} + +void __stdcall WrappedD3D12Device::CreateRenderTargetView(ID3D12Resource* pResource, const D3D12_RENDER_TARGET_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + return m_device->CreateRenderTargetView(pResource, pDesc, DestDescriptor); +} + +void __stdcall WrappedD3D12Device::CreateDepthStencilView(ID3D12Resource* pResource, const D3D12_DEPTH_STENCIL_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + return m_device->CreateDepthStencilView(pResource, pDesc, DestDescriptor); +} + +void __stdcall WrappedD3D12Device::CreateSampler(const D3D12_SAMPLER_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + return m_device->CreateSampler(pDesc, DestDescriptor); +} + +void __stdcall WrappedD3D12Device::CopyDescriptors(UINT NumDestDescriptorRanges, const D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, const UINT* pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges, const D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, const UINT* pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) +{ + return m_device->CopyDescriptors(NumDestDescriptorRanges, pDestDescriptorRangeStarts, pDestDescriptorRangeSizes, NumSrcDescriptorRanges, pSrcDescriptorRangeStarts, pSrcDescriptorRangeSizes, DescriptorHeapsType); +} + +void __stdcall WrappedD3D12Device::CopyDescriptorsSimple(UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) +{ + return m_device->CopyDescriptorsSimple(NumDescriptors, DestDescriptorRangeStart, SrcDescriptorRangeStart, DescriptorHeapsType); +} + +D3D12_RESOURCE_ALLOCATION_INFO __stdcall WrappedD3D12Device::GetResourceAllocationInfo(UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC* pResourceDescs) +{ + return m_device->GetResourceAllocationInfo(visibleMask, numResourceDescs, pResourceDescs); +} + +D3D12_HEAP_PROPERTIES __stdcall WrappedD3D12Device::GetCustomHeapProperties(UINT nodeMask, D3D12_HEAP_TYPE heapType) +{ + return m_device->GetCustomHeapProperties(nodeMask, heapType); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommittedResource(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riidResource, void** ppvResource) +{ + return m_device->CreateCommittedResource(pHeapProperties, HeapFlags, pDesc, InitialResourceState, pOptimizedClearValue, riidResource, ppvResource); +} + +HRESULT __stdcall WrappedD3D12Device::CreateHeap(const D3D12_HEAP_DESC* pDesc, REFIID riid, void** ppvHeap) +{ + return m_device->CreateHeap(pDesc, riid, ppvHeap); +} + +HRESULT __stdcall WrappedD3D12Device::CreatePlacedResource(ID3D12Heap* pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riid, void** ppvResource) +{ + return m_device->CreatePlacedResource(pHeap, HeapOffset, pDesc, InitialState, pOptimizedClearValue, riid, ppvResource); +} + +HRESULT __stdcall WrappedD3D12Device::CreateReservedResource(const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riid, void** ppvResource) +{ + return m_device->CreateReservedResource(pDesc, InitialState, pOptimizedClearValue, riid, ppvResource); +} + +HRESULT __stdcall WrappedD3D12Device::CreateSharedHandle(ID3D12DeviceChild* pObject, const SECURITY_ATTRIBUTES* pAttributes, DWORD Access, LPCWSTR Name, HANDLE* pHandle) +{ + return m_device->CreateSharedHandle(pObject, pAttributes, Access, Name, pHandle); +} + +HRESULT __stdcall WrappedD3D12Device::OpenSharedHandle(HANDLE NTHandle, REFIID riid, void** ppvObj) +{ + return m_device->OpenSharedHandle(NTHandle, riid, ppvObj); +} + +HRESULT __stdcall WrappedD3D12Device::OpenSharedHandleByName(LPCWSTR Name, DWORD Access, HANDLE* pNTHandle) +{ + return m_device->OpenSharedHandleByName(Name, Access, pNTHandle); +} + +HRESULT __stdcall WrappedD3D12Device::MakeResident(UINT NumObjects, ID3D12Pageable* const* ppObjects) +{ + return m_device->MakeResident(NumObjects, ppObjects); +} + +HRESULT __stdcall WrappedD3D12Device::Evict(UINT NumObjects, ID3D12Pageable* const* ppObjects) +{ + return m_device->Evict(NumObjects, ppObjects); +} + +HRESULT __stdcall WrappedD3D12Device::CreateFence(UINT64 InitialValue, D3D12_FENCE_FLAGS Flags, REFIID riid, void** ppFence) +{ + return m_device->CreateFence(InitialValue, Flags, riid, ppFence); +} + +HRESULT __stdcall WrappedD3D12Device::GetDeviceRemovedReason(void) +{ + return m_device->GetDeviceRemovedReason(); +} + +void __stdcall WrappedD3D12Device::GetCopyableFootprints(const D3D12_RESOURCE_DESC* pResourceDesc, UINT FirstSubresource, UINT NumSubresources, UINT64 BaseOffset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, UINT* pNumRows, UINT64* pRowSizeInBytes, UINT64* pTotalBytes) +{ + return m_device->GetCopyableFootprints(pResourceDesc, FirstSubresource, NumSubresources, BaseOffset, pLayouts, pNumRows, pRowSizeInBytes, pTotalBytes); +} + +HRESULT __stdcall WrappedD3D12Device::CreateQueryHeap(const D3D12_QUERY_HEAP_DESC* pDesc, REFIID riid, void** ppvHeap) +{ + return m_device->CreateQueryHeap(pDesc, riid, ppvHeap); +} + +HRESULT __stdcall WrappedD3D12Device::SetStablePowerState(BOOL Enable) +{ + return m_device->SetStablePowerState(Enable); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC* pDesc, ID3D12RootSignature* pRootSignature, REFIID riid, void** ppvCommandSignature) +{ + return m_device->CreateCommandSignature(pDesc, pRootSignature, riid, ppvCommandSignature); +} + +void __stdcall WrappedD3D12Device::GetResourceTiling(ID3D12Resource* pTiledResource, UINT* pNumTilesForEntireResource, D3D12_PACKED_MIP_INFO* pPackedMipDesc, D3D12_TILE_SHAPE* pStandardTileShapeForNonPackedMips, UINT* pNumSubresourceTilings, UINT FirstSubresourceTilingToGet, D3D12_SUBRESOURCE_TILING* pSubresourceTilingsForNonPackedMips) +{ + return m_device->GetResourceTiling(pTiledResource, pNumTilesForEntireResource, pPackedMipDesc, pStandardTileShapeForNonPackedMips, pNumSubresourceTilings, FirstSubresourceTilingToGet, pSubresourceTilingsForNonPackedMips); +} + +LUID __stdcall WrappedD3D12Device::GetAdapterLuid(void) +{ + return LUID{ 0, 56090 }; +} + +HRESULT __stdcall WrappedD3D12Device::CreatePipelineLibrary(const void* pLibraryBlob, SIZE_T BlobLength, REFIID riid, void** ppPipelineLibrary) +{ + return m_device1->CreatePipelineLibrary(pLibraryBlob, BlobLength, riid, ppPipelineLibrary); +} + +HRESULT __stdcall WrappedD3D12Device::SetEventOnMultipleFenceCompletion(ID3D12Fence* const* ppFences, const UINT64* pFenceValues, UINT NumFences, D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, HANDLE hEvent) +{ + return m_device1->SetEventOnMultipleFenceCompletion(ppFences, pFenceValues, NumFences, Flags, hEvent); +} + +HRESULT __stdcall WrappedD3D12Device::SetResidencyPriority(UINT NumObjects, ID3D12Pageable* const* ppObjects, const D3D12_RESIDENCY_PRIORITY* pPriorities) +{ + return m_device1->SetResidencyPriority(NumObjects, ppObjects, pPriorities); +} + +HRESULT __stdcall WrappedD3D12Device::CreatePipelineState(const D3D12_PIPELINE_STATE_STREAM_DESC* pDesc, REFIID riid, void** ppPipelineState) +{ + return m_device2->CreatePipelineState(pDesc, riid, ppPipelineState); +} + +HRESULT __stdcall WrappedD3D12Device::OpenExistingHeapFromAddress(const void* pAddress, REFIID riid, void** ppvHeap) +{ + return m_device3->OpenExistingHeapFromAddress(pAddress, riid, ppvHeap); +} + +HRESULT __stdcall WrappedD3D12Device::OpenExistingHeapFromFileMapping(HANDLE hFileMapping, REFIID riid, void** ppvHeap) +{ + return m_device3->OpenExistingHeapFromFileMapping(hFileMapping, riid, ppvHeap); +} + +HRESULT __stdcall WrappedD3D12Device::EnqueueMakeResident(D3D12_RESIDENCY_FLAGS Flags, UINT NumObjects, ID3D12Pageable* const* ppObjects, ID3D12Fence* pFenceToSignal, UINT64 FenceValueToSignal) +{ + return m_device3->EnqueueMakeResident(Flags, NumObjects, ppObjects, pFenceToSignal, FenceValueToSignal); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommandList1(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type, D3D12_COMMAND_LIST_FLAGS flags, REFIID riid, void** ppCommandList) +{ + return m_device4->CreateCommandList1(nodeMask, type, flags, riid, ppCommandList); +} + +HRESULT __stdcall WrappedD3D12Device::CreateProtectedResourceSession(const D3D12_PROTECTED_RESOURCE_SESSION_DESC* pDesc, REFIID riid, void** ppSession) +{ + return m_device4->CreateProtectedResourceSession(pDesc, riid, ppSession); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommittedResource1(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riidResource, void** ppvResource) +{ + return m_device4->CreateCommittedResource1(pHeapProperties, HeapFlags, pDesc, InitialResourceState, pOptimizedClearValue, pProtectedSession, riidResource, ppvResource); +} + +HRESULT __stdcall WrappedD3D12Device::CreateHeap1(const D3D12_HEAP_DESC* pDesc, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riid, void** ppvHeap) +{ + return m_device4->CreateHeap1(pDesc, pProtectedSession, riid, ppvHeap); +} + +HRESULT __stdcall WrappedD3D12Device::CreateReservedResource1(const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riid, void** ppvResource) +{ + return m_device4->CreateReservedResource1(pDesc, InitialState, pOptimizedClearValue, pProtectedSession, riid, ppvResource); +} + +D3D12_RESOURCE_ALLOCATION_INFO __stdcall WrappedD3D12Device::GetResourceAllocationInfo1(UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC* pResourceDescs, D3D12_RESOURCE_ALLOCATION_INFO1* pResourceAllocationInfo1) +{ + return m_device4->GetResourceAllocationInfo1(visibleMask, numResourceDescs, pResourceDescs, pResourceAllocationInfo1); +} + +HRESULT __stdcall WrappedD3D12Device::CreateLifetimeTracker(ID3D12LifetimeOwner* pOwner, REFIID riid, void** ppvTracker) +{ + return m_device5->CreateLifetimeTracker(pOwner, riid, ppvTracker); +} + +void __stdcall WrappedD3D12Device::RemoveDevice(void) +{ + return m_device5->RemoveDevice(); +} + +HRESULT __stdcall WrappedD3D12Device::EnumerateMetaCommands(UINT* pNumMetaCommands, D3D12_META_COMMAND_DESC* pDescs) +{ + return m_device5->EnumerateMetaCommands(pNumMetaCommands, pDescs); +} + +HRESULT __stdcall WrappedD3D12Device::EnumerateMetaCommandParameters(REFGUID CommandId, D3D12_META_COMMAND_PARAMETER_STAGE Stage, UINT* pTotalStructureSizeInBytes, UINT* pParameterCount, D3D12_META_COMMAND_PARAMETER_DESC* pParameterDescs) +{ + return m_device5->EnumerateMetaCommandParameters(CommandId, Stage, pTotalStructureSizeInBytes, pParameterCount, pParameterDescs); +} + +HRESULT __stdcall WrappedD3D12Device::CreateMetaCommand(REFGUID CommandId, UINT NodeMask, const void* pCreationParametersData, SIZE_T CreationParametersDataSizeInBytes, REFIID riid, void** ppMetaCommand) +{ + return m_device5->CreateMetaCommand(CommandId, NodeMask, pCreationParametersData, CreationParametersDataSizeInBytes, riid, ppMetaCommand); +} + +HRESULT __stdcall WrappedD3D12Device::CreateStateObject(const D3D12_STATE_OBJECT_DESC* pDesc, REFIID riid, void** ppStateObject) +{ + return m_device5->CreateStateObject(pDesc, riid, ppStateObject); +} + +void __stdcall WrappedD3D12Device::GetRaytracingAccelerationStructurePrebuildInfo(const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS* pDesc, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO* pInfo) +{ + return m_device5->GetRaytracingAccelerationStructurePrebuildInfo(pDesc, pInfo); +} + +D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS __stdcall WrappedD3D12Device::CheckDriverMatchingIdentifier(D3D12_SERIALIZED_DATA_TYPE SerializedDataType, const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER* pIdentifierToCheck) +{ + return m_device5->CheckDriverMatchingIdentifier(SerializedDataType, pIdentifierToCheck); +} + +HRESULT __stdcall WrappedD3D12Device::SetBackgroundProcessingMode(D3D12_BACKGROUND_PROCESSING_MODE Mode, D3D12_MEASUREMENTS_ACTION MeasurementsAction, HANDLE hEventToSignalUponCompletion, BOOL* pbFurtherMeasurementsDesired) +{ + return m_device6->SetBackgroundProcessingMode(Mode, MeasurementsAction, hEventToSignalUponCompletion, pbFurtherMeasurementsDesired); +} + +HRESULT __stdcall WrappedD3D12Device::AddToStateObject(const D3D12_STATE_OBJECT_DESC* pAddition, ID3D12StateObject* pStateObjectToGrowFrom, REFIID riid, void** ppNewStateObject) +{ + return m_device7->AddToStateObject(pAddition, pStateObjectToGrowFrom, riid, ppNewStateObject); +} + +HRESULT __stdcall WrappedD3D12Device::CreateProtectedResourceSession1(const D3D12_PROTECTED_RESOURCE_SESSION_DESC1* pDesc, REFIID riid, void** ppSession) +{ + return m_device7->CreateProtectedResourceSession1(pDesc, riid, ppSession); +} + +D3D12_RESOURCE_ALLOCATION_INFO __stdcall WrappedD3D12Device::GetResourceAllocationInfo2(UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC1* pResourceDescs, D3D12_RESOURCE_ALLOCATION_INFO1* pResourceAllocationInfo1) +{ + return m_device8->GetResourceAllocationInfo2(visibleMask, numResourceDescs, pResourceDescs, pResourceAllocationInfo1); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommittedResource2(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC1* pDesc, D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riidResource, void** ppvResource) +{ + return m_device8->CreateCommittedResource2(pHeapProperties, HeapFlags, pDesc, InitialResourceState, pOptimizedClearValue, pProtectedSession, riidResource, ppvResource); +} + +HRESULT __stdcall WrappedD3D12Device::CreatePlacedResource1(ID3D12Heap* pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC1* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riid, void** ppvResource) +{ + return m_device8->CreatePlacedResource1(pHeap, HeapOffset, pDesc, InitialState, pOptimizedClearValue, riid, ppvResource); +} + +void __stdcall WrappedD3D12Device::CreateSamplerFeedbackUnorderedAccessView(ID3D12Resource* pTargetedResource, ID3D12Resource* pFeedbackResource, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) +{ + return m_device8->CreateSamplerFeedbackUnorderedAccessView(pTargetedResource, pFeedbackResource, DestDescriptor); +} + +void __stdcall WrappedD3D12Device::GetCopyableFootprints1(const D3D12_RESOURCE_DESC1* pResourceDesc, UINT FirstSubresource, UINT NumSubresources, UINT64 BaseOffset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, UINT* pNumRows, UINT64* pRowSizeInBytes, UINT64* pTotalBytes) +{ + return m_device8->GetCopyableFootprints1(pResourceDesc, FirstSubresource, NumSubresources, BaseOffset, pLayouts, pNumRows, pRowSizeInBytes, pTotalBytes); +} + +HRESULT __stdcall WrappedD3D12Device::CreateShaderCacheSession(const D3D12_SHADER_CACHE_SESSION_DESC* pDesc, REFIID riid, void** ppvSession) +{ + return m_device9->CreateShaderCacheSession(pDesc, riid, ppvSession); +} + +HRESULT __stdcall WrappedD3D12Device::ShaderCacheControl(D3D12_SHADER_CACHE_KIND_FLAGS Kinds, D3D12_SHADER_CACHE_CONTROL_FLAGS Control) +{ + return m_device9->ShaderCacheControl(Kinds, Control); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommandQueue1(const D3D12_COMMAND_QUEUE_DESC* pDesc, REFIID CreatorID, REFIID riid, void** ppCommandQueue) +{ + return m_device9->CreateCommandQueue1(pDesc, CreatorID, riid, ppCommandQueue); +} + +HRESULT __stdcall WrappedD3D12Device::CreateCommittedResource3(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC1* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, UINT32 NumCastableFormats, DXGI_FORMAT* pCastableFormats, REFIID riidResource, void** ppvResource) +{ + return m_device10->CreateCommittedResource3(pHeapProperties, HeapFlags, pDesc, InitialLayout, pOptimizedClearValue, pProtectedSession, NumCastableFormats, pCastableFormats, riidResource, ppvResource); +} + +HRESULT __stdcall WrappedD3D12Device::CreatePlacedResource2(ID3D12Heap* pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC1* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, UINT32 NumCastableFormats, DXGI_FORMAT* pCastableFormats, REFIID riid, void** ppvResource) +{ + return m_device10->CreatePlacedResource2(pHeap, HeapOffset, pDesc, InitialLayout, pOptimizedClearValue, NumCastableFormats, pCastableFormats, riid, ppvResource); +} + +HRESULT __stdcall WrappedD3D12Device::CreateReservedResource2(const D3D12_RESOURCE_DESC* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, UINT32 NumCastableFormats, DXGI_FORMAT* pCastableFormats, REFIID riid, void** ppvResource) +{ + return m_device10->CreateReservedResource2(pDesc, InitialLayout, pOptimizedClearValue, pProtectedSession, NumCastableFormats, pCastableFormats, riid, ppvResource); +} diff --git a/CyberXeSS_YEDEK/WrappedD3D12Device.h b/CyberXeSS_YEDEK/WrappedD3D12Device.h new file mode 100644 index 00000000..f27ecf32 --- /dev/null +++ b/CyberXeSS_YEDEK/WrappedD3D12Device.h @@ -0,0 +1,245 @@ +#pragma once + +#include "WrappedDXGIObjects.h" + +class RefCountD3D12Object : public ID3D12Object +{ + ID3D12Object* m_pReal; + unsigned int m_iRefcount; + +public: + RefCountD3D12Object(ID3D12Object* real) : m_pReal(real), m_iRefcount(1) {} + virtual ~RefCountD3D12Object() {} + static bool HandleWrap(const char* ifaceName, REFIID riid, void** ppvObject); + static HRESULT WrapQueryInterface(IUnknown* real, const char* ifaceName, REFIID riid, void** ppvObject); + + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ __RPC__deref_out void** ppvObject) + { + LOG("RefCountD3D12Object.QueryInterface"); + auto result = QueryInterface("IUnknown", riid, ppvObject); + LOG("RefCountD3D12Object.QueryInterface result: " + int_to_hex(result)); + + return result; + } + + // optional overload that's useful for passing down the name of the current interface to put in + // any 'unknown interface' query logs. + HRESULT STDMETHODCALLTYPE QueryInterface(const char* ifaceName, REFIID riid, void** ppvObject) + { + if (riid == __uuidof(IUnknown)) + { + AddRef(); + *ppvObject = (IUnknown*)(ID3D12Object*)this; + return S_OK; + } + else if (riid == __uuidof(ID3D12Object)) + { + AddRef(); + *ppvObject = (ID3D12Object*)this; + return S_OK; + } + + return WrapQueryInterface(m_pReal, ifaceName, riid, ppvObject); + } + + ULONG STDMETHODCALLTYPE AddRef() + { + LOG("RefCountD3D12Object.AddRef"); + InterlockedIncrement(&m_iRefcount); + LOG("RefCountD3D12Object.AddRef result: " + int_to_hex(m_iRefcount)); + return m_iRefcount; + } + ULONG STDMETHODCALLTYPE Release() + { + LOG("RefCountD3D12Object.Release"); + + unsigned int ret = InterlockedDecrement(&m_iRefcount); + + LOG("RefCountD3D12Object.Release result: " + int_to_hex(m_iRefcount)); + + if (ret == 0) + { + LOG("RefCountD3D12Object.Release deleting object"); + delete this; + } + + return ret; + } + + ////////////////////////////// + // implement ID3D12Object + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( /* [in] */ REFGUID Name, /* [in] */ UINT DataSize, /* [in] */ const void* pData) + { + LOG("RefCountDXGIObject.SetPrivateData"); + auto result = m_pReal->SetPrivateData(Name, DataSize, pData); + LOG("RefCountDXGIObject.SetPrivateData result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( /* [in] */ REFGUID Name, /* [in] */ const IUnknown* pUnknown) + { + LOG("RefCountDXGIObject.SetPrivateDataInterface"); + auto result = m_pReal->SetPrivateDataInterface(Name, pUnknown); + LOG("RefCountDXGIObject.SetPrivateDataInterface result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( /* [in] */ REFGUID Name, /* [out][in] */ UINT* pDataSize, /* [out] */ void* pData) + { + LOG("RefCountDXGIObject.GetPrivateData"); + auto result = m_pReal->GetPrivateData(Name, pDataSize, pData); + LOG("RefCountDXGIObject.GetPrivateData result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE SetName(_In_z_ LPCWSTR Name); +}; + +#define IMPLEMENT_ID3D12OBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY \ + ULONG STDMETHODCALLTYPE AddRef() \ + { \ + return RefCountD3D12Object::AddRef(); \ + } \ + ULONG STDMETHODCALLTYPE Release() \ + { \ + return RefCountD3D12Object::Release(); \ + } \ + HRESULT STDMETHODCALLTYPE SetPrivateData(REFIID Name, UINT DataSize, const void *pData) \ + { \ + return RefCountD3D12Object::SetPrivateData(Name, DataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFIID Name, const IUnknown *pUnknown) \ + { \ + return RefCountD3D12Object::SetPrivateDataInterface(Name, pUnknown); \ + } \ + HRESULT STDMETHODCALLTYPE GetPrivateData(REFIID Name, UINT *pDataSize, void *pData) \ + { \ + return RefCountD3D12Object::GetPrivateData(Name, pDataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE SetName(_In_z_ LPCWSTR Name) \ + { \ + return RefCountD3D12Object::SetName(Name); \ + } + +MIDL_INTERFACE("fa4994ad-dbe4-44b9-8c5c-bb5cf7188b6e") +ID3D12ProxyDevice : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE GetProxyAdapter(IDXGIProxyAdapter** adapter); + virtual HRESULT STDMETHODCALLTYPE SetProxyAdapter(IDXGIProxyAdapter* adapter); +}; + +class WrappedD3D12Device : public ID3D12Device10, public RefCountD3D12Object, public ID3D12ProxyDevice +{ + ID3D12Device1* m_device1; + ID3D12Device2* m_device2; + ID3D12Device3* m_device3; + ID3D12Device4* m_device4; + ID3D12Device5* m_device5; + ID3D12Device6* m_device6; + ID3D12Device7* m_device7; + ID3D12Device8* m_device8; + ID3D12Device9* m_device9; + ID3D12Device10* m_device10; + IDXGIProxyAdapter* m_adapter; + +public: + ID3D12Device* m_device; + WrappedD3D12Device(ID3D12Device* device); + + virtual ~WrappedD3D12Device(); + + IMPLEMENT_ID3D12OBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + + // Inherited via ID3D12Device10 + + HRESULT __stdcall QueryInterface(REFIID riid, void** ppvObject) override; + UINT __stdcall GetNodeCount(void) override; + HRESULT __stdcall CreateCommandQueue(const D3D12_COMMAND_QUEUE_DESC* pDesc, REFIID riid, void** ppCommandQueue) override; + HRESULT __stdcall CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE type, REFIID riid, void** ppCommandAllocator) override; + HRESULT __stdcall CreateGraphicsPipelineState(const D3D12_GRAPHICS_PIPELINE_STATE_DESC* pDesc, REFIID riid, void** ppPipelineState) override; + HRESULT __stdcall CreateComputePipelineState(const D3D12_COMPUTE_PIPELINE_STATE_DESC* pDesc, REFIID riid, void** ppPipelineState) override; + HRESULT __stdcall CreateCommandList(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type, ID3D12CommandAllocator* pCommandAllocator, ID3D12PipelineState* pInitialState, REFIID riid, void** ppCommandList) override; + HRESULT __stdcall CheckFeatureSupport(D3D12_FEATURE Feature, void* pFeatureSupportData, UINT FeatureSupportDataSize) override; + HRESULT __stdcall CreateDescriptorHeap(const D3D12_DESCRIPTOR_HEAP_DESC* pDescriptorHeapDesc, REFIID riid, void** ppvHeap) override; + UINT __stdcall GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapType) override; + HRESULT __stdcall CreateRootSignature(UINT nodeMask, const void* pBlobWithRootSignature, SIZE_T blobLengthInBytes, REFIID riid, void** ppvRootSignature) override; + void __stdcall CreateConstantBufferView(const D3D12_CONSTANT_BUFFER_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override; + void __stdcall CreateShaderResourceView(ID3D12Resource* pResource, const D3D12_SHADER_RESOURCE_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override; + void __stdcall CreateUnorderedAccessView(ID3D12Resource* pResource, ID3D12Resource* pCounterResource, const D3D12_UNORDERED_ACCESS_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override; + void __stdcall CreateRenderTargetView(ID3D12Resource* pResource, const D3D12_RENDER_TARGET_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override; + void __stdcall CreateDepthStencilView(ID3D12Resource* pResource, const D3D12_DEPTH_STENCIL_VIEW_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override; + void __stdcall CreateSampler(const D3D12_SAMPLER_DESC* pDesc, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override; + void __stdcall CopyDescriptors(UINT NumDestDescriptorRanges, const D3D12_CPU_DESCRIPTOR_HANDLE* pDestDescriptorRangeStarts, const UINT* pDestDescriptorRangeSizes, UINT NumSrcDescriptorRanges, const D3D12_CPU_DESCRIPTOR_HANDLE* pSrcDescriptorRangeStarts, const UINT* pSrcDescriptorRangeSizes, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) override; + void __stdcall CopyDescriptorsSimple(UINT NumDescriptors, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptorRangeStart, D3D12_CPU_DESCRIPTOR_HANDLE SrcDescriptorRangeStart, D3D12_DESCRIPTOR_HEAP_TYPE DescriptorHeapsType) override; + D3D12_RESOURCE_ALLOCATION_INFO __stdcall GetResourceAllocationInfo(UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC* pResourceDescs) override; + D3D12_HEAP_PROPERTIES __stdcall GetCustomHeapProperties(UINT nodeMask, D3D12_HEAP_TYPE heapType) override; + HRESULT __stdcall CreateCommittedResource(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riidResource, void** ppvResource) override; + HRESULT __stdcall CreateHeap(const D3D12_HEAP_DESC* pDesc, REFIID riid, void** ppvHeap) override; + HRESULT __stdcall CreatePlacedResource(ID3D12Heap* pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riid, void** ppvResource) override; + HRESULT __stdcall CreateReservedResource(const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riid, void** ppvResource) override; + HRESULT __stdcall CreateSharedHandle(ID3D12DeviceChild* pObject, const SECURITY_ATTRIBUTES* pAttributes, DWORD Access, LPCWSTR Name, HANDLE* pHandle) override; + HRESULT __stdcall OpenSharedHandle(HANDLE NTHandle, REFIID riid, void** ppvObj) override; + HRESULT __stdcall OpenSharedHandleByName(LPCWSTR Name, DWORD Access, HANDLE* pNTHandle) override; + HRESULT __stdcall MakeResident(UINT NumObjects, ID3D12Pageable* const* ppObjects) override; + HRESULT __stdcall Evict(UINT NumObjects, ID3D12Pageable* const* ppObjects) override; + HRESULT __stdcall CreateFence(UINT64 InitialValue, D3D12_FENCE_FLAGS Flags, REFIID riid, void** ppFence) override; + HRESULT __stdcall GetDeviceRemovedReason(void) override; + void __stdcall GetCopyableFootprints(const D3D12_RESOURCE_DESC* pResourceDesc, UINT FirstSubresource, UINT NumSubresources, UINT64 BaseOffset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, UINT* pNumRows, UINT64* pRowSizeInBytes, UINT64* pTotalBytes) override; + HRESULT __stdcall CreateQueryHeap(const D3D12_QUERY_HEAP_DESC* pDesc, REFIID riid, void** ppvHeap) override; + HRESULT __stdcall SetStablePowerState(BOOL Enable) override; + HRESULT __stdcall CreateCommandSignature(const D3D12_COMMAND_SIGNATURE_DESC* pDesc, ID3D12RootSignature* pRootSignature, REFIID riid, void** ppvCommandSignature) override; + void __stdcall GetResourceTiling(ID3D12Resource* pTiledResource, UINT* pNumTilesForEntireResource, D3D12_PACKED_MIP_INFO* pPackedMipDesc, D3D12_TILE_SHAPE* pStandardTileShapeForNonPackedMips, UINT* pNumSubresourceTilings, UINT FirstSubresourceTilingToGet, D3D12_SUBRESOURCE_TILING* pSubresourceTilingsForNonPackedMips) override; + LUID __stdcall GetAdapterLuid(void) override; + HRESULT __stdcall CreatePipelineLibrary(const void* pLibraryBlob, SIZE_T BlobLength, REFIID riid, void** ppPipelineLibrary) override; + HRESULT __stdcall SetEventOnMultipleFenceCompletion(ID3D12Fence* const* ppFences, const UINT64* pFenceValues, UINT NumFences, D3D12_MULTIPLE_FENCE_WAIT_FLAGS Flags, HANDLE hEvent) override; + HRESULT __stdcall SetResidencyPriority(UINT NumObjects, ID3D12Pageable* const* ppObjects, const D3D12_RESIDENCY_PRIORITY* pPriorities) override; + HRESULT __stdcall CreatePipelineState(const D3D12_PIPELINE_STATE_STREAM_DESC* pDesc, REFIID riid, void** ppPipelineState) override; + HRESULT __stdcall OpenExistingHeapFromAddress(const void* pAddress, REFIID riid, void** ppvHeap) override; + HRESULT __stdcall OpenExistingHeapFromFileMapping(HANDLE hFileMapping, REFIID riid, void** ppvHeap) override; + HRESULT __stdcall EnqueueMakeResident(D3D12_RESIDENCY_FLAGS Flags, UINT NumObjects, ID3D12Pageable* const* ppObjects, ID3D12Fence* pFenceToSignal, UINT64 FenceValueToSignal) override; + HRESULT __stdcall CreateCommandList1(UINT nodeMask, D3D12_COMMAND_LIST_TYPE type, D3D12_COMMAND_LIST_FLAGS flags, REFIID riid, void** ppCommandList) override; + HRESULT __stdcall CreateProtectedResourceSession(const D3D12_PROTECTED_RESOURCE_SESSION_DESC* pDesc, REFIID riid, void** ppSession) override; + HRESULT __stdcall CreateCommittedResource1(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riidResource, void** ppvResource) override; + HRESULT __stdcall CreateHeap1(const D3D12_HEAP_DESC* pDesc, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riid, void** ppvHeap) override; + HRESULT __stdcall CreateReservedResource1(const D3D12_RESOURCE_DESC* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riid, void** ppvResource) override; + D3D12_RESOURCE_ALLOCATION_INFO __stdcall GetResourceAllocationInfo1(UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC* pResourceDescs, D3D12_RESOURCE_ALLOCATION_INFO1* pResourceAllocationInfo1) override; + HRESULT __stdcall CreateLifetimeTracker(ID3D12LifetimeOwner* pOwner, REFIID riid, void** ppvTracker) override; + void __stdcall RemoveDevice(void) override; + HRESULT __stdcall EnumerateMetaCommands(UINT* pNumMetaCommands, D3D12_META_COMMAND_DESC* pDescs) override; + HRESULT __stdcall EnumerateMetaCommandParameters(REFGUID CommandId, D3D12_META_COMMAND_PARAMETER_STAGE Stage, UINT* pTotalStructureSizeInBytes, UINT* pParameterCount, D3D12_META_COMMAND_PARAMETER_DESC* pParameterDescs) override; + HRESULT __stdcall CreateMetaCommand(REFGUID CommandId, UINT NodeMask, const void* pCreationParametersData, SIZE_T CreationParametersDataSizeInBytes, REFIID riid, void** ppMetaCommand) override; + HRESULT __stdcall CreateStateObject(const D3D12_STATE_OBJECT_DESC* pDesc, REFIID riid, void** ppStateObject) override; + void __stdcall GetRaytracingAccelerationStructurePrebuildInfo(const D3D12_BUILD_RAYTRACING_ACCELERATION_STRUCTURE_INPUTS* pDesc, D3D12_RAYTRACING_ACCELERATION_STRUCTURE_PREBUILD_INFO* pInfo) override; + D3D12_DRIVER_MATCHING_IDENTIFIER_STATUS __stdcall CheckDriverMatchingIdentifier(D3D12_SERIALIZED_DATA_TYPE SerializedDataType, const D3D12_SERIALIZED_DATA_DRIVER_MATCHING_IDENTIFIER* pIdentifierToCheck) override; + HRESULT __stdcall SetBackgroundProcessingMode(D3D12_BACKGROUND_PROCESSING_MODE Mode, D3D12_MEASUREMENTS_ACTION MeasurementsAction, HANDLE hEventToSignalUponCompletion, BOOL* pbFurtherMeasurementsDesired) override; + HRESULT __stdcall AddToStateObject(const D3D12_STATE_OBJECT_DESC* pAddition, ID3D12StateObject* pStateObjectToGrowFrom, REFIID riid, void** ppNewStateObject) override; + HRESULT __stdcall CreateProtectedResourceSession1(const D3D12_PROTECTED_RESOURCE_SESSION_DESC1* pDesc, REFIID riid, void** ppSession) override; + D3D12_RESOURCE_ALLOCATION_INFO __stdcall GetResourceAllocationInfo2(UINT visibleMask, UINT numResourceDescs, const D3D12_RESOURCE_DESC1* pResourceDescs, D3D12_RESOURCE_ALLOCATION_INFO1* pResourceAllocationInfo1) override; + HRESULT __stdcall CreateCommittedResource2(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC1* pDesc, D3D12_RESOURCE_STATES InitialResourceState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, REFIID riidResource, void** ppvResource) override; + HRESULT __stdcall CreatePlacedResource1(ID3D12Heap* pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC1* pDesc, D3D12_RESOURCE_STATES InitialState, const D3D12_CLEAR_VALUE* pOptimizedClearValue, REFIID riid, void** ppvResource) override; + void __stdcall CreateSamplerFeedbackUnorderedAccessView(ID3D12Resource* pTargetedResource, ID3D12Resource* pFeedbackResource, D3D12_CPU_DESCRIPTOR_HANDLE DestDescriptor) override; + void __stdcall GetCopyableFootprints1(const D3D12_RESOURCE_DESC1* pResourceDesc, UINT FirstSubresource, UINT NumSubresources, UINT64 BaseOffset, D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, UINT* pNumRows, UINT64* pRowSizeInBytes, UINT64* pTotalBytes) override; + HRESULT __stdcall CreateShaderCacheSession(const D3D12_SHADER_CACHE_SESSION_DESC* pDesc, REFIID riid, void** ppvSession) override; + HRESULT __stdcall ShaderCacheControl(D3D12_SHADER_CACHE_KIND_FLAGS Kinds, D3D12_SHADER_CACHE_CONTROL_FLAGS Control) override; + HRESULT __stdcall CreateCommandQueue1(const D3D12_COMMAND_QUEUE_DESC* pDesc, REFIID CreatorID, REFIID riid, void** ppCommandQueue) override; + HRESULT __stdcall CreateCommittedResource3(const D3D12_HEAP_PROPERTIES* pHeapProperties, D3D12_HEAP_FLAGS HeapFlags, const D3D12_RESOURCE_DESC1* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, UINT32 NumCastableFormats, DXGI_FORMAT* pCastableFormats, REFIID riidResource, void** ppvResource) override; + HRESULT __stdcall CreatePlacedResource2(ID3D12Heap* pHeap, UINT64 HeapOffset, const D3D12_RESOURCE_DESC1* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, UINT32 NumCastableFormats, DXGI_FORMAT* pCastableFormats, REFIID riid, void** ppvResource) override; + HRESULT __stdcall CreateReservedResource2(const D3D12_RESOURCE_DESC* pDesc, D3D12_BARRIER_LAYOUT InitialLayout, const D3D12_CLEAR_VALUE* pOptimizedClearValue, ID3D12ProtectedResourceSession* pProtectedSession, UINT32 NumCastableFormats, DXGI_FORMAT* pCastableFormats, REFIID riid, void** ppvResource) override; + + virtual HRESULT STDMETHODCALLTYPE GetProxyAdapter(IDXGIProxyAdapter** adapter) + { + *adapter = m_adapter; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE SetProxyAdapter(IDXGIProxyAdapter* adapter) + { + m_adapter = adapter; + return S_OK; + } +}; + diff --git a/CyberXeSS_YEDEK/WrappedDXGIObjects.cpp b/CyberXeSS_YEDEK/WrappedDXGIObjects.cpp new file mode 100644 index 00000000..4e44a561 --- /dev/null +++ b/CyberXeSS_YEDEK/WrappedDXGIObjects.cpp @@ -0,0 +1,542 @@ +#include "pch.h" +#include "dxgi1_6.h" +#include "WrappedDXGIObjects.h" + +bool RefCountDXGIObject::HandleWrap(const char* ifaceName, REFIID riid, void** ppvObject) +{ + LOG("RefCountDXGIObject.HandleWrap"); + + if (ppvObject == NULL || *ppvObject == NULL) + { + std::string str(ifaceName); + LOG("RefCountDXGIObject.HandleWrap called with NULL ppvObject querying " + str); + return false; + } + + // unknown GUID that we only want to print once to avoid log spam + // {79D2046C-22EF-451B-9E74-2245D9C760EA} + static const GUID Unknown_uuid = { 0x79d2046c, 0x22ef, 0x451b, {0x9e, 0x74, 0x22, 0x45, 0xd9, 0xc7, 0x60, 0xea} }; + + // ditto + // {9B7E4C04-342C-4106-A19F-4F2704F689F0} + static const GUID ID3D10Texture2D_uuid = { 0x9b7e4c04, 0x342c, 0x4106, {0xa1, 0x9f, 0x4f, 0x27, 0x04, 0xf6, 0x89, 0xf0} }; + +#ifdef BLOCK_IDXGIAdapterInternal2 + // unknown/undocumented internal interface + // {7abb6563-02bc-47c4-8ef9-acc4795edbcf} + static const GUID IDXGIAdapterInternal2_uuid = { 0x7abb6563, 0x02bc, 0x47c4, {0x8e, 0xf9, 0xac, 0xc4, 0x79, 0x5e, 0xdb, 0xcf} }; +#endif + + + if (riid == __uuidof(IDXGIDevice) || + riid == __uuidof(IDXGIDevice1)) + { + // should have been handled elsewhere, so we can properly create this device + std::string str(ifaceName); + LOG("Unexpected uuid in RefCountDXGIObject::HandleWrap querying : " + str); + return false; + } + else if (riid == __uuidof(IDXGIAdapter)) + { + if (b_wrappingEnabled) + { + IDXGIAdapter* real = (IDXGIAdapter*)(*ppvObject); + *ppvObject = (IDXGIAdapter*)(new WrappedIDXGIAdapter4(real)); + } + } + else if (riid == __uuidof(IDXGIAdapter1)) + { + if (b_wrappingEnabled) + { + IDXGIAdapter1* real = (IDXGIAdapter1*)(*ppvObject); + *ppvObject = (IDXGIAdapter1*)(new WrappedIDXGIAdapter4(real)); + } + } + else if (riid == __uuidof(IDXGIAdapter2)) + { + if (b_wrappingEnabled) + { + IDXGIAdapter2* real = (IDXGIAdapter2*)(*ppvObject); + *ppvObject = (IDXGIAdapter2*)(new WrappedIDXGIAdapter4(real)); + } + } + else if (riid == __uuidof(IDXGIAdapter3)) + { + if (b_wrappingEnabled) + { + IDXGIAdapter3* real = (IDXGIAdapter3*)(*ppvObject); + *ppvObject = (IDXGIAdapter3*)(new WrappedIDXGIAdapter4(real)); + } + } + else if (riid == __uuidof(IDXGIAdapter4)) + { + if (b_spoofEnabled) + { + IDXGIAdapter4* real = (IDXGIAdapter4*)(*ppvObject); + *ppvObject = (IDXGIAdapter4*)(new WrappedIDXGIAdapter4(real)); + } + } + else if (riid == __uuidof(IDXGIFactory)) + { + // yes I know PRECISELY how fucked up this is. Speak to microsoft - after KB2670838 the internal + // D3D11 device creation function will pass in __uuidof(IDXGIFactory) then attempt to call + // EnumDevices1 (which is in the IDXGIFactory1 vtable). Doing this *should* be safe as using a + // IDXGIFactory1 like a IDXGIFactory should all just work by definition, but there's no way to + // know now if someone trying to create a IDXGIFactory really means it or not. + IDXGIFactory* real = (IDXGIFactory*)(*ppvObject); + *ppvObject = (IDXGIFactory*)(new WrappedIDXGIFactory(real)); + } + else if (riid == __uuidof(IDXGIFactory1)) + { + IDXGIFactory1* real = (IDXGIFactory1*)(*ppvObject); + *ppvObject = (IDXGIFactory1*)(new WrappedIDXGIFactory(real)); + } + else if (riid == __uuidof(IDXGIFactory2)) + { + IDXGIFactory2* real = (IDXGIFactory2*)(*ppvObject); + *ppvObject = (IDXGIFactory2*)(new WrappedIDXGIFactory(real)); + } + else if (riid == __uuidof(IDXGIFactory3)) + { + IDXGIFactory3* real = (IDXGIFactory3*)(*ppvObject); + *ppvObject = (IDXGIFactory3*)(new WrappedIDXGIFactory(real)); + } + else if (riid == __uuidof(IDXGIFactory4)) + { + IDXGIFactory4* real = (IDXGIFactory4*)(*ppvObject); + *ppvObject = (IDXGIFactory4*)(new WrappedIDXGIFactory(real)); + } + else if (riid == __uuidof(IDXGIFactory5)) + { + IDXGIFactory5* real = (IDXGIFactory5*)(*ppvObject); + *ppvObject = (IDXGIFactory5*)(new WrappedIDXGIFactory(real)); + } + else if (riid == __uuidof(IDXGIFactory6)) + { + IDXGIFactory6* real = (IDXGIFactory6*)(*ppvObject); + *ppvObject = (IDXGIFactory6*)(new WrappedIDXGIFactory(real)); + } + else if (riid == __uuidof(IDXGIFactory7)) + { + IDXGIFactory7* real = (IDXGIFactory7*)(*ppvObject); + *ppvObject = (IDXGIFactory7*)(new WrappedIDXGIFactory(real)); + } + else if (riid == ID3D10Texture2D_uuid) + { + static bool printed = false; + + if (!printed) + { + printed = true; + std::string str(ifaceName); + LOG("RefCountDXGIObject.HandleWrap Querying " + str + " for unsupported ID3D10Texture2D_uuid interface: " + ToString(riid)); + } + + return false; + } + else if (riid == Unknown_uuid) + { + static bool printed = false; + if (!printed) + { + printed = true; + std::string str(ifaceName); + LOG("RefCountDXGIObject.HandleWrap Querying " + str + " for unknown GUID: " + ToString(riid)); + } + + return false; + } +#ifdef BLOCK_IDXGIAdapterInternal2 + else if (riid == IDXGIAdapterInternal2_uuid) + { + static bool printed = false; + if (!printed) + { + printed = true; + std::string str(ifaceName); + LOG("RefCountDXGIObject.HandleWrap Querying " + str + " for unsupported/undocumented interface: IDXGIAdapterInternal2"); + } + + return false; + } +#endif + else + { + std::string str(ifaceName); + LOG("RefCountDXGIObject.HandleWrap Querying " + str + " for unrecognized GUID: " + ToString(riid)); + } + + return true; +} + +HRESULT STDMETHODCALLTYPE RefCountDXGIObject::GetParent( + /* [in] */ REFIID riid, + /* [retval][out] */ void** ppParent) +{ + LOG("RefCountDXGIObject.GetParent"); + + HRESULT ret = m_pReal->GetParent(riid, ppParent); + + if (ret == S_OK) + HandleWrap("GetParent", riid, ppParent); + + return ret; +} + +HRESULT RefCountDXGIObject::WrapQueryInterface(IUnknown* real, const char* ifaceName, REFIID riid, void** ppvObject) +{ + LOG("RefCountDXGIObject.WrapQueryInterface riid: " + ToString(riid)); + +#ifdef BLOCK_IDXGIAdapterInternal2 + // unknown/undocumented internal interface + // {7abb6563-02bc-47c4-8ef9-acc4795edbcf} + static const GUID IDXGIAdapterInternal2_uuid = { 0x7abb6563, 0x02bc, 0x47c4, {0x8e, 0xf9, 0xac, 0xc4, 0x79, 0x5e, 0xdb, 0xcf} }; + + if (riid == IDXGIAdapterInternal2_uuid) + { + LOG("RefCountDXGIObject.WrapQueryInterface IDXGIAdapterInternal2 result: " + int_to_hex(E_NOINTERFACE)); + return E_NOINTERFACE; + } +#endif + + HRESULT ret = real->QueryInterface(riid, ppvObject); + LOG("RefCountDXGIObject.WrapQueryInterface real->QueryInterface result: " + int_to_hex(ret)); + + if (ret == S_OK && HandleWrap(ifaceName, riid, ppvObject)) + { + LOG("RefCountDXGIObject.WrapQueryInterface HandleWrap result: " + int_to_hex(ret)); + return ret; + } + + LOG("RefCountDXGIObject.WrapQueryInterface result: E_NOINTERFACE"); + return E_NOINTERFACE; +} + + +WrappedIDXGIAdapter4::WrappedIDXGIAdapter4(IDXGIAdapter* real) + : RefCountDXGIObject(real), m_pReal(real) +{ + LOG("WrappedIDXGIAdapter4.ctor"); + + m_pReal1 = NULL; + real->QueryInterface(__uuidof(IDXGIAdapter1), (void**)&m_pReal1); + m_pReal2 = NULL; + real->QueryInterface(__uuidof(IDXGIAdapter2), (void**)&m_pReal2); + m_pReal3 = NULL; + real->QueryInterface(__uuidof(IDXGIAdapter3), (void**)&m_pReal3); + m_pReal4 = NULL; + real->QueryInterface(__uuidof(IDXGIAdapter4), (void**)&m_pReal4); + + b_spoofEnabled = true; +} + +WrappedIDXGIAdapter4::~WrappedIDXGIAdapter4() +{ + LOG("WrappedIDXGIAdapter4.dtor"); + + SAFE_RELEASE(m_pReal1); + SAFE_RELEASE(m_pReal2); + SAFE_RELEASE(m_pReal3); + SAFE_RELEASE(m_pReal4); + SAFE_RELEASE(m_pReal); +} + +HRESULT STDMETHODCALLTYPE WrappedIDXGIAdapter4::QueryInterface(REFIID riid, void** ppvObject) +{ + LOG("WrappedIDXGIAdapter4.QueryInterface riid: " + ToString(riid)); + +#ifndef BLOCK_IDXGIAdapterInternal2 + // unknown/undocumented internal interface + // {7abb6563-02bc-47c4-8ef9-acc4795edbcf} + static const GUID IDXGIAdapterInternal2_uuid = { 0x7abb6563, 0x02bc, 0x47c4, {0x8e, 0xf9, 0xac, 0xc4, 0x79, 0x5e, 0xdb, 0xcf} }; +#endif + + + if (riid == __uuidof(IDXGIAdapter)) + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter"); + AddRef(); + *ppvObject = (IDXGIAdapter*)this; + return S_OK; + } + else if (riid == __uuidof(IDXGIProxyAdapter)) + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIProxyAdapter"); + AddRef(); + *ppvObject = (IDXGIProxyAdapter*)this; + return S_OK; + } + else if (riid == __uuidof(IDXGIAdapter1)) + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter1"); + + if (m_pReal1) + { + AddRef(); + *ppvObject = (IDXGIAdapter1*)this; + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter1 result: OK"); + return S_OK; + } + else + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter1 result: E_NOINTERFACE"); + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIAdapter2)) + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter2"); + + if (m_pReal2) + { + AddRef(); + *ppvObject = (IDXGIAdapter2*)this; + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter2 result: OK"); + return S_OK; + } + else + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter2 result: E_NOINTERFACE"); + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIAdapter3)) + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter3"); + + if (m_pReal3) + { + AddRef(); + *ppvObject = (IDXGIAdapter3*)this; + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter3 result: OK"); + return S_OK; + } + else + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter3 result: E_NOINTERFACE"); + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIAdapter4)) + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter4"); + + if (m_pReal4) + { + AddRef(); + *ppvObject = (IDXGIAdapter4*)this; + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter4 result: OK"); + return S_OK; + } + else + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapter4 result: E_NOINTERFACE"); + return E_NOINTERFACE; + } + } +#ifndef BLOCK_IDXGIAdapterInternal2 + else if (riid == IDXGIAdapterInternal2_uuid && m_pReal != nullptr) + { + LOG("WrappedIDXGIAdapter4.QueryInterface for IDXGIAdapterInternal2, returning real adapter"); + return m_pReal->QueryInterface(riid, ppvObject); + } +#endif + + return RefCountDXGIObject::QueryInterface("IDXGIAdapter", riid, ppvObject); +} + +WrappedIDXGIFactory::WrappedIDXGIFactory(IDXGIFactory* real) + : RefCountDXGIObject(real), m_pReal(real) +{ + LOG("WrappedIDXGIFactory.ctor"); + + m_pReal1 = NULL; + real->QueryInterface(__uuidof(IDXGIFactory1), (void**)&m_pReal1); + m_pReal2 = NULL; + real->QueryInterface(__uuidof(IDXGIFactory2), (void**)&m_pReal2); + m_pReal3 = NULL; + real->QueryInterface(__uuidof(IDXGIFactory3), (void**)&m_pReal3); + m_pReal4 = NULL; + real->QueryInterface(__uuidof(IDXGIFactory4), (void**)&m_pReal4); + m_pReal5 = NULL; + real->QueryInterface(__uuidof(IDXGIFactory5), (void**)&m_pReal5); + m_pReal6 = NULL; + real->QueryInterface(__uuidof(IDXGIFactory6), (void**)&m_pReal6); + m_pReal7 = NULL; + real->QueryInterface(__uuidof(IDXGIFactory7), (void**)&m_pReal7); +} + +WrappedIDXGIFactory::~WrappedIDXGIFactory() +{ + LOG("WrappedIDXGIFactory.dtor"); + + SAFE_RELEASE(m_pReal1); + SAFE_RELEASE(m_pReal2); + SAFE_RELEASE(m_pReal3); + SAFE_RELEASE(m_pReal4); + SAFE_RELEASE(m_pReal5); + SAFE_RELEASE(m_pReal6); + SAFE_RELEASE(m_pReal7); + SAFE_RELEASE(m_pReal); +} + +HRESULT STDMETHODCALLTYPE WrappedIDXGIFactory::QueryInterface(REFIID riid, void** ppvObject) +{ + LOG("WrappedIDXGIFactory.QueryInterface"); + + // {713f394e-92ca-47e7-ab81-1159c2791e54} + static const GUID IDXGIFactoryDWM_uuid = { + 0x713f394e, 0x92ca, 0x47e7, {0xab, 0x81, 0x11, 0x59, 0xc2, 0x79, 0x1e, 0x54} }; + + // {1ddd77aa-9a4a-4cc8-9e55-98c196bafc8f} + static const GUID IDXGIFactoryDWM8_uuid = { + 0x1ddd77aa, 0x9a4a, 0x4cc8, {0x9e, 0x55, 0x98, 0xc1, 0x96, 0xba, 0xfc, 0x8f} }; + + if (riid == __uuidof(IDXGIFactory)) + { + AddRef(); + *ppvObject = (IDXGIFactory*)this; + return S_OK; + } + else if (riid == __uuidof(IDXGIFactory1)) + { + if (m_pReal1) + { + AddRef(); + *ppvObject = (IDXGIFactory1*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIFactory2)) + { + if (m_pReal2) + { + AddRef(); + *ppvObject = (IDXGIFactory2*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIFactory3)) + { + if (m_pReal3) + { + AddRef(); + *ppvObject = (IDXGIFactory3*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIFactory4)) + { + if (m_pReal4) + { + AddRef(); + *ppvObject = (IDXGIFactory4*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIFactory5)) + { + if (m_pReal5) + { + AddRef(); + *ppvObject = (IDXGIFactory5*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIFactory6)) + { + if (m_pReal6) + { + AddRef(); + *ppvObject = (IDXGIFactory6*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if (riid == __uuidof(IDXGIFactory7)) + { + if (m_pReal7) + { + AddRef(); + *ppvObject = (IDXGIFactory7*)this; + return S_OK; + } + else + { + return E_NOINTERFACE; + } + } + else if (riid == IDXGIFactoryDWM_uuid) + { + //RDCWARN("Blocking QueryInterface for IDXGIFactoryDWM"); + return E_NOINTERFACE; + } + else if (riid == IDXGIFactoryDWM8_uuid) + { + //RDCWARN("Blocking QueryInterface for IDXGIFactoryDWM8"); + return E_NOINTERFACE; + } + + return RefCountDXGIObject::QueryInterface("IDXGIFactory", riid, ppvObject); +} + +HRESULT WrappedIDXGIFactory::CreateSwapChain(IUnknown* pDevice, DXGI_SWAP_CHAIN_DESC* pDesc, + IDXGISwapChain** ppSwapChain) +{ + LOG("WrappedIDXGIFactory.CreateSwapChain"); + + return m_pReal->CreateSwapChain(pDevice, pDesc, ppSwapChain); +} + +HRESULT WrappedIDXGIFactory::CreateSwapChainForHwnd( + IUnknown* pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1* pDesc, + const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, IDXGIOutput* pRestrictToOutput, + IDXGISwapChain1** ppSwapChain) +{ + LOG("WrappedIDXGIFactory.CreateSwapChainForHwnd"); + + return m_pReal2->CreateSwapChainForHwnd(pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain); +} + +HRESULT WrappedIDXGIFactory::CreateSwapChainForCoreWindow(IUnknown* pDevice, IUnknown* pWindow, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + IDXGIOutput* pRestrictToOutput, + IDXGISwapChain1** ppSwapChain) +{ + LOG("WrappedIDXGIFactory.CreateSwapChainForCoreWindow"); + + return m_pReal2->CreateSwapChainForCoreWindow(pDevice, pWindow, pDesc, pRestrictToOutput, ppSwapChain); +} + +HRESULT WrappedIDXGIFactory::CreateSwapChainForComposition(IUnknown* pDevice, + const DXGI_SWAP_CHAIN_DESC1* pDesc, + IDXGIOutput* pRestrictToOutput, + IDXGISwapChain1** ppSwapChain) +{ + LOG("WrappedIDXGIFactory.CreateSwapChainForComposition"); + + return m_pReal2->CreateSwapChainForComposition(pDevice, pDesc, pRestrictToOutput, ppSwapChain); +} diff --git a/CyberXeSS_YEDEK/WrappedDXGIObjects.h b/CyberXeSS_YEDEK/WrappedDXGIObjects.h new file mode 100644 index 00000000..c7044f0c --- /dev/null +++ b/CyberXeSS_YEDEK/WrappedDXGIObjects.h @@ -0,0 +1,882 @@ +#include "pch.h" +#include "dxgi1_6.h" + +//#define BLOCK_IDXGIAdapterInternal2 + +class RefCountDXGIObject : public IDXGIObject +{ + IDXGIObject* m_pReal; + unsigned int m_iRefcount; + +public: + RefCountDXGIObject(IDXGIObject* real) : m_pReal(real), m_iRefcount(1) {} + virtual ~RefCountDXGIObject() {} + static bool HandleWrap(const char* ifaceName, REFIID riid, void** ppvObject); + static HRESULT WrapQueryInterface(IUnknown* real, const char* ifaceName, REFIID riid, void** ppvObject); + + ////////////////////////////// + // implement IUnknown + HRESULT STDMETHODCALLTYPE QueryInterface( /* [in] */ REFIID riid, /* [annotation][iid_is][out] */ __RPC__deref_out void** ppvObject) + { + LOG("RefCountDXGIObject.QueryInterface"); + auto result = QueryInterface("IUnknown", riid, ppvObject); + LOG("RefCountDXGIObject.QueryInterface result: " + int_to_hex(result)); + + return result; + } + + // optional overload that's useful for passing down the name of the current interface to put in + // any 'unknown interface' query logs. + HRESULT STDMETHODCALLTYPE QueryInterface(const char* ifaceName, REFIID riid, void** ppvObject) + { + if (riid == __uuidof(IUnknown)) + { + AddRef(); + *ppvObject = (IUnknown*)(IDXGIObject*)this; + return S_OK; + } + else if (riid == __uuidof(IDXGIObject)) + { + AddRef(); + *ppvObject = (IDXGIObject*)this; + return S_OK; + } + + return WrapQueryInterface(m_pReal, ifaceName, riid, ppvObject); + } + + ULONG STDMETHODCALLTYPE AddRef() + { + LOG("RefCountDXGIObject.AddRef"); + InterlockedIncrement(&m_iRefcount); + LOG("RefCountDXGIObject.AddRef result: " + int_to_hex(m_iRefcount)); + return m_iRefcount; + } + ULONG STDMETHODCALLTYPE Release() + { + LOG("RefCountDXGIObject.Release"); + + unsigned int ret = InterlockedDecrement(&m_iRefcount); + + LOG("RefCountDXGIObject.Release result: " + int_to_hex(m_iRefcount)); + + if (ret == 0) + { + LOG("RefCountDXGIObject.Release deleting object"); + delete this; + } + + return ret; + } + + ////////////////////////////// + // implement IDXGIObject + + virtual HRESULT STDMETHODCALLTYPE SetPrivateData( + /* [in] */ REFGUID Name, + /* [in] */ UINT DataSize, + /* [in] */ const void* pData) + { + LOG("RefCountDXGIObject.SetPrivateData"); + auto result = m_pReal->SetPrivateData(Name, DataSize, pData); + LOG("RefCountDXGIObject.SetPrivateData result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE SetPrivateDataInterface( + /* [in] */ REFGUID Name, + /* [in] */ const IUnknown* pUnknown) + { + LOG("RefCountDXGIObject.SetPrivateDataInterface"); + auto result = m_pReal->SetPrivateDataInterface(Name, pUnknown); + LOG("RefCountDXGIObject.SetPrivateDataInterface result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE GetPrivateData( + /* [in] */ REFGUID Name, + /* [out][in] */ UINT* pDataSize, + /* [out] */ void* pData) + { + LOG("RefCountDXGIObject.GetPrivateData"); + auto result = m_pReal->GetPrivateData(Name, pDataSize, pData); + LOG("RefCountDXGIObject.GetPrivateData result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE GetParent( + /* [in] */ REFIID riid, + /* [retval][out] */ void** ppParent); +}; + +#define IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY \ + ULONG STDMETHODCALLTYPE AddRef() \ + { \ + return RefCountDXGIObject::AddRef(); \ + } \ + ULONG STDMETHODCALLTYPE Release() \ + { \ + return RefCountDXGIObject::Release(); \ + } \ + HRESULT STDMETHODCALLTYPE SetPrivateData(REFIID Name, UINT DataSize, const void *pData) \ + { \ + return RefCountDXGIObject::SetPrivateData(Name, DataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFIID Name, const IUnknown *pUnknown) \ + { \ + return RefCountDXGIObject::SetPrivateDataInterface(Name, pUnknown); \ + } \ + HRESULT STDMETHODCALLTYPE GetPrivateData(REFIID Name, UINT *pDataSize, void *pData) \ + { \ + return RefCountDXGIObject::GetPrivateData(Name, pDataSize, pData); \ + } \ + HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppvObject) \ + { \ + return RefCountDXGIObject::GetParent(riid, ppvObject); \ + } + + +MIDL_INTERFACE("cfdf09b3-a084-4453-a755-7d4e5389b845") +IDXGIProxyAdapter : public IUnknown +{ +public: + virtual HRESULT STDMETHODCALLTYPE Spoofing(bool enable); + virtual HRESULT STDMETHODCALLTYPE Wrapping(bool enable); +}; + +static bool b_spoofEnabled = true; +static bool b_wrappingEnabled = true; + +class WrappedIDXGIAdapter4 : public IDXGIAdapter4, public RefCountDXGIObject, public IDXGIProxyAdapter +{ + IDXGIAdapter* m_pReal; + IDXGIAdapter1* m_pReal1; + IDXGIAdapter2* m_pReal2; + IDXGIAdapter3* m_pReal3; + IDXGIAdapter4* m_pReal4; + +public: + WrappedIDXGIAdapter4(IDXGIAdapter* real); + virtual ~WrappedIDXGIAdapter4(); + + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + ////////////////////////////// + // implement IDXGIAdapter + + virtual HRESULT STDMETHODCALLTYPE EnumOutputs( /* [in] */ UINT Output, /* [annotation][out][in] */ __out IDXGIOutput** ppOutput) + { + LOG("WrappedIDXGIAdapter4.EnumOutputs"); + HRESULT ret = m_pReal->EnumOutputs(Output, ppOutput); + LOG("WrappedIDXGIAdapter4.EnumOutputs result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE GetDesc( /* [annotation][out] */ __out DXGI_ADAPTER_DESC* pDesc) + { + LOG("WrappedIDXGIAdapter4.GetDesc"); + + HRESULT hr; + hr = m_pReal->GetDesc(pDesc); + + if (hr == S_OK && b_spoofEnabled && pDesc != nullptr && (pDesc->VendorId == 0x8086 || pDesc->VendorId == 0x1002)) + { + LOG("WrappedIDXGIAdapter4.GetDesc Spoofing card info"); + pDesc->VendorId = 0x10de; + pDesc->DeviceId = 0x24c9; + pDesc->SubSysId = 0x88ac1043; + pDesc->Revision = 0x00a1; + + std::wstring name(L"NVIDIA GeForce RTX 3060 Ti"); + const wchar_t* szName = name.c_str(); + std::memset(pDesc->Description, 0, sizeof(pDesc->Description)); + std::memcpy(pDesc->Description, szName, 54); + + LUID luid = LUID{ 0, 56090 }; + std::memcpy(&pDesc->AdapterLuid, &luid, 8); + } + + //b_spoofEnabled = true; + + LOG("WrappedIDXGIAdapter4.GetDesc result: " + int_to_hex(hr)); + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE CheckInterfaceSupport( + /* [annotation][in] */ + __in REFGUID InterfaceName, + /* [annotation][out] */ + __out LARGE_INTEGER* pUMDVersion) + { + LOG("WrappedIDXGIAdapter4.CheckInterfaceSupport"); + auto result = m_pReal->CheckInterfaceSupport(InterfaceName, pUMDVersion); + LOG("WrappedIDXGIAdapter4.CheckInterfaceSupport result: " + int_to_hex(result)); + return result; + } + + ////////////////////////////// + // implement IDXGIAdapter1 + + virtual HRESULT STDMETHODCALLTYPE GetDesc1( + /* [out] */ DXGI_ADAPTER_DESC1* pDesc) + { + LOG("WrappedIDXGIAdapter4.GetDesc1"); + + if (!m_pReal1) + { + LOG("WrappedIDXGIAdapter4.GetDesc1 no adapter!"); + return E_NOINTERFACE; + } + + + HRESULT hr; + hr = m_pReal1->GetDesc1(pDesc); + + if (hr == S_OK && b_spoofEnabled && pDesc != nullptr && (pDesc->VendorId == 0x8086 || pDesc->VendorId == 0x1002)) + { + LOG("WrappedIDXGIAdapter4.GetDesc1 Spoofing card info"); + + pDesc->VendorId = 0x10de; + pDesc->DeviceId = 0x24c9; + pDesc->SubSysId = 0x88ac1043; + pDesc->Revision = 0x00a1; + + std::wstring name(L"NVIDIA GeForce RTX 3060 Ti"); + const wchar_t* szName = name.c_str(); + std::memset(pDesc->Description, 0, sizeof(pDesc->Description)); + std::memcpy(pDesc->Description, szName, 54); + + LUID luid = LUID{ 0, 56090 }; + std::memcpy(&pDesc->AdapterLuid, &luid, 8); + } + + //b_spoofEnabled = true; + + LOG("WrappedIDXGIAdapter4.GetDesc1 result: " + int_to_hex(hr)); + return hr; + } + + ////////////////////////////// + // implement IDXGIAdapter2 + + virtual HRESULT STDMETHODCALLTYPE GetDesc2( + /* [annotation][out] */ + _Out_ DXGI_ADAPTER_DESC2* pDesc) + { + LOG("WrappedIDXGIAdapter4.GetDesc2"); + + if (!m_pReal2) + { + LOG("WrappedIDXGIAdapter4.GetDesc2 no adapter!"); + return E_NOINTERFACE; + } + + HRESULT hr; + hr = m_pReal2->GetDesc2(pDesc); + + if (hr == S_OK && b_spoofEnabled && pDesc != nullptr && (pDesc->VendorId == 0x8086 || pDesc->VendorId == 0x1002)) + { + LOG("WrappedIDXGIAdapter4.GetDesc2 Spoofing card info"); + + pDesc->VendorId = 0x10de; + pDesc->DeviceId = 0x24c9; + pDesc->SubSysId = 0x88ac1043; + pDesc->Revision = 0x00a1; + + std::wstring name(L"NVIDIA GeForce RTX 3060 Ti"); + const wchar_t* szName = name.c_str(); + std::memset(pDesc->Description, 0, sizeof(pDesc->Description)); + std::memcpy(pDesc->Description, szName, 54); + + LUID luid = LUID{ 0, 56090 }; + std::memcpy(&pDesc->AdapterLuid, &luid, 8); + } + + //b_spoofEnabled = true; + + LOG("WrappedIDXGIAdapter4.GetDesc2 result: " + int_to_hex(hr)); + + return hr; + } + + ////////////////////////////// + // implement IDXGIAdapter3 + + virtual HRESULT STDMETHODCALLTYPE RegisterHardwareContentProtectionTeardownStatusEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD* pdwCookie) + { + LOG("WrappedIDXGIAdapter4.RegisterHardwareContentProtectionTeardownStatusEvent"); + auto result = m_pReal3->RegisterHardwareContentProtectionTeardownStatusEvent(hEvent, pdwCookie); + LOG("WrappedIDXGIAdapter4.RegisterHardwareContentProtectionTeardownStatusEvent result: " + int_to_hex(result)); + return result; + } + + virtual void STDMETHODCALLTYPE UnregisterHardwareContentProtectionTeardownStatus( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + LOG("WrappedIDXGIAdapter4.UnregisterHardwareContentProtectionTeardownStatus"); + m_pReal3->UnregisterHardwareContentProtectionTeardownStatus(dwCookie); + LOG("WrappedIDXGIAdapter4.UnregisterHardwareContentProtectionTeardownStatus done"); + } + + virtual HRESULT STDMETHODCALLTYPE QueryVideoMemoryInfo( + /* [annotation][in] */ + _In_ UINT NodeIndex, + /* [annotation][in] */ + _In_ DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup, + /* [annotation][out] */ + _Out_ DXGI_QUERY_VIDEO_MEMORY_INFO* pVideoMemoryInfo) + { + LOG("WrappedIDXGIAdapter4.QueryVideoMemoryInfo"); + + auto result = m_pReal3->QueryVideoMemoryInfo(NodeIndex, MemorySegmentGroup, pVideoMemoryInfo); + LOG("WrappedIDXGIAdapter4.QueryVideoMemoryInfo result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE SetVideoMemoryReservation( + /* [annotation][in] */ + _In_ UINT NodeIndex, + /* [annotation][in] */ + _In_ DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup, + /* [annotation][in] */ + _In_ UINT64 Reservation) + { + LOG("WrappedIDXGIAdapter4.SetVideoMemoryReservation"); + + auto result = m_pReal3->SetVideoMemoryReservation(NodeIndex, MemorySegmentGroup, Reservation); + LOG("WrappedIDXGIAdapter4.SetVideoMemoryReservation result: " + int_to_hex(result)); + return result; + } + + virtual HRESULT STDMETHODCALLTYPE RegisterVideoMemoryBudgetChangeNotificationEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD* pdwCookie) + { + LOG("WrappedIDXGIAdapter4.RegisterVideoMemoryBudgetChangeNotificationEvent"); + + auto result = m_pReal3->RegisterVideoMemoryBudgetChangeNotificationEvent(hEvent, pdwCookie); + LOG("WrappedIDXGIAdapter4.RegisterVideoMemoryBudgetChangeNotificationEvent result: " + int_to_hex(result)); + return result; + } + + virtual void STDMETHODCALLTYPE UnregisterVideoMemoryBudgetChangeNotification( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + LOG("WrappedIDXGIAdapter4.UnregisterVideoMemoryBudgetChangeNotification"); + + m_pReal3->UnregisterVideoMemoryBudgetChangeNotification(dwCookie); + LOG("WrappedIDXGIAdapter4.UnregisterVideoMemoryBudgetChangeNotification done"); + } + + ////////////////////////////// + // implement IDXGIAdapter4 + + virtual HRESULT STDMETHODCALLTYPE GetDesc3( + /* [annotation][out] */ + _Out_ DXGI_ADAPTER_DESC3* pDesc) + { + LOG("WrappedIDXGIAdapter4.GetDesc3"); + + if (!m_pReal4) + { + LOG("WrappedIDXGIAdapter4.GetDesc3 no adapter!"); + return E_NOINTERFACE; + } + + HRESULT hr; + hr = m_pReal4->GetDesc3(pDesc); + + if (hr == S_OK && b_spoofEnabled && pDesc != nullptr && (pDesc->VendorId == 0x8086 || pDesc->VendorId == 0x1002)) + { + LOG("WrappedIDXGIAdapter4.GetDesc3 Spoofing card info"); + + pDesc->VendorId = 0x10de; + pDesc->DeviceId = 0x24c9; + pDesc->SubSysId = 0x88ac1043; + pDesc->Revision = 0x00a1; + + std::wstring name(L"NVIDIA GeForce RTX 3060 Ti"); + const wchar_t* szName = name.c_str(); + std::memset(pDesc->Description, 0, sizeof(pDesc->Description)); + std::memcpy(pDesc->Description, szName, 54); + + LUID luid = LUID{ 0, 56090 }; + std::memcpy(&pDesc->AdapterLuid, &luid, 8); + } + + //b_spoofEnabled = true; + + LOG("WrappedIDXGIAdapter4.GetDesc3 result: " + int_to_hex(hr)); + + return hr; + } + + virtual HRESULT STDMETHODCALLTYPE Spoofing(bool enable) + { + LOG("WrappedIDXGIAdapter4.Spoofing : " + std::to_string(enable)); + b_spoofEnabled = enable; + return S_OK; + } + + virtual HRESULT STDMETHODCALLTYPE Wrapping(bool enable) + { + LOG("WrappedIDXGIAdapter4.Wrapping : " + std::to_string(enable)); + b_wrappingEnabled = enable; + return S_OK; + } +}; + +class WrappedIDXGIFactory : public IDXGIFactory7, public RefCountDXGIObject +{ + IDXGIFactory* m_pReal; + IDXGIFactory1* m_pReal1; + IDXGIFactory2* m_pReal2; + IDXGIFactory3* m_pReal3; + IDXGIFactory4* m_pReal4; + IDXGIFactory5* m_pReal5; + IDXGIFactory6* m_pReal6; + IDXGIFactory7* m_pReal7; + +public: + WrappedIDXGIFactory(IDXGIFactory* real); + virtual ~WrappedIDXGIFactory(); + + IMPLEMENT_IDXGIOBJECT_WITH_REFCOUNTDXGIOBJECT_CUSTOMQUERY; + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + ////////////////////////////// + // implement IDXGIFactory + + virtual HRESULT STDMETHODCALLTYPE EnumAdapters( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter** ppAdapter) + { + LOG("WrappedIDXGIFactory.EnumAdapters " + std::to_string(Adapter)); + + HRESULT ret = m_pReal->EnumAdapters(Adapter, ppAdapter); + + if (ret == S_OK && b_wrappingEnabled) + *ppAdapter = (IDXGIAdapter*)(new WrappedIDXGIAdapter4(*ppAdapter)); + + LOG("WrappedIDXGIFactory.EnumAdapters result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE MakeWindowAssociation(HWND WindowHandle, UINT Flags) + { + LOG("WrappedIDXGIFactory.MakeWindowAssociation"); + + auto ret = m_pReal->MakeWindowAssociation(WindowHandle, Flags); + LOG("WrappedIDXGIFactory.MakeWindowAssociation result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE GetWindowAssociation( + /* [annotation][out] */ + __out HWND* pWindowHandle) + { + LOG("WrappedIDXGIFactory.GetWindowAssociation"); + + auto ret = m_pReal->GetWindowAssociation(pWindowHandle); + LOG("WrappedIDXGIFactory.GetWindowAssociation result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChain( + /* [annotation][in] */ + __in IUnknown* pDevice, + /* [annotation][in] */ + __in DXGI_SWAP_CHAIN_DESC* pDesc, + /* [annotation][out] */ + __out IDXGISwapChain** ppSwapChain); + + virtual HRESULT STDMETHODCALLTYPE CreateSoftwareAdapter( + /* [in] */ HMODULE Module, + /* [annotation][out] */ + __out IDXGIAdapter** ppAdapter) + { + LOG("WrappedIDXGIFactory.CreateSoftwareAdapter"); + + HRESULT ret = m_pReal->CreateSoftwareAdapter(Module, ppAdapter); + + if (ret == S_OK && b_wrappingEnabled) + *ppAdapter = (IDXGIAdapter*)(new WrappedIDXGIAdapter4(*ppAdapter)); + + LOG("WrappedIDXGIFactory.CreateSoftwareAdapter result: " + int_to_hex(ret)); + return ret; + } + + ////////////////////////////// + // implement IDXGIFactory1 + + virtual HRESULT STDMETHODCALLTYPE EnumAdapters1( + /* [in] */ UINT Adapter, + /* [annotation][out] */ + __out IDXGIAdapter1** ppAdapter) + { + LOG("WrappedIDXGIFactory.EnumAdapters1 " + std::to_string(Adapter)); + + IDXGIFactory1* factory = m_pReal1; + if (m_pReal1 == NULL) + { + // see comment in RefCountDXGIObject::HandleWrap for IDXGIFactory + //RDCWARN("Calling EnumAdapters1 with no IDXGIFactory1 - assuming weird internal call"); + factory = (IDXGIFactory1*)m_pReal; + } + + HRESULT ret = factory->EnumAdapters1(Adapter, ppAdapter); + + if (ret == S_OK && b_wrappingEnabled) + *ppAdapter = (IDXGIAdapter1*)(new WrappedIDXGIAdapter4(*ppAdapter)); + + LOG("WrappedIDXGIFactory.EnumAdapters1 result: " + int_to_hex(ret)); + return ret; + } + + virtual BOOL STDMETHODCALLTYPE IsCurrent(void) + { + LOG("WrappedIDXGIFactory.IsCurrent"); + + auto ret = m_pReal1->IsCurrent(); + LOG("WrappedIDXGIFactory.IsCurrent result: " + std::to_string(ret)); + return ret; + } + ////////////////////////////// + // implement IDXGIFactory2 + + virtual BOOL STDMETHODCALLTYPE IsWindowedStereoEnabled(void) + { + LOG("WrappedIDXGIFactory.IsWindowedStereoEnabled"); + + auto ret = m_pReal2->IsWindowedStereoEnabled(); + LOG("WrappedIDXGIFactory.IsCurrent result: " + std::to_string(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForHwnd( + /* [annotation][in] */ + _In_ IUnknown* pDevice, + /* [annotation][in] */ + _In_ HWND hWnd, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1* pDesc, + /* [annotation][in] */ + _In_opt_ const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput* pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1** ppSwapChain); + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForCoreWindow( + /* [annotation][in] */ + _In_ IUnknown* pDevice, + /* [annotation][in] */ + _In_ IUnknown* pWindow, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1* pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput* pRestrictToOutput, + /* [annotation][out] */ + _Out_ IDXGISwapChain1** ppSwapChain); + + virtual HRESULT STDMETHODCALLTYPE GetSharedResourceAdapterLuid( + /* [annotation] */ + _In_ HANDLE hResource, + /* [annotation] */ + _Out_ LUID* pLuid) + { + LOG("WrappedIDXGIFactory.GetSharedResourceAdapterLuid"); + + auto ret = m_pReal2->GetSharedResourceAdapterLuid(hResource, pLuid); + LOG("WrappedIDXGIFactory.GetSharedResourceAdapterLuid result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusWindow( + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD* pdwCookie) + { + LOG("WrappedIDXGIFactory.RegisterStereoStatusWindow"); + + auto ret = m_pReal2->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); + LOG("WrappedIDXGIFactory.RegisterStereoStatusWindow result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE RegisterStereoStatusEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD* pdwCookie) + { + LOG("WrappedIDXGIFactory.RegisterStereoStatusEvent"); + + auto ret = m_pReal2->RegisterStereoStatusEvent(hEvent, pdwCookie); + LOG("WrappedIDXGIFactory.RegisterStereoStatusEvent result: " + int_to_hex(ret)); + return ret; + } + + virtual void STDMETHODCALLTYPE UnregisterStereoStatus( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + LOG("WrappedIDXGIFactory.UnregisterStereoStatus"); + + m_pReal2->UnregisterStereoStatus(dwCookie); + LOG("WrappedIDXGIFactory.UnregisterStereoStatus done"); + } + + virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusWindow( + /* [annotation][in] */ + _In_ HWND WindowHandle, + /* [annotation][in] */ + _In_ UINT wMsg, + /* [annotation][out] */ + _Out_ DWORD* pdwCookie) + { + LOG("WrappedIDXGIFactory.RegisterOcclusionStatusWindow"); + + auto ret = m_pReal2->RegisterOcclusionStatusWindow(WindowHandle, wMsg, pdwCookie); + LOG("WrappedIDXGIFactory.RegisterOcclusionStatusWindow result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE RegisterOcclusionStatusEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD* pdwCookie) + { + LOG("WrappedIDXGIFactory.RegisterOcclusionStatusEvent"); + + auto ret = m_pReal2->RegisterOcclusionStatusEvent(hEvent, pdwCookie); + LOG("WrappedIDXGIFactory.RegisterOcclusionStatusEvent result: " + int_to_hex(ret)); + return ret; + } + + virtual void STDMETHODCALLTYPE UnregisterOcclusionStatus( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + LOG("WrappedIDXGIFactory.UnregisterOcclusionStatus"); + + m_pReal2->UnregisterOcclusionStatus(dwCookie); + LOG("WrappedIDXGIFactory.UnregisterOcclusionStatus done"); + } + + virtual HRESULT STDMETHODCALLTYPE CreateSwapChainForComposition( + /* [annotation][in] */ + _In_ IUnknown* pDevice, + /* [annotation][in] */ + _In_ const DXGI_SWAP_CHAIN_DESC1* pDesc, + /* [annotation][in] */ + _In_opt_ IDXGIOutput* pRestrictToOutput, + /* [annotation][out] */ + _Outptr_ IDXGISwapChain1** ppSwapChain); + + ////////////////////////////// + // implement IDXGIFactory3 + + virtual UINT STDMETHODCALLTYPE GetCreationFlags(void) + { + LOG("WrappedIDXGIFactory.GetCreationFlags"); + + auto ret = m_pReal3->GetCreationFlags(); + LOG("WrappedIDXGIFactory.GetCreationFlags result: " + int_to_hex(ret)); + return ret; + } + ////////////////////////////// + // implement IDXGIFactory4 + + bool WrapAdapter(REFIID riid, void** ppvAdapter) + { + LOG("WrappedIDXGIFactory.WrapAdapter"); + + if (ppvAdapter == NULL || *ppvAdapter == NULL) + { + LOG("WrappedIDXGIFactory.WrapAdapter ppvAdapter is NULL!"); + return false; + } + + if (riid == __uuidof(IDXGIAdapter4) && b_wrappingEnabled) + { + IDXGIAdapter4* adapter = (IDXGIAdapter4*)*ppvAdapter; + *ppvAdapter = (IDXGIAdapter4*)(new WrappedIDXGIAdapter4(adapter)); + return true; + } + else if (riid == __uuidof(IDXGIAdapter3) && b_wrappingEnabled) + { + IDXGIAdapter3* adapter = (IDXGIAdapter3*)*ppvAdapter; + *ppvAdapter = (IDXGIAdapter3*)(new WrappedIDXGIAdapter4(adapter)); + return true; + } + else if (riid == __uuidof(IDXGIAdapter2) && b_wrappingEnabled) + { + IDXGIAdapter2* adapter = (IDXGIAdapter2*)*ppvAdapter; + *ppvAdapter = (IDXGIAdapter2*)(new WrappedIDXGIAdapter4(adapter)); + return true; + } + else if (riid == __uuidof(IDXGIAdapter1) && b_wrappingEnabled) + { + IDXGIAdapter1* adapter = (IDXGIAdapter1*)*ppvAdapter; + *ppvAdapter = (IDXGIAdapter1*)(new WrappedIDXGIAdapter4(adapter)); + return true; + } + else if (riid == __uuidof(IDXGIAdapter) && b_wrappingEnabled) + { + IDXGIAdapter* adapter = (IDXGIAdapter*)*ppvAdapter; + *ppvAdapter = (IDXGIAdapter*)(new WrappedIDXGIAdapter4(adapter)); + return true; + } + else + { + return RefCountDXGIObject::HandleWrap("IDXGIAdapter", riid, ppvAdapter); + } + + return false; + } + + virtual HRESULT STDMETHODCALLTYPE EnumAdapterByLuid( /* [annotation] */ _In_ LUID AdapterLuid, /* [annotation] */ _In_ REFIID riid, /* [annotation] */ _COM_Outptr_ void** ppvAdapter) + + { +#ifdef BLOCK_IDXGIAdapterInternal2 + // unknown/undocumented internal interface + // {7abb6563-02bc-47c4-8ef9-acc4795edbcf} + static const GUID IDXGIAdapterInternal2_uuid = { + 0x7abb6563, 0x02bc, 0x47c4, {0x8e, 0xf9, 0xac, 0xc4, 0x79, 0x5e, 0xdb, 0xcf} }; + + if (riid == IDXGIAdapterInternal2_uuid) + { + LOG("WrappedIDXGIFactory.EnumAdapterByLuid IDXGIAdapterInternal2_uuid result: " + int_to_hex(DXGI_ERROR_NOT_FOUND)); + return DXGI_ERROR_NOT_FOUND; + } +#endif + + LOG("WrappedIDXGIFactory.EnumAdapterByLuid LUID: " + int_to_hex(AdapterLuid.HighPart) + "-" + int_to_hex(AdapterLuid.LowPart) + " riid: " + ToString(riid)); + + HRESULT ret = m_pReal4->EnumAdapterByLuid(AdapterLuid, riid, ppvAdapter); + + if (ret == S_OK && b_wrappingEnabled) + { + auto wrapResult = this->WrapAdapter(riid, ppvAdapter); + + if (!wrapResult) + { + LOG("WrappedIDXGIFactory.EnumAdapterByLuid wrapResult result: " + int_to_hex(DXGI_ERROR_NOT_FOUND)); + return DXGI_ERROR_NOT_FOUND; + } + } + else + { + LOG("WrappedIDXGIFactory.EnumAdapterByLuid can't get adapter by LUID, user first adapter"); + IDXGIAdapter* wrappedAdapter; + ret = this->EnumAdapters(0, &wrappedAdapter); + + if (ret == S_OK) + *ppvAdapter = wrappedAdapter; + } + + LOG("WrappedIDXGIFactory.EnumAdapterByLuid result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE EnumWarpAdapter( + /* [annotation] */ + _In_ REFIID riid, + /* [annotation] */ + _COM_Outptr_ void** ppvAdapter) + { + LOG("WrappedIDXGIFactory.EnumWarpAdapter"); + + HRESULT ret = m_pReal4->EnumWarpAdapter(riid, ppvAdapter); + + if (ret == S_OK && b_wrappingEnabled) + WrapAdapter(riid, ppvAdapter); + + LOG("WrappedIDXGIFactory.EnumWarpAdapter result: " + int_to_hex(ret)); + return ret; + } + + ////////////////////////////// + // implement IDXGIFactory5 + + virtual HRESULT STDMETHODCALLTYPE + CheckFeatureSupport(DXGI_FEATURE Feature, + /* [annotation] */ + _Inout_updates_bytes_(FeatureSupportDataSize) void* pFeatureSupportData, + UINT FeatureSupportDataSize) + { + LOG("WrappedIDXGIFactory.CheckFeatureSupport"); + + auto ret = m_pReal5->CheckFeatureSupport(Feature, pFeatureSupportData, FeatureSupportDataSize); + LOG("WrappedIDXGIFactory.CheckFeatureSupport result: " + int_to_hex(ret)); + return ret; + } + + ////////////////////////////// + // implement IDXGIFactory6 + + virtual HRESULT STDMETHODCALLTYPE EnumAdapterByGpuPreference( + /* [annotation] */ + _In_ UINT Adapter, + /* [annotation] */ + _In_ DXGI_GPU_PREFERENCE GpuPreference, + /* [annotation] */ + _In_ REFIID riid, + /* [annotation] */ + _COM_Outptr_ void** ppvAdapter) + { + LOG("WrappedIDXGIFactory.EnumAdapterByGpuPreference " + std::to_string(Adapter) + ", GpuPreference: " + int_to_hex(GpuPreference)); + + HRESULT ret = m_pReal6->EnumAdapterByGpuPreference(Adapter, GpuPreference, riid, ppvAdapter); + + if (ret == S_OK && b_wrappingEnabled) + WrapAdapter(riid, ppvAdapter); + + LOG("WrappedIDXGIFactory.EnumAdapterByGpuPreference result: " + int_to_hex(ret)); + return ret; + } + + ////////////////////////////// + // implement IDXGIFactory7 + + virtual HRESULT STDMETHODCALLTYPE RegisterAdaptersChangedEvent( + /* [annotation][in] */ + _In_ HANDLE hEvent, + /* [annotation][out] */ + _Out_ DWORD* pdwCookie) + { + LOG("WrappedIDXGIFactory.RegisterAdaptersChangedEvent"); + + auto ret = m_pReal7->RegisterAdaptersChangedEvent(hEvent, pdwCookie); + LOG("WrappedIDXGIFactory.RegisterAdaptersChangedEvent result: " + int_to_hex(ret)); + return ret; + } + + virtual HRESULT STDMETHODCALLTYPE UnregisterAdaptersChangedEvent( + /* [annotation][in] */ + _In_ DWORD dwCookie) + { + LOG("WrappedIDXGIFactory.UnregisterAdaptersChangedEvent"); + + auto ret = m_pReal7->UnregisterAdaptersChangedEvent(dwCookie); + LOG("WrappedIDXGIFactory.UnregisterAdaptersChangedEvent result: " + int_to_hex(ret)); + return ret; + } +}; + diff --git a/CyberXeSS_YEDEK/d3dx12.h b/CyberXeSS_YEDEK/d3dx12.h new file mode 100644 index 00000000..3959e94c --- /dev/null +++ b/CyberXeSS_YEDEK/d3dx12.h @@ -0,0 +1,3905 @@ +//********************************************************* +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the MIT License (MIT). +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//********************************************************* + +#ifndef __D3DX12_H__ +#define __D3DX12_H__ + +#include "d3d12.h" + +#if defined( __cplusplus ) + +struct CD3DX12_DEFAULT {}; +extern const DECLSPEC_SELECTANY CD3DX12_DEFAULT D3D12_DEFAULT; + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) noexcept +{ + return l.TopLeftX == r.TopLeftX && l.TopLeftY == r.TopLeftY && l.Width == r.Width && + l.Height == r.Height && l.MinDepth == r.MinDepth && l.MaxDepth == r.MaxDepth; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator!=( const D3D12_VIEWPORT& l, const D3D12_VIEWPORT& r ) noexcept +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RECT : public D3D12_RECT +{ + CD3DX12_RECT() = default; + explicit CD3DX12_RECT( const D3D12_RECT& o ) noexcept : + D3D12_RECT( o ) + {} + explicit CD3DX12_RECT( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) noexcept + { + left = Left; + top = Top; + right = Right; + bottom = Bottom; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VIEWPORT : public D3D12_VIEWPORT +{ + CD3DX12_VIEWPORT() = default; + explicit CD3DX12_VIEWPORT( const D3D12_VIEWPORT& o ) noexcept : + D3D12_VIEWPORT( o ) + {} + explicit CD3DX12_VIEWPORT( + FLOAT topLeftX, + FLOAT topLeftY, + FLOAT width, + FLOAT height, + FLOAT minDepth = D3D12_MIN_DEPTH, + FLOAT maxDepth = D3D12_MAX_DEPTH ) noexcept + { + TopLeftX = topLeftX; + TopLeftY = topLeftY; + Width = width; + Height = height; + MinDepth = minDepth; + MaxDepth = maxDepth; + } + explicit CD3DX12_VIEWPORT( + _In_ ID3D12Resource* pResource, + UINT mipSlice = 0, + FLOAT topLeftX = 0.0f, + FLOAT topLeftY = 0.0f, + FLOAT minDepth = D3D12_MIN_DEPTH, + FLOAT maxDepth = D3D12_MAX_DEPTH ) noexcept + { + auto Desc = pResource->GetDesc(); + const UINT64 SubresourceWidth = Desc.Width >> mipSlice; + const UINT64 SubresourceHeight = Desc.Height >> mipSlice; + switch (Desc.Dimension) + { + case D3D12_RESOURCE_DIMENSION_BUFFER: + TopLeftX = topLeftX; + TopLeftY = 0.0f; + Width = float(Desc.Width) - topLeftX; + Height = 1.0f; + break; + case D3D12_RESOURCE_DIMENSION_TEXTURE1D: + TopLeftX = topLeftX; + TopLeftY = 0.0f; + Width = (SubresourceWidth ? float(SubresourceWidth) : 1.0f) - topLeftX; + Height = 1.0f; + break; + case D3D12_RESOURCE_DIMENSION_TEXTURE2D: + case D3D12_RESOURCE_DIMENSION_TEXTURE3D: + TopLeftX = topLeftX; + TopLeftY = topLeftY; + Width = (SubresourceWidth ? float(SubresourceWidth) : 1.0f) - topLeftX; + Height = (SubresourceHeight ? float(SubresourceHeight) : 1.0f) - topLeftY; + break; + default: break; + } + + MinDepth = minDepth; + MaxDepth = maxDepth; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BOX : public D3D12_BOX +{ + CD3DX12_BOX() = default; + explicit CD3DX12_BOX( const D3D12_BOX& o ) noexcept : + D3D12_BOX( o ) + {} + explicit CD3DX12_BOX( + LONG Left, + LONG Right ) noexcept + { + left = static_cast(Left); + top = 0; + front = 0; + right = static_cast(Right); + bottom = 1; + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Right, + LONG Bottom ) noexcept + { + left = static_cast(Left); + top = static_cast(Top); + front = 0; + right = static_cast(Right); + bottom = static_cast(Bottom); + back = 1; + } + explicit CD3DX12_BOX( + LONG Left, + LONG Top, + LONG Front, + LONG Right, + LONG Bottom, + LONG Back ) noexcept + { + left = static_cast(Left); + top = static_cast(Top); + front = static_cast(Front); + right = static_cast(Right); + bottom = static_cast(Bottom); + back = static_cast(Back); + } +}; +inline bool operator==( const D3D12_BOX& l, const D3D12_BOX& r ) noexcept +{ + return l.left == r.left && l.top == r.top && l.front == r.front && + l.right == r.right && l.bottom == r.bottom && l.back == r.back; +} +inline bool operator!=( const D3D12_BOX& l, const D3D12_BOX& r ) noexcept +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC : public D3D12_DEPTH_STENCIL_DESC +{ + CD3DX12_DEPTH_STENCIL_DESC() = default; + explicit CD3DX12_DEPTH_STENCIL_DESC( const D3D12_DEPTH_STENCIL_DESC& o ) noexcept : + D3D12_DEPTH_STENCIL_DESC( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC( CD3DX12_DEFAULT ) noexcept + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + } + explicit CD3DX12_DEPTH_STENCIL_DESC( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc ) noexcept + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DEPTH_STENCIL_DESC1 : public D3D12_DEPTH_STENCIL_DESC1 +{ + CD3DX12_DEPTH_STENCIL_DESC1() = default; + explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC1& o ) noexcept : + D3D12_DEPTH_STENCIL_DESC1( o ) + {} + explicit CD3DX12_DEPTH_STENCIL_DESC1( const D3D12_DEPTH_STENCIL_DESC& o ) noexcept + { + DepthEnable = o.DepthEnable; + DepthWriteMask = o.DepthWriteMask; + DepthFunc = o.DepthFunc; + StencilEnable = o.StencilEnable; + StencilReadMask = o.StencilReadMask; + StencilWriteMask = o.StencilWriteMask; + FrontFace.StencilFailOp = o.FrontFace.StencilFailOp; + FrontFace.StencilDepthFailOp = o.FrontFace.StencilDepthFailOp; + FrontFace.StencilPassOp = o.FrontFace.StencilPassOp; + FrontFace.StencilFunc = o.FrontFace.StencilFunc; + BackFace.StencilFailOp = o.BackFace.StencilFailOp; + BackFace.StencilDepthFailOp = o.BackFace.StencilDepthFailOp; + BackFace.StencilPassOp = o.BackFace.StencilPassOp; + BackFace.StencilFunc = o.BackFace.StencilFunc; + DepthBoundsTestEnable = FALSE; + } + explicit CD3DX12_DEPTH_STENCIL_DESC1( CD3DX12_DEFAULT ) noexcept + { + DepthEnable = TRUE; + DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; + DepthFunc = D3D12_COMPARISON_FUNC_LESS; + StencilEnable = FALSE; + StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK; + StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK; + const D3D12_DEPTH_STENCILOP_DESC defaultStencilOp = + { D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_STENCIL_OP_KEEP, D3D12_COMPARISON_FUNC_ALWAYS }; + FrontFace = defaultStencilOp; + BackFace = defaultStencilOp; + DepthBoundsTestEnable = FALSE; + } + explicit CD3DX12_DEPTH_STENCIL_DESC1( + BOOL depthEnable, + D3D12_DEPTH_WRITE_MASK depthWriteMask, + D3D12_COMPARISON_FUNC depthFunc, + BOOL stencilEnable, + UINT8 stencilReadMask, + UINT8 stencilWriteMask, + D3D12_STENCIL_OP frontStencilFailOp, + D3D12_STENCIL_OP frontStencilDepthFailOp, + D3D12_STENCIL_OP frontStencilPassOp, + D3D12_COMPARISON_FUNC frontStencilFunc, + D3D12_STENCIL_OP backStencilFailOp, + D3D12_STENCIL_OP backStencilDepthFailOp, + D3D12_STENCIL_OP backStencilPassOp, + D3D12_COMPARISON_FUNC backStencilFunc, + BOOL depthBoundsTestEnable ) noexcept + { + DepthEnable = depthEnable; + DepthWriteMask = depthWriteMask; + DepthFunc = depthFunc; + StencilEnable = stencilEnable; + StencilReadMask = stencilReadMask; + StencilWriteMask = stencilWriteMask; + FrontFace.StencilFailOp = frontStencilFailOp; + FrontFace.StencilDepthFailOp = frontStencilDepthFailOp; + FrontFace.StencilPassOp = frontStencilPassOp; + FrontFace.StencilFunc = frontStencilFunc; + BackFace.StencilFailOp = backStencilFailOp; + BackFace.StencilDepthFailOp = backStencilDepthFailOp; + BackFace.StencilPassOp = backStencilPassOp; + BackFace.StencilFunc = backStencilFunc; + DepthBoundsTestEnable = depthBoundsTestEnable; + } + operator D3D12_DEPTH_STENCIL_DESC() const noexcept + { + D3D12_DEPTH_STENCIL_DESC D; + D.DepthEnable = DepthEnable; + D.DepthWriteMask = DepthWriteMask; + D.DepthFunc = DepthFunc; + D.StencilEnable = StencilEnable; + D.StencilReadMask = StencilReadMask; + D.StencilWriteMask = StencilWriteMask; + D.FrontFace.StencilFailOp = FrontFace.StencilFailOp; + D.FrontFace.StencilDepthFailOp = FrontFace.StencilDepthFailOp; + D.FrontFace.StencilPassOp = FrontFace.StencilPassOp; + D.FrontFace.StencilFunc = FrontFace.StencilFunc; + D.BackFace.StencilFailOp = BackFace.StencilFailOp; + D.BackFace.StencilDepthFailOp = BackFace.StencilDepthFailOp; + D.BackFace.StencilPassOp = BackFace.StencilPassOp; + D.BackFace.StencilFunc = BackFace.StencilFunc; + return D; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_BLEND_DESC : public D3D12_BLEND_DESC +{ + CD3DX12_BLEND_DESC() = default; + explicit CD3DX12_BLEND_DESC( const D3D12_BLEND_DESC& o ) noexcept : + D3D12_BLEND_DESC( o ) + {} + explicit CD3DX12_BLEND_DESC( CD3DX12_DEFAULT ) noexcept + { + AlphaToCoverageEnable = FALSE; + IndependentBlendEnable = FALSE; + const D3D12_RENDER_TARGET_BLEND_DESC defaultRenderTargetBlendDesc = + { + FALSE,FALSE, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_BLEND_ONE, D3D12_BLEND_ZERO, D3D12_BLEND_OP_ADD, + D3D12_LOGIC_OP_NOOP, + D3D12_COLOR_WRITE_ENABLE_ALL, + }; + for (UINT i = 0; i < D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT; ++i) + RenderTarget[ i ] = defaultRenderTargetBlendDesc; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RASTERIZER_DESC : public D3D12_RASTERIZER_DESC +{ + CD3DX12_RASTERIZER_DESC() = default; + explicit CD3DX12_RASTERIZER_DESC( const D3D12_RASTERIZER_DESC& o ) noexcept : + D3D12_RASTERIZER_DESC( o ) + {} + explicit CD3DX12_RASTERIZER_DESC( CD3DX12_DEFAULT ) noexcept + { + FillMode = D3D12_FILL_MODE_SOLID; + CullMode = D3D12_CULL_MODE_BACK; + FrontCounterClockwise = FALSE; + DepthBias = D3D12_DEFAULT_DEPTH_BIAS; + DepthBiasClamp = D3D12_DEFAULT_DEPTH_BIAS_CLAMP; + SlopeScaledDepthBias = D3D12_DEFAULT_SLOPE_SCALED_DEPTH_BIAS; + DepthClipEnable = TRUE; + MultisampleEnable = FALSE; + AntialiasedLineEnable = FALSE; + ForcedSampleCount = 0; + ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF; + } + explicit CD3DX12_RASTERIZER_DESC( + D3D12_FILL_MODE fillMode, + D3D12_CULL_MODE cullMode, + BOOL frontCounterClockwise, + INT depthBias, + FLOAT depthBiasClamp, + FLOAT slopeScaledDepthBias, + BOOL depthClipEnable, + BOOL multisampleEnable, + BOOL antialiasedLineEnable, + UINT forcedSampleCount, + D3D12_CONSERVATIVE_RASTERIZATION_MODE conservativeRaster) noexcept + { + FillMode = fillMode; + CullMode = cullMode; + FrontCounterClockwise = frontCounterClockwise; + DepthBias = depthBias; + DepthBiasClamp = depthBiasClamp; + SlopeScaledDepthBias = slopeScaledDepthBias; + DepthClipEnable = depthClipEnable; + MultisampleEnable = multisampleEnable; + AntialiasedLineEnable = antialiasedLineEnable; + ForcedSampleCount = forcedSampleCount; + ConservativeRaster = conservativeRaster; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_ALLOCATION_INFO : public D3D12_RESOURCE_ALLOCATION_INFO +{ + CD3DX12_RESOURCE_ALLOCATION_INFO() = default; + explicit CD3DX12_RESOURCE_ALLOCATION_INFO( const D3D12_RESOURCE_ALLOCATION_INFO& o ) noexcept : + D3D12_RESOURCE_ALLOCATION_INFO( o ) + {} + CD3DX12_RESOURCE_ALLOCATION_INFO( + UINT64 size, + UINT64 alignment ) noexcept + { + SizeInBytes = size; + Alignment = alignment; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_PROPERTIES : public D3D12_HEAP_PROPERTIES +{ + CD3DX12_HEAP_PROPERTIES() = default; + explicit CD3DX12_HEAP_PROPERTIES(const D3D12_HEAP_PROPERTIES &o) noexcept : + D3D12_HEAP_PROPERTIES(o) + {} + CD3DX12_HEAP_PROPERTIES( + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) noexcept + { + Type = D3D12_HEAP_TYPE_CUSTOM; + CPUPageProperty = cpuPageProperty; + MemoryPoolPreference = memoryPoolPreference; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + explicit CD3DX12_HEAP_PROPERTIES( + D3D12_HEAP_TYPE type, + UINT creationNodeMask = 1, + UINT nodeMask = 1 ) noexcept + { + Type = type; + CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + CreationNodeMask = creationNodeMask; + VisibleNodeMask = nodeMask; + } + bool IsCPUAccessible() const noexcept + { + return Type == D3D12_HEAP_TYPE_UPLOAD || Type == D3D12_HEAP_TYPE_READBACK || (Type == D3D12_HEAP_TYPE_CUSTOM && + (CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_COMBINE || CPUPageProperty == D3D12_CPU_PAGE_PROPERTY_WRITE_BACK)); + } +}; +inline bool operator==( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) noexcept +{ + return l.Type == r.Type && l.CPUPageProperty == r.CPUPageProperty && + l.MemoryPoolPreference == r.MemoryPoolPreference && + l.CreationNodeMask == r.CreationNodeMask && + l.VisibleNodeMask == r.VisibleNodeMask; +} +inline bool operator!=( const D3D12_HEAP_PROPERTIES& l, const D3D12_HEAP_PROPERTIES& r ) noexcept +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_HEAP_DESC : public D3D12_HEAP_DESC +{ + CD3DX12_HEAP_DESC() = default; + explicit CD3DX12_HEAP_DESC(const D3D12_HEAP_DESC &o) noexcept : + D3D12_HEAP_DESC(o) + {} + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_PROPERTIES properties, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) noexcept + { + SizeInBytes = size; + Properties = properties; + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_HEAP_TYPE type, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) noexcept + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + UINT64 size, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + UINT64 alignment = 0, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) noexcept + { + SizeInBytes = size; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_PROPERTIES properties, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) noexcept + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = properties; + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_HEAP_TYPE type, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) noexcept + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( type ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + CD3DX12_HEAP_DESC( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_CPU_PAGE_PROPERTY cpuPageProperty, + D3D12_MEMORY_POOL memoryPoolPreference, + D3D12_HEAP_FLAGS flags = D3D12_HEAP_FLAG_NONE ) noexcept + { + SizeInBytes = resAllocInfo.SizeInBytes; + Properties = CD3DX12_HEAP_PROPERTIES( cpuPageProperty, memoryPoolPreference ); + Alignment = resAllocInfo.Alignment; + Flags = flags; + } + bool IsCPUAccessible() const noexcept + { return static_cast< const CD3DX12_HEAP_PROPERTIES* >( &Properties )->IsCPUAccessible(); } +}; +inline bool operator==( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) noexcept +{ + return l.SizeInBytes == r.SizeInBytes && + l.Properties == r.Properties && + l.Alignment == r.Alignment && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_HEAP_DESC& l, const D3D12_HEAP_DESC& r ) noexcept +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CLEAR_VALUE : public D3D12_CLEAR_VALUE +{ + CD3DX12_CLEAR_VALUE() = default; + explicit CD3DX12_CLEAR_VALUE(const D3D12_CLEAR_VALUE &o) noexcept : + D3D12_CLEAR_VALUE(o) + {} + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + const FLOAT color[4] ) noexcept + { + Format = format; + memcpy( Color, color, sizeof( Color ) ); + } + CD3DX12_CLEAR_VALUE( + DXGI_FORMAT format, + FLOAT depth, + UINT8 stencil ) noexcept + { + Format = format; + memset( &Color, 0, sizeof( Color ) ); + /* Use memcpy to preserve NAN values */ + memcpy( &DepthStencil.Depth, &depth, sizeof( depth ) ); + DepthStencil.Stencil = stencil; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE : public D3D12_RANGE +{ + CD3DX12_RANGE() = default; + explicit CD3DX12_RANGE(const D3D12_RANGE &o) noexcept : + D3D12_RANGE(o) + {} + CD3DX12_RANGE( + SIZE_T begin, + SIZE_T end ) noexcept + { + Begin = begin; + End = end; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RANGE_UINT64 : public D3D12_RANGE_UINT64 +{ + CD3DX12_RANGE_UINT64() = default; + explicit CD3DX12_RANGE_UINT64(const D3D12_RANGE_UINT64 &o) noexcept : + D3D12_RANGE_UINT64(o) + {} + CD3DX12_RANGE_UINT64( + UINT64 begin, + UINT64 end ) noexcept + { + Begin = begin; + End = end; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_RANGE_UINT64 : public D3D12_SUBRESOURCE_RANGE_UINT64 +{ + CD3DX12_SUBRESOURCE_RANGE_UINT64() = default; + explicit CD3DX12_SUBRESOURCE_RANGE_UINT64(const D3D12_SUBRESOURCE_RANGE_UINT64 &o) noexcept : + D3D12_SUBRESOURCE_RANGE_UINT64(o) + {} + CD3DX12_SUBRESOURCE_RANGE_UINT64( + UINT subresource, + const D3D12_RANGE_UINT64& range ) noexcept + { + Subresource = subresource; + Range = range; + } + CD3DX12_SUBRESOURCE_RANGE_UINT64( + UINT subresource, + UINT64 begin, + UINT64 end ) noexcept + { + Subresource = subresource; + Range.Begin = begin; + Range.End = end; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SHADER_BYTECODE : public D3D12_SHADER_BYTECODE +{ + CD3DX12_SHADER_BYTECODE() = default; + explicit CD3DX12_SHADER_BYTECODE(const D3D12_SHADER_BYTECODE &o) noexcept : + D3D12_SHADER_BYTECODE(o) + {} + CD3DX12_SHADER_BYTECODE( + _In_ ID3DBlob* pShaderBlob ) noexcept + { + pShaderBytecode = pShaderBlob->GetBufferPointer(); + BytecodeLength = pShaderBlob->GetBufferSize(); + } + CD3DX12_SHADER_BYTECODE( + const void* _pShaderBytecode, + SIZE_T bytecodeLength ) noexcept + { + pShaderBytecode = _pShaderBytecode; + BytecodeLength = bytecodeLength; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILED_RESOURCE_COORDINATE : public D3D12_TILED_RESOURCE_COORDINATE +{ + CD3DX12_TILED_RESOURCE_COORDINATE() = default; + explicit CD3DX12_TILED_RESOURCE_COORDINATE(const D3D12_TILED_RESOURCE_COORDINATE &o) noexcept : + D3D12_TILED_RESOURCE_COORDINATE(o) + {} + CD3DX12_TILED_RESOURCE_COORDINATE( + UINT x, + UINT y, + UINT z, + UINT subresource ) noexcept + { + X = x; + Y = y; + Z = z; + Subresource = subresource; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_REGION_SIZE : public D3D12_TILE_REGION_SIZE +{ + CD3DX12_TILE_REGION_SIZE() = default; + explicit CD3DX12_TILE_REGION_SIZE(const D3D12_TILE_REGION_SIZE &o) noexcept : + D3D12_TILE_REGION_SIZE(o) + {} + CD3DX12_TILE_REGION_SIZE( + UINT numTiles, + BOOL useBox, + UINT width, + UINT16 height, + UINT16 depth ) noexcept + { + NumTiles = numTiles; + UseBox = useBox; + Width = width; + Height = height; + Depth = depth; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_TILING : public D3D12_SUBRESOURCE_TILING +{ + CD3DX12_SUBRESOURCE_TILING() = default; + explicit CD3DX12_SUBRESOURCE_TILING(const D3D12_SUBRESOURCE_TILING &o) noexcept : + D3D12_SUBRESOURCE_TILING(o) + {} + CD3DX12_SUBRESOURCE_TILING( + UINT widthInTiles, + UINT16 heightInTiles, + UINT16 depthInTiles, + UINT startTileIndexInOverallResource ) noexcept + { + WidthInTiles = widthInTiles; + HeightInTiles = heightInTiles; + DepthInTiles = depthInTiles; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TILE_SHAPE : public D3D12_TILE_SHAPE +{ + CD3DX12_TILE_SHAPE() = default; + explicit CD3DX12_TILE_SHAPE(const D3D12_TILE_SHAPE &o) noexcept : + D3D12_TILE_SHAPE(o) + {} + CD3DX12_TILE_SHAPE( + UINT widthInTexels, + UINT heightInTexels, + UINT depthInTexels ) noexcept + { + WidthInTexels = widthInTexels; + HeightInTexels = heightInTexels; + DepthInTexels = depthInTexels; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_BARRIER : public D3D12_RESOURCE_BARRIER +{ + CD3DX12_RESOURCE_BARRIER() = default; + explicit CD3DX12_RESOURCE_BARRIER(const D3D12_RESOURCE_BARRIER &o) noexcept : + D3D12_RESOURCE_BARRIER(o) + {} + static inline CD3DX12_RESOURCE_BARRIER Transition( + _In_ ID3D12Resource* pResource, + D3D12_RESOURCE_STATES stateBefore, + D3D12_RESOURCE_STATES stateAfter, + UINT subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES, + D3D12_RESOURCE_BARRIER_FLAGS flags = D3D12_RESOURCE_BARRIER_FLAG_NONE) noexcept + { + CD3DX12_RESOURCE_BARRIER result = {}; + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + result.Flags = flags; + barrier.Transition.pResource = pResource; + barrier.Transition.StateBefore = stateBefore; + barrier.Transition.StateAfter = stateAfter; + barrier.Transition.Subresource = subresource; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER Aliasing( + _In_ ID3D12Resource* pResourceBefore, + _In_ ID3D12Resource* pResourceAfter) noexcept + { + CD3DX12_RESOURCE_BARRIER result = {}; + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_ALIASING; + barrier.Aliasing.pResourceBefore = pResourceBefore; + barrier.Aliasing.pResourceAfter = pResourceAfter; + return result; + } + static inline CD3DX12_RESOURCE_BARRIER UAV( + _In_ ID3D12Resource* pResource) noexcept + { + CD3DX12_RESOURCE_BARRIER result = {}; + D3D12_RESOURCE_BARRIER &barrier = result; + result.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; + barrier.UAV.pResource = pResource; + return result; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_PACKED_MIP_INFO : public D3D12_PACKED_MIP_INFO +{ + CD3DX12_PACKED_MIP_INFO() = default; + explicit CD3DX12_PACKED_MIP_INFO(const D3D12_PACKED_MIP_INFO &o) noexcept : + D3D12_PACKED_MIP_INFO(o) + {} + CD3DX12_PACKED_MIP_INFO( + UINT8 numStandardMips, + UINT8 numPackedMips, + UINT numTilesForPackedMips, + UINT startTileIndexInOverallResource ) noexcept + { + NumStandardMips = numStandardMips; + NumPackedMips = numPackedMips; + NumTilesForPackedMips = numTilesForPackedMips; + StartTileIndexInOverallResource = startTileIndexInOverallResource; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_SUBRESOURCE_FOOTPRINT : public D3D12_SUBRESOURCE_FOOTPRINT +{ + CD3DX12_SUBRESOURCE_FOOTPRINT() = default; + explicit CD3DX12_SUBRESOURCE_FOOTPRINT(const D3D12_SUBRESOURCE_FOOTPRINT &o) noexcept : + D3D12_SUBRESOURCE_FOOTPRINT(o) + {} + CD3DX12_SUBRESOURCE_FOOTPRINT( + DXGI_FORMAT format, + UINT width, + UINT height, + UINT depth, + UINT rowPitch ) noexcept + { + Format = format; + Width = width; + Height = height; + Depth = depth; + RowPitch = rowPitch; + } + explicit CD3DX12_SUBRESOURCE_FOOTPRINT( + const D3D12_RESOURCE_DESC& resDesc, + UINT rowPitch ) noexcept + { + Format = resDesc.Format; + Width = UINT( resDesc.Width ); + Height = resDesc.Height; + Depth = (resDesc.Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? resDesc.DepthOrArraySize : 1); + RowPitch = rowPitch; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_TEXTURE_COPY_LOCATION : public D3D12_TEXTURE_COPY_LOCATION +{ + CD3DX12_TEXTURE_COPY_LOCATION() = default; + explicit CD3DX12_TEXTURE_COPY_LOCATION(const D3D12_TEXTURE_COPY_LOCATION &o) noexcept : + D3D12_TEXTURE_COPY_LOCATION(o) + {} + CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes) noexcept + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + PlacedFootprint = {}; + } + CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, D3D12_PLACED_SUBRESOURCE_FOOTPRINT const& Footprint) noexcept + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + PlacedFootprint = Footprint; + } + CD3DX12_TEXTURE_COPY_LOCATION(_In_ ID3D12Resource* pRes, UINT Sub) noexcept + { + pResource = pRes; + Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + PlacedFootprint = {}; + SubresourceIndex = Sub; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE : public D3D12_DESCRIPTOR_RANGE +{ + CD3DX12_DESCRIPTOR_RANGE() = default; + explicit CD3DX12_DESCRIPTOR_RANGE(const D3D12_DESCRIPTOR_RANGE &o) noexcept : + D3D12_DESCRIPTOR_RANGE(o) + {} + CD3DX12_DESCRIPTOR_RANGE( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) noexcept + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) noexcept + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) noexcept + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE : public D3D12_ROOT_DESCRIPTOR_TABLE +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE() = default; + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE(const D3D12_ROOT_DESCRIPTOR_TABLE &o) noexcept : + D3D12_ROOT_DESCRIPTOR_TABLE(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) noexcept + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) noexcept + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* _pDescriptorRanges) noexcept + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_CONSTANTS : public D3D12_ROOT_CONSTANTS +{ + CD3DX12_ROOT_CONSTANTS() = default; + explicit CD3DX12_ROOT_CONSTANTS(const D3D12_ROOT_CONSTANTS &o) noexcept : + D3D12_ROOT_CONSTANTS(o) + {} + CD3DX12_ROOT_CONSTANTS( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) noexcept + { + Init(num32BitValues, shaderRegister, registerSpace); + } + + inline void Init( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) noexcept + { + Init(*this, num32BitValues, shaderRegister, registerSpace); + } + + static inline void Init( + _Out_ D3D12_ROOT_CONSTANTS &rootConstants, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0) noexcept + { + rootConstants.Num32BitValues = num32BitValues; + rootConstants.ShaderRegister = shaderRegister; + rootConstants.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR : public D3D12_ROOT_DESCRIPTOR +{ + CD3DX12_ROOT_DESCRIPTOR() = default; + explicit CD3DX12_ROOT_DESCRIPTOR(const D3D12_ROOT_DESCRIPTOR &o) noexcept : + D3D12_ROOT_DESCRIPTOR(o) + {} + CD3DX12_ROOT_DESCRIPTOR( + UINT shaderRegister, + UINT registerSpace = 0) noexcept + { + Init(shaderRegister, registerSpace); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0) noexcept + { + Init(*this, shaderRegister, registerSpace); + } + + static inline void Init(_Out_ D3D12_ROOT_DESCRIPTOR &table, UINT shaderRegister, UINT registerSpace = 0) noexcept + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER : public D3D12_ROOT_PARAMETER +{ + CD3DX12_ROOT_PARAMETER() = default; + explicit CD3DX12_ROOT_PARAMETER(const D3D12_ROOT_PARAMETER &o) noexcept : + D3D12_ROOT_PARAMETER(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR::Init(rootParam.Descriptor, shaderRegister, registerSpace); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_STATIC_SAMPLER_DESC : public D3D12_STATIC_SAMPLER_DESC +{ + CD3DX12_STATIC_SAMPLER_DESC() = default; + explicit CD3DX12_STATIC_SAMPLER_DESC(const D3D12_STATIC_SAMPLER_DESC &o) noexcept : + D3D12_STATIC_SAMPLER_DESC(o) + {} + CD3DX12_STATIC_SAMPLER_DESC( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) noexcept + { + Init( + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + + static inline void Init( + _Out_ D3D12_STATIC_SAMPLER_DESC &samplerDesc, + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) noexcept + { + samplerDesc.ShaderRegister = shaderRegister; + samplerDesc.Filter = filter; + samplerDesc.AddressU = addressU; + samplerDesc.AddressV = addressV; + samplerDesc.AddressW = addressW; + samplerDesc.MipLODBias = mipLODBias; + samplerDesc.MaxAnisotropy = maxAnisotropy; + samplerDesc.ComparisonFunc = comparisonFunc; + samplerDesc.BorderColor = borderColor; + samplerDesc.MinLOD = minLOD; + samplerDesc.MaxLOD = maxLOD; + samplerDesc.ShaderVisibility = shaderVisibility; + samplerDesc.RegisterSpace = registerSpace; + } + inline void Init( + UINT shaderRegister, + D3D12_FILTER filter = D3D12_FILTER_ANISOTROPIC, + D3D12_TEXTURE_ADDRESS_MODE addressU = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressV = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + D3D12_TEXTURE_ADDRESS_MODE addressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP, + FLOAT mipLODBias = 0, + UINT maxAnisotropy = 16, + D3D12_COMPARISON_FUNC comparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL, + D3D12_STATIC_BORDER_COLOR borderColor = D3D12_STATIC_BORDER_COLOR_OPAQUE_WHITE, + FLOAT minLOD = 0.f, + FLOAT maxLOD = D3D12_FLOAT32_MAX, + D3D12_SHADER_VISIBILITY shaderVisibility = D3D12_SHADER_VISIBILITY_ALL, + UINT registerSpace = 0) noexcept + { + Init( + *this, + shaderRegister, + filter, + addressU, + addressV, + addressW, + mipLODBias, + maxAnisotropy, + comparisonFunc, + borderColor, + minLOD, + maxLOD, + shaderVisibility, + registerSpace); + } + +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_SIGNATURE_DESC : public D3D12_ROOT_SIGNATURE_DESC +{ + CD3DX12_ROOT_SIGNATURE_DESC() = default; + explicit CD3DX12_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) noexcept : + D3D12_ROOT_SIGNATURE_DESC(o) + {} + CD3DX12_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + Init(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) noexcept + { + Init(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + Init(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + desc.NumParameters = numParameters; + desc.pParameters = _pParameters; + desc.NumStaticSamplers = numStaticSamplers; + desc.pStaticSamplers = _pStaticSamplers; + desc.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_DESCRIPTOR_RANGE1 : public D3D12_DESCRIPTOR_RANGE1 +{ + CD3DX12_DESCRIPTOR_RANGE1() = default; + explicit CD3DX12_DESCRIPTOR_RANGE1(const D3D12_DESCRIPTOR_RANGE1 &o) noexcept : + D3D12_DESCRIPTOR_RANGE1(o) + {} + CD3DX12_DESCRIPTOR_RANGE1( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) noexcept + { + Init(rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); + } + + inline void Init( + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) noexcept + { + Init(*this, rangeType, numDescriptors, baseShaderRegister, registerSpace, flags, offsetInDescriptorsFromTableStart); + } + + static inline void Init( + _Out_ D3D12_DESCRIPTOR_RANGE1 &range, + D3D12_DESCRIPTOR_RANGE_TYPE rangeType, + UINT numDescriptors, + UINT baseShaderRegister, + UINT registerSpace = 0, + D3D12_DESCRIPTOR_RANGE_FLAGS flags = D3D12_DESCRIPTOR_RANGE_FLAG_NONE, + UINT offsetInDescriptorsFromTableStart = + D3D12_DESCRIPTOR_RANGE_OFFSET_APPEND) noexcept + { + range.RangeType = rangeType; + range.NumDescriptors = numDescriptors; + range.BaseShaderRegister = baseShaderRegister; + range.RegisterSpace = registerSpace; + range.Flags = flags; + range.OffsetInDescriptorsFromTableStart = offsetInDescriptorsFromTableStart; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR_TABLE1 : public D3D12_ROOT_DESCRIPTOR_TABLE1 +{ + CD3DX12_ROOT_DESCRIPTOR_TABLE1() = default; + explicit CD3DX12_ROOT_DESCRIPTOR_TABLE1(const D3D12_ROOT_DESCRIPTOR_TABLE1 &o) noexcept : + D3D12_ROOT_DESCRIPTOR_TABLE1(o) + {} + CD3DX12_ROOT_DESCRIPTOR_TABLE1( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) noexcept + { + Init(numDescriptorRanges, _pDescriptorRanges); + } + + inline void Init( + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) noexcept + { + Init(*this, numDescriptorRanges, _pDescriptorRanges); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR_TABLE1 &rootDescriptorTable, + UINT numDescriptorRanges, + _In_reads_opt_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* _pDescriptorRanges) noexcept + { + rootDescriptorTable.NumDescriptorRanges = numDescriptorRanges; + rootDescriptorTable.pDescriptorRanges = _pDescriptorRanges; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_DESCRIPTOR1 : public D3D12_ROOT_DESCRIPTOR1 +{ + CD3DX12_ROOT_DESCRIPTOR1() = default; + explicit CD3DX12_ROOT_DESCRIPTOR1(const D3D12_ROOT_DESCRIPTOR1 &o) noexcept : + D3D12_ROOT_DESCRIPTOR1(o) + {} + CD3DX12_ROOT_DESCRIPTOR1( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) noexcept + { + Init(shaderRegister, registerSpace, flags); + } + + inline void Init( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) noexcept + { + Init(*this, shaderRegister, registerSpace, flags); + } + + static inline void Init( + _Out_ D3D12_ROOT_DESCRIPTOR1 &table, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE) noexcept + { + table.ShaderRegister = shaderRegister; + table.RegisterSpace = registerSpace; + table.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_ROOT_PARAMETER1 : public D3D12_ROOT_PARAMETER1 +{ + CD3DX12_ROOT_PARAMETER1() = default; + explicit CD3DX12_ROOT_PARAMETER1(const D3D12_ROOT_PARAMETER1 &o) noexcept : + D3D12_ROOT_PARAMETER1(o) + {} + + static inline void InitAsDescriptorTable( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR_TABLE1::Init(rootParam.DescriptorTable, numDescriptorRanges, pDescriptorRanges); + } + + static inline void InitAsConstants( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_CONSTANTS::Init(rootParam.Constants, num32BitValues, shaderRegister, registerSpace); + } + + static inline void InitAsConstantBufferView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_CBV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + static inline void InitAsShaderResourceView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_SRV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + static inline void InitAsUnorderedAccessView( + _Out_ D3D12_ROOT_PARAMETER1 &rootParam, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + rootParam.ParameterType = D3D12_ROOT_PARAMETER_TYPE_UAV; + rootParam.ShaderVisibility = visibility; + CD3DX12_ROOT_DESCRIPTOR1::Init(rootParam.Descriptor, shaderRegister, registerSpace, flags); + } + + inline void InitAsDescriptorTable( + UINT numDescriptorRanges, + _In_reads_(numDescriptorRanges) const D3D12_DESCRIPTOR_RANGE1* pDescriptorRanges, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsDescriptorTable(*this, numDescriptorRanges, pDescriptorRanges, visibility); + } + + inline void InitAsConstants( + UINT num32BitValues, + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsConstants(*this, num32BitValues, shaderRegister, registerSpace, visibility); + } + + inline void InitAsConstantBufferView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsConstantBufferView(*this, shaderRegister, registerSpace, flags, visibility); + } + + inline void InitAsShaderResourceView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsShaderResourceView(*this, shaderRegister, registerSpace, flags, visibility); + } + + inline void InitAsUnorderedAccessView( + UINT shaderRegister, + UINT registerSpace = 0, + D3D12_ROOT_DESCRIPTOR_FLAGS flags = D3D12_ROOT_DESCRIPTOR_FLAG_NONE, + D3D12_SHADER_VISIBILITY visibility = D3D12_SHADER_VISIBILITY_ALL) noexcept + { + InitAsUnorderedAccessView(*this, shaderRegister, registerSpace, flags, visibility); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC : public D3D12_VERSIONED_ROOT_SIGNATURE_DESC +{ + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC() = default; + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_VERSIONED_ROOT_SIGNATURE_DESC &o) noexcept : + D3D12_VERSIONED_ROOT_SIGNATURE_DESC(o) + {} + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC &o) noexcept + { + Version = D3D_ROOT_SIGNATURE_VERSION_1_0; + Desc_1_0 = o; + } + explicit CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(const D3D12_ROOT_SIGNATURE_DESC1 &o) noexcept + { + Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + Desc_1_1 = o; + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + Init_1_0(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + Init_1_1(numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + CD3DX12_VERSIONED_ROOT_SIGNATURE_DESC(CD3DX12_DEFAULT) noexcept + { + Init_1_1(0, nullptr, 0, nullptr, D3D12_ROOT_SIGNATURE_FLAG_NONE); + } + + inline void Init_1_0( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + Init_1_0(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init_1_0( + _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_0; + desc.Desc_1_0.NumParameters = numParameters; + desc.Desc_1_0.pParameters = _pParameters; + desc.Desc_1_0.NumStaticSamplers = numStaticSamplers; + desc.Desc_1_0.pStaticSamplers = _pStaticSamplers; + desc.Desc_1_0.Flags = flags; + } + + inline void Init_1_1( + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + Init_1_1(*this, numParameters, _pParameters, numStaticSamplers, _pStaticSamplers, flags); + } + + static inline void Init_1_1( + _Out_ D3D12_VERSIONED_ROOT_SIGNATURE_DESC &desc, + UINT numParameters, + _In_reads_opt_(numParameters) const D3D12_ROOT_PARAMETER1* _pParameters, + UINT numStaticSamplers = 0, + _In_reads_opt_(numStaticSamplers) const D3D12_STATIC_SAMPLER_DESC* _pStaticSamplers = nullptr, + D3D12_ROOT_SIGNATURE_FLAGS flags = D3D12_ROOT_SIGNATURE_FLAG_NONE) noexcept + { + desc.Version = D3D_ROOT_SIGNATURE_VERSION_1_1; + desc.Desc_1_1.NumParameters = numParameters; + desc.Desc_1_1.pParameters = _pParameters; + desc.Desc_1_1.NumStaticSamplers = numStaticSamplers; + desc.Desc_1_1.pStaticSamplers = _pStaticSamplers; + desc.Desc_1_1.Flags = flags; + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_CPU_DESCRIPTOR_HANDLE : public D3D12_CPU_DESCRIPTOR_HANDLE +{ + CD3DX12_CPU_DESCRIPTOR_HANDLE() = default; + explicit CD3DX12_CPU_DESCRIPTOR_HANDLE(const D3D12_CPU_DESCRIPTOR_HANDLE &o) noexcept : + D3D12_CPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_CPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) noexcept { ptr = 0; } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) noexcept + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + ptr = SIZE_T(INT64(ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + return *this; + } + CD3DX12_CPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) noexcept + { + ptr = SIZE_T(INT64(ptr) + INT64(offsetScaledByIncrementSize)); + return *this; + } + bool operator==(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const noexcept + { + return (ptr == other.ptr); + } + bool operator!=(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE& other) const noexcept + { + return (ptr != other.ptr); + } + CD3DX12_CPU_DESCRIPTOR_HANDLE &operator=(const D3D12_CPU_DESCRIPTOR_HANDLE &other) noexcept + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) noexcept + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) noexcept + { + handle.ptr = SIZE_T(INT64(base.ptr) + INT64(offsetScaledByIncrementSize)); + } + + static inline void InitOffsetted(_Out_ D3D12_CPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_CPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + handle.ptr = SIZE_T(INT64(base.ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + } +}; + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_GPU_DESCRIPTOR_HANDLE : public D3D12_GPU_DESCRIPTOR_HANDLE +{ + CD3DX12_GPU_DESCRIPTOR_HANDLE() = default; + explicit CD3DX12_GPU_DESCRIPTOR_HANDLE(const D3D12_GPU_DESCRIPTOR_HANDLE &o) noexcept : + D3D12_GPU_DESCRIPTOR_HANDLE(o) + {} + CD3DX12_GPU_DESCRIPTOR_HANDLE(CD3DX12_DEFAULT) noexcept { ptr = 0; } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetScaledByIncrementSize) noexcept + { + InitOffsetted(other, offsetScaledByIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &other, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + InitOffsetted(other, offsetInDescriptors, descriptorIncrementSize); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + ptr = UINT64(INT64(ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + return *this; + } + CD3DX12_GPU_DESCRIPTOR_HANDLE& Offset(INT offsetScaledByIncrementSize) noexcept + { + ptr = UINT64(INT64(ptr) + INT64(offsetScaledByIncrementSize)); + return *this; + } + inline bool operator==(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const noexcept + { + return (ptr == other.ptr); + } + inline bool operator!=(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE& other) const noexcept + { + return (ptr != other.ptr); + } + CD3DX12_GPU_DESCRIPTOR_HANDLE &operator=(const D3D12_GPU_DESCRIPTOR_HANDLE &other) noexcept + { + ptr = other.ptr; + return *this; + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) noexcept + { + InitOffsetted(*this, base, offsetScaledByIncrementSize); + } + + inline void InitOffsetted(_In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + InitOffsetted(*this, base, offsetInDescriptors, descriptorIncrementSize); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetScaledByIncrementSize) noexcept + { + handle.ptr = UINT64(INT64(base.ptr) + INT64(offsetScaledByIncrementSize)); + } + + static inline void InitOffsetted(_Out_ D3D12_GPU_DESCRIPTOR_HANDLE &handle, _In_ const D3D12_GPU_DESCRIPTOR_HANDLE &base, INT offsetInDescriptors, UINT descriptorIncrementSize) noexcept + { + handle.ptr = UINT64(INT64(base.ptr) + INT64(offsetInDescriptors) * INT64(descriptorIncrementSize)); + } +}; + +//------------------------------------------------------------------------------------------------ +inline constexpr UINT D3D12CalcSubresource( UINT MipSlice, UINT ArraySlice, UINT PlaneSlice, UINT MipLevels, UINT ArraySize ) noexcept +{ + return MipSlice + ArraySlice * MipLevels + PlaneSlice * MipLevels * ArraySize; +} + +//------------------------------------------------------------------------------------------------ +template +inline void D3D12DecomposeSubresource( UINT Subresource, UINT MipLevels, UINT ArraySize, _Out_ T& MipSlice, _Out_ U& ArraySlice, _Out_ V& PlaneSlice ) noexcept +{ + MipSlice = static_cast(Subresource % MipLevels); + ArraySlice = static_cast((Subresource / MipLevels) % ArraySize); + PlaneSlice = static_cast(Subresource / (MipLevels * ArraySize)); +} + +//------------------------------------------------------------------------------------------------ +inline UINT8 D3D12GetFormatPlaneCount( + _In_ ID3D12Device* pDevice, + DXGI_FORMAT Format + ) noexcept +{ + D3D12_FEATURE_DATA_FORMAT_INFO formatInfo = { Format, 0 }; + if (FAILED(pDevice->CheckFeatureSupport(D3D12_FEATURE_FORMAT_INFO, &formatInfo, sizeof(formatInfo)))) + { + return 0; + } + return formatInfo.PlaneCount; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC : public D3D12_RESOURCE_DESC +{ + CD3DX12_RESOURCE_DESC() = default; + explicit CD3DX12_RESOURCE_DESC( const D3D12_RESOURCE_DESC& o ) noexcept : + D3D12_RESOURCE_DESC( o ) + {} + CD3DX12_RESOURCE_DESC( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags ) noexcept + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + } + static inline CD3DX12_RESOURCE_DESC Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) noexcept + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) noexcept + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) noexcept + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) noexcept + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags ); + } + static inline CD3DX12_RESOURCE_DESC Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) noexcept + { + return CD3DX12_RESOURCE_DESC( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags ); + } + inline UINT16 Depth() const noexcept + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const noexcept + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const noexcept + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const noexcept + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) noexcept + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } +}; +inline bool operator==( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) noexcept +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags; +} +inline bool operator!=( const D3D12_RESOURCE_DESC& l, const D3D12_RESOURCE_DESC& r ) noexcept +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RESOURCE_DESC1 : public D3D12_RESOURCE_DESC1 +{ + CD3DX12_RESOURCE_DESC1() = default; + explicit CD3DX12_RESOURCE_DESC1( const D3D12_RESOURCE_DESC1& o ) noexcept : + D3D12_RESOURCE_DESC1( o ) + {} + CD3DX12_RESOURCE_DESC1( + D3D12_RESOURCE_DIMENSION dimension, + UINT64 alignment, + UINT64 width, + UINT height, + UINT16 depthOrArraySize, + UINT16 mipLevels, + DXGI_FORMAT format, + UINT sampleCount, + UINT sampleQuality, + D3D12_TEXTURE_LAYOUT layout, + D3D12_RESOURCE_FLAGS flags, + UINT samplerFeedbackMipRegionWidth = 0, + UINT samplerFeedbackMipRegionHeight = 0, + UINT samplerFeedbackMipRegionDepth = 0) noexcept + { + Dimension = dimension; + Alignment = alignment; + Width = width; + Height = height; + DepthOrArraySize = depthOrArraySize; + MipLevels = mipLevels; + Format = format; + SampleDesc.Count = sampleCount; + SampleDesc.Quality = sampleQuality; + Layout = layout; + Flags = flags; + SamplerFeedbackMipRegion.Width = samplerFeedbackMipRegionWidth; + SamplerFeedbackMipRegion.Height = samplerFeedbackMipRegionHeight; + SamplerFeedbackMipRegion.Depth = samplerFeedbackMipRegionDepth; + } + static inline CD3DX12_RESOURCE_DESC1 Buffer( + const D3D12_RESOURCE_ALLOCATION_INFO& resAllocInfo, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE ) noexcept + { + return CD3DX12_RESOURCE_DESC1( D3D12_RESOURCE_DIMENSION_BUFFER, resAllocInfo.Alignment, resAllocInfo.SizeInBytes, + 1, 1, 1, DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags, 0, 0, 0 ); + } + static inline CD3DX12_RESOURCE_DESC1 Buffer( + UINT64 width, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + UINT64 alignment = 0 ) noexcept + { + return CD3DX12_RESOURCE_DESC1( D3D12_RESOURCE_DIMENSION_BUFFER, alignment, width, 1, 1, 1, + DXGI_FORMAT_UNKNOWN, 1, 0, D3D12_TEXTURE_LAYOUT_ROW_MAJOR, flags, 0, 0, 0 ); + } + static inline CD3DX12_RESOURCE_DESC1 Tex1D( + DXGI_FORMAT format, + UINT64 width, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) noexcept + { + return CD3DX12_RESOURCE_DESC1( D3D12_RESOURCE_DIMENSION_TEXTURE1D, alignment, width, 1, arraySize, + mipLevels, format, 1, 0, layout, flags, 0, 0, 0 ); + } + static inline CD3DX12_RESOURCE_DESC1 Tex2D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 arraySize = 1, + UINT16 mipLevels = 0, + UINT sampleCount = 1, + UINT sampleQuality = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0, + UINT samplerFeedbackMipRegionWidth = 0, + UINT samplerFeedbackMipRegionHeight = 0, + UINT samplerFeedbackMipRegionDepth = 0) noexcept + { + return CD3DX12_RESOURCE_DESC1( D3D12_RESOURCE_DIMENSION_TEXTURE2D, alignment, width, height, arraySize, + mipLevels, format, sampleCount, sampleQuality, layout, flags, samplerFeedbackMipRegionWidth, + samplerFeedbackMipRegionHeight, samplerFeedbackMipRegionDepth ); + } + static inline CD3DX12_RESOURCE_DESC1 Tex3D( + DXGI_FORMAT format, + UINT64 width, + UINT height, + UINT16 depth, + UINT16 mipLevels = 0, + D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE, + D3D12_TEXTURE_LAYOUT layout = D3D12_TEXTURE_LAYOUT_UNKNOWN, + UINT64 alignment = 0 ) noexcept + { + return CD3DX12_RESOURCE_DESC1( D3D12_RESOURCE_DIMENSION_TEXTURE3D, alignment, width, height, depth, + mipLevels, format, 1, 0, layout, flags, 0, 0, 0 ); + } + inline UINT16 Depth() const noexcept + { return (Dimension == D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT16 ArraySize() const noexcept + { return (Dimension != D3D12_RESOURCE_DIMENSION_TEXTURE3D ? DepthOrArraySize : 1); } + inline UINT8 PlaneCount(_In_ ID3D12Device* pDevice) const noexcept + { return D3D12GetFormatPlaneCount(pDevice, Format); } + inline UINT Subresources(_In_ ID3D12Device* pDevice) const noexcept + { return MipLevels * ArraySize() * PlaneCount(pDevice); } + inline UINT CalcSubresource(UINT MipSlice, UINT ArraySlice, UINT PlaneSlice) noexcept + { return D3D12CalcSubresource(MipSlice, ArraySlice, PlaneSlice, MipLevels, ArraySize()); } +}; +inline bool operator==( const D3D12_RESOURCE_DESC1& l, const D3D12_RESOURCE_DESC1& r ) noexcept +{ + return l.Dimension == r.Dimension && + l.Alignment == r.Alignment && + l.Width == r.Width && + l.Height == r.Height && + l.DepthOrArraySize == r.DepthOrArraySize && + l.MipLevels == r.MipLevels && + l.Format == r.Format && + l.SampleDesc.Count == r.SampleDesc.Count && + l.SampleDesc.Quality == r.SampleDesc.Quality && + l.Layout == r.Layout && + l.Flags == r.Flags && + l.SamplerFeedbackMipRegion.Width == r.SamplerFeedbackMipRegion.Width && + l.SamplerFeedbackMipRegion.Height == r.SamplerFeedbackMipRegion.Height && + l.SamplerFeedbackMipRegion.Depth == r.SamplerFeedbackMipRegion.Depth; +} +inline bool operator!=( const D3D12_RESOURCE_DESC1& l, const D3D12_RESOURCE_DESC1& r ) noexcept +{ return !( l == r ); } + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_VIEW_INSTANCING_DESC : public D3D12_VIEW_INSTANCING_DESC +{ + CD3DX12_VIEW_INSTANCING_DESC() = default; + explicit CD3DX12_VIEW_INSTANCING_DESC( const D3D12_VIEW_INSTANCING_DESC& o ) noexcept : + D3D12_VIEW_INSTANCING_DESC( o ) + {} + explicit CD3DX12_VIEW_INSTANCING_DESC( CD3DX12_DEFAULT ) noexcept + { + ViewInstanceCount = 0; + pViewInstanceLocations = nullptr; + Flags = D3D12_VIEW_INSTANCING_FLAG_NONE; + } + explicit CD3DX12_VIEW_INSTANCING_DESC( + UINT InViewInstanceCount, + const D3D12_VIEW_INSTANCE_LOCATION* InViewInstanceLocations, + D3D12_VIEW_INSTANCING_FLAGS InFlags) noexcept + { + ViewInstanceCount = InViewInstanceCount; + pViewInstanceLocations = InViewInstanceLocations; + Flags = InFlags; + } +}; + +//------------------------------------------------------------------------------------------------ +// Row-by-row memcpy +inline void MemcpySubresource( + _In_ const D3D12_MEMCPY_DEST* pDest, + _In_ const D3D12_SUBRESOURCE_DATA* pSrc, + SIZE_T RowSizeInBytes, + UINT NumRows, + UINT NumSlices) noexcept +{ + for (UINT z = 0; z < NumSlices; ++z) + { + auto pDestSlice = static_cast(pDest->pData) + pDest->SlicePitch * z; + auto pSrcSlice = static_cast(pSrc->pData) + pSrc->SlicePitch * LONG_PTR(z); + for (UINT y = 0; y < NumRows; ++y) + { + memcpy(pDestSlice + pDest->RowPitch * y, + pSrcSlice + pSrc->RowPitch * LONG_PTR(y), + RowSizeInBytes); + } + } +} + +//------------------------------------------------------------------------------------------------ +// Returns required size of a buffer to be used for data upload +inline UINT64 GetRequiredIntermediateSize( + _In_ ID3D12Resource* pDestinationResource, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources) noexcept +{ + auto Desc = pDestinationResource->GetDesc(); + UINT64 RequiredSize = 0; + + ID3D12Device* pDevice = nullptr; + pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, 0, nullptr, nullptr, nullptr, &RequiredSize); + pDevice->Release(); + + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// All arrays must be populated (e.g. by calling GetCopyableFootprints) +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + UINT64 RequiredSize, + _In_reads_(NumSubresources) const D3D12_PLACED_SUBRESOURCE_FOOTPRINT* pLayouts, + _In_reads_(NumSubresources) const UINT* pNumRows, + _In_reads_(NumSubresources) const UINT64* pRowSizesInBytes, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept +{ + // Minor validation + auto IntermediateDesc = pIntermediate->GetDesc(); + auto DestinationDesc = pDestinationResource->GetDesc(); + if (IntermediateDesc.Dimension != D3D12_RESOURCE_DIMENSION_BUFFER || + IntermediateDesc.Width < RequiredSize + pLayouts[0].Offset || + RequiredSize > SIZE_T(-1) || + (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER && + (FirstSubresource != 0 || NumSubresources != 1))) + { + return 0; + } + + BYTE* pData; + HRESULT hr = pIntermediate->Map(0, nullptr, reinterpret_cast(&pData)); + if (FAILED(hr)) + { + return 0; + } + + for (UINT i = 0; i < NumSubresources; ++i) + { + if (pRowSizesInBytes[i] > SIZE_T(-1)) return 0; + D3D12_MEMCPY_DEST DestData = { pData + pLayouts[i].Offset, pLayouts[i].Footprint.RowPitch, SIZE_T(pLayouts[i].Footprint.RowPitch) * SIZE_T(pNumRows[i]) }; + MemcpySubresource(&DestData, &pSrcData[i], static_cast(pRowSizesInBytes[i]), pNumRows[i], pLayouts[i].Footprint.Depth); + } + pIntermediate->Unmap(0, nullptr); + + if (DestinationDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER) + { + pCmdList->CopyBufferRegion( + pDestinationResource, 0, pIntermediate, pLayouts[0].Offset, pLayouts[0].Footprint.Width); + } + else + { + for (UINT i = 0; i < NumSubresources; ++i) + { + CD3DX12_TEXTURE_COPY_LOCATION Dst(pDestinationResource, i + FirstSubresource); + CD3DX12_TEXTURE_COPY_LOCATION Src(pIntermediate, pLayouts[i]); + pCmdList->CopyTextureRegion(&Dst, 0, 0, 0, &Src, nullptr); + } + } + return RequiredSize; +} + +//------------------------------------------------------------------------------------------------ +// Heap-allocating UpdateSubresources implementation +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0,D3D12_REQ_SUBRESOURCES) UINT FirstSubresource, + _In_range_(0,D3D12_REQ_SUBRESOURCES-FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept +{ + UINT64 RequiredSize = 0; + UINT64 MemToAlloc = static_cast(sizeof(D3D12_PLACED_SUBRESOURCE_FOOTPRINT) + sizeof(UINT) + sizeof(UINT64)) * NumSubresources; + if (MemToAlloc > SIZE_MAX) + { + return 0; + } + void* pMem = HeapAlloc(GetProcessHeap(), 0, static_cast(MemToAlloc)); + if (pMem == nullptr) + { + return 0; + } + auto pLayouts = static_cast(pMem); + UINT64* pRowSizesInBytes = reinterpret_cast(pLayouts + NumSubresources); + UINT* pNumRows = reinterpret_cast(pRowSizesInBytes + NumSubresources); + + auto Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice = nullptr; + pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, pLayouts, pNumRows, pRowSizesInBytes, &RequiredSize); + pDevice->Release(); + + UINT64 Result = UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, pLayouts, pNumRows, pRowSizesInBytes, pSrcData); + HeapFree(GetProcessHeap(), 0, pMem); + return Result; +} + +//------------------------------------------------------------------------------------------------ +// Stack-allocating UpdateSubresources implementation +template +inline UINT64 UpdateSubresources( + _In_ ID3D12GraphicsCommandList* pCmdList, + _In_ ID3D12Resource* pDestinationResource, + _In_ ID3D12Resource* pIntermediate, + UINT64 IntermediateOffset, + _In_range_(0, MaxSubresources) UINT FirstSubresource, + _In_range_(1, MaxSubresources - FirstSubresource) UINT NumSubresources, + _In_reads_(NumSubresources) const D3D12_SUBRESOURCE_DATA* pSrcData) noexcept +{ + UINT64 RequiredSize = 0; + D3D12_PLACED_SUBRESOURCE_FOOTPRINT Layouts[MaxSubresources]; + UINT NumRows[MaxSubresources]; + UINT64 RowSizesInBytes[MaxSubresources]; + + auto Desc = pDestinationResource->GetDesc(); + ID3D12Device* pDevice = nullptr; + pDestinationResource->GetDevice(IID_ID3D12Device, reinterpret_cast(&pDevice)); + pDevice->GetCopyableFootprints(&Desc, FirstSubresource, NumSubresources, IntermediateOffset, Layouts, NumRows, RowSizesInBytes, &RequiredSize); + pDevice->Release(); + + return UpdateSubresources(pCmdList, pDestinationResource, pIntermediate, FirstSubresource, NumSubresources, RequiredSize, Layouts, NumRows, RowSizesInBytes, pSrcData); +} + +//------------------------------------------------------------------------------------------------ +inline constexpr bool D3D12IsLayoutOpaque( D3D12_TEXTURE_LAYOUT Layout ) noexcept +{ return Layout == D3D12_TEXTURE_LAYOUT_UNKNOWN || Layout == D3D12_TEXTURE_LAYOUT_64KB_UNDEFINED_SWIZZLE; } + +//------------------------------------------------------------------------------------------------ +template +inline ID3D12CommandList * const * CommandListCast(t_CommandListType * const * pp) noexcept +{ + // This cast is useful for passing strongly typed command list pointers into + // ExecuteCommandLists. + // This cast is valid as long as the const-ness is respected. D3D12 APIs do + // respect the const-ness of their arguments. + return reinterpret_cast(pp); +} + +//------------------------------------------------------------------------------------------------ +// D3D12 exports a new method for serializing root signatures in the Windows 10 Anniversary Update. +// To help enable root signature 1.1 features when they are available and not require maintaining +// two code paths for building root signatures, this helper method reconstructs a 1.0 signature when +// 1.1 is not supported. +inline HRESULT D3DX12SerializeVersionedRootSignature( + _In_ const D3D12_VERSIONED_ROOT_SIGNATURE_DESC* pRootSignatureDesc, + D3D_ROOT_SIGNATURE_VERSION MaxVersion, + _Outptr_ ID3DBlob** ppBlob, + _Always_(_Outptr_opt_result_maybenull_) ID3DBlob** ppErrorBlob) noexcept +{ + if (ppErrorBlob != nullptr) + { + *ppErrorBlob = nullptr; + } + + switch (MaxVersion) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + switch (pRootSignatureDesc->Version) + { + case D3D_ROOT_SIGNATURE_VERSION_1_0: + return D3D12SerializeRootSignature(&pRootSignatureDesc->Desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); + + case D3D_ROOT_SIGNATURE_VERSION_1_1: + { + HRESULT hr = S_OK; + const D3D12_ROOT_SIGNATURE_DESC1& desc_1_1 = pRootSignatureDesc->Desc_1_1; + + const SIZE_T ParametersSize = sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters; + void* pParameters = (ParametersSize > 0) ? HeapAlloc(GetProcessHeap(), 0, ParametersSize) : nullptr; + if (ParametersSize > 0 && pParameters == nullptr) + { + hr = E_OUTOFMEMORY; + } + auto pParameters_1_0 = static_cast(pParameters); + + if (SUCCEEDED(hr)) + { + for (UINT n = 0; n < desc_1_1.NumParameters; n++) + { + __analysis_assume(ParametersSize == sizeof(D3D12_ROOT_PARAMETER) * desc_1_1.NumParameters); + pParameters_1_0[n].ParameterType = desc_1_1.pParameters[n].ParameterType; + pParameters_1_0[n].ShaderVisibility = desc_1_1.pParameters[n].ShaderVisibility; + + switch (desc_1_1.pParameters[n].ParameterType) + { + case D3D12_ROOT_PARAMETER_TYPE_32BIT_CONSTANTS: + pParameters_1_0[n].Constants.Num32BitValues = desc_1_1.pParameters[n].Constants.Num32BitValues; + pParameters_1_0[n].Constants.RegisterSpace = desc_1_1.pParameters[n].Constants.RegisterSpace; + pParameters_1_0[n].Constants.ShaderRegister = desc_1_1.pParameters[n].Constants.ShaderRegister; + break; + + case D3D12_ROOT_PARAMETER_TYPE_CBV: + case D3D12_ROOT_PARAMETER_TYPE_SRV: + case D3D12_ROOT_PARAMETER_TYPE_UAV: + pParameters_1_0[n].Descriptor.RegisterSpace = desc_1_1.pParameters[n].Descriptor.RegisterSpace; + pParameters_1_0[n].Descriptor.ShaderRegister = desc_1_1.pParameters[n].Descriptor.ShaderRegister; + break; + + case D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE: + const D3D12_ROOT_DESCRIPTOR_TABLE1& table_1_1 = desc_1_1.pParameters[n].DescriptorTable; + + const SIZE_T DescriptorRangesSize = sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges; + void* pDescriptorRanges = (DescriptorRangesSize > 0 && SUCCEEDED(hr)) ? HeapAlloc(GetProcessHeap(), 0, DescriptorRangesSize) : nullptr; + if (DescriptorRangesSize > 0 && pDescriptorRanges == nullptr) + { + hr = E_OUTOFMEMORY; + } + auto pDescriptorRanges_1_0 = static_cast(pDescriptorRanges); + + if (SUCCEEDED(hr)) + { + for (UINT x = 0; x < table_1_1.NumDescriptorRanges; x++) + { + __analysis_assume(DescriptorRangesSize == sizeof(D3D12_DESCRIPTOR_RANGE) * table_1_1.NumDescriptorRanges); + pDescriptorRanges_1_0[x].BaseShaderRegister = table_1_1.pDescriptorRanges[x].BaseShaderRegister; + pDescriptorRanges_1_0[x].NumDescriptors = table_1_1.pDescriptorRanges[x].NumDescriptors; + pDescriptorRanges_1_0[x].OffsetInDescriptorsFromTableStart = table_1_1.pDescriptorRanges[x].OffsetInDescriptorsFromTableStart; + pDescriptorRanges_1_0[x].RangeType = table_1_1.pDescriptorRanges[x].RangeType; + pDescriptorRanges_1_0[x].RegisterSpace = table_1_1.pDescriptorRanges[x].RegisterSpace; + } + } + + D3D12_ROOT_DESCRIPTOR_TABLE& table_1_0 = pParameters_1_0[n].DescriptorTable; + table_1_0.NumDescriptorRanges = table_1_1.NumDescriptorRanges; + table_1_0.pDescriptorRanges = pDescriptorRanges_1_0; + } + } + } + + if (SUCCEEDED(hr)) + { + CD3DX12_ROOT_SIGNATURE_DESC desc_1_0(desc_1_1.NumParameters, pParameters_1_0, desc_1_1.NumStaticSamplers, desc_1_1.pStaticSamplers, desc_1_1.Flags); + hr = D3D12SerializeRootSignature(&desc_1_0, D3D_ROOT_SIGNATURE_VERSION_1, ppBlob, ppErrorBlob); + } + + if (pParameters) + { + for (UINT n = 0; n < desc_1_1.NumParameters; n++) + { + if (desc_1_1.pParameters[n].ParameterType == D3D12_ROOT_PARAMETER_TYPE_DESCRIPTOR_TABLE) + { + HeapFree(GetProcessHeap(), 0, reinterpret_cast(const_cast(pParameters_1_0[n].DescriptorTable.pDescriptorRanges))); + } + } + HeapFree(GetProcessHeap(), 0, pParameters); + } + return hr; + } + } + break; + + case D3D_ROOT_SIGNATURE_VERSION_1_1: + return D3D12SerializeVersionedRootSignature(pRootSignatureDesc, ppBlob, ppErrorBlob); + } + + return E_INVALIDARG; +} + +//------------------------------------------------------------------------------------------------ +struct CD3DX12_RT_FORMAT_ARRAY : public D3D12_RT_FORMAT_ARRAY +{ + CD3DX12_RT_FORMAT_ARRAY() = default; + explicit CD3DX12_RT_FORMAT_ARRAY(const D3D12_RT_FORMAT_ARRAY& o) noexcept + : D3D12_RT_FORMAT_ARRAY(o) + {} + explicit CD3DX12_RT_FORMAT_ARRAY(_In_reads_(NumFormats) const DXGI_FORMAT* pFormats, UINT NumFormats) noexcept + { + NumRenderTargets = NumFormats; + memcpy(RTFormats, pFormats, sizeof(RTFormats)); + // assumes ARRAY_SIZE(pFormats) == ARRAY_SIZE(RTFormats) + } +}; + +//------------------------------------------------------------------------------------------------ +// Pipeline State Stream Helpers +//------------------------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------------------------ +// Stream Subobjects, i.e. elements of a stream + +struct DefaultSampleMask { operator UINT() noexcept { return UINT_MAX; } }; +struct DefaultSampleDesc { operator DXGI_SAMPLE_DESC() noexcept { return DXGI_SAMPLE_DESC{1, 0}; } }; + +#pragma warning(push) +#pragma warning(disable : 4324) +template +class alignas(void*) CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT +{ +private: + D3D12_PIPELINE_STATE_SUBOBJECT_TYPE _Type; + InnerStructType _Inner; +public: + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT() noexcept : _Type(Type), _Inner(DefaultArg()) {} + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT(InnerStructType const& i) noexcept : _Type(Type), _Inner(i) {} + CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT& operator=(InnerStructType const& i) noexcept { _Type = Type; _Inner = i; return *this; } + operator InnerStructType const&() const noexcept { return _Inner; } + operator InnerStructType&() noexcept { return _Inner; } + InnerStructType* operator&() noexcept { return &_Inner; } + InnerStructType const* operator&() const noexcept { return &_Inner; } +}; +#pragma warning(pop) +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PIPELINE_STATE_FLAGS, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS> CD3DX12_PIPELINE_STATE_STREAM_FLAGS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK> CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< ID3D12RootSignature*, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE> CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INPUT_LAYOUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT> CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_INDEX_BUFFER_STRIP_CUT_VALUE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE> CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_PRIMITIVE_TOPOLOGY_TYPE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY> CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS> CD3DX12_PIPELINE_STATE_STREAM_VS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS> CD3DX12_PIPELINE_STATE_STREAM_GS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_STREAM_OUTPUT_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT> CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS> CD3DX12_PIPELINE_STATE_STREAM_HS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS> CD3DX12_PIPELINE_STATE_STREAM_DS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS> CD3DX12_PIPELINE_STATE_STREAM_PS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS> CD3DX12_PIPELINE_STATE_STREAM_AS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS> CD3DX12_PIPELINE_STATE_STREAM_MS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_SHADER_BYTECODE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS> CD3DX12_PIPELINE_STATE_STREAM_CS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_BLEND_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_DEPTH_STENCIL_DESC1, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_FORMAT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT> CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_RASTERIZER_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_RT_FORMAT_ARRAY, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS> CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< DXGI_SAMPLE_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC, DefaultSampleDesc> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< UINT, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK, DefaultSampleMask> CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< D3D12_CACHED_PIPELINE_STATE, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO> CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO; +typedef CD3DX12_PIPELINE_STATE_STREAM_SUBOBJECT< CD3DX12_VIEW_INSTANCING_DESC, D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING, CD3DX12_DEFAULT> CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING; + +//------------------------------------------------------------------------------------------------ +// Stream Parser Helpers + +struct ID3DX12PipelineParserCallbacks +{ + // Subobject Callbacks + virtual void FlagsCb(D3D12_PIPELINE_STATE_FLAGS) {} + virtual void NodeMaskCb(UINT) {} + virtual void RootSignatureCb(ID3D12RootSignature*) {} + virtual void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC&) {} + virtual void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE) {} + virtual void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE) {} + virtual void VSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void GSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC&) {} + virtual void HSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void DSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void PSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void CSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void ASCb(const D3D12_SHADER_BYTECODE&) {} + virtual void MSCb(const D3D12_SHADER_BYTECODE&) {} + virtual void BlendStateCb(const D3D12_BLEND_DESC&) {} + virtual void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC&) {} + virtual void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1&) {} + virtual void DSVFormatCb(DXGI_FORMAT) {} + virtual void RasterizerStateCb(const D3D12_RASTERIZER_DESC&) {} + virtual void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY&) {} + virtual void SampleDescCb(const DXGI_SAMPLE_DESC&) {} + virtual void SampleMaskCb(UINT) {} + virtual void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC&) {} + virtual void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE&) {} + + // Error Callbacks + virtual void ErrorBadInputParameter(UINT /*ParameterIndex*/) {} + virtual void ErrorDuplicateSubobject(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE /*DuplicateType*/) {} + virtual void ErrorUnknownSubobject(UINT /*UnknownTypeValue*/) {} + + virtual ~ID3DX12PipelineParserCallbacks() = default; +}; + +struct D3DX12_MESH_SHADER_PIPELINE_STATE_DESC +{ + ID3D12RootSignature* pRootSignature; + D3D12_SHADER_BYTECODE AS; + D3D12_SHADER_BYTECODE MS; + D3D12_SHADER_BYTECODE PS; + D3D12_BLEND_DESC BlendState; + UINT SampleMask; + D3D12_RASTERIZER_DESC RasterizerState; + D3D12_DEPTH_STENCIL_DESC DepthStencilState; + D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType; + UINT NumRenderTargets; + DXGI_FORMAT RTVFormats[ D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT ]; + DXGI_FORMAT DSVFormat; + DXGI_SAMPLE_DESC SampleDesc; + UINT NodeMask; + D3D12_CACHED_PIPELINE_STATE CachedPSO; + D3D12_PIPELINE_STATE_FLAGS Flags; +}; + +// CD3DX12_PIPELINE_STATE_STREAM2 Works on OS Build 19041+ (where there is a new mesh shader pipeline). +// Use CD3DX12_PIPELINE_STATE_STREAM1 for OS Build 16299+ (where there is a new view instancing subobject). +// Use CD3DX12_PIPELINE_STATE_STREAM for OS Build 15063+ support. +struct CD3DX12_PIPELINE_STATE_STREAM2 +{ + CD3DX12_PIPELINE_STATE_STREAM2() = default; + // Mesh and amplification shaders must be set manually, since they do not have representation in D3D12_GRAPHICS_PIPELINE_STATE_DESC + CD3DX12_PIPELINE_STATE_STREAM2(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , InputLayout(Desc.InputLayout) + , IBStripCutValue(Desc.IBStripCutValue) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , VS(Desc.VS) + , GS(Desc.GS) + , StreamOutput(Desc.StreamOutput) + , HS(Desc.HS) + , DS(Desc.DS) + , PS(Desc.PS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM2(const D3DX12_MESH_SHADER_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , PS(Desc.PS) + , AS(Desc.AS) + , MS(Desc.MS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM2(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) + , CachedPSO(Desc.CachedPSO) + { + static_cast(DepthStencilState).DepthEnable = false; + } + CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; + CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; + CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; + CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; + CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; + CD3DX12_PIPELINE_STATE_STREAM_VS VS; + CD3DX12_PIPELINE_STATE_STREAM_GS GS; + CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; + CD3DX12_PIPELINE_STATE_STREAM_HS HS; + CD3DX12_PIPELINE_STATE_STREAM_DS DS; + CD3DX12_PIPELINE_STATE_STREAM_PS PS; + CD3DX12_PIPELINE_STATE_STREAM_AS AS; + CD3DX12_PIPELINE_STATE_STREAM_MS MS; + CD3DX12_PIPELINE_STATE_STREAM_CS CS; + CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; + CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; + CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; + CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; + CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING ViewInstancingDesc; + D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const noexcept + { + D3D12_GRAPHICS_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.InputLayout = this->InputLayout; + D.IBStripCutValue = this->IBStripCutValue; + D.PrimitiveTopologyType = this->PrimitiveTopologyType; + D.VS = this->VS; + D.GS = this->GS; + D.StreamOutput = this->StreamOutput; + D.HS = this->HS; + D.DS = this->DS; + D.PS = this->PS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; + return D; + } + D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const noexcept + { + D3D12_COMPUTE_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.CS = this->CS; + D.CachedPSO = this->CachedPSO; + return D; + } +}; + +// CD3DX12_PIPELINE_STATE_STREAM1 Works on OS Build 16299+ (where there is a new view instancing subobject). +// Use CD3DX12_PIPELINE_STATE_STREAM for OS Build 15063+ support. +struct CD3DX12_PIPELINE_STATE_STREAM1 +{ + CD3DX12_PIPELINE_STATE_STREAM1() = default; + // Mesh and amplification shaders must be set manually, since they do not have representation in D3D12_GRAPHICS_PIPELINE_STATE_DESC + CD3DX12_PIPELINE_STATE_STREAM1(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , InputLayout(Desc.InputLayout) + , IBStripCutValue(Desc.IBStripCutValue) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , VS(Desc.VS) + , GS(Desc.GS) + , StreamOutput(Desc.StreamOutput) + , HS(Desc.HS) + , DS(Desc.DS) + , PS(Desc.PS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM1(const D3DX12_MESH_SHADER_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , PS(Desc.PS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM1(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) + , CachedPSO(Desc.CachedPSO) + { + static_cast(DepthStencilState).DepthEnable = false; + } + CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; + CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; + CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; + CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; + CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; + CD3DX12_PIPELINE_STATE_STREAM_VS VS; + CD3DX12_PIPELINE_STATE_STREAM_GS GS; + CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; + CD3DX12_PIPELINE_STATE_STREAM_HS HS; + CD3DX12_PIPELINE_STATE_STREAM_DS DS; + CD3DX12_PIPELINE_STATE_STREAM_PS PS; + CD3DX12_PIPELINE_STATE_STREAM_CS CS; + CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; + CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; + CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; + CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; + CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING ViewInstancingDesc; + D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const noexcept + { + D3D12_GRAPHICS_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.InputLayout = this->InputLayout; + D.IBStripCutValue = this->IBStripCutValue; + D.PrimitiveTopologyType = this->PrimitiveTopologyType; + D.VS = this->VS; + D.GS = this->GS; + D.StreamOutput = this->StreamOutput; + D.HS = this->HS; + D.DS = this->DS; + D.PS = this->PS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; + return D; + } + D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const noexcept + { + D3D12_COMPUTE_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.CS = this->CS; + D.CachedPSO = this->CachedPSO; + return D; + } +}; + + +struct CD3DX12_PIPELINE_MESH_STATE_STREAM +{ + CD3DX12_PIPELINE_MESH_STATE_STREAM() = default; + CD3DX12_PIPELINE_MESH_STATE_STREAM(const D3DX12_MESH_SHADER_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , PS(Desc.PS) + , AS(Desc.AS) + , MS(Desc.MS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + , ViewInstancingDesc(CD3DX12_VIEW_INSTANCING_DESC(CD3DX12_DEFAULT())) + {} + CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; + CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; + CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_PS PS; + CD3DX12_PIPELINE_STATE_STREAM_AS AS; + CD3DX12_PIPELINE_STATE_STREAM_MS MS; + CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; + CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; + CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; + CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; + CD3DX12_PIPELINE_STATE_STREAM_VIEW_INSTANCING ViewInstancingDesc; + D3DX12_MESH_SHADER_PIPELINE_STATE_DESC MeshShaderDescV0() const noexcept + { + D3DX12_MESH_SHADER_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.PS = this->PS; + D.AS = this->AS; + D.MS = this->MS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; + return D; + } +}; + +// CD3DX12_PIPELINE_STATE_STREAM works on OS Build 15063+ but does not support new subobject(s) added in OS Build 16299+. +// See CD3DX12_PIPELINE_STATE_STREAM1 for instance. +struct CD3DX12_PIPELINE_STATE_STREAM +{ + CD3DX12_PIPELINE_STATE_STREAM() = default; + CD3DX12_PIPELINE_STATE_STREAM(const D3D12_GRAPHICS_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , InputLayout(Desc.InputLayout) + , IBStripCutValue(Desc.IBStripCutValue) + , PrimitiveTopologyType(Desc.PrimitiveTopologyType) + , VS(Desc.VS) + , GS(Desc.GS) + , StreamOutput(Desc.StreamOutput) + , HS(Desc.HS) + , DS(Desc.DS) + , PS(Desc.PS) + , BlendState(CD3DX12_BLEND_DESC(Desc.BlendState)) + , DepthStencilState(CD3DX12_DEPTH_STENCIL_DESC1(Desc.DepthStencilState)) + , DSVFormat(Desc.DSVFormat) + , RasterizerState(CD3DX12_RASTERIZER_DESC(Desc.RasterizerState)) + , RTVFormats(CD3DX12_RT_FORMAT_ARRAY(Desc.RTVFormats, Desc.NumRenderTargets)) + , SampleDesc(Desc.SampleDesc) + , SampleMask(Desc.SampleMask) + , CachedPSO(Desc.CachedPSO) + {} + CD3DX12_PIPELINE_STATE_STREAM(const D3D12_COMPUTE_PIPELINE_STATE_DESC& Desc) noexcept + : Flags(Desc.Flags) + , NodeMask(Desc.NodeMask) + , pRootSignature(Desc.pRootSignature) + , CS(CD3DX12_SHADER_BYTECODE(Desc.CS)) + , CachedPSO(Desc.CachedPSO) + {} + CD3DX12_PIPELINE_STATE_STREAM_FLAGS Flags; + CD3DX12_PIPELINE_STATE_STREAM_NODE_MASK NodeMask; + CD3DX12_PIPELINE_STATE_STREAM_ROOT_SIGNATURE pRootSignature; + CD3DX12_PIPELINE_STATE_STREAM_INPUT_LAYOUT InputLayout; + CD3DX12_PIPELINE_STATE_STREAM_IB_STRIP_CUT_VALUE IBStripCutValue; + CD3DX12_PIPELINE_STATE_STREAM_PRIMITIVE_TOPOLOGY PrimitiveTopologyType; + CD3DX12_PIPELINE_STATE_STREAM_VS VS; + CD3DX12_PIPELINE_STATE_STREAM_GS GS; + CD3DX12_PIPELINE_STATE_STREAM_STREAM_OUTPUT StreamOutput; + CD3DX12_PIPELINE_STATE_STREAM_HS HS; + CD3DX12_PIPELINE_STATE_STREAM_DS DS; + CD3DX12_PIPELINE_STATE_STREAM_PS PS; + CD3DX12_PIPELINE_STATE_STREAM_CS CS; + CD3DX12_PIPELINE_STATE_STREAM_BLEND_DESC BlendState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL1 DepthStencilState; + CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL_FORMAT DSVFormat; + CD3DX12_PIPELINE_STATE_STREAM_RASTERIZER RasterizerState; + CD3DX12_PIPELINE_STATE_STREAM_RENDER_TARGET_FORMATS RTVFormats; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_DESC SampleDesc; + CD3DX12_PIPELINE_STATE_STREAM_SAMPLE_MASK SampleMask; + CD3DX12_PIPELINE_STATE_STREAM_CACHED_PSO CachedPSO; + D3D12_GRAPHICS_PIPELINE_STATE_DESC GraphicsDescV0() const noexcept + { + D3D12_GRAPHICS_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.InputLayout = this->InputLayout; + D.IBStripCutValue = this->IBStripCutValue; + D.PrimitiveTopologyType = this->PrimitiveTopologyType; + D.VS = this->VS; + D.GS = this->GS; + D.StreamOutput = this->StreamOutput; + D.HS = this->HS; + D.DS = this->DS; + D.PS = this->PS; + D.BlendState = this->BlendState; + D.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(D3D12_DEPTH_STENCIL_DESC1(this->DepthStencilState)); + D.DSVFormat = this->DSVFormat; + D.RasterizerState = this->RasterizerState; + D.NumRenderTargets = D3D12_RT_FORMAT_ARRAY(this->RTVFormats).NumRenderTargets; + memcpy(D.RTVFormats, D3D12_RT_FORMAT_ARRAY(this->RTVFormats).RTFormats, sizeof(D.RTVFormats)); + D.SampleDesc = this->SampleDesc; + D.SampleMask = this->SampleMask; + D.CachedPSO = this->CachedPSO; + return D; + } + D3D12_COMPUTE_PIPELINE_STATE_DESC ComputeDescV0() const noexcept + { + D3D12_COMPUTE_PIPELINE_STATE_DESC D; + D.Flags = this->Flags; + D.NodeMask = this->NodeMask; + D.pRootSignature = this->pRootSignature; + D.CS = this->CS; + D.CachedPSO = this->CachedPSO; + return D; + } +}; + +struct CD3DX12_PIPELINE_STATE_STREAM2_PARSE_HELPER : public ID3DX12PipelineParserCallbacks +{ + CD3DX12_PIPELINE_STATE_STREAM2 PipelineStream; + CD3DX12_PIPELINE_STATE_STREAM2_PARSE_HELPER() noexcept + : SeenDSS(false) + { + // Adjust defaults to account for absent members. + PipelineStream.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + + // Depth disabled if no DSV format specified. + static_cast(PipelineStream.DepthStencilState).DepthEnable = false; + } + + // ID3DX12PipelineParserCallbacks + void FlagsCb(D3D12_PIPELINE_STATE_FLAGS Flags) override {PipelineStream.Flags = Flags;} + void NodeMaskCb(UINT NodeMask) override {PipelineStream.NodeMask = NodeMask;} + void RootSignatureCb(ID3D12RootSignature* pRootSignature) override {PipelineStream.pRootSignature = pRootSignature;} + void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC& InputLayout) override {PipelineStream.InputLayout = InputLayout;} + void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) override {PipelineStream.IBStripCutValue = IBStripCutValue;} + void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType) override {PipelineStream.PrimitiveTopologyType = PrimitiveTopologyType;} + void VSCb(const D3D12_SHADER_BYTECODE& VS) override {PipelineStream.VS = VS;} + void GSCb(const D3D12_SHADER_BYTECODE& GS) override {PipelineStream.GS = GS;} + void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC& StreamOutput) override {PipelineStream.StreamOutput = StreamOutput;} + void HSCb(const D3D12_SHADER_BYTECODE& HS) override {PipelineStream.HS = HS;} + void DSCb(const D3D12_SHADER_BYTECODE& DS) override {PipelineStream.DS = DS;} + void PSCb(const D3D12_SHADER_BYTECODE& PS) override {PipelineStream.PS = PS;} + void CSCb(const D3D12_SHADER_BYTECODE& CS) override {PipelineStream.CS = CS;} + void ASCb(const D3D12_SHADER_BYTECODE& AS) override {PipelineStream.AS = AS;} + void MSCb(const D3D12_SHADER_BYTECODE& MS) override {PipelineStream.MS = MS;} + void BlendStateCb(const D3D12_BLEND_DESC& BlendState) override {PipelineStream.BlendState = CD3DX12_BLEND_DESC(BlendState);} + void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); + SeenDSS = true; + } + void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); + SeenDSS = true; + } + void DSVFormatCb(DXGI_FORMAT DSVFormat) override + { + PipelineStream.DSVFormat = DSVFormat; + if (!SeenDSS && DSVFormat != DXGI_FORMAT_UNKNOWN) + { + // Re-enable depth for the default state. + static_cast(PipelineStream.DepthStencilState).DepthEnable = true; + } + } + void RasterizerStateCb(const D3D12_RASTERIZER_DESC& RasterizerState) override {PipelineStream.RasterizerState = CD3DX12_RASTERIZER_DESC(RasterizerState);} + void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY& RTVFormats) override {PipelineStream.RTVFormats = RTVFormats;} + void SampleDescCb(const DXGI_SAMPLE_DESC& SampleDesc) override {PipelineStream.SampleDesc = SampleDesc;} + void SampleMaskCb(UINT SampleMask) override {PipelineStream.SampleMask = SampleMask;} + void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC& ViewInstancingDesc) override {PipelineStream.ViewInstancingDesc = CD3DX12_VIEW_INSTANCING_DESC(ViewInstancingDesc);} + void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE& CachedPSO) override {PipelineStream.CachedPSO = CachedPSO;} + +private: + bool SeenDSS; +}; + + +struct CD3DX12_PIPELINE_STATE_STREAM_PARSE_HELPER : public ID3DX12PipelineParserCallbacks +{ + CD3DX12_PIPELINE_STATE_STREAM1 PipelineStream; + CD3DX12_PIPELINE_STATE_STREAM_PARSE_HELPER() noexcept + : SeenDSS(false) + { + // Adjust defaults to account for absent members. + PipelineStream.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + + // Depth disabled if no DSV format specified. + static_cast(PipelineStream.DepthStencilState).DepthEnable = false; + } + + // ID3DX12PipelineParserCallbacks + void FlagsCb(D3D12_PIPELINE_STATE_FLAGS Flags) override {PipelineStream.Flags = Flags;} + void NodeMaskCb(UINT NodeMask) override {PipelineStream.NodeMask = NodeMask;} + void RootSignatureCb(ID3D12RootSignature* pRootSignature) override {PipelineStream.pRootSignature = pRootSignature;} + void InputLayoutCb(const D3D12_INPUT_LAYOUT_DESC& InputLayout) override {PipelineStream.InputLayout = InputLayout;} + void IBStripCutValueCb(D3D12_INDEX_BUFFER_STRIP_CUT_VALUE IBStripCutValue) override {PipelineStream.IBStripCutValue = IBStripCutValue;} + void PrimitiveTopologyTypeCb(D3D12_PRIMITIVE_TOPOLOGY_TYPE PrimitiveTopologyType) override {PipelineStream.PrimitiveTopologyType = PrimitiveTopologyType;} + void VSCb(const D3D12_SHADER_BYTECODE& VS) override {PipelineStream.VS = VS;} + void GSCb(const D3D12_SHADER_BYTECODE& GS) override {PipelineStream.GS = GS;} + void StreamOutputCb(const D3D12_STREAM_OUTPUT_DESC& StreamOutput) override {PipelineStream.StreamOutput = StreamOutput;} + void HSCb(const D3D12_SHADER_BYTECODE& HS) override {PipelineStream.HS = HS;} + void DSCb(const D3D12_SHADER_BYTECODE& DS) override {PipelineStream.DS = DS;} + void PSCb(const D3D12_SHADER_BYTECODE& PS) override {PipelineStream.PS = PS;} + void CSCb(const D3D12_SHADER_BYTECODE& CS) override {PipelineStream.CS = CS;} + void BlendStateCb(const D3D12_BLEND_DESC& BlendState) override {PipelineStream.BlendState = CD3DX12_BLEND_DESC(BlendState);} + void DepthStencilStateCb(const D3D12_DEPTH_STENCIL_DESC& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); + SeenDSS = true; + } + void DepthStencilState1Cb(const D3D12_DEPTH_STENCIL_DESC1& DepthStencilState) override + { + PipelineStream.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC1(DepthStencilState); + SeenDSS = true; + } + void DSVFormatCb(DXGI_FORMAT DSVFormat) override + { + PipelineStream.DSVFormat = DSVFormat; + if (!SeenDSS && DSVFormat != DXGI_FORMAT_UNKNOWN) + { + // Re-enable depth for the default state. + static_cast(PipelineStream.DepthStencilState).DepthEnable = true; + } + } + void RasterizerStateCb(const D3D12_RASTERIZER_DESC& RasterizerState) override {PipelineStream.RasterizerState = CD3DX12_RASTERIZER_DESC(RasterizerState);} + void RTVFormatsCb(const D3D12_RT_FORMAT_ARRAY& RTVFormats) override {PipelineStream.RTVFormats = RTVFormats;} + void SampleDescCb(const DXGI_SAMPLE_DESC& SampleDesc) override {PipelineStream.SampleDesc = SampleDesc;} + void SampleMaskCb(UINT SampleMask) override {PipelineStream.SampleMask = SampleMask;} + void ViewInstancingCb(const D3D12_VIEW_INSTANCING_DESC& ViewInstancingDesc) override {PipelineStream.ViewInstancingDesc = CD3DX12_VIEW_INSTANCING_DESC(ViewInstancingDesc);} + void CachedPSOCb(const D3D12_CACHED_PIPELINE_STATE& CachedPSO) override {PipelineStream.CachedPSO = CachedPSO;} + +private: + bool SeenDSS; +}; + +inline D3D12_PIPELINE_STATE_SUBOBJECT_TYPE D3DX12GetBaseSubobjectType(D3D12_PIPELINE_STATE_SUBOBJECT_TYPE SubobjectType) noexcept +{ + switch (SubobjectType) + { + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1: + return D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL; + default: + return SubobjectType; + } +} + +inline HRESULT D3DX12ParsePipelineStream(const D3D12_PIPELINE_STATE_STREAM_DESC& Desc, ID3DX12PipelineParserCallbacks* pCallbacks) +{ + if (pCallbacks == nullptr) + { + return E_INVALIDARG; + } + + if (Desc.SizeInBytes == 0 || Desc.pPipelineStateSubobjectStream == nullptr) + { + pCallbacks->ErrorBadInputParameter(1); // first parameter issue + return E_INVALIDARG; + } + + bool SubobjectSeen[D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID] = {}; + for (SIZE_T CurOffset = 0, SizeOfSubobject = 0; CurOffset < Desc.SizeInBytes; CurOffset += SizeOfSubobject) + { + BYTE* pStream = static_cast(Desc.pPipelineStateSubobjectStream)+CurOffset; + auto SubobjectType = *reinterpret_cast(pStream); + if (SubobjectType < 0 || SubobjectType >= D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MAX_VALID) + { + pCallbacks->ErrorUnknownSubobject(SubobjectType); + return E_INVALIDARG; + } + if (SubobjectSeen[D3DX12GetBaseSubobjectType(SubobjectType)]) + { + pCallbacks->ErrorDuplicateSubobject(SubobjectType); + return E_INVALIDARG; // disallow subobject duplicates in a stream + } + SubobjectSeen[SubobjectType] = true; + switch (SubobjectType) + { + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_ROOT_SIGNATURE: + pCallbacks->RootSignatureCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::pRootSignature); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VS: + pCallbacks->VSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::VS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PS: + pCallbacks->PSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::PS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DS: + pCallbacks->DSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_HS: + pCallbacks->HSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::HS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_GS: + pCallbacks->GSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::GS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CS: + pCallbacks->CSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::CS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_AS: + pCallbacks->ASCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM2::AS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_MS: + pCallbacks->MSCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM2::MS); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_STREAM_OUTPUT: + pCallbacks->StreamOutputCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::StreamOutput); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_BLEND: + pCallbacks->BlendStateCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::BlendState); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_MASK: + pCallbacks->SampleMaskCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::SampleMask); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RASTERIZER: + pCallbacks->RasterizerStateCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::RasterizerState); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL: + pCallbacks->DepthStencilStateCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM_DEPTH_STENCIL); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL1: + pCallbacks->DepthStencilState1Cb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DepthStencilState); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_INPUT_LAYOUT: + pCallbacks->InputLayoutCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::InputLayout); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_IB_STRIP_CUT_VALUE: + pCallbacks->IBStripCutValueCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::IBStripCutValue); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_PRIMITIVE_TOPOLOGY: + pCallbacks->PrimitiveTopologyTypeCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::PrimitiveTopologyType); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_RENDER_TARGET_FORMATS: + pCallbacks->RTVFormatsCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::RTVFormats); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_DEPTH_STENCIL_FORMAT: + pCallbacks->DSVFormatCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::DSVFormat); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_SAMPLE_DESC: + pCallbacks->SampleDescCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::SampleDesc); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_NODE_MASK: + pCallbacks->NodeMaskCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::NodeMask); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_CACHED_PSO: + pCallbacks->CachedPSOCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::CachedPSO); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_FLAGS: + pCallbacks->FlagsCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM::Flags); + break; + case D3D12_PIPELINE_STATE_SUBOBJECT_TYPE_VIEW_INSTANCING: + pCallbacks->ViewInstancingCb(*reinterpret_cast(pStream)); + SizeOfSubobject = sizeof(CD3DX12_PIPELINE_STATE_STREAM1::ViewInstancingDesc); + break; + default: + pCallbacks->ErrorUnknownSubobject(SubobjectType); + return E_INVALIDARG; + } + } + + return S_OK; +} + +//------------------------------------------------------------------------------------------------ +inline bool operator==( const D3D12_CLEAR_VALUE &a, const D3D12_CLEAR_VALUE &b) noexcept +{ + if (a.Format != b.Format) return false; + if (a.Format == DXGI_FORMAT_D24_UNORM_S8_UINT + || a.Format == DXGI_FORMAT_D16_UNORM + || a.Format == DXGI_FORMAT_D32_FLOAT + || a.Format == DXGI_FORMAT_D32_FLOAT_S8X24_UINT) + { + return (a.DepthStencil.Depth == b.DepthStencil.Depth) && + (a.DepthStencil.Stencil == b.DepthStencil.Stencil); + } else { + return (a.Color[0] == b.Color[0]) && + (a.Color[1] == b.Color[1]) && + (a.Color[2] == b.Color[2]) && + (a.Color[3] == b.Color[3]); + } +} +inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS_CLEAR_PARAMETERS &b) noexcept +{ + return a.ClearValue == b.ClearValue; +} +inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &a, const D3D12_RENDER_PASS_ENDING_ACCESS_RESOLVE_PARAMETERS &b) noexcept +{ + if (a.pSrcResource != b.pSrcResource) return false; + if (a.pDstResource != b.pDstResource) return false; + if (a.SubresourceCount != b.SubresourceCount) return false; + if (a.Format != b.Format) return false; + if (a.ResolveMode != b.ResolveMode) return false; + if (a.PreserveResolveSource != b.PreserveResolveSource) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_BEGINNING_ACCESS &a, const D3D12_RENDER_PASS_BEGINNING_ACCESS &b) noexcept +{ + if (a.Type != b.Type) return false; + if (a.Type == D3D12_RENDER_PASS_BEGINNING_ACCESS_TYPE_CLEAR && !(a.Clear == b.Clear)) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_ENDING_ACCESS &a, const D3D12_RENDER_PASS_ENDING_ACCESS &b) noexcept +{ + if (a.Type != b.Type) return false; + if (a.Type == D3D12_RENDER_PASS_ENDING_ACCESS_TYPE_RESOLVE && !(a.Resolve == b.Resolve)) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_RENDER_TARGET_DESC &a, const D3D12_RENDER_PASS_RENDER_TARGET_DESC &b) noexcept +{ + if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false; + if (!(a.BeginningAccess == b.BeginningAccess)) return false; + if (!(a.EndingAccess == b.EndingAccess)) return false; + return true; +} +inline bool operator==( const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &a, const D3D12_RENDER_PASS_DEPTH_STENCIL_DESC &b) noexcept +{ + if (a.cpuDescriptor.ptr != b.cpuDescriptor.ptr) return false; + if (!(a.DepthBeginningAccess == b.DepthBeginningAccess)) return false; + if (!(a.StencilBeginningAccess == b.StencilBeginningAccess)) return false; + if (!(a.DepthEndingAccess == b.DepthEndingAccess)) return false; + if (!(a.StencilEndingAccess == b.StencilEndingAccess)) return false; + return true; +} + + +#ifndef D3DX12_NO_STATE_OBJECT_HELPERS + +//================================================================================================ +// D3DX12 State Object Creation Helpers +// +// Helper classes for creating new style state objects out of an arbitrary set of subobjects. +// Uses STL +// +// Start by instantiating CD3DX12_STATE_OBJECT_DESC (see it's public methods). +// One of its methods is CreateSubobject(), which has a comment showing a couple of options for +// defining subobjects using the helper classes for each subobject (CD3DX12_DXIL_LIBRARY_SUBOBJECT +// etc.). The subobject helpers each have methods specific to the subobject for configuring it's +// contents. +// +//================================================================================================ +#include +#include +#include +#include +#ifndef D3DX12_USE_ATL +#include +#define D3DX12_COM_PTR Microsoft::WRL::ComPtr +#define D3DX12_COM_PTR_GET(x) x.Get() +#define D3DX12_COM_PTR_ADDRESSOF(x) x.GetAddressOf() +#else +#include +#define D3DX12_COM_PTR ATL::CComPtr +#define D3DX12_COM_PTR_GET(x) x.p +#define D3DX12_COM_PTR_ADDRESSOF(x) &x.p +#endif + +//------------------------------------------------------------------------------------------------ +class CD3DX12_STATE_OBJECT_DESC +{ +public: + CD3DX12_STATE_OBJECT_DESC() noexcept + { + Init(D3D12_STATE_OBJECT_TYPE_COLLECTION); + } + CD3DX12_STATE_OBJECT_DESC(D3D12_STATE_OBJECT_TYPE Type) noexcept + { + Init(Type); + } + void SetStateObjectType(D3D12_STATE_OBJECT_TYPE Type) noexcept { m_Desc.Type = Type; } + operator const D3D12_STATE_OBJECT_DESC&() + { + // Do final preparation work + m_RepointedAssociations.clear(); + m_SubobjectArray.clear(); + m_SubobjectArray.reserve(m_Desc.NumSubobjects); + // Flatten subobjects into an array (each flattened subobject still has a + // member that's a pointer to it's desc that's not flattened) + for (auto Iter = m_SubobjectList.begin(); + Iter != m_SubobjectList.end(); Iter++) + { + m_SubobjectArray.push_back(*Iter); + // Store new location in array so we can redirect pointers contained in subobjects + Iter->pSubobjectArrayLocation = &m_SubobjectArray.back(); + } + // For subobjects with pointer fields, create a new copy of those subobject definitions + // with fixed pointers + for (UINT i = 0; i < m_Desc.NumSubobjects; i++) + { + if (m_SubobjectArray[i].Type == D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION) + { + auto pOriginalSubobjectAssociation = + static_cast(m_SubobjectArray[i].pDesc); + D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION Repointed = *pOriginalSubobjectAssociation; + auto pWrapper = + static_cast(pOriginalSubobjectAssociation->pSubobjectToAssociate); + Repointed.pSubobjectToAssociate = pWrapper->pSubobjectArrayLocation; + m_RepointedAssociations.push_back(Repointed); + m_SubobjectArray[i].pDesc = &m_RepointedAssociations.back(); + } + } + // Below: using ugly way to get pointer in case .data() is not defined + m_Desc.pSubobjects = m_Desc.NumSubobjects ? &m_SubobjectArray[0] : nullptr; + return m_Desc; + } + operator const D3D12_STATE_OBJECT_DESC*() + { + // Cast calls the above final preparation work + return &static_cast(*this); + } + + // CreateSubobject creates a sububject helper (e.g. CD3DX12_HIT_GROUP_SUBOBJECT) + // whose lifetime is owned by this class. + // e.g. + // + // CD3DX12_STATE_OBJECT_DESC Collection1(D3D12_STATE_OBJECT_TYPE_COLLECTION); + // auto Lib0 = Collection1.CreateSubobject(); + // Lib0->SetDXILLibrary(&pMyAppDxilLibs[0]); + // Lib0->DefineExport(L"rayGenShader0"); // in practice these export listings might be + // // data/engine driven + // etc. + // + // Alternatively, users can instantiate sububject helpers explicitly, such as via local + // variables instead, passing the state object desc that should point to it into the helper + // constructor (or call mySubobjectHelper.AddToStateObject(Collection1)). + // In this alternative scenario, the user must keep the subobject alive as long as the state + // object it is associated with is alive, else it's pointer references will be stale. + // e.g. + // + // CD3DX12_STATE_OBJECT_DESC RaytracingState2(D3D12_STATE_OBJECT_TYPE_RAYTRACING_PIPELINE); + // CD3DX12_DXIL_LIBRARY_SUBOBJECT LibA(RaytracingState2); + // LibA.SetDXILLibrary(&pMyAppDxilLibs[4]); // not manually specifying exports + // // - meaning all exports in the libraries + // // are exported + // etc. + + template + T* CreateSubobject() + { + T* pSubobject = new T(*this); + m_OwnedSubobjectHelpers.emplace_back(pSubobject); + return pSubobject; + } + +private: + D3D12_STATE_SUBOBJECT* TrackSubobject(D3D12_STATE_SUBOBJECT_TYPE Type, void* pDesc) + { + SUBOBJECT_WRAPPER Subobject; + Subobject.pSubobjectArrayLocation = nullptr; + Subobject.Type = Type; + Subobject.pDesc = pDesc; + m_SubobjectList.push_back(Subobject); + m_Desc.NumSubobjects++; + return &m_SubobjectList.back(); + } + void Init(D3D12_STATE_OBJECT_TYPE Type) noexcept + { + SetStateObjectType(Type); + m_Desc.pSubobjects = nullptr; + m_Desc.NumSubobjects = 0; + m_SubobjectList.clear(); + m_SubobjectArray.clear(); + m_RepointedAssociations.clear(); + } + typedef struct SUBOBJECT_WRAPPER : public D3D12_STATE_SUBOBJECT + { + D3D12_STATE_SUBOBJECT* pSubobjectArrayLocation; // new location when flattened into array + // for repointing pointers in subobjects + } SUBOBJECT_WRAPPER; + D3D12_STATE_OBJECT_DESC m_Desc; + std::list m_SubobjectList; // Pointers to list nodes handed out so + // these can be edited live + std::vector m_SubobjectArray; // Built at the end, copying list contents + + std::list + m_RepointedAssociations; // subobject type that contains pointers to other subobjects, + // repointed to flattened array + + class StringContainer + { + public: + LPCWSTR LocalCopy(LPCWSTR string, bool bSingleString = false) + { + if (string) + { + if (bSingleString) + { + m_Strings.clear(); + m_Strings.push_back(string); + } + else + { + m_Strings.push_back(string); + } + return m_Strings.back().c_str(); + } + else + { + return nullptr; + } + } + void clear() noexcept { m_Strings.clear(); } + private: + std::list m_Strings; + }; + + class SUBOBJECT_HELPER_BASE + { + public: + SUBOBJECT_HELPER_BASE() noexcept { Init(); } + virtual ~SUBOBJECT_HELPER_BASE() = default; + virtual D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept = 0; + void AddToStateObject(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + m_pSubobject = ContainingStateObject.TrackSubobject(Type(), Data()); + } + protected: + virtual void* Data() noexcept = 0; + void Init() noexcept { m_pSubobject = nullptr; } + D3D12_STATE_SUBOBJECT* m_pSubobject; + }; + +#if(__cplusplus >= 201103L) + std::list> m_OwnedSubobjectHelpers; +#else + class OWNED_HELPER + { + public: + OWNED_HELPER(const SUBOBJECT_HELPER_BASE* pHelper) noexcept { m_pHelper = pHelper; } + ~OWNED_HELPER() { delete m_pHelper; } + const SUBOBJECT_HELPER_BASE* m_pHelper; + }; + + std::list m_OwnedSubobjectHelpers; +#endif + + friend class CD3DX12_DXIL_LIBRARY_SUBOBJECT; + friend class CD3DX12_EXISTING_COLLECTION_SUBOBJECT; + friend class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT; + friend class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + friend class CD3DX12_HIT_GROUP_SUBOBJECT; + friend class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT; + friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT; + friend class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT; + friend class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT; + friend class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT; + friend class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT; + friend class CD3DX12_NODE_MASK_SUBOBJECT; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DXIL_LIBRARY_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DXIL_LIBRARY_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_DXIL_LIBRARY_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetDXILLibrary(const D3D12_SHADER_BYTECODE* pCode) noexcept + { + static const D3D12_SHADER_BYTECODE Default = {}; + m_Desc.DXILLibrary = pCode ? *pCode : Default; + } + void DefineExport( + LPCWSTR Name, + LPCWSTR ExportToRename = nullptr, + D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE) + { + D3D12_EXPORT_DESC Export; + Export.Name = m_Strings.LocalCopy(Name); + Export.ExportToRename = m_Strings.LocalCopy(ExportToRename); + Export.Flags = Flags; + m_Exports.push_back(Export); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + m_Desc.NumExports = static_cast(m_Exports.size()); + } + template + void DefineExports(LPCWSTR(&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + void DefineExports(const LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_DXIL_LIBRARY; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_DXIL_LIBRARY_DESC&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_Strings.clear(); + m_Exports.clear(); + } + void* Data() noexcept override { return &m_Desc; } + D3D12_DXIL_LIBRARY_DESC m_Desc; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_EXISTING_COLLECTION_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_EXISTING_COLLECTION_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_EXISTING_COLLECTION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetExistingCollection(ID3D12StateObject*pExistingCollection) noexcept + { + m_Desc.pExistingCollection = pExistingCollection; + m_CollectionRef = pExistingCollection; + } + void DefineExport( + LPCWSTR Name, + LPCWSTR ExportToRename = nullptr, + D3D12_EXPORT_FLAGS Flags = D3D12_EXPORT_FLAG_NONE) + { + D3D12_EXPORT_DESC Export; + Export.Name = m_Strings.LocalCopy(Name); + Export.ExportToRename = m_Strings.LocalCopy(ExportToRename); + Export.Flags = Flags; + m_Exports.push_back(Export); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + m_Desc.NumExports = static_cast(m_Exports.size()); + } + template + void DefineExports(LPCWSTR(&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + void DefineExports(const LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + DefineExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_EXISTING_COLLECTION; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_EXISTING_COLLECTION_DESC&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_CollectionRef = nullptr; + m_Strings.clear(); + m_Exports.clear(); + } + void* Data() noexcept override { return &m_Desc; } + D3D12_EXISTING_COLLECTION_DESC m_Desc; + D3DX12_COM_PTR m_CollectionRef; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_SUBOBJECT_TO_EXPORTS_ASSOCIATION_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetSubobjectToAssociate(const D3D12_STATE_SUBOBJECT& SubobjectToAssociate) noexcept + { + m_Desc.pSubobjectToAssociate = &SubobjectToAssociate; + } + void AddExport(LPCWSTR Export) + { + m_Desc.NumExports++; + m_Exports.push_back(m_Strings.LocalCopy(Export)); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + } + template + void AddExports(LPCWSTR (&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + void AddExports(const LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_Strings.clear(); + m_Exports.clear(); + } + void* Data() noexcept override { return &m_Desc; } + D3D12_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION() noexcept + { + Init(); + } + CD3DX12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetSubobjectNameToAssociate(LPCWSTR SubobjectToAssociate) + { + m_Desc.SubobjectToAssociate = m_SubobjectName.LocalCopy(SubobjectToAssociate, true); + } + void AddExport(LPCWSTR Export) + { + m_Desc.NumExports++; + m_Exports.push_back(m_Strings.LocalCopy(Export)); + m_Desc.pExports = &m_Exports[0]; // using ugly way to get pointer in case .data() is not defined + } + template + void AddExports(LPCWSTR (&Exports)[N]) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + void AddExports(const LPCWSTR* Exports, UINT N) + { + for (UINT i = 0; i < N; i++) + { + AddExport(Exports[i]); + } + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + m_Strings.clear(); + m_SubobjectName.clear(); + m_Exports.clear(); + } + void* Data() noexcept override { return &m_Desc; } + D3D12_DXIL_SUBOBJECT_TO_EXPORTS_ASSOCIATION m_Desc; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_Strings; + CD3DX12_STATE_OBJECT_DESC::StringContainer m_SubobjectName; + std::vector m_Exports; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_HIT_GROUP_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_HIT_GROUP_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_HIT_GROUP_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetHitGroupExport(LPCWSTR exportName) + { + m_Desc.HitGroupExport = m_Strings[0].LocalCopy(exportName, true); + } + void SetHitGroupType(D3D12_HIT_GROUP_TYPE Type) noexcept { m_Desc.Type = Type; } + void SetAnyHitShaderImport(LPCWSTR importName) + { + m_Desc.AnyHitShaderImport = m_Strings[1].LocalCopy(importName, true); + } + void SetClosestHitShaderImport(LPCWSTR importName) + { + m_Desc.ClosestHitShaderImport = m_Strings[2].LocalCopy(importName, true); + } + void SetIntersectionShaderImport(LPCWSTR importName) + { + m_Desc.IntersectionShaderImport = m_Strings[3].LocalCopy(importName, true); + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_HIT_GROUP; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_HIT_GROUP_DESC&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + for (UINT i = 0; i < m_NumStrings; i++) + { + m_Strings[i].clear(); + } + } + void* Data() noexcept override { return &m_Desc; } + D3D12_HIT_GROUP_DESC m_Desc; + static const UINT m_NumStrings = 4; + CD3DX12_STATE_OBJECT_DESC::StringContainer + m_Strings[m_NumStrings]; // one string for every entrypoint name +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_RAYTRACING_SHADER_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void Config(UINT MaxPayloadSizeInBytes, UINT MaxAttributeSizeInBytes) noexcept + { + m_Desc.MaxPayloadSizeInBytes = MaxPayloadSizeInBytes; + m_Desc.MaxAttributeSizeInBytes = MaxAttributeSizeInBytes; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_SHADER_CONFIG; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_RAYTRACING_SHADER_CONFIG&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_RAYTRACING_SHADER_CONFIG m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_RAYTRACING_PIPELINE_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void Config(UINT MaxTraceRecursionDepth) noexcept + { + m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_RAYTRACING_PIPELINE_CONFIG&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_RAYTRACING_PIPELINE_CONFIG m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_RAYTRACING_PIPELINE_CONFIG1_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void Config(UINT MaxTraceRecursionDepth, D3D12_RAYTRACING_PIPELINE_FLAGS Flags) noexcept + { + m_Desc.MaxTraceRecursionDepth = MaxTraceRecursionDepth; + m_Desc.Flags = Flags; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_RAYTRACING_PIPELINE_CONFIG1; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_RAYTRACING_PIPELINE_CONFIG1&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_RAYTRACING_PIPELINE_CONFIG1 m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_GLOBAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetRootSignature(ID3D12RootSignature* pRootSig) noexcept + { + m_pRootSig = pRootSig; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_GLOBAL_ROOT_SIGNATURE; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_pRootSig = nullptr; + } + void* Data() noexcept override { return D3DX12_COM_PTR_ADDRESSOF(m_pRootSig); } + D3DX12_COM_PTR m_pRootSig; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_LOCAL_ROOT_SIGNATURE_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetRootSignature(ID3D12RootSignature* pRootSig) noexcept + { + m_pRootSig = pRootSig; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_LOCAL_ROOT_SIGNATURE; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator ID3D12RootSignature*() const noexcept { return D3DX12_COM_PTR_GET(m_pRootSig); } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_pRootSig = nullptr; + } + void* Data() noexcept override { return D3DX12_COM_PTR_ADDRESSOF(m_pRootSig); } + D3DX12_COM_PTR m_pRootSig; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_STATE_OBJECT_CONFIG_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetFlags(D3D12_STATE_OBJECT_FLAGS Flags) noexcept + { + m_Desc.Flags = Flags; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_STATE_OBJECT_CONFIG; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_STATE_OBJECT_CONFIG&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_STATE_OBJECT_CONFIG m_Desc; +}; + +//------------------------------------------------------------------------------------------------ +class CD3DX12_NODE_MASK_SUBOBJECT + : public CD3DX12_STATE_OBJECT_DESC::SUBOBJECT_HELPER_BASE +{ +public: + CD3DX12_NODE_MASK_SUBOBJECT() noexcept + { + Init(); + } + CD3DX12_NODE_MASK_SUBOBJECT(CD3DX12_STATE_OBJECT_DESC& ContainingStateObject) + { + Init(); + AddToStateObject(ContainingStateObject); + } + void SetNodeMask(UINT NodeMask) noexcept + { + m_Desc.NodeMask = NodeMask; + } + D3D12_STATE_SUBOBJECT_TYPE Type() const noexcept override + { + return D3D12_STATE_SUBOBJECT_TYPE_NODE_MASK; + } + operator const D3D12_STATE_SUBOBJECT&() const noexcept { return *m_pSubobject; } + operator const D3D12_NODE_MASK&() const noexcept { return m_Desc; } +private: + void Init() noexcept + { + SUBOBJECT_HELPER_BASE::Init(); + m_Desc = {}; + } + void* Data() noexcept override { return &m_Desc; } + D3D12_NODE_MASK m_Desc; +}; + +#undef D3DX12_COM_PTR +#undef D3DX12_COM_PTR_GET +#undef D3DX12_COM_PTR_ADDRESSOF +#endif // #ifndef D3DX12_NO_STATE_OBJECT_HELPERS + +#endif // defined( __cplusplus ) + +#endif //__D3DX12_H__ + + diff --git a/CyberXeSS_YEDEK/dllmain.cpp b/CyberXeSS_YEDEK/dllmain.cpp new file mode 100644 index 00000000..19c37623 --- /dev/null +++ b/CyberXeSS_YEDEK/dllmain.cpp @@ -0,0 +1,29 @@ +#include "pch.h" + +HMODULE dllModule; + +BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + DisableThreadLibraryCalls(hModule); + dllModule = hModule; + break; + + case DLL_THREAD_ATTACH: + break; + + case DLL_THREAD_DETACH: + break; + + case DLL_PROCESS_DETACH: +#ifdef LOGGING_ACTIVE + closeOfs(); +#endif + break; + } + + return TRUE; +} + diff --git a/CyberXeSS_YEDEK/framework.h b/CyberXeSS_YEDEK/framework.h new file mode 100644 index 00000000..5ba7896a --- /dev/null +++ b/CyberXeSS_YEDEK/framework.h @@ -0,0 +1,33 @@ +#pragma once + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#define WIN32_NO_STATUS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define NV_WINDOWS +#define NVSDK_NGX +#define NGX_ENABLE_DEPRECATED_GET_PARAMETERS +#define NGX_ENABLE_DEPRECATED_SHUTDOWN +#include +#include + +#include +#include + + + diff --git a/CyberXeSS_YEDEK/pch.cpp b/CyberXeSS_YEDEK/pch.cpp new file mode 100644 index 00000000..11558320 --- /dev/null +++ b/CyberXeSS_YEDEK/pch.cpp @@ -0,0 +1,28 @@ +#include "pch.h" + +#ifdef LOGGING_ACTIVE + +std::ofstream ofs; +log_level_t logLevel = LEVEL_NONE; + +void logprintf(std::string logMsg, log_level_t level) +{ + if (level < logLevel) + return; + + ofs << GetTicks() << ": " << logMsg << '\n'; + ofs.flush(); +} + +void prepareOfs(std::string fileName, log_level_t level) +{ + logLevel = level; + ofs = std::ofstream(fileName, std::ios_base::out | std::ios_base::app); +} + +void closeOfs() +{ + ofs.close(); +} + +#endif \ No newline at end of file diff --git a/CyberXeSS_YEDEK/pch.h b/CyberXeSS_YEDEK/pch.h new file mode 100644 index 00000000..058d6b78 --- /dev/null +++ b/CyberXeSS_YEDEK/pch.h @@ -0,0 +1,79 @@ +#pragma once +#include "framework.h" + +//#define LOGGING_ACTIVE +//#define D3D11on12 + +typedef enum _log_level_t +{ + LEVEL_NONE = -1, + LEVEL_DEBUG = 0, + LEVEL_INFO = 1, + LEVEL_WARNING = 2, + LEVEL_ERROR = 3 +} log_level_t; + +#define SAFE_RELEASE(p) \ + do \ + { \ + if(p) \ + { \ + (p)->Release(); \ + (p) = NULL; \ + } \ + } while((void)0, 0) + +#ifdef LOGGING_ACTIVE +#define LOG(string, ...) logprintf(string, __VA_ARGS__) +#else +#define LOG(string, level) +#endif + +#ifdef LOGGING_ACTIVE + +#include +#include +#include "Config.h" + +void logprintf(std::string logMsg, log_level_t level = LEVEL_DEBUG); + +void prepareOfs(std::string fileName, log_level_t level); + +void closeOfs(); + +static inline int64_t GetTicks() +{ + LARGE_INTEGER ticks; + if (!QueryPerformanceCounter(&ticks)) + return 0; + + return ticks.QuadPart; +} + +template< typename T > +static inline std::string int_to_hex(T i) +{ + std::stringstream stream; + stream << "0x" + << std::setfill('0') + << std::setw(sizeof(T) * 2) + << std::hex << i; + return stream.str(); +} + +static inline std::string ToString(REFIID guid) +{ + char guid_string[37]; // 32 hex chars + 4 hyphens + null terminator + + snprintf( + guid_string, sizeof(guid_string), + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], + guid.Data4[3], guid.Data4[4], guid.Data4[5], + guid.Data4[6], guid.Data4[7]); + + return guid_string; +} + +#endif \ No newline at end of file