From 8ad59f8ccf95e5e6906887d40ed30717a33b84f6 Mon Sep 17 00:00:00 2001 From: Scott Mansell Date: Sun, 29 Jan 2023 23:58:54 +1300 Subject: [PATCH] Add AbstractGfx for DX12 --- Source/Core/DolphinLib.props | 4 +- .../Core/VideoBackends/D3D12/CMakeLists.txt | 4 +- .../VideoBackends/D3D12/D3D12BoundingBox.cpp | 8 +- .../D3D12/{D3D12Renderer.cpp => D3D12Gfx.cpp} | 142 ++++++++---------- .../D3D12/{D3D12Renderer.h => D3D12Gfx.h} | 25 ++- .../VideoBackends/D3D12/D3D12PerfQuery.cpp | 7 +- .../D3D12/D3D12VertexManager.cpp | 40 ++--- .../Core/VideoBackends/D3D12/DX12Texture.cpp | 6 +- .../Core/VideoBackends/D3D12/VideoBackend.cpp | 32 ++-- 9 files changed, 119 insertions(+), 149 deletions(-) rename Source/Core/VideoBackends/D3D12/{D3D12Renderer.cpp => D3D12Gfx.cpp} (84%) rename Source/Core/VideoBackends/D3D12/{D3D12Renderer.h => D3D12Gfx.h} (92%) diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 4df8e0cd84..9bf63bbb51 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -545,7 +545,7 @@ - + @@ -1157,7 +1157,7 @@ - + diff --git a/Source/Core/VideoBackends/D3D12/CMakeLists.txt b/Source/Core/VideoBackends/D3D12/CMakeLists.txt index 16f458e2e9..bc89b89df3 100644 --- a/Source/Core/VideoBackends/D3D12/CMakeLists.txt +++ b/Source/Core/VideoBackends/D3D12/CMakeLists.txt @@ -3,8 +3,8 @@ add_library(videod3d12 D3D12BoundingBox.h D3D12PerfQuery.cpp D3D12PerfQuery.h - D3D12Renderer.cpp - D3D12Renderer.h + D3D12Gfx.cpp + D3D12Gfx.h D3D12StreamBuffer.cpp D3D12StreamBuffer.h D3D12SwapChain.cpp diff --git a/Source/Core/VideoBackends/D3D12/D3D12BoundingBox.cpp b/Source/Core/VideoBackends/D3D12/D3D12BoundingBox.cpp index 4eec9f2e22..1627e39343 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12BoundingBox.cpp +++ b/Source/Core/VideoBackends/D3D12/D3D12BoundingBox.cpp @@ -6,7 +6,7 @@ #include "Common/Assert.h" #include "Common/Logging/Log.h" -#include "VideoBackends/D3D12/D3D12Renderer.h" +#include "VideoBackends/D3D12/D3D12Gfx.h" #include "VideoBackends/D3D12/DX12Context.h" namespace DX12 @@ -22,7 +22,7 @@ bool D3D12BoundingBox::Initialize() if (!CreateBuffers()) return false; - Renderer::GetInstance()->SetPixelShaderUAV(m_gpu_descriptor.cpu_handle); + Gfx::GetInstance()->SetPixelShaderUAV(m_gpu_descriptor.cpu_handle); return true; } @@ -35,7 +35,7 @@ std::vector D3D12BoundingBox::Read(u32 index, u32 length) 0, BUFFER_SIZE); ResourceBarrier(g_dx_context->GetCommandList(), m_gpu_buffer.Get(), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS); - Renderer::GetInstance()->ExecuteCommandList(true); + Gfx::GetInstance()->ExecuteCommandList(true); // Read back to cached values. std::vector values(length); @@ -62,7 +62,7 @@ void D3D12BoundingBox::Write(u32 index, const std::vector& values) if (!m_upload_buffer.ReserveMemory(copy_size, sizeof(BBoxType))) { WARN_LOG_FMT(VIDEO, "Executing command list while waiting for space in bbox stream buffer"); - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); if (!m_upload_buffer.ReserveMemory(copy_size, sizeof(BBoxType))) { PanicAlertFmt("Failed to allocate bbox stream buffer space"); diff --git a/Source/Core/VideoBackends/D3D12/D3D12Renderer.cpp b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp similarity index 84% rename from Source/Core/VideoBackends/D3D12/D3D12Renderer.cpp rename to Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp index ab6b1a464b..ea9610ae34 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12Renderer.cpp +++ b/Source/Core/VideoBackends/D3D12/D3D12Gfx.cpp @@ -1,7 +1,7 @@ // Copyright 2019 Dolphin Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "VideoBackends/D3D12/D3D12Renderer.h" +#include "VideoBackends/D3D12/D3D12Gfx.h" #include "Common/Logging/Log.h" @@ -28,11 +28,8 @@ static bool UsesDynamicVertexLoader(const AbstractPipeline* pipeline) (g_ActiveConfig.UseVSForLinePointExpand() && usage != AbstractPipelineUsage::Utility); } -Renderer::Renderer(std::unique_ptr swap_chain, float backbuffer_scale) - : ::Renderer(swap_chain ? swap_chain->GetWidth() : 0, swap_chain ? swap_chain->GetHeight() : 0, - backbuffer_scale, - swap_chain ? swap_chain->GetFormat() : AbstractTextureFormat::Undefined), - m_swap_chain(std::move(swap_chain)) +Gfx::Gfx(std::unique_ptr swap_chain, float backbuffer_scale) + : m_backbuffer_scale(backbuffer_scale), m_swap_chain(std::move(swap_chain)) { m_state.root_signature = g_dx_context->GetGXRootSignature(); @@ -44,41 +41,26 @@ Renderer::Renderer(std::unique_ptr swap_chain, float backbuffer_scale } } -Renderer::~Renderer() = default; +Gfx::~Gfx() = default; -bool Renderer::IsHeadless() const +bool Gfx::IsHeadless() const { return !m_swap_chain; } -bool Renderer::Initialize() -{ - if (!::Renderer::Initialize()) - return false; - - return true; -} - -void Renderer::Shutdown() -{ - m_swap_chain.reset(); - - ::Renderer::Shutdown(); -} - -std::unique_ptr Renderer::CreateTexture(const TextureConfig& config, +std::unique_ptr Gfx::CreateTexture(const TextureConfig& config, std::string_view name) { return DXTexture::Create(config, name); } -std::unique_ptr Renderer::CreateStagingTexture(StagingTextureType type, +std::unique_ptr Gfx::CreateStagingTexture(StagingTextureType type, const TextureConfig& config) { return DXStagingTexture::Create(type, config); } -std::unique_ptr Renderer::CreateFramebuffer(AbstractTexture* color_attachment, +std::unique_ptr Gfx::CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) { return DXFramebuffer::Create(static_cast(color_attachment), @@ -86,12 +68,12 @@ std::unique_ptr Renderer::CreateFramebuffer(AbstractTexture } std::unique_ptr -Renderer::CreateShaderFromSource(ShaderStage stage, std::string_view source, std::string_view name) +Gfx::CreateShaderFromSource(ShaderStage stage, std::string_view source, std::string_view name) { return DXShader::CreateFromSource(stage, source, name); } -std::unique_ptr Renderer::CreateShaderFromBinary(ShaderStage stage, +std::unique_ptr Gfx::CreateShaderFromBinary(ShaderStage stage, const void* data, size_t length, std::string_view name) { @@ -99,43 +81,36 @@ std::unique_ptr Renderer::CreateShaderFromBinary(ShaderStage sta } std::unique_ptr -Renderer::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) +Gfx::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) { return std::make_unique(vtx_decl); } -std::unique_ptr Renderer::CreatePipeline(const AbstractPipelineConfig& config, +std::unique_ptr Gfx::CreatePipeline(const AbstractPipelineConfig& config, const void* cache_data, size_t cache_data_length) { return DXPipeline::Create(config, cache_data, cache_data_length); } -std::unique_ptr Renderer::CreateBoundingBox() const -{ - return std::make_unique(); -} - -void Renderer::Flush() +void Gfx::Flush() { ExecuteCommandList(false); } -void Renderer::WaitForGPUIdle() +void Gfx::WaitForGPUIdle() { ExecuteCommandList(true); } -void Renderer::ClearScreen(const MathUtil::Rectangle& rc, bool color_enable, bool alpha_enable, - bool z_enable, u32 color, u32 z) +void Gfx::ClearRegion(const MathUtil::Rectangle& rc, const MathUtil::Rectangle& target_rc, + bool color_enable, bool alpha_enable, bool z_enable, u32 color, u32 z) { // Use a fast path without the shader if both color/alpha are enabled. - const bool fast_color_clear = color_enable && (alpha_enable || !EFBHasAlphaChannel()); + const bool fast_color_clear = color_enable && alpha_enable; if (fast_color_clear || z_enable) { - MathUtil::Rectangle native_rc = ConvertEFBRectangle(rc); - native_rc.ClampUL(0, 0, m_current_framebuffer->GetWidth(), m_current_framebuffer->GetHeight()); - const D3D12_RECT d3d_clear_rc{native_rc.left, native_rc.top, native_rc.right, native_rc.bottom}; + const D3D12_RECT d3d_clear_rc{target_rc.left, target_rc.top, target_rc.right, target_rc.bottom}; if (fast_color_clear) { @@ -170,10 +145,10 @@ void Renderer::ClearScreen(const MathUtil::Rectangle& rc, bool color_enable // Anything left over, fall back to clear triangle. if (color_enable || alpha_enable || z_enable) - ::Renderer::ClearScreen(rc, color_enable, alpha_enable, z_enable, color, z); + ::AbstractGfx::ClearRegion(rc, target_rc, color_enable, alpha_enable, z_enable, color, z); } -void Renderer::SetPipeline(const AbstractPipeline* pipeline) +void Gfx::SetPipeline(const AbstractPipeline* pipeline) { const DXPipeline* dx_pipeline = static_cast(pipeline); if (m_current_pipeline == dx_pipeline) @@ -205,7 +180,7 @@ void Renderer::SetPipeline(const AbstractPipeline* pipeline) } } -void Renderer::BindFramebuffer(DXFramebuffer* fb) +void Gfx::BindFramebuffer(DXFramebuffer* fb) { if (fb->HasColorBuffer()) { @@ -226,7 +201,7 @@ void Renderer::BindFramebuffer(DXFramebuffer* fb) m_dirty_bits &= ~DirtyState_Framebuffer; } -void Renderer::SetFramebuffer(AbstractFramebuffer* framebuffer) +void Gfx::SetFramebuffer(AbstractFramebuffer* framebuffer) { if (m_current_framebuffer == framebuffer) return; @@ -235,7 +210,7 @@ void Renderer::SetFramebuffer(AbstractFramebuffer* framebuffer) m_dirty_bits |= DirtyState_Framebuffer; } -void Renderer::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer) +void Gfx::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer) { SetFramebuffer(framebuffer); @@ -254,7 +229,7 @@ void Renderer::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer) } } -void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, +void Gfx::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, const ClearColor& color_value, float depth_value) { DXFramebuffer* dxfb = static_cast(framebuffer); @@ -273,7 +248,7 @@ void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, } } -void Renderer::SetScissorRect(const MathUtil::Rectangle& rc) +void Gfx::SetScissorRect(const MathUtil::Rectangle& rc) { if (m_state.scissor.left == rc.left && m_state.scissor.right == rc.right && m_state.scissor.top == rc.top && m_state.scissor.bottom == rc.bottom) @@ -288,7 +263,7 @@ void Renderer::SetScissorRect(const MathUtil::Rectangle& rc) m_dirty_bits |= DirtyState_ScissorRect; } -void Renderer::SetTexture(u32 index, const AbstractTexture* texture) +void Gfx::SetTexture(u32 index, const AbstractTexture* texture) { const DXTexture* dxtex = static_cast(texture); if (m_state.textures[index].ptr == dxtex->GetSRVDescriptor().cpu_handle.ptr) @@ -301,7 +276,7 @@ void Renderer::SetTexture(u32 index, const AbstractTexture* texture) m_dirty_bits |= DirtyState_Textures; } -void Renderer::SetSamplerState(u32 index, const SamplerState& state) +void Gfx::SetSamplerState(u32 index, const SamplerState& state) { if (m_state.samplers.states[index] == state) return; @@ -310,7 +285,7 @@ void Renderer::SetSamplerState(u32 index, const SamplerState& state) m_dirty_bits |= DirtyState_Samplers; } -void Renderer::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) +void Gfx::SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) { const DXTexture* dxtex = static_cast(texture); if (m_state.compute_image_texture == dxtex) @@ -323,7 +298,7 @@ void Renderer::SetComputeImageTexture(AbstractTexture* texture, bool read, bool m_dirty_bits |= DirtyState_ComputeImageTexture; } -void Renderer::UnbindTexture(const AbstractTexture* texture) +void Gfx::UnbindTexture(const AbstractTexture* texture) { const auto srv_shadow_descriptor = static_cast(texture)->GetSRVDescriptor().cpu_handle; @@ -342,7 +317,7 @@ void Renderer::UnbindTexture(const AbstractTexture* texture) } } -void Renderer::SetViewport(float x, float y, float width, float height, float near_depth, +void Gfx::SetViewport(float x, float y, float width, float height, float near_depth, float far_depth) { if (m_state.viewport.TopLeftX == x && m_state.viewport.TopLeftY == y && @@ -361,7 +336,7 @@ void Renderer::SetViewport(float x, float y, float width, float height, float ne m_dirty_bits |= DirtyState_Viewport; } -void Renderer::Draw(u32 base_vertex, u32 num_vertices) +void Gfx::Draw(u32 base_vertex, u32 num_vertices) { if (!ApplyState()) return; @@ -369,7 +344,7 @@ void Renderer::Draw(u32 base_vertex, u32 num_vertices) g_dx_context->GetCommandList()->DrawInstanced(num_vertices, 1, base_vertex, 0); } -void Renderer::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) +void Gfx::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) { if (!ApplyState()) return; @@ -381,7 +356,7 @@ void Renderer::DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) g_dx_context->GetCommandList()->DrawIndexedInstanced(num_indices, 1, base_index, base_vertex, 0); } -void Renderer::DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x, u32 groupsize_y, +void Gfx::DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x, u32 groupsize_y, u32 groupsize_z, u32 groups_x, u32 groups_y, u32 groups_z) { SetRootSignatures(); @@ -412,13 +387,13 @@ void Renderer::DispatchComputeShader(const AbstractShader* shader, u32 groupsize m_dirty_bits |= DirtyState_Pipeline; } -void Renderer::BindBackbuffer(const ClearColor& clear_color) +void Gfx::BindBackbuffer(const ClearColor& clear_color) { CheckForSwapChainChanges(); SetAndClearFramebuffer(m_swap_chain->GetCurrentFramebuffer(), clear_color); } -void Renderer::CheckForSwapChainChanges() +void Gfx::CheckForSwapChainChanges() { const bool surface_changed = g_presenter->SurfaceChangedTestAndClear(); const bool surface_resized = @@ -437,11 +412,10 @@ void Renderer::CheckForSwapChainChanges() m_swap_chain->ResizeSwapChain(); } - m_backbuffer_width = m_swap_chain->GetWidth(); - m_backbuffer_height = m_swap_chain->GetHeight(); + g_presenter->SetBackbuffer(m_swap_chain->GetWidth(), m_swap_chain->GetHeight()); } -void Renderer::PresentBackbuffer() +void Gfx::PresentBackbuffer() { m_current_framebuffer = nullptr; @@ -451,10 +425,18 @@ void Renderer::PresentBackbuffer() m_swap_chain->Present(); } -void Renderer::OnConfigChanged(u32 bits) +SurfaceInfo Gfx::GetSurfaceInfo() const { - ::Renderer::OnConfigChanged(bits); + return { + m_swap_chain ? static_cast(m_swap_chain->GetWidth()) : 0, + m_swap_chain ? static_cast(m_swap_chain->GetHeight()) : 0, + m_backbuffer_scale, + m_swap_chain ? m_swap_chain->GetFormat() : AbstractTextureFormat::Undefined + }; +} +void Gfx::OnConfigChanged(u32 bits) +{ // For quad-buffered stereo we need to change the layer count, so recreate the swap chain. if (m_swap_chain && bits & CONFIG_CHANGE_BIT_STEREO_MODE) { @@ -475,14 +457,14 @@ void Renderer::OnConfigChanged(u32 bits) g_dx_context->RecreateGXRootSignature(); } -void Renderer::ExecuteCommandList(bool wait_for_completion) +void Gfx::ExecuteCommandList(bool wait_for_completion) { PerfQuery::GetInstance()->ResolveQueries(); g_dx_context->ExecuteCommandList(wait_for_completion); m_dirty_bits = DirtyState_All; } -void Renderer::SetConstantBuffer(u32 index, D3D12_GPU_VIRTUAL_ADDRESS address) +void Gfx::SetConstantBuffer(u32 index, D3D12_GPU_VIRTUAL_ADDRESS address) { if (m_state.constant_buffers[index] == address) return; @@ -491,7 +473,7 @@ void Renderer::SetConstantBuffer(u32 index, D3D12_GPU_VIRTUAL_ADDRESS address) m_dirty_bits |= DirtyState_PS_CBV << index; } -void Renderer::SetTextureDescriptor(u32 index, D3D12_CPU_DESCRIPTOR_HANDLE handle) +void Gfx::SetTextureDescriptor(u32 index, D3D12_CPU_DESCRIPTOR_HANDLE handle) { if (m_state.textures[index].ptr == handle.ptr) return; @@ -500,7 +482,7 @@ void Renderer::SetTextureDescriptor(u32 index, D3D12_CPU_DESCRIPTOR_HANDLE handl m_dirty_bits |= DirtyState_Textures; } -void Renderer::SetPixelShaderUAV(D3D12_CPU_DESCRIPTOR_HANDLE handle) +void Gfx::SetPixelShaderUAV(D3D12_CPU_DESCRIPTOR_HANDLE handle) { if (m_state.ps_uav.ptr == handle.ptr) return; @@ -509,7 +491,7 @@ void Renderer::SetPixelShaderUAV(D3D12_CPU_DESCRIPTOR_HANDLE handle) m_dirty_bits |= DirtyState_PS_UAV; } -void Renderer::SetVertexBuffer(D3D12_GPU_VIRTUAL_ADDRESS address, D3D12_CPU_DESCRIPTOR_HANDLE srv, +void Gfx::SetVertexBuffer(D3D12_GPU_VIRTUAL_ADDRESS address, D3D12_CPU_DESCRIPTOR_HANDLE srv, u32 stride, u32 size) { if (m_state.vertex_buffer.BufferLocation != address || @@ -527,7 +509,7 @@ void Renderer::SetVertexBuffer(D3D12_GPU_VIRTUAL_ADDRESS address, D3D12_CPU_DESC } } -void Renderer::SetIndexBuffer(D3D12_GPU_VIRTUAL_ADDRESS address, u32 size, DXGI_FORMAT format) +void Gfx::SetIndexBuffer(D3D12_GPU_VIRTUAL_ADDRESS address, u32 size, DXGI_FORMAT format) { if (m_state.index_buffer.BufferLocation == address && m_state.index_buffer.SizeInBytes == size && m_state.index_buffer.Format == format) @@ -541,7 +523,7 @@ void Renderer::SetIndexBuffer(D3D12_GPU_VIRTUAL_ADDRESS address, u32 size, DXGI_ m_dirty_bits |= DirtyState_IndexBuffer; } -bool Renderer::ApplyState() +bool Gfx::ApplyState() { if (!m_current_framebuffer || !m_current_pipeline) return false; @@ -637,7 +619,7 @@ bool Renderer::ApplyState() return true; } -void Renderer::SetRootSignatures() +void Gfx::SetRootSignatures() { const u32 dirty_bits = m_dirty_bits; if (dirty_bits & DirtyState_RootSignature) @@ -650,7 +632,7 @@ void Renderer::SetRootSignatures() m_dirty_bits &= ~(DirtyState_RootSignature | DirtyState_ComputeRootSignature); } -void Renderer::SetDescriptorHeaps() +void Gfx::SetDescriptorHeaps() { if (m_dirty_bits & DirtyState_DescriptorHeaps) { @@ -660,7 +642,7 @@ void Renderer::SetDescriptorHeaps() } } -void Renderer::UpdateDescriptorTables() +void Gfx::UpdateDescriptorTables() { // Samplers force a full sync because any of the samplers could be in use. const bool texture_update_failed = @@ -684,7 +666,7 @@ void Renderer::UpdateDescriptorTables() } } -bool Renderer::UpdateSRVDescriptorTable() +bool Gfx::UpdateSRVDescriptorTable() { static constexpr std::array src_sizes = {1, 1, 1, 1, 1, 1, 1, 1}; DescriptorHandle dst_base_handle; @@ -700,7 +682,7 @@ bool Renderer::UpdateSRVDescriptorTable() return true; } -bool Renderer::UpdateSamplerDescriptorTable() +bool Gfx::UpdateSamplerDescriptorTable() { if (!g_dx_context->GetSamplerAllocator()->GetGroupHandle(m_state.samplers, &m_state.sampler_descriptor_base)) @@ -713,7 +695,7 @@ bool Renderer::UpdateSamplerDescriptorTable() return true; } -bool Renderer::UpdateUAVDescriptorTable() +bool Gfx::UpdateUAVDescriptorTable() { // We can skip writing the UAV descriptor if bbox isn't enabled, since it's not used otherwise. if (!g_ActiveConfig.bBBoxEnable) @@ -730,7 +712,7 @@ bool Renderer::UpdateUAVDescriptorTable() return true; } -bool Renderer::UpdateVSSRVDescriptorTable() +bool Gfx::UpdateVSSRVDescriptorTable() { if (!UsesDynamicVertexLoader(m_current_pipeline)) { @@ -748,7 +730,7 @@ bool Renderer::UpdateVSSRVDescriptorTable() return true; } -bool Renderer::UpdateComputeUAVDescriptorTable() +bool Gfx::UpdateComputeUAVDescriptorTable() { DescriptorHandle handle; if (!g_dx_context->GetDescriptorAllocator()->Allocate(1, &handle)) diff --git a/Source/Core/VideoBackends/D3D12/D3D12Renderer.h b/Source/Core/VideoBackends/D3D12/D3D12Gfx.h similarity index 92% rename from Source/Core/VideoBackends/D3D12/D3D12Renderer.h rename to Source/Core/VideoBackends/D3D12/D3D12Gfx.h index 19188a5acf..26dc669ffc 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12Renderer.h +++ b/Source/Core/VideoBackends/D3D12/D3D12Gfx.h @@ -6,9 +6,7 @@ #include #include "VideoBackends/D3D12/DescriptorAllocator.h" #include "VideoBackends/D3D12/DescriptorHeapManager.h" -#include "VideoCommon/RenderBase.h" - -class BoundingBox; +#include "VideoCommon/AbstractGfx.h" namespace DX12 { @@ -18,19 +16,16 @@ class DXShader; class DXPipeline; class SwapChain; -class Renderer final : public ::Renderer +class Gfx final : public ::AbstractGfx { public: - Renderer(std::unique_ptr swap_chain, float backbuffer_scale); - ~Renderer() override; + Gfx(std::unique_ptr swap_chain, float backbuffer_scale); + ~Gfx() override; - static Renderer* GetInstance() { return static_cast(g_renderer.get()); } + static Gfx* GetInstance() { return static_cast(g_gfx.get()); } bool IsHeadless() const override; - bool Initialize() override; - void Shutdown() override; - std::unique_ptr CreateTexture(const TextureConfig& config, std::string_view name) override; std::unique_ptr @@ -52,8 +47,8 @@ public: void Flush() override; void WaitForGPUIdle() override; - void ClearScreen(const MathUtil::Rectangle& rc, bool color_enable, bool alpha_enable, - bool z_enable, u32 color, u32 z) override; + void ClearRegion(const MathUtil::Rectangle& rc, const MathUtil::Rectangle& target_rc, + bool color_enable, bool alpha_enable, bool z_enable, u32 color, u32 z) override; void SetPipeline(const AbstractPipeline* pipeline) override; void SetFramebuffer(AbstractFramebuffer* framebuffer) override; @@ -74,6 +69,8 @@ public: void BindBackbuffer(const ClearColor& clear_color = {}) override; void PresentBackbuffer() override; + SurfaceInfo GetSurfaceInfo() const override; + // Completes the current render pass, executes the command buffer, and restores state ready for // next render. Use when you want to kick the current buffer to make room for new data. void ExecuteCommandList(bool wait_for_completion); @@ -98,8 +95,6 @@ public: protected: void OnConfigChanged(u32 bits) override; - std::unique_ptr CreateBoundingBox() const override; - private: static const u32 MAX_TEXTURES = 8; static const u32 NUM_CONSTANT_BUFFERS = 3; @@ -152,6 +147,8 @@ private: bool UpdateComputeUAVDescriptorTable(); bool UpdateSamplerDescriptorTable(); + float m_backbuffer_scale; + // Owned objects std::unique_ptr m_swap_chain; diff --git a/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp b/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp index 06f6f9dbcc..a6c466b646 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp +++ b/Source/Core/VideoBackends/D3D12/D3D12PerfQuery.cpp @@ -9,9 +9,10 @@ #include "Common/Logging/Log.h" #include "VideoBackends/D3D12/Common.h" -#include "VideoBackends/D3D12/D3D12Renderer.h" +#include "VideoBackends/D3D12/D3D12Gfx.h" #include "VideoBackends/D3D12/DX12Context.h" #include "VideoCommon/VideoCommon.h" +#include "VideoCommon/RenderBase.h" namespace DX12 { @@ -64,7 +65,7 @@ void PerfQuery::EnableQuery(PerfQueryGroup group) // This is because we can't leave a query open when submitting a command list, and the draw // call itself may need to execute a command list if we run out of descriptors. Note that // this assumes that the caller has bound all required state prior to enabling the query. - Renderer::GetInstance()->ApplyState(); + Gfx::GetInstance()->ApplyState(); if (group == PQG_ZCOMP_ZCOMPLOC || group == PQG_ZCOMP) { @@ -261,7 +262,7 @@ void PerfQuery::PartialFlush(bool resolve, bool blocking) { // Submit a command buffer if there are unresolved queries (to write them to the buffer). if (resolve && m_unresolved_queries > 0) - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); ReadbackQueries(blocking); } diff --git a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp index 3ea1008413..55f13630a9 100644 --- a/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp +++ b/Source/Core/VideoBackends/D3D12/D3D12VertexManager.cpp @@ -10,7 +10,7 @@ #include "Core/System.h" -#include "VideoBackends/D3D12/D3D12Renderer.h" +#include "VideoBackends/D3D12/D3D12Gfx.h" #include "VideoBackends/D3D12/D3D12StreamBuffer.h" #include "VideoBackends/D3D12/DX12Context.h" @@ -92,7 +92,7 @@ void VertexManager::ResetBuffer(u32 vertex_stride) { // Flush any pending commands first, so that we can wait on the fences WARN_LOG_FMT(VIDEO, "Executing command list while waiting for space in vertex/index buffer"); - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); // Attempt to allocate again, this may cause a fence wait if (!has_vbuffer_allocation) @@ -129,10 +129,10 @@ void VertexManager::CommitBuffer(u32 num_vertices, u32 vertex_stride, u32 num_in ADDSTAT(g_stats.this_frame.bytes_vertex_streamed, static_cast(vertex_data_size)); ADDSTAT(g_stats.this_frame.bytes_index_streamed, static_cast(index_data_size)); - Renderer::GetInstance()->SetVertexBuffer(m_vertex_stream_buffer.GetGPUPointer(), + Gfx::GetInstance()->SetVertexBuffer(m_vertex_stream_buffer.GetGPUPointer(), m_vertex_srv.cpu_handle, vertex_stride, m_vertex_stream_buffer.GetSize()); - Renderer::GetInstance()->SetIndexBuffer(m_index_stream_buffer.GetGPUPointer(), + Gfx::GetInstance()->SetIndexBuffer(m_index_stream_buffer.GetGPUPointer(), m_index_stream_buffer.GetSize(), DXGI_FORMAT_R16_UINT); } @@ -151,7 +151,7 @@ void VertexManager::UpdateVertexShaderConstants() if (!vertex_shader_manager.dirty || !ReserveConstantStorage()) return; - Renderer::GetInstance()->SetConstantBuffer(1, m_uniform_stream_buffer.GetCurrentGPUPointer()); + Gfx::GetInstance()->SetConstantBuffer(1, m_uniform_stream_buffer.GetCurrentGPUPointer()); std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(), &vertex_shader_manager.constants, sizeof(VertexShaderConstants)); m_uniform_stream_buffer.CommitMemory(sizeof(VertexShaderConstants)); @@ -167,7 +167,7 @@ void VertexManager::UpdateGeometryShaderConstants() if (!geometry_shader_manager.dirty || !ReserveConstantStorage()) return; - Renderer::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer()); + Gfx::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer()); std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(), &geometry_shader_manager.constants, sizeof(GeometryShaderConstants)); m_uniform_stream_buffer.CommitMemory(sizeof(GeometryShaderConstants)); @@ -183,7 +183,7 @@ void VertexManager::UpdatePixelShaderConstants() if (!pixel_shader_manager.dirty || !ReserveConstantStorage()) return; - Renderer::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer()); + Gfx::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer()); std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(), &pixel_shader_manager.constants, sizeof(PixelShaderConstants)); m_uniform_stream_buffer.CommitMemory(sizeof(PixelShaderConstants)); @@ -204,7 +204,7 @@ bool VertexManager::ReserveConstantStorage() // The only places that call constant updates are safe to have state restored. WARN_LOG_FMT(VIDEO, "Executing command list while waiting for space in uniform buffer"); - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); // Since we are on a new command buffer, all constants have been invalidated, and we need // to reupload them. We may as well do this now, since we're issuing a draw anyway. @@ -234,11 +234,11 @@ void VertexManager::UploadAllConstants() } // Update bindings - Renderer::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer() + + Gfx::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer() + pixel_constants_offset); - Renderer::GetInstance()->SetConstantBuffer(1, m_uniform_stream_buffer.GetCurrentGPUPointer() + + Gfx::GetInstance()->SetConstantBuffer(1, m_uniform_stream_buffer.GetCurrentGPUPointer() + vertex_constants_offset); - Renderer::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer() + + Gfx::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer() + geometry_constants_offset); auto& system = Core::System::GetInstance(); @@ -271,12 +271,12 @@ void VertexManager::UploadUtilityUniforms(const void* data, u32 data_size) D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT)) { WARN_LOG_FMT(VIDEO, "Executing command buffer while waiting for ext space in uniform buffer"); - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); } - Renderer::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer()); - Renderer::GetInstance()->SetConstantBuffer(1, m_uniform_stream_buffer.GetCurrentGPUPointer()); - Renderer::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer()); + Gfx::GetInstance()->SetConstantBuffer(0, m_uniform_stream_buffer.GetCurrentGPUPointer()); + Gfx::GetInstance()->SetConstantBuffer(1, m_uniform_stream_buffer.GetCurrentGPUPointer()); + Gfx::GetInstance()->SetConstantBuffer(2, m_uniform_stream_buffer.GetCurrentGPUPointer()); std::memcpy(m_uniform_stream_buffer.GetCurrentHostPointer(), data, data_size); m_uniform_stream_buffer.CommitMemory(data_size); ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, data_size); @@ -293,7 +293,7 @@ bool VertexManager::UploadTexelBuffer(const void* data, u32 data_size, TexelBuff { // Try submitting cmdbuffer. WARN_LOG_FMT(VIDEO, "Submitting command buffer while waiting for space in texel buffer"); - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); if (!m_texel_stream_buffer.ReserveMemory(data_size, elem_size)) { PanicAlertFmt("Failed to allocate {} bytes from texel buffer", data_size); @@ -305,7 +305,7 @@ bool VertexManager::UploadTexelBuffer(const void* data, u32 data_size, TexelBuff *out_offset = static_cast(m_texel_stream_buffer.GetCurrentOffset()) / elem_size; m_texel_stream_buffer.CommitMemory(data_size); ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, data_size); - Renderer::GetInstance()->SetTextureDescriptor(0, m_texel_buffer_views[format].cpu_handle); + Gfx::GetInstance()->SetTextureDescriptor(0, m_texel_buffer_views[format].cpu_handle); return true; } @@ -323,7 +323,7 @@ bool VertexManager::UploadTexelBuffer(const void* data, u32 data_size, TexelBuff { // Try submitting cmdbuffer. WARN_LOG_FMT(VIDEO, "Submitting command buffer while waiting for space in texel buffer"); - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); if (!m_texel_stream_buffer.ReserveMemory(reserve_size, elem_size)) { PanicAlertFmt("Failed to allocate {} bytes from texel buffer", reserve_size); @@ -342,8 +342,8 @@ bool VertexManager::UploadTexelBuffer(const void* data, u32 data_size, TexelBuff m_texel_stream_buffer.CommitMemory(palette_byte_offset + palette_size); ADDSTAT(g_stats.this_frame.bytes_uniform_streamed, palette_byte_offset + palette_size); - Renderer::GetInstance()->SetTextureDescriptor(0, m_texel_buffer_views[format].cpu_handle); - Renderer::GetInstance()->SetTextureDescriptor(1, m_texel_buffer_views[palette_format].cpu_handle); + Gfx::GetInstance()->SetTextureDescriptor(0, m_texel_buffer_views[format].cpu_handle); + Gfx::GetInstance()->SetTextureDescriptor(1, m_texel_buffer_views[palette_format].cpu_handle); return true; } diff --git a/Source/Core/VideoBackends/D3D12/DX12Texture.cpp b/Source/Core/VideoBackends/D3D12/DX12Texture.cpp index 31951b1e95..1c5db02687 100644 --- a/Source/Core/VideoBackends/D3D12/DX12Texture.cpp +++ b/Source/Core/VideoBackends/D3D12/DX12Texture.cpp @@ -8,7 +8,7 @@ #include "Common/StringUtil.h" #include "VideoBackends/D3D12/Common.h" -#include "VideoBackends/D3D12/D3D12Renderer.h" +#include "VideoBackends/D3D12/D3D12Gfx.h" #include "VideoBackends/D3D12/D3D12StreamBuffer.h" #include "VideoBackends/D3D12/DX12Context.h" #include "VideoBackends/D3D12/DescriptorHeapManager.h" @@ -254,7 +254,7 @@ void DXTexture::Load(u32 level, u32 width, u32 height, u32 row_length, const u8* { WARN_LOG_FMT(VIDEO, "Executing command list while waiting for space in texture upload buffer"); - Renderer::GetInstance()->ExecuteCommandList(false); + Gfx::GetInstance()->ExecuteCommandList(false); if (!g_dx_context->GetTextureUploadBuffer().ReserveMemory( upload_size, D3D12_TEXTURE_DATA_PLACEMENT_ALIGNMENT)) { @@ -632,7 +632,7 @@ void DXStagingTexture::Flush() // the current list and wait for it to complete. This is the slowest path. Otherwise, if the // command list with the copy has been submitted, we only need to wait for the fence. if (m_completed_fence == g_dx_context->GetCurrentFenceValue()) - Renderer::GetInstance()->ExecuteCommandList(true); + Gfx::GetInstance()->ExecuteCommandList(true); else g_dx_context->WaitForFence(m_completed_fence); } diff --git a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp index 209a74dfc9..dbf51bd7f8 100644 --- a/Source/Core/VideoBackends/D3D12/VideoBackend.cpp +++ b/Source/Core/VideoBackends/D3D12/VideoBackend.cpp @@ -11,8 +11,9 @@ #include "Core/ConfigManager.h" #include "VideoBackends/D3D12/Common.h" +#include "VideoBackends/D3D12/D3D12BoundingBox.h" #include "VideoBackends/D3D12/D3D12PerfQuery.h" -#include "VideoBackends/D3D12/D3D12Renderer.h" +#include "VideoBackends/D3D12/D3D12Gfx.h" #include "VideoBackends/D3D12/D3D12SwapChain.h" #include "VideoBackends/D3D12/D3D12VertexManager.h" #include "VideoBackends/D3D12/DX12Context.h" @@ -111,7 +112,7 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi) } FillBackendInfo(); - InitializeShared(); + UpdateActiveConfig(); if (!g_dx_context->CreateGlobalResources()) { @@ -131,31 +132,20 @@ bool VideoBackend::Initialize(const WindowSystemInfo& wsi) } // Create main wrapper instances. - g_renderer = std::make_unique(std::move(swap_chain), wsi.render_surface_scale); - g_vertex_manager = std::make_unique(); - g_shader_cache = std::make_unique(); - g_framebuffer_manager = std::make_unique(); - g_texture_cache = std::make_unique(); - g_perf_query = std::make_unique(); + auto gfx = std::make_unique(std::move(swap_chain), wsi.render_surface_scale); + auto vertex_manager = std::make_unique(); + auto perf_query = std::make_unique(); + auto bounding_box = std::make_unique(); - if (!g_vertex_manager->Initialize() || !g_shader_cache->Initialize() || - !g_renderer->Initialize() || !g_framebuffer_manager->Initialize() || - !g_texture_cache->Initialize() || !PerfQuery::GetInstance()->Initialize()) - { - PanicAlertFmtT("Failed to initialize renderer classes"); - Shutdown(); - return false; - } - - g_shader_cache->InitializeShaderCache(); - return true; + return InitializeShared(std::move(gfx), std::move(vertex_manager), std::move(perf_query), + std::move(bounding_box)); } void VideoBackend::Shutdown() { // Keep the debug runtime happy... - if (g_renderer) - Renderer::GetInstance()->ExecuteCommandList(true); + if (g_gfx) + Gfx::GetInstance()->ExecuteCommandList(true); ShutdownShared(); DXContext::Destroy();