diff --git a/include/RE/C/CreationRenderer.h b/include/RE/C/CreationRenderer.h new file mode 100644 index 0000000..38976ae --- /dev/null +++ b/include/RE/C/CreationRenderer.h @@ -0,0 +1,92 @@ +#pragma once + +#include "REX/W32/D3D12.h" +#include "REX/W32/DXGI.h" +#include "REX/W32/DXGI_2.h" + +namespace RE::CreationRendererPrivate +{ + struct DeviceProperties; + + namespace detail + { + struct QueueOwnerA; + struct QueueOwnerB; + } + + // No RTTI - names from engine assert strings, not RTTI. accessor over g_RendererRoot; + class Renderer + { + public: + [[nodiscard]] static Renderer* GetSingleton() + { + static REL::Relocation singleton{ ID::CreationRendererPrivate::Renderer::Singleton }; + return *singleton; + } + + [[nodiscard]] REX::W32::ID3D12Device* GetDevice() const; + + [[nodiscard]] REX::W32::ID3D12CommandQueue* GetGraphicsQueue() const; + + [[nodiscard]] REX::W32::IDXGIFactory2* GetDXGIFactory() const; + [[nodiscard]] REX::W32::IDXGIAdapter* GetAdapter() const; + + // members + std::byte pad00[0x28]; // 00 + detail::QueueOwnerA* queueOwnerA; // 28 + DeviceProperties* deviceProperties; // 30 (arDeviceProperties) + }; + static_assert(offsetof(Renderer, queueOwnerA) == 0x28); + static_assert(offsetof(Renderer, deviceProperties) == 0x30); + + struct DeviceProperties + { + std::byte pad000[0x408]; // 000 + REX::W32::IDXGIFactory2* dxgiFactory; // 408 (pDXGIFactory) + REX::W32::IDXGIAdapter* dxActiveGPU; // 410 (pDxActiveGPU) + REX::W32::ID3D12Device* dxDevice; // 418 (pDxDevice) + }; + static_assert(offsetof(DeviceProperties, dxgiFactory) == 0x408); + static_assert(offsetof(DeviceProperties, dxActiveGPU) == 0x410); + static_assert(offsetof(DeviceProperties, dxDevice) == 0x418); + + namespace detail + { + struct QueueOwnerA + { + std::byte pad00[0x08]; // 00 + QueueOwnerB* inner; // 08 + }; + static_assert(offsetof(QueueOwnerA, inner) == 0x08); + + struct QueueOwnerB + { + std::byte pad00[0x60]; // 00 + REX::W32::ID3D12CommandQueue* graphicsQueue; // 60 (pgraphicsQueue) + }; + static_assert(offsetof(QueueOwnerB, graphicsQueue) == 0x60); + } + + inline REX::W32::ID3D12Device* Renderer::GetDevice() const + { + return deviceProperties ? deviceProperties->dxDevice : nullptr; + } + + inline REX::W32::ID3D12CommandQueue* Renderer::GetGraphicsQueue() const + { + if (!queueOwnerA || !queueOwnerA->inner) { + return nullptr; + } + return queueOwnerA->inner->graphicsQueue; + } + + inline REX::W32::IDXGIFactory2* Renderer::GetDXGIFactory() const + { + return deviceProperties ? deviceProperties->dxgiFactory : nullptr; + } + + inline REX::W32::IDXGIAdapter* Renderer::GetAdapter() const + { + return deviceProperties ? deviceProperties->dxActiveGPU : nullptr; + } +} diff --git a/include/RE/IDs.h b/include/RE/IDs.h index a4f874e..d80a947 100644 --- a/include/RE/IDs.h +++ b/include/RE/IDs.h @@ -798,6 +798,11 @@ namespace RE::ID inline constexpr REL::ID GetEventSource{ 0 }; // 132107 } + namespace CreationRendererPrivate::Renderer + { + inline constexpr REL::ID Singleton{ 944397 }; + } + namespace CriticalHitEvent::Event { inline constexpr REL::ID GetEventSource{ 0 }; // 153653 diff --git a/include/RE/Starfield.h b/include/RE/Starfield.h index 4e5b881..7da4aae 100644 --- a/include/RE/Starfield.h +++ b/include/RE/Starfield.h @@ -242,6 +242,7 @@ #include "RE/C/ConeProjectile.h" #include "RE/C/Console.h" #include "RE/C/ConsoleLog.h" +#include "RE/C/CreationRenderer.h" #include "RE/D/DebuggerMessages.h" #include "RE/D/DecalData.h" #include "RE/D/DetectionState.h"