diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index 80daf63a32..bc0f486082 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -618,6 +618,7 @@ + @@ -1219,6 +1220,7 @@ + diff --git a/Source/Core/DolphinQt/Host.cpp b/Source/Core/DolphinQt/Host.cpp index 5eb2055486..036dc2cffa 100644 --- a/Source/Core/DolphinQt/Host.cpp +++ b/Source/Core/DolphinQt/Host.cpp @@ -36,9 +36,9 @@ #include "UICommon/DiscordPresence.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/Fifo.cpp" #include "VideoCommon/Present.h" -#include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoConfig.h" static thread_local bool tls_is_host_thread = false; @@ -150,11 +150,11 @@ bool Host::GetRenderFullFocus() void Host::SetRenderFocus(bool focus) { m_render_focus = focus; - if (g_renderer && m_render_fullscreen && g_ActiveConfig.ExclusiveFullscreenEnabled()) + if (g_gfx && m_render_fullscreen && g_ActiveConfig.ExclusiveFullscreenEnabled()) { RunWithGPUThreadInactive([focus] { if (!Config::Get(Config::MAIN_RENDER_TO_MAIN)) - g_renderer->SetFullscreen(focus); + g_gfx->SetFullscreen(focus); }); } } @@ -182,10 +182,9 @@ void Host::SetRenderFullscreen(bool fullscreen) { m_render_fullscreen = fullscreen; - if (g_renderer && g_renderer->IsFullscreen() != fullscreen && - g_ActiveConfig.ExclusiveFullscreenEnabled()) + if (g_gfx && g_gfx->IsFullscreen() != fullscreen && g_ActiveConfig.ExclusiveFullscreenEnabled()) { - RunWithGPUThreadInactive([fullscreen] { g_renderer->SetFullscreen(fullscreen); }); + RunWithGPUThreadInactive([fullscreen] { g_gfx->SetFullscreen(fullscreen); }); } } diff --git a/Source/Core/VideoCommon/AbstractGfx.cpp b/Source/Core/VideoCommon/AbstractGfx.cpp new file mode 100644 index 0000000000..4406cd46b6 --- /dev/null +++ b/Source/Core/VideoCommon/AbstractGfx.cpp @@ -0,0 +1,138 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "VideoCommon/AbstractGfx.h" + +#include "Common/Assert.h" + +#include "VideoCommon/AbstractFramebuffer.h" +#include "VideoCommon/AbstractTexture.h" +#include "VideoCommon/FramebufferManager.h" +#include "VideoCommon/RenderBase.h" +#include "VideoCommon/ShaderCache.h" +#include "VideoCommon/VertexManagerBase.h" +#include "VideoCommon/VideoConfig.h" + +bool AbstractGfx::IsHeadless() const +{ + return true; +} + +void AbstractGfx::BeginUtilityDrawing() +{ + if (g_renderer) + g_renderer->BeginUtilityDrawing(); +} + +void AbstractGfx::EndUtilityDrawing() +{ + if (g_renderer) + g_renderer->EndUtilityDrawing(); +} + +void AbstractGfx::SetFramebuffer(AbstractFramebuffer* framebuffer) +{ + m_current_framebuffer = framebuffer; +} + +void AbstractGfx::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer) +{ + m_current_framebuffer = framebuffer; +} + +void AbstractGfx::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, + const ClearColor& color_value, float depth_value) +{ + m_current_framebuffer = framebuffer; +} + +void AbstractGfx::ClearRegion(const MathUtil::Rectangle& rc, + const MathUtil::Rectangle& target_rc, bool colorEnable, + bool alphaEnable, bool zEnable, u32 color, u32 z) +{ + g_framebuffer_manager->ClearEFB(rc, colorEnable, alphaEnable, zEnable, color, z); +} + +void AbstractGfx::SetViewportAndScissor(const MathUtil::Rectangle& rect, float min_depth, + float max_depth) +{ + SetViewport(static_cast(rect.left), static_cast(rect.top), + static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), min_depth, + max_depth); + SetScissorRect(rect); +} + +void AbstractGfx::ScaleTexture(AbstractFramebuffer* dst_framebuffer, + const MathUtil::Rectangle& dst_rect, + const AbstractTexture* src_texture, + const MathUtil::Rectangle& src_rect) +{ + ASSERT(dst_framebuffer->GetColorFormat() == AbstractTextureFormat::RGBA8); + + BeginUtilityDrawing(); + + // The shader needs to know the source rectangle. + const auto converted_src_rect = + ConvertFramebufferRectangle(src_rect, src_texture->GetWidth(), src_texture->GetHeight()); + const float rcp_src_width = 1.0f / src_texture->GetWidth(); + const float rcp_src_height = 1.0f / src_texture->GetHeight(); + const std::array uniforms = {{converted_src_rect.left * rcp_src_width, + converted_src_rect.top * rcp_src_height, + converted_src_rect.GetWidth() * rcp_src_width, + converted_src_rect.GetHeight() * rcp_src_height}}; + g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); + + // Discard if we're overwriting the whole thing. + if (static_cast(dst_rect.GetWidth()) == dst_framebuffer->GetWidth() && + static_cast(dst_rect.GetHeight()) == dst_framebuffer->GetHeight()) + { + SetAndDiscardFramebuffer(dst_framebuffer); + } + else + { + SetFramebuffer(dst_framebuffer); + } + + SetViewportAndScissor(ConvertFramebufferRectangle(dst_rect, dst_framebuffer)); + SetPipeline(dst_framebuffer->GetLayers() > 1 ? g_shader_cache->GetRGBA8StereoCopyPipeline() : + g_shader_cache->GetRGBA8CopyPipeline()); + SetTexture(0, src_texture); + SetSamplerState(0, RenderState::GetLinearSamplerState()); + Draw(0, 3); + EndUtilityDrawing(); + if (dst_framebuffer->GetColorAttachment()) + dst_framebuffer->GetColorAttachment()->FinishedRendering(); +} + +MathUtil::Rectangle +AbstractGfx::ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, + const AbstractFramebuffer* framebuffer) const +{ + return ConvertFramebufferRectangle(rect, framebuffer->GetWidth(), framebuffer->GetHeight()); +} + +MathUtil::Rectangle +AbstractGfx::ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, u32 fb_width, + u32 fb_height) const +{ + MathUtil::Rectangle ret = rect; + if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin) + { + ret.top = fb_height - rect.bottom; + ret.bottom = fb_height - rect.top; + } + return ret; +} + +std::unique_ptr AbstractGfx::CreateAsyncShaderCompiler() +{ + return std::make_unique(); +} + +bool AbstractGfx::UseGeometryShaderForUI() const +{ + // OpenGL doesn't render to a 2-layer backbuffer like D3D/Vulkan for quad-buffered stereo, + // instead drawing twice and the eye selected by glDrawBuffer() (see Presenter::RenderXFBToScreen) + return g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer && + g_ActiveConfig.backend_info.api_type != APIType::OpenGL; +} diff --git a/Source/Core/VideoCommon/AbstractGfx.h b/Source/Core/VideoCommon/AbstractGfx.h new file mode 100644 index 0000000000..2db077c98c --- /dev/null +++ b/Source/Core/VideoCommon/AbstractGfx.h @@ -0,0 +1,174 @@ +// Copyright 2023 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "Common/MathUtil.h" + +#include "VideoCommon/RenderState.h" + +#include +#include + +class AbstractFramebuffer; +class AbstractPipeline; +class AbstractShader; +class AbstractTexture; +class AbstractStagingTexture; +class NativeVertexFormat; +struct ComputePipelineConfig; +struct AbstractPipelineConfig; +struct PortableVertexDeclaration; +struct TextureConfig; +enum class AbstractTextureFormat : u32; +enum class ShaderStage; +enum class StagingTextureType; + +struct SurfaceInfo +{ + u32 width = 0; + u32 height = 0; + float scale = 0.0f; + AbstractTextureFormat format = {}; +}; + +namespace VideoCommon +{ +class AsyncShaderCompiler; +} + +// Bitmask containing information about which configuration has changed for the backend. +enum ConfigChangeBits : u32 +{ + CONFIG_CHANGE_BIT_HOST_CONFIG = (1 << 0), + CONFIG_CHANGE_BIT_MULTISAMPLES = (1 << 1), + CONFIG_CHANGE_BIT_STEREO_MODE = (1 << 2), + CONFIG_CHANGE_BIT_TARGET_SIZE = (1 << 3), + CONFIG_CHANGE_BIT_ANISOTROPY = (1 << 4), + CONFIG_CHANGE_BIT_FORCE_TEXTURE_FILTERING = (1 << 5), + CONFIG_CHANGE_BIT_VSYNC = (1 << 6), + CONFIG_CHANGE_BIT_BBOX = (1 << 7) +}; + +using ClearColor = std::array; + +class AbstractGfx +{ +public: + virtual bool IsHeadless() const = 0; + + virtual void SetPipeline(const AbstractPipeline* pipeline) {} + virtual void SetScissorRect(const MathUtil::Rectangle& rc) {} + virtual void SetTexture(u32 index, const AbstractTexture* texture) {} + virtual void SetSamplerState(u32 index, const SamplerState& state) {} + virtual void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) {} + virtual void UnbindTexture(const AbstractTexture* texture) {} + virtual void SetViewport(float x, float y, float width, float height, float near_depth, + float far_depth) + { + } + virtual void SetFullscreen(bool enable_fullscreen) {} + virtual bool IsFullscreen() const { return false; } + virtual void BeginUtilityDrawing(); + virtual void EndUtilityDrawing(); + virtual std::unique_ptr CreateTexture(const TextureConfig& config, + std::string_view name = "") = 0; + virtual std::unique_ptr + CreateStagingTexture(StagingTextureType type, const TextureConfig& config) = 0; + virtual std::unique_ptr + CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) = 0; + + // Framebuffer operations. + virtual void SetFramebuffer(AbstractFramebuffer* framebuffer); + virtual void SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer); + virtual void SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, + const ClearColor& color_value = {}, float depth_value = 0.0f); + + virtual void ClearRegion(const MathUtil::Rectangle& rc, + const MathUtil::Rectangle& target_rc, bool colorEnable, + bool alphaEnable, bool zEnable, u32 color, u32 z); + + // Drawing with currently-bound pipeline state. + virtual void Draw(u32 base_vertex, u32 num_vertices) {} + virtual void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) {} + + // Dispatching compute shaders with currently-bound state. + virtual void DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x, u32 groupsize_y, + u32 groupsize_z, u32 groups_x, u32 groups_y, u32 groups_z) + { + } + + // Binds the backbuffer for rendering. The buffer will be cleared immediately after binding. + // This is where any window size changes are detected, therefore m_backbuffer_width and/or + // m_backbuffer_height may change after this function returns. + virtual void BindBackbuffer(const ClearColor& clear_color = {}) {} + + // Presents the backbuffer to the window system, or "swaps buffers". + virtual void PresentBackbuffer() {} + + // Shader modules/objects. + virtual std::unique_ptr CreateShaderFromSource(ShaderStage stage, + std::string_view source, + std::string_view name = "") = 0; + virtual std::unique_ptr CreateShaderFromBinary(ShaderStage stage, + const void* data, size_t length, + std::string_view name = "") = 0; + virtual std::unique_ptr + CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) = 0; + virtual std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, + const void* cache_data = nullptr, + size_t cache_data_length = 0) = 0; + + AbstractFramebuffer* GetCurrentFramebuffer() const { return m_current_framebuffer; } + + // Sets viewport and scissor to the specified rectangle. rect is assumed to be in framebuffer + // coordinates, i.e. lower-left origin in OpenGL. + void SetViewportAndScissor(const MathUtil::Rectangle& rect, float min_depth = 0.0f, + float max_depth = 1.0f); + + // Scales a GPU texture using a copy shader. + virtual void ScaleTexture(AbstractFramebuffer* dst_framebuffer, + const MathUtil::Rectangle& dst_rect, + const AbstractTexture* src_texture, + const MathUtil::Rectangle& src_rect); + + // Converts an upper-left to lower-left if required by the backend, optionally + // clamping to the framebuffer size. + MathUtil::Rectangle ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, + u32 fb_width, u32 fb_height) const; + MathUtil::Rectangle + ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, + const AbstractFramebuffer* framebuffer) const; + + virtual void Flush() {} + virtual void WaitForGPUIdle() {} + + // For opengl's glDrawBuffer + virtual void SelectLeftBuffer() {} + virtual void SelectRightBuffer() {} + virtual void SelectMainBuffer() {} + + // A simple presentation fallback, only used by video software + virtual void ShowImage(const AbstractTexture* source_texture, + const MathUtil::Rectangle& source_rc) + { + } + + virtual std::unique_ptr CreateAsyncShaderCompiler(); + + // Called when the configuration changes, and backend structures need to be updated. + virtual void OnConfigChanged(u32 bits) {} + + // Returns true if a layer-expanding geometry shader should be used when rendering the user + // interface and final XFB. + bool UseGeometryShaderForUI() const; + + // Returns info about the main surface (aka backbuffer) + virtual SurfaceInfo GetSurfaceInfo() const { return {}; } + +protected: + AbstractFramebuffer* m_current_framebuffer = nullptr; + const AbstractPipeline* m_current_pipeline = nullptr; +}; + +extern std::unique_ptr g_gfx; diff --git a/Source/Core/VideoCommon/AbstractTexture.cpp b/Source/Core/VideoCommon/AbstractTexture.cpp index fb34e2413e..03b83b21cc 100644 --- a/Source/Core/VideoCommon/AbstractTexture.cpp +++ b/Source/Core/VideoCommon/AbstractTexture.cpp @@ -8,8 +8,8 @@ #include "Common/Assert.h" #include "Common/Image.h" #include "Common/MsgHandler.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractStagingTexture.h" -#include "VideoCommon/RenderBase.h" AbstractTexture::AbstractTexture(const TextureConfig& c) : m_config(c) { @@ -36,7 +36,7 @@ bool AbstractTexture::Save(const std::string& filename, unsigned int level) TextureConfig readback_texture_config(level_width, level_height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0); auto readback_texture = - g_renderer->CreateStagingTexture(StagingTextureType::Readback, readback_texture_config); + g_gfx->CreateStagingTexture(StagingTextureType::Readback, readback_texture_config); if (!readback_texture) return false; diff --git a/Source/Core/VideoCommon/BPFunctions.cpp b/Source/Core/VideoCommon/BPFunctions.cpp index c065f1cc5f..a37e3720ff 100644 --- a/Source/Core/VideoCommon/BPFunctions.cpp +++ b/Source/Core/VideoCommon/BPFunctions.cpp @@ -12,6 +12,7 @@ #include "Common/Logging/Log.h" #include "VideoCommon/AbstractFramebuffer.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/FramebufferManager.h" #include "VideoCommon/RenderBase.h" @@ -198,9 +199,8 @@ void SetScissorAndViewport() auto native_rc = ComputeScissorRects().Best(); auto target_rc = g_renderer->ConvertEFBRectangle(native_rc.rect); - auto converted_rc = - g_renderer->ConvertFramebufferRectangle(target_rc, g_renderer->GetCurrentFramebuffer()); - g_renderer->SetScissorRect(converted_rc); + auto converted_rc = g_gfx->ConvertFramebufferRectangle(target_rc, g_gfx->GetCurrentFramebuffer()); + g_gfx->SetScissorRect(converted_rc); float raw_x = (xfmem.viewport.xOrig - native_rc.x_off) - xfmem.viewport.wd; float raw_y = (xfmem.viewport.yOrig - native_rc.y_off) + xfmem.viewport.ht; @@ -280,9 +280,9 @@ void SetScissorAndViewport() // Lower-left flip. if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin) - y = static_cast(g_renderer->GetCurrentFramebuffer()->GetHeight()) - y - height; + y = static_cast(g_gfx->GetCurrentFramebuffer()->GetHeight()) - y - height; - g_renderer->SetViewport(x, y, width, height, near_depth, far_depth); + g_gfx->SetViewport(x, y, width, height, near_depth, far_depth); } void SetDepthMode() diff --git a/Source/Core/VideoCommon/BoundingBox.h b/Source/Core/VideoCommon/BoundingBox.h index bf8ceeb818..d8d2508716 100644 --- a/Source/Core/VideoCommon/BoundingBox.h +++ b/Source/Core/VideoCommon/BoundingBox.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include "Common/CommonTypes.h" @@ -49,3 +50,5 @@ private: std::array m_dirty = {}; bool m_is_valid = true; }; + +extern std::unique_ptr g_bounding_box; diff --git a/Source/Core/VideoCommon/CMakeLists.txt b/Source/Core/VideoCommon/CMakeLists.txt index 20b3257082..4507904afd 100644 --- a/Source/Core/VideoCommon/CMakeLists.txt +++ b/Source/Core/VideoCommon/CMakeLists.txt @@ -1,6 +1,8 @@ add_library(videocommon AbstractFramebuffer.cpp AbstractFramebuffer.h + AbstractGfx.cpp + AbstractGfx.h AbstractShader.h AbstractStagingTexture.cpp AbstractStagingTexture.h diff --git a/Source/Core/VideoCommon/FrameDumper.cpp b/Source/Core/VideoCommon/FrameDumper.cpp index db0d099376..35431a4abf 100644 --- a/Source/Core/VideoCommon/FrameDumper.cpp +++ b/Source/Core/VideoCommon/FrameDumper.cpp @@ -11,6 +11,7 @@ #include "Core/Config/MainSettings.h" #include "VideoCommon/AbstractFramebuffer.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/AbstractTexture.h" #include "VideoCommon/OnScreenDisplay.h" @@ -51,8 +52,8 @@ void FrameDumper::DumpCurrentFrame(const AbstractTexture* src_texture, if (!CheckFrameDumpRenderTexture(target_width, target_height)) return; - g_renderer->ScaleTexture(m_frame_dump_render_framebuffer.get(), - m_frame_dump_render_framebuffer->GetRect(), src_texture, src_rect); + g_gfx->ScaleTexture(m_frame_dump_render_framebuffer.get(), + m_frame_dump_render_framebuffer->GetRect(), src_texture, src_rect); src_texture = m_frame_dump_render_texture.get(); copy_rect = src_texture->GetRect(); } @@ -79,7 +80,7 @@ bool FrameDumper::CheckFrameDumpRenderTexture(u32 target_width, u32 target_heigh // Recreate texture, but release before creating so we don't temporarily use twice the RAM. m_frame_dump_render_framebuffer.reset(); m_frame_dump_render_texture.reset(); - m_frame_dump_render_texture = g_renderer->CreateTexture( + m_frame_dump_render_texture = g_gfx->CreateTexture( TextureConfig(target_width, target_height, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_RenderTarget), "Frame dump render texture"); @@ -89,7 +90,7 @@ bool FrameDumper::CheckFrameDumpRenderTexture(u32 target_width, u32 target_heigh return false; } m_frame_dump_render_framebuffer = - g_renderer->CreateFramebuffer(m_frame_dump_render_texture.get(), nullptr); + g_gfx->CreateFramebuffer(m_frame_dump_render_texture.get(), nullptr); ASSERT(m_frame_dump_render_framebuffer); return true; } @@ -101,7 +102,7 @@ bool FrameDumper::CheckFrameDumpReadbackTexture(u32 target_width, u32 target_hei return true; rbtex.reset(); - rbtex = g_renderer->CreateStagingTexture( + rbtex = g_gfx->CreateStagingTexture( StagingTextureType::Readback, TextureConfig(target_width, target_height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0)); if (!rbtex) diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp index f025b2dfde..861536813e 100644 --- a/Source/Core/VideoCommon/FramebufferManager.cpp +++ b/Source/Core/VideoCommon/FramebufferManager.cpp @@ -11,6 +11,7 @@ #include "Common/MsgHandler.h" #include "Core/Config/GraphicsSettings.h" #include "VideoCommon/AbstractFramebuffer.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractShader.h" #include "VideoCommon/AbstractStagingTexture.h" @@ -171,17 +172,17 @@ bool FramebufferManager::CreateEFBFramebuffer() const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig(); // We need a second texture to swap with for changing pixel formats - m_efb_color_texture = g_renderer->CreateTexture(efb_color_texture_config, "EFB color texture"); - m_efb_depth_texture = g_renderer->CreateTexture(efb_depth_texture_config, "EFB depth texture"); + m_efb_color_texture = g_gfx->CreateTexture(efb_color_texture_config, "EFB color texture"); + m_efb_depth_texture = g_gfx->CreateTexture(efb_depth_texture_config, "EFB depth texture"); m_efb_convert_color_texture = - g_renderer->CreateTexture(efb_color_texture_config, "EFB convert color texture"); + g_gfx->CreateTexture(efb_color_texture_config, "EFB convert color texture"); if (!m_efb_color_texture || !m_efb_depth_texture || !m_efb_convert_color_texture) return false; m_efb_framebuffer = - g_renderer->CreateFramebuffer(m_efb_color_texture.get(), m_efb_depth_texture.get()); + g_gfx->CreateFramebuffer(m_efb_color_texture.get(), m_efb_depth_texture.get()); m_efb_convert_framebuffer = - g_renderer->CreateFramebuffer(m_efb_convert_color_texture.get(), m_efb_depth_texture.get()); + g_gfx->CreateFramebuffer(m_efb_convert_color_texture.get(), m_efb_depth_texture.get()); if (!m_efb_framebuffer || !m_efb_convert_framebuffer) return false; @@ -191,7 +192,7 @@ bool FramebufferManager::CreateEFBFramebuffer() u32 flags = 0; if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve) flags |= AbstractTextureFlag_RenderTarget; - m_efb_resolve_color_texture = g_renderer->CreateTexture( + m_efb_resolve_color_texture = g_gfx->CreateTexture( TextureConfig(efb_color_texture_config.width, efb_color_texture_config.height, 1, efb_color_texture_config.layers, 1, efb_color_texture_config.format, flags), "EFB color resolve texture"); @@ -201,7 +202,7 @@ bool FramebufferManager::CreateEFBFramebuffer() if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve) { m_efb_color_resolve_framebuffer = - g_renderer->CreateFramebuffer(m_efb_resolve_color_texture.get(), nullptr); + g_gfx->CreateFramebuffer(m_efb_resolve_color_texture.get(), nullptr); if (!m_efb_color_resolve_framebuffer) return false; } @@ -210,7 +211,7 @@ bool FramebufferManager::CreateEFBFramebuffer() // We also need one to convert the D24S8 to R32F if that is being used (Adreno). if (g_ActiveConfig.MultisamplingEnabled() || GetEFBDepthFormat() != AbstractTextureFormat::R32F) { - m_efb_depth_resolve_texture = g_renderer->CreateTexture( + m_efb_depth_resolve_texture = g_gfx->CreateTexture( TextureConfig(efb_depth_texture_config.width, efb_depth_texture_config.height, 1, efb_depth_texture_config.layers, 1, GetEFBDepthCopyFormat(), AbstractTextureFlag_RenderTarget), @@ -219,15 +220,15 @@ bool FramebufferManager::CreateEFBFramebuffer() return false; m_efb_depth_resolve_framebuffer = - g_renderer->CreateFramebuffer(m_efb_depth_resolve_texture.get(), nullptr); + g_gfx->CreateFramebuffer(m_efb_depth_resolve_texture.get(), nullptr); if (!m_efb_depth_resolve_framebuffer) return false; } // Clear the renderable textures out. - g_renderer->SetAndClearFramebuffer( - m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}}, - g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f); + g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}}, + g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : + 0.0f); return true; } @@ -245,7 +246,7 @@ void FramebufferManager::DestroyEFBFramebuffer() void FramebufferManager::BindEFBFramebuffer() { - g_renderer->SetFramebuffer(m_efb_framebuffer.get()); + g_gfx->SetFramebuffer(m_efb_framebuffer.get()); } AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rectangle& region) @@ -270,15 +271,15 @@ AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rect else { m_efb_color_texture->FinishedRendering(); - g_renderer->BeginUtilityDrawing(); - g_renderer->SetAndDiscardFramebuffer(m_efb_color_resolve_framebuffer.get()); - g_renderer->SetPipeline(m_efb_color_resolve_pipeline.get()); - g_renderer->SetTexture(0, m_efb_color_texture.get()); - g_renderer->SetSamplerState(0, RenderState::GetPointSamplerState()); - g_renderer->SetViewportAndScissor(clamped_region); - g_renderer->Draw(0, 3); + g_gfx->BeginUtilityDrawing(); + g_gfx->SetAndDiscardFramebuffer(m_efb_color_resolve_framebuffer.get()); + g_gfx->SetPipeline(m_efb_color_resolve_pipeline.get()); + g_gfx->SetTexture(0, m_efb_color_texture.get()); + g_gfx->SetSamplerState(0, RenderState::GetPointSamplerState()); + g_gfx->SetViewportAndScissor(clamped_region); + g_gfx->Draw(0, 3); m_efb_resolve_color_texture->FinishedRendering(); - g_renderer->EndUtilityDrawing(); + g_gfx->EndUtilityDrawing(); } m_efb_resolve_color_texture->FinishedRendering(); return m_efb_resolve_color_texture.get(); @@ -298,16 +299,16 @@ AbstractTexture* FramebufferManager::ResolveEFBDepthTexture(const MathUtil::Rect clamped_region.ClampUL(0, 0, GetEFBWidth(), GetEFBHeight()); m_efb_depth_texture->FinishedRendering(); - g_renderer->BeginUtilityDrawing(); - g_renderer->SetAndDiscardFramebuffer(m_efb_depth_resolve_framebuffer.get()); - g_renderer->SetPipeline(IsEFBMultisampled() ? m_efb_depth_resolve_pipeline.get() : - m_efb_depth_cache.copy_pipeline.get()); - g_renderer->SetTexture(0, m_efb_depth_texture.get()); - g_renderer->SetSamplerState(0, RenderState::GetPointSamplerState()); - g_renderer->SetViewportAndScissor(clamped_region); - g_renderer->Draw(0, 3); + g_gfx->BeginUtilityDrawing(); + g_gfx->SetAndDiscardFramebuffer(m_efb_depth_resolve_framebuffer.get()); + g_gfx->SetPipeline(IsEFBMultisampled() ? m_efb_depth_resolve_pipeline.get() : + m_efb_depth_cache.copy_pipeline.get()); + g_gfx->SetTexture(0, m_efb_depth_texture.get()); + g_gfx->SetSamplerState(0, RenderState::GetPointSamplerState()); + g_gfx->SetViewportAndScissor(clamped_region); + g_gfx->Draw(0, 3); m_efb_depth_resolve_texture->FinishedRendering(); - g_renderer->EndUtilityDrawing(); + g_gfx->EndUtilityDrawing(); return m_efb_depth_resolve_texture.get(); } @@ -322,17 +323,17 @@ bool FramebufferManager::ReinterpretPixelData(EFBReinterpretType convtype) // buffer, which we want to preserve. If we find this to be hindering performance in the // future (e.g. on mobile/tilers), it may be worth discarding only the color buffer. m_efb_color_texture->FinishedRendering(); - g_renderer->BeginUtilityDrawing(); - g_renderer->SetFramebuffer(m_efb_convert_framebuffer.get()); - g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect()); - g_renderer->SetPipeline(m_format_conversion_pipelines[static_cast(convtype)].get()); - g_renderer->SetTexture(0, m_efb_color_texture.get()); - g_renderer->Draw(0, 3); + g_gfx->BeginUtilityDrawing(); + g_gfx->SetFramebuffer(m_efb_convert_framebuffer.get()); + g_gfx->SetViewportAndScissor(m_efb_framebuffer->GetRect()); + g_gfx->SetPipeline(m_format_conversion_pipelines[static_cast(convtype)].get()); + g_gfx->SetTexture(0, m_efb_color_texture.get()); + g_gfx->Draw(0, 3); // And swap the framebuffers around, so we do new drawing to the converted framebuffer. std::swap(m_efb_color_texture, m_efb_convert_color_texture); std::swap(m_efb_framebuffer, m_efb_convert_framebuffer); - g_renderer->EndUtilityDrawing(); + g_gfx->EndUtilityDrawing(); InvalidatePeekCache(true); return true; } @@ -342,7 +343,7 @@ bool FramebufferManager::CompileConversionPipelines() for (u32 i = 0; i < NUM_EFB_REINTERPRET_TYPES; i++) { EFBReinterpretType convtype = static_cast(i); - std::unique_ptr pixel_shader = g_renderer->CreateShaderFromSource( + std::unique_ptr pixel_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, FramebufferShaderGen::GenerateFormatConversionShader(convtype, GetEFBSamples()), fmt::format("Framebuffer conversion pixel shader {}", convtype)); @@ -358,7 +359,7 @@ bool FramebufferManager::CompileConversionPipelines() config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = GetEFBFramebufferState(); config.usage = AbstractPipelineUsage::Utility; - m_format_conversion_pipelines[i] = g_renderer->CreatePipeline(config); + m_format_conversion_pipelines[i] = g_gfx->CreatePipeline(config); if (!m_format_conversion_pipelines[i]) return false; } @@ -493,7 +494,7 @@ void FramebufferManager::RefreshPeekCache() if (flush_command_buffer) { - g_renderer->Flush(); + g_gfx->Flush(); } } @@ -562,33 +563,33 @@ bool FramebufferManager::CompileReadbackPipelines() config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = RenderState::GetColorFramebufferState(GetEFBColorFormat()); config.usage = AbstractPipelineUsage::Utility; - m_efb_color_cache.copy_pipeline = g_renderer->CreatePipeline(config); + m_efb_color_cache.copy_pipeline = g_gfx->CreatePipeline(config); if (!m_efb_color_cache.copy_pipeline) return false; // same for depth, except different format config.framebuffer_state.color_texture_format = GetEFBDepthCopyFormat(); - m_efb_depth_cache.copy_pipeline = g_renderer->CreatePipeline(config); + m_efb_depth_cache.copy_pipeline = g_gfx->CreatePipeline(config); if (!m_efb_depth_cache.copy_pipeline) return false; if (IsEFBMultisampled()) { - auto depth_resolve_shader = g_renderer->CreateShaderFromSource( + auto depth_resolve_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, FramebufferShaderGen::GenerateResolveDepthPixelShader(GetEFBSamples()), "Depth resolve pixel shader"); if (!depth_resolve_shader) return false; config.pixel_shader = depth_resolve_shader.get(); - m_efb_depth_resolve_pipeline = g_renderer->CreatePipeline(config); + m_efb_depth_resolve_pipeline = g_gfx->CreatePipeline(config); if (!m_efb_depth_resolve_pipeline) return false; if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve) { config.framebuffer_state.color_texture_format = GetEFBColorFormat(); - auto color_resolve_shader = g_renderer->CreateShaderFromSource( + auto color_resolve_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, FramebufferShaderGen::GenerateResolveColorPixelShader(GetEFBSamples()), "Color resolve pixel shader"); @@ -596,14 +597,14 @@ bool FramebufferManager::CompileReadbackPipelines() return false; config.pixel_shader = color_resolve_shader.get(); - m_efb_color_resolve_pipeline = g_renderer->CreatePipeline(config); + m_efb_color_resolve_pipeline = g_gfx->CreatePipeline(config); if (!m_efb_color_resolve_pipeline) return false; } } // EFB restore pipeline - auto restore_shader = g_renderer->CreateShaderFromSource( + auto restore_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, FramebufferShaderGen::GenerateEFBRestorePixelShader(), "EFB restore pixel shader"); if (!restore_shader) @@ -614,7 +615,7 @@ bool FramebufferManager::CompileReadbackPipelines() config.framebuffer_state.per_sample_shading = false; config.vertex_shader = g_shader_cache->GetScreenQuadVertexShader(); config.pixel_shader = restore_shader.get(); - m_efb_restore_pipeline = g_renderer->CreatePipeline(config); + m_efb_restore_pipeline = g_gfx->CreatePipeline(config); if (!m_efb_restore_pipeline) return false; @@ -635,12 +636,12 @@ bool FramebufferManager::CreateReadbackFramebuffer() const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, 1, 1, GetEFBColorFormat(), AbstractTextureFlag_RenderTarget); - m_efb_color_cache.texture = g_renderer->CreateTexture(color_config, "EFB color cache"); + m_efb_color_cache.texture = g_gfx->CreateTexture(color_config, "EFB color cache"); if (!m_efb_color_cache.texture) return false; m_efb_color_cache.framebuffer = - g_renderer->CreateFramebuffer(m_efb_color_cache.texture.get(), nullptr); + g_gfx->CreateFramebuffer(m_efb_color_cache.texture.get(), nullptr); if (!m_efb_color_cache.framebuffer) return false; } @@ -657,21 +658,21 @@ bool FramebufferManager::CreateReadbackFramebuffer() IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, 1, 1, GetEFBDepthCopyFormat(), AbstractTextureFlag_RenderTarget); - m_efb_depth_cache.texture = g_renderer->CreateTexture(depth_config, "EFB depth cache"); + m_efb_depth_cache.texture = g_gfx->CreateTexture(depth_config, "EFB depth cache"); if (!m_efb_depth_cache.texture) return false; m_efb_depth_cache.framebuffer = - g_renderer->CreateFramebuffer(m_efb_depth_cache.texture.get(), nullptr); + g_gfx->CreateFramebuffer(m_efb_depth_cache.texture.get(), nullptr); if (!m_efb_depth_cache.framebuffer) return false; } // Staging texture use the full EFB dimensions, as this is the buffer for the whole cache. - m_efb_color_cache.readback_texture = g_renderer->CreateStagingTexture( + m_efb_color_cache.readback_texture = g_gfx->CreateStagingTexture( StagingTextureType::Mutable, TextureConfig(EFB_WIDTH, EFB_HEIGHT, 1, 1, 1, GetEFBColorFormat(), 0)); - m_efb_depth_cache.readback_texture = g_renderer->CreateStagingTexture( + m_efb_depth_cache.readback_texture = g_gfx->CreateStagingTexture( StagingTextureType::Mutable, TextureConfig(EFB_WIDTH, EFB_HEIGHT, 1, 1, 1, GetEFBDepthCopyFormat(), 0)); if (!m_efb_color_cache.readback_texture || !m_efb_depth_cache.readback_texture) @@ -737,7 +738,7 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async // TODO: This won't produce correct results at IRs above 2x. More samples are required. // This is the same issue as with EFB copies. src_texture->FinishedRendering(); - g_renderer->BeginUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); const float rcp_src_width = 1.0f / m_efb_framebuffer->GetWidth(); const float rcp_src_height = 1.0f / m_efb_framebuffer->GetHeight(); @@ -748,14 +749,13 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async // Viewport will not be TILE_SIZExTILE_SIZE for the last row of tiles, assuming a tile size of // 64, because 528 is not evenly divisible by 64. - g_renderer->SetAndDiscardFramebuffer(data.framebuffer.get()); - g_renderer->SetViewportAndScissor( - MathUtil::Rectangle(0, 0, rect.GetWidth(), rect.GetHeight())); - g_renderer->SetPipeline(data.copy_pipeline.get()); - g_renderer->SetTexture(0, src_texture); - g_renderer->SetSamplerState(0, depth ? RenderState::GetPointSamplerState() : - RenderState::GetLinearSamplerState()); - g_renderer->Draw(0, 3); + g_gfx->SetAndDiscardFramebuffer(data.framebuffer.get()); + g_gfx->SetViewportAndScissor(MathUtil::Rectangle(0, 0, rect.GetWidth(), rect.GetHeight())); + g_gfx->SetPipeline(data.copy_pipeline.get()); + g_gfx->SetTexture(0, src_texture); + g_gfx->SetSamplerState(0, depth ? RenderState::GetPointSamplerState() : + RenderState::GetLinearSamplerState()); + g_gfx->Draw(0, 3); // Copy from EFB or copy texture to staging texture. // No need to call FinishedRendering() here because CopyFromTexture() transitions. @@ -763,7 +763,7 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async data.texture.get(), MathUtil::Rectangle(0, 0, rect.GetWidth(), rect.GetHeight()), 0, 0, rect); - g_renderer->EndUtilityDrawing(); + g_gfx->EndUtilityDrawing(); } else { @@ -790,7 +790,7 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle& rc, bool clear { FlushEFBPokes(); FlagPeekCacheAsOutOfDate(); - g_renderer->BeginUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); // Set up uniforms. struct Uniforms @@ -809,17 +809,17 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle& rc, bool clear uniforms.clear_depth = 1.0f - uniforms.clear_depth; g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); - const auto target_rc = g_renderer->ConvertFramebufferRectangle( - g_renderer->ConvertEFBRectangle(rc), m_efb_framebuffer.get()); - g_renderer->SetPipeline(m_efb_clear_pipelines[clear_color][clear_alpha][clear_z].get()); - g_renderer->SetViewportAndScissor(target_rc); - g_renderer->Draw(0, 3); - g_renderer->EndUtilityDrawing(); + const auto target_rc = g_gfx->ConvertFramebufferRectangle(g_renderer->ConvertEFBRectangle(rc), + m_efb_framebuffer.get()); + g_gfx->SetPipeline(m_efb_clear_pipelines[clear_color][clear_alpha][clear_z].get()); + g_gfx->SetViewportAndScissor(target_rc); + g_gfx->Draw(0, 3); + g_gfx->EndUtilityDrawing(); } bool FramebufferManager::CompileClearPipelines() { - auto vertex_shader = g_renderer->CreateShaderFromSource( + auto vertex_shader = g_gfx->CreateShaderFromSource( ShaderStage::Vertex, FramebufferShaderGen::GenerateClearVertexShader(), "Clear vertex shader"); if (!vertex_shader) @@ -848,7 +848,7 @@ bool FramebufferManager::CompileClearPipelines() config.depth_state.updateenable = depth_enable != 0; m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable] = - g_renderer->CreatePipeline(config); + g_gfx->CreatePipeline(config); if (!m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable]) return false; } @@ -957,17 +957,17 @@ void FramebufferManager::DrawPokeVertices(const EFBPokeVertex* vertices, u32 ver const AbstractPipeline* pipeline) { // Copy to vertex buffer. - g_renderer->BeginUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); u32 base_vertex, base_index; g_vertex_manager->UploadUtilityVertices(vertices, sizeof(EFBPokeVertex), static_cast(vertex_count), nullptr, 0, &base_vertex, &base_index); // Now we can draw. - g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect()); - g_renderer->SetPipeline(pipeline); - g_renderer->Draw(base_vertex, vertex_count); - g_renderer->EndUtilityDrawing(); + g_gfx->SetViewportAndScissor(m_efb_framebuffer->GetRect()); + g_gfx->SetPipeline(pipeline); + g_gfx->Draw(base_vertex, vertex_count); + g_gfx->EndUtilityDrawing(); } bool FramebufferManager::CompilePokePipelines() @@ -985,11 +985,11 @@ bool FramebufferManager::CompilePokePipelines() vtx_decl.colors[0].offset = offsetof(EFBPokeVertex, color); vtx_decl.stride = sizeof(EFBPokeVertex); - m_poke_vertex_format = g_renderer->CreateNativeVertexFormat(vtx_decl); + m_poke_vertex_format = g_gfx->CreateNativeVertexFormat(vtx_decl); if (!m_poke_vertex_format) return false; - auto poke_vertex_shader = g_renderer->CreateShaderFromSource( + auto poke_vertex_shader = g_gfx->CreateShaderFromSource( ShaderStage::Vertex, FramebufferShaderGen::GenerateEFBPokeVertexShader(), "EFB poke vertex shader"); if (!poke_vertex_shader) @@ -1007,14 +1007,14 @@ bool FramebufferManager::CompilePokePipelines() config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = GetEFBFramebufferState(); config.usage = AbstractPipelineUsage::Utility; - m_color_poke_pipeline = g_renderer->CreatePipeline(config); + m_color_poke_pipeline = g_gfx->CreatePipeline(config); if (!m_color_poke_pipeline) return false; // Turn off color writes, depth writes on for depth pokes. config.depth_state = RenderState::GetAlwaysWriteDepthState(); config.blending_state = RenderState::GetNoColorWriteBlendState(); - m_depth_poke_pipeline = g_renderer->CreatePipeline(config); + m_depth_poke_pipeline = g_gfx->CreatePipeline(config); if (!m_depth_poke_pipeline) return false; @@ -1077,9 +1077,9 @@ void FramebufferManager::DoLoadState(PointerWrap& p) color_tex->texture->GetLayers() != m_efb_color_texture->GetLayers()) { WARN_LOG_FMT(VIDEO, "Failed to deserialize EFB contents. Clearing instead."); - g_renderer->SetAndClearFramebuffer( - m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}}, - g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f); + g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}}, + g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : + 0.0f); return; } @@ -1089,15 +1089,15 @@ void FramebufferManager::DoLoadState(PointerWrap& p) color_tex->texture->GetHeight() != m_efb_color_texture->GetHeight(); // Draw the deserialized textures over the EFB. - g_renderer->BeginUtilityDrawing(); - g_renderer->SetAndDiscardFramebuffer(m_efb_framebuffer.get()); - g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect()); - g_renderer->SetPipeline(m_efb_restore_pipeline.get()); - g_renderer->SetTexture(0, color_tex->texture.get()); - g_renderer->SetTexture(1, depth_tex->texture.get()); - g_renderer->SetSamplerState(0, rescale ? RenderState::GetLinearSamplerState() : - RenderState::GetPointSamplerState()); - g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); - g_renderer->Draw(0, 3); - g_renderer->EndUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); + g_gfx->SetAndDiscardFramebuffer(m_efb_framebuffer.get()); + g_gfx->SetViewportAndScissor(m_efb_framebuffer->GetRect()); + g_gfx->SetPipeline(m_efb_restore_pipeline.get()); + g_gfx->SetTexture(0, color_tex->texture.get()); + g_gfx->SetTexture(1, depth_tex->texture.get()); + g_gfx->SetSamplerState(0, rescale ? RenderState::GetLinearSamplerState() : + RenderState::GetPointSamplerState()); + g_gfx->SetSamplerState(1, RenderState::GetPointSamplerState()); + g_gfx->Draw(0, 3); + g_gfx->EndUtilityDrawing(); } diff --git a/Source/Core/VideoCommon/OnScreenUI.cpp b/Source/Core/VideoCommon/OnScreenUI.cpp index 72f0c8f08a..291f0c23e2 100644 --- a/Source/Core/VideoCommon/OnScreenUI.cpp +++ b/Source/Core/VideoCommon/OnScreenUI.cpp @@ -10,6 +10,7 @@ #include "Core/Config/NetplaySettings.h" #include "Core/Movie.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractShader.h" #include "VideoCommon/FramebufferShaderGen.h" @@ -18,7 +19,6 @@ #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PerformanceMetrics.h" #include "VideoCommon/Present.h" -#include "VideoCommon/RenderBase.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoConfig.h" @@ -61,7 +61,7 @@ bool OnScreenUI::Initialize(u32 width, u32 height, float scale) vdecl.texcoords[0] = {ComponentFormat::Float, 2, offsetof(ImDrawVert, uv), true, false}; vdecl.colors[0] = {ComponentFormat::UByte, 4, offsetof(ImDrawVert, col), true, false}; vdecl.stride = sizeof(ImDrawVert); - m_imgui_vertex_format = g_renderer->CreateNativeVertexFormat(vdecl); + m_imgui_vertex_format = g_gfx->CreateNativeVertexFormat(vdecl); if (!m_imgui_vertex_format) { PanicAlertFmt("Failed to create ImGui vertex format"); @@ -78,7 +78,7 @@ bool OnScreenUI::Initialize(u32 width, u32 height, float scale) TextureConfig font_tex_config(font_tex_width, font_tex_height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0); std::unique_ptr font_tex = - g_renderer->CreateTexture(font_tex_config, "ImGui font texture"); + g_gfx->CreateTexture(font_tex_config, "ImGui font texture"); if (!font_tex) { PanicAlertFmt("Failed to create ImGui texture"); @@ -120,10 +120,10 @@ bool OnScreenUI::RecompileImGuiPipeline() return true; } - std::unique_ptr vertex_shader = g_renderer->CreateShaderFromSource( + std::unique_ptr vertex_shader = g_gfx->CreateShaderFromSource( ShaderStage::Vertex, FramebufferShaderGen::GenerateImGuiVertexShader(), "ImGui vertex shader"); - std::unique_ptr pixel_shader = g_renderer->CreateShaderFromSource( + std::unique_ptr pixel_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, FramebufferShaderGen::GenerateImGuiPixelShader(), "ImGui pixel shader"); if (!vertex_shader || !pixel_shader) { @@ -133,9 +133,9 @@ bool OnScreenUI::RecompileImGuiPipeline() // GS is used to render the UI to both eyes in stereo modes. std::unique_ptr geometry_shader; - if (g_renderer->UseGeometryShaderForUI()) + if (g_gfx->UseGeometryShaderForUI()) { - geometry_shader = g_renderer->CreateShaderFromSource( + geometry_shader = g_gfx->CreateShaderFromSource( ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(1, 1), "ImGui passthrough geometry shader"); if (!geometry_shader) @@ -163,7 +163,7 @@ bool OnScreenUI::RecompileImGuiPipeline() pconfig.framebuffer_state.samples = 1; pconfig.framebuffer_state.per_sample_shading = false; pconfig.usage = AbstractPipelineUsage::Utility; - m_imgui_pipeline = g_renderer->CreatePipeline(pconfig); + m_imgui_pipeline = g_gfx->CreatePipeline(pconfig); if (!m_imgui_pipeline) { PanicAlertFmt("Failed to create imgui pipeline"); @@ -204,8 +204,8 @@ void OnScreenUI::DrawImGui() if (!draw_data) return; - g_renderer->SetViewport(0.0f, 0.0f, static_cast(m_backbuffer_width), - static_cast(m_backbuffer_height), 0.0f, 1.0f); + g_gfx->SetViewport(0.0f, 0.0f, static_cast(m_backbuffer_width), + static_cast(m_backbuffer_height), 0.0f, 1.0f); // Uniform buffer for draws. struct ImGuiUbo @@ -216,8 +216,8 @@ void OnScreenUI::DrawImGui() ImGuiUbo ubo = {{1.0f / m_backbuffer_width * 2.0f, 1.0f / m_backbuffer_height * 2.0f}}; // Set up common state for drawing. - g_renderer->SetPipeline(m_imgui_pipeline.get()); - g_renderer->SetSamplerState(0, RenderState::GetPointSamplerState()); + g_gfx->SetPipeline(m_imgui_pipeline.get()); + g_gfx->SetSamplerState(0, RenderState::GetPointSamplerState()); g_vertex_manager->UploadUtilityUniforms(&ubo, sizeof(ubo)); for (int i = 0; i < draw_data->CmdListsCount; i++) @@ -239,13 +239,13 @@ void OnScreenUI::DrawImGui() continue; } - g_renderer->SetScissorRect(g_renderer->ConvertFramebufferRectangle( + g_gfx->SetScissorRect(g_gfx->ConvertFramebufferRectangle( MathUtil::Rectangle( static_cast(cmd.ClipRect.x), static_cast(cmd.ClipRect.y), static_cast(cmd.ClipRect.z), static_cast(cmd.ClipRect.w)), - g_renderer->GetCurrentFramebuffer())); - g_renderer->SetTexture(0, reinterpret_cast(cmd.TextureId)); - g_renderer->DrawIndexed(base_index, cmd.ElemCount, base_vertex); + g_gfx->GetCurrentFramebuffer())); + g_gfx->SetTexture(0, reinterpret_cast(cmd.TextureId)); + g_gfx->DrawIndexed(base_index, cmd.ElemCount, base_vertex); base_index += cmd.ElemCount; } } @@ -255,9 +255,9 @@ void OnScreenUI::DrawImGui() // itself will be clipped to whatever bounds were last set by ImGui, resulting in a rather useless // capture whenever any ImGui windows are open. We'll reset the scissor rectangle to the entire // viewport here to avoid this problem. - g_renderer->SetScissorRect(g_renderer->ConvertFramebufferRectangle( + g_gfx->SetScissorRect(g_gfx->ConvertFramebufferRectangle( MathUtil::Rectangle(0, 0, m_backbuffer_width, m_backbuffer_height), - g_renderer->GetCurrentFramebuffer())); + g_gfx->GetCurrentFramebuffer())); } // Create On-Screen-Messages diff --git a/Source/Core/VideoCommon/PostProcessing.cpp b/Source/Core/VideoCommon/PostProcessing.cpp index f14b8f892b..7f4faed582 100644 --- a/Source/Core/VideoCommon/PostProcessing.cpp +++ b/Source/Core/VideoCommon/PostProcessing.cpp @@ -20,12 +20,12 @@ #include "Common/StringUtil.h" #include "VideoCommon/AbstractFramebuffer.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractShader.h" #include "VideoCommon/AbstractTexture.h" #include "VideoCommon/FramebufferManager.h" #include "VideoCommon/Present.h" -#include "VideoCommon/RenderBase.h" #include "VideoCommon/ShaderCache.h" #include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VideoCommon.h" @@ -417,9 +417,9 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle& dst, const MathUtil::Rectangle& src, const AbstractTexture* src_tex, int src_layer) { - if (g_renderer->GetCurrentFramebuffer()->GetColorFormat() != m_framebuffer_format) + if (g_gfx->GetCurrentFramebuffer()->GetColorFormat() != m_framebuffer_format) { - m_framebuffer_format = g_renderer->GetCurrentFramebuffer()->GetColorFormat(); + m_framebuffer_format = g_gfx->GetCurrentFramebuffer()->GetColorFormat(); RecompilePipeline(); } @@ -430,12 +430,12 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle& dst, g_vertex_manager->UploadUtilityUniforms(m_uniform_staging_buffer.data(), static_cast(m_uniform_staging_buffer.size())); - g_renderer->SetViewportAndScissor( - g_renderer->ConvertFramebufferRectangle(dst, g_renderer->GetCurrentFramebuffer())); - g_renderer->SetPipeline(m_pipeline.get()); - g_renderer->SetTexture(0, src_tex); - g_renderer->SetSamplerState(0, RenderState::GetLinearSamplerState()); - g_renderer->Draw(0, 3); + g_gfx->SetViewportAndScissor( + g_gfx->ConvertFramebufferRectangle(dst, g_gfx->GetCurrentFramebuffer())); + g_gfx->SetPipeline(m_pipeline.get()); + g_gfx->SetTexture(0, src_tex); + g_gfx->SetSamplerState(0, RenderState::GetLinearSamplerState()); + g_gfx->Draw(0, 3); } std::string PostProcessing::GetUniformBufferHeader() const @@ -598,8 +598,8 @@ bool PostProcessing::CompileVertexShader() ss << "}\n"; - m_vertex_shader = g_renderer->CreateShaderFromSource(ShaderStage::Vertex, ss.str(), - "Post-processing vertex shader"); + m_vertex_shader = + g_gfx->CreateShaderFromSource(ShaderStage::Vertex, ss.str(), "Post-processing vertex shader"); if (!m_vertex_shader) { PanicAlertFmt("Failed to compile post-processing vertex shader"); @@ -688,7 +688,7 @@ bool PostProcessing::CompilePixelShader() // Generate GLSL and compile the new shader. m_config.LoadShader(g_ActiveConfig.sPostProcessingShader); - m_pixel_shader = g_renderer->CreateShaderFromSource( + m_pixel_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, GetHeader() + m_config.GetShaderCode() + GetFooter(), fmt::format("Post-processing pixel shader: {}", m_config.GetShader())); if (!m_pixel_shader) @@ -697,7 +697,7 @@ bool PostProcessing::CompilePixelShader() // Use default shader. m_config.LoadDefaultShader(); - m_pixel_shader = g_renderer->CreateShaderFromSource( + m_pixel_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, GetHeader() + m_config.GetShaderCode() + GetFooter(), "Default post-processing pixel shader"); if (!m_pixel_shader) @@ -716,14 +716,14 @@ bool PostProcessing::CompilePipeline() AbstractPipelineConfig config = {}; config.vertex_shader = m_vertex_shader.get(); config.geometry_shader = - g_renderer->UseGeometryShaderForUI() ? g_shader_cache->GetTexcoordGeometryShader() : nullptr; + g_gfx->UseGeometryShaderForUI() ? g_shader_cache->GetTexcoordGeometryShader() : nullptr; config.pixel_shader = m_pixel_shader.get(); config.rasterization_state = RenderState::GetNoCullRasterizationState(PrimitiveType::Triangles); config.depth_state = RenderState::GetNoDepthTestingDepthState(); config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = RenderState::GetColorFramebufferState(m_framebuffer_format); config.usage = AbstractPipelineUsage::Utility; - m_pipeline = g_renderer->CreatePipeline(config); + m_pipeline = g_gfx->CreatePipeline(config); if (!m_pipeline) return false; diff --git a/Source/Core/VideoCommon/Present.cpp b/Source/Core/VideoCommon/Present.cpp index 5cddf38aa3..8f10707d0d 100644 --- a/Source/Core/VideoCommon/Present.cpp +++ b/Source/Core/VideoCommon/Present.cpp @@ -8,6 +8,7 @@ #include "InputCommon/ControllerInterface/ControllerInterface.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/FrameDumper.h" #include "VideoCommon/OnScreenUI.h" #include "VideoCommon/PostProcessing.h" @@ -47,6 +48,9 @@ bool Presenter::Initialize() if (!m_onscreen_ui->Initialize(m_backbuffer_width, m_backbuffer_height, m_backbuffer_scale)) return false; + if (!g_gfx->IsHeadless()) + SetBackbuffer(g_gfx->GetSurfaceInfo()); + return true; } @@ -57,13 +61,12 @@ void Presenter::SetBackbuffer(int backbuffer_width, int backbuffer_height) UpdateDrawRectangle(); } -void Presenter::SetBackbuffer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, - AbstractTextureFormat backbuffer_format) +void Presenter::SetBackbuffer(SurfaceInfo info) { - m_backbuffer_width = backbuffer_width; - m_backbuffer_height = backbuffer_height; - m_backbuffer_scale = backbuffer_scale; - m_backbuffer_format = backbuffer_format; + m_backbuffer_width = info.width; + m_backbuffer_height = info.height; + m_backbuffer_scale = info.scale; + m_backbuffer_format = info.format; UpdateDrawRectangle(); } @@ -74,14 +77,14 @@ void Presenter::CheckForConfigChanges(u32 changed_bits) if (m_post_processor->GetConfig()->GetShader() != g_ActiveConfig.sPostProcessingShader) { // The existing shader must not be in use when it's destroyed - g_renderer->WaitForGPUIdle(); + g_gfx->WaitForGPUIdle(); m_post_processor->RecompileShader(); } // Stereo mode change requires recompiling our post processing pipeline and imgui pipelines for // rendering the UI. - if (changed_bits & Renderer::ConfigChangeBits::CONFIG_CHANGE_BIT_STEREO_MODE) + if (changed_bits & ConfigChangeBits::CONFIG_CHANGE_BIT_STEREO_MODE) { m_onscreen_ui->RecompileImGuiPipeline(); m_post_processor->RecompilePipeline(); @@ -90,24 +93,24 @@ void Presenter::CheckForConfigChanges(u32 changed_bits) void Presenter::BeginUIFrame() { - if (g_renderer->IsHeadless()) + if (g_gfx->IsHeadless()) return; - g_renderer->BeginUtilityDrawing(); - g_renderer->BindBackbuffer({0.0f, 0.0f, 0.0f, 1.0f}); + g_gfx->BeginUtilityDrawing(); + g_gfx->BindBackbuffer({0.0f, 0.0f, 0.0f, 1.0f}); } void Presenter::EndUIFrame() { m_onscreen_ui->Finalize(); - if (g_renderer->IsHeadless()) + if (g_gfx->IsHeadless()) { m_onscreen_ui->DrawImGui(); std::lock_guard guard(m_swap_mutex); - g_renderer->PresentBackbuffer(); - g_renderer->EndUtilityDrawing(); + g_gfx->PresentBackbuffer(); + g_gfx->EndUtilityDrawing(); } m_onscreen_ui->BeginImGuiFrame(m_backbuffer_width, m_backbuffer_height); @@ -392,7 +395,7 @@ void Presenter::RenderXFBToScreen(const MathUtil::Rectangle& target_rc, { if (!g_ActiveConfig.backend_info.bSupportsPostProcessing) { - g_renderer->ShowImage(source_texture, source_rc); + g_gfx->ShowImage(source_texture, source_rc); return; } @@ -400,13 +403,13 @@ void Presenter::RenderXFBToScreen(const MathUtil::Rectangle& target_rc, g_ActiveConfig.backend_info.bUsesExplictQuadBuffering) { // Quad-buffered stereo is annoying on GL. - g_renderer->SelectLeftBuffer(); + g_gfx->SelectLeftBuffer(); m_post_processor->BlitFromTexture(target_rc, source_rc, source_texture, 0); - g_renderer->SelectRightBuffer(); + g_gfx->SelectRightBuffer(); m_post_processor->BlitFromTexture(target_rc, source_rc, source_texture, 1); - g_renderer->SelectMainBuffer(); + g_gfx->SelectMainBuffer(); } else if (g_ActiveConfig.stereo_mode == StereoMode::SBS || g_ActiveConfig.stereo_mode == StereoMode::TAB) @@ -436,7 +439,7 @@ bool Presenter::SubmitXFB(RcTcacheEntry xfb_entry, MathUtil::Rectangle& xfb if (g_frame_dumper->IsFrameDumping()) { MathUtil::Rectangle target_rect; - if (!g_ActiveConfig.bInternalResolutionFrameDumps && !g_renderer->IsHeadless()) + if (!g_ActiveConfig.bInternalResolutionFrameDumps && !g_gfx->IsHeadless()) { target_rect = GetTargetRectangle(); } @@ -469,10 +472,10 @@ void Presenter::Present() m_onscreen_ui->Finalize(); // Render the XFB to the screen. - g_renderer->BeginUtilityDrawing(); - if (!g_renderer->IsHeadless()) + g_gfx->BeginUtilityDrawing(); + if (!g_gfx->IsHeadless()) { - g_renderer->BindBackbuffer({{0.0f, 0.0f, 0.0f, 1.0f}}); + g_gfx->BindBackbuffer({{0.0f, 0.0f, 0.0f, 1.0f}}); UpdateDrawRectangle(); @@ -488,7 +491,7 @@ void Presenter::Present() // Present to the window system. { std::lock_guard guard(m_swap_mutex); - g_renderer->PresentBackbuffer(); + g_gfx->PresentBackbuffer(); } // Update the window size based on the frame that was just rendered. @@ -498,7 +501,7 @@ void Presenter::Present() m_onscreen_ui->BeginImGuiFrame(m_backbuffer_width, m_backbuffer_height); - g_renderer->EndUtilityDrawing(); + g_gfx->EndUtilityDrawing(); } void Presenter::SetKeyMap(std::span> key_map) diff --git a/Source/Core/VideoCommon/Present.h b/Source/Core/VideoCommon/Present.h index 5f535f7208..3b99c3207d 100644 --- a/Source/Core/VideoCommon/Present.h +++ b/Source/Core/VideoCommon/Present.h @@ -16,6 +16,7 @@ #include class AbstractTexture; +struct SurfaceInfo; namespace VideoCommon { @@ -51,8 +52,7 @@ public: AbstractTextureFormat GetBackbufferFormat() const { return m_backbuffer_format; } void SetWindowSize(int width, int height); void SetBackbuffer(int backbuffer_width, int backbuffer_height); - void SetBackbuffer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, - AbstractTextureFormat backbuffer_format); + void SetBackbuffer(SurfaceInfo info); void UpdateDrawRectangle(); diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp index 86725f534e..ec5f25267f 100644 --- a/Source/Core/VideoCommon/RenderBase.cpp +++ b/Source/Core/VideoCommon/RenderBase.cpp @@ -38,6 +38,7 @@ #include "Core/System.h" #include "VideoCommon/AbstractFramebuffer.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractTexture.h" #include "VideoCommon/BoundingBox.h" #include "VideoCommon/CommandProcessor.h" @@ -59,17 +60,12 @@ std::unique_ptr g_renderer; -Renderer::Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, - AbstractTextureFormat backbuffer_format) - : m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT} +Renderer::Renderer() : m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT} { UpdateActiveConfig(); FreeLook::UpdateActiveConfig(); CalculateTargetSize(); - g_presenter->SetBackbuffer(backbuffer_width, backbuffer_height, backbuffer_scale, - backbuffer_format); - m_is_game_widescreen = SConfig::GetInstance().bWii && Config::Get(Config::SYSCONF_WIDESCREEN); g_freelook_camera.SetControlType(FreeLook::GetActiveConfig().camera_config.control_type); } @@ -78,13 +74,6 @@ Renderer::~Renderer() = default; bool Renderer::Initialize() { - m_bounding_box = CreateBoundingBox(); - if (g_ActiveConfig.backend_info.bSupportsBBox && !m_bounding_box->Initialize()) - { - PanicAlertFmt("Failed to initialize bounding box."); - return false; - } - if (g_ActiveConfig.bGraphicMods) { // If a config change occurred in a previous session, @@ -101,12 +90,12 @@ bool Renderer::Initialize() m_graphics_mod_manager.Load(*g_ActiveConfig.graphics_mod_config); } - return g_presenter->Initialize(); + return true; } void Renderer::Shutdown() { - m_bounding_box.reset(); + g_bounding_box.reset(); } void Renderer::BeginUtilityDrawing() @@ -121,31 +110,38 @@ void Renderer::EndUtilityDrawing() BPFunctions::SetScissorAndViewport(); } -void Renderer::SetFramebuffer(AbstractFramebuffer* framebuffer) -{ - m_current_framebuffer = framebuffer; -} - -void Renderer::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer) -{ - m_current_framebuffer = framebuffer; -} - -void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, - const ClearColor& color_value, float depth_value) -{ - m_current_framebuffer = framebuffer; -} - bool Renderer::EFBHasAlphaChannel() const { return m_prev_efb_format == PixelFormat::RGBA6_Z24; } -void Renderer::ClearScreen(const MathUtil::Rectangle& rc, bool colorEnable, bool alphaEnable, - bool zEnable, u32 color, u32 z) +void Renderer::ClearScreen(const MathUtil::Rectangle& rc, bool color_enable, bool alpha_enable, + bool z_enable, u32 color, u32 z) { - g_framebuffer_manager->ClearEFB(rc, colorEnable, alphaEnable, zEnable, color, z); + g_framebuffer_manager->FlushEFBPokes(); + g_framebuffer_manager->FlagPeekCacheAsOutOfDate(); + + // Native -> EFB coordinates + MathUtil::Rectangle target_rc = Renderer::ConvertEFBRectangle(rc); + target_rc.ClampUL(0, 0, m_target_width, m_target_height); + + // Determine whether the EFB has an alpha channel. If it doesn't, we can clear the alpha + // channel to 0xFF. + // On backends that don't allow masking Alpha clears, this allows us to use the fast path + // almost all the time + if (bpmem.zcontrol.pixel_format == PixelFormat::RGB565_Z16 || + bpmem.zcontrol.pixel_format == PixelFormat::RGB8_Z24 || + bpmem.zcontrol.pixel_format == PixelFormat::Z24) + { + // Force alpha writes, and clear the alpha channel. + alpha_enable = true; + color &= 0x00FFFFFF; + } + + g_gfx->ClearRegion(rc, target_rc, color_enable, alpha_enable, z_enable, color, z); + + // Scissor rect must be restored. + BPFunctions::SetScissorAndViewport(); } void Renderer::ReinterpretPixelData(EFBReinterpretType convtype) @@ -155,17 +151,17 @@ void Renderer::ReinterpretPixelData(EFBReinterpretType convtype) bool Renderer::IsBBoxEnabled() const { - return m_bounding_box->IsEnabled(); + return g_bounding_box->IsEnabled(); } void Renderer::BBoxEnable(PixelShaderManager& pixel_shader_manager) { - m_bounding_box->Enable(pixel_shader_manager); + g_bounding_box->Enable(pixel_shader_manager); } void Renderer::BBoxDisable(PixelShaderManager& pixel_shader_manager) { - m_bounding_box->Disable(pixel_shader_manager); + g_bounding_box->Disable(pixel_shader_manager); } u16 Renderer::BBoxRead(u32 index) @@ -173,7 +169,7 @@ u16 Renderer::BBoxRead(u32 index) if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) return m_bounding_box_fallback[index]; - return m_bounding_box->Get(index); + return g_bounding_box->Get(index); } void Renderer::BBoxWrite(u32 index, u16 value) @@ -184,7 +180,7 @@ void Renderer::BBoxWrite(u32 index, u16 value) return; } - m_bounding_box->Set(index, value); + g_bounding_box->Set(index, value); } void Renderer::BBoxFlush() @@ -192,7 +188,7 @@ void Renderer::BBoxFlush() if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) return; - m_bounding_box->Flush(); + g_bounding_box->Flush(); } u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) @@ -436,13 +432,13 @@ void Renderer::CheckForConfigChanges() return; // Notify the backend of the changes, if any. - OnConfigChanged(changed_bits); + g_gfx->OnConfigChanged(changed_bits); // If there's any shader changes, wait for the GPU to finish before destroying anything. if (changed_bits & (CONFIG_CHANGE_BIT_HOST_CONFIG | CONFIG_CHANGE_BIT_MULTISAMPLES)) { - WaitForGPUIdle(); - SetPipeline(nullptr); + g_gfx->WaitForGPUIdle(); + g_gfx->SetPipeline(nullptr); } // Framebuffer changed? @@ -469,81 +465,6 @@ void Renderer::CheckForConfigChanges() } } -bool Renderer::IsHeadless() const -{ - return true; -} - -void Renderer::SetViewportAndScissor(const MathUtil::Rectangle& rect, float min_depth, - float max_depth) -{ - SetViewport(static_cast(rect.left), static_cast(rect.top), - static_cast(rect.GetWidth()), static_cast(rect.GetHeight()), min_depth, - max_depth); - SetScissorRect(rect); -} - -void Renderer::ScaleTexture(AbstractFramebuffer* dst_framebuffer, - const MathUtil::Rectangle& dst_rect, - const AbstractTexture* src_texture, - const MathUtil::Rectangle& src_rect) -{ - ASSERT(dst_framebuffer->GetColorFormat() == AbstractTextureFormat::RGBA8); - - BeginUtilityDrawing(); - - // The shader needs to know the source rectangle. - const auto converted_src_rect = - ConvertFramebufferRectangle(src_rect, src_texture->GetWidth(), src_texture->GetHeight()); - const float rcp_src_width = 1.0f / src_texture->GetWidth(); - const float rcp_src_height = 1.0f / src_texture->GetHeight(); - const std::array uniforms = {{converted_src_rect.left * rcp_src_width, - converted_src_rect.top * rcp_src_height, - converted_src_rect.GetWidth() * rcp_src_width, - converted_src_rect.GetHeight() * rcp_src_height}}; - g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); - - // Discard if we're overwriting the whole thing. - if (static_cast(dst_rect.GetWidth()) == dst_framebuffer->GetWidth() && - static_cast(dst_rect.GetHeight()) == dst_framebuffer->GetHeight()) - { - SetAndDiscardFramebuffer(dst_framebuffer); - } - else - { - SetFramebuffer(dst_framebuffer); - } - - SetViewportAndScissor(ConvertFramebufferRectangle(dst_rect, dst_framebuffer)); - SetPipeline(dst_framebuffer->GetLayers() > 1 ? g_shader_cache->GetRGBA8StereoCopyPipeline() : - g_shader_cache->GetRGBA8CopyPipeline()); - SetTexture(0, src_texture); - SetSamplerState(0, RenderState::GetLinearSamplerState()); - Draw(0, 3); - EndUtilityDrawing(); - if (dst_framebuffer->GetColorAttachment()) - dst_framebuffer->GetColorAttachment()->FinishedRendering(); -} - -MathUtil::Rectangle -Renderer::ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, - const AbstractFramebuffer* framebuffer) const -{ - return ConvertFramebufferRectangle(rect, framebuffer->GetWidth(), framebuffer->GetHeight()); -} - -MathUtil::Rectangle Renderer::ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, - u32 fb_width, u32 fb_height) const -{ - MathUtil::Rectangle ret = rect; - if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin) - { - ret.top = fb_height - rect.bottom; - ret.bottom = fb_height - rect.top; - } - return ret; -} - MathUtil::Rectangle Renderer::ConvertEFBRectangle(const MathUtil::Rectangle& rc) const { MathUtil::Rectangle result; @@ -590,14 +511,6 @@ void Renderer::RecordVideoMemory() texMem); } -bool Renderer::UseGeometryShaderForUI() const -{ - // OpenGL doesn't render to a 2-layer backbuffer like D3D/Vulkan for quad-buffered stereo, - // instead drawing twice and the eye selected by glDrawBuffer() (see Presenter::RenderXFBToScreen) - return g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer && - g_ActiveConfig.backend_info.api_type != APIType::OpenGL; -} - void Renderer::ForceReloadTextures() { m_force_reload_textures.Set(); @@ -756,7 +669,7 @@ void Renderer::Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u6 } else { - Flush(); + g_gfx->Flush(); } // Update our last xfb values @@ -768,7 +681,7 @@ void Renderer::Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u6 } else { - Flush(); + g_gfx->Flush(); } } @@ -803,7 +716,7 @@ void Renderer::DoState(PointerWrap& p) p.Do(m_last_xfb_height); p.DoArray(m_bounding_box_fallback); - m_bounding_box->DoState(p); + g_bounding_box->DoState(p); if (p.IsReadMode()) { @@ -821,11 +734,6 @@ void Renderer::DoState(PointerWrap& p) #endif } -std::unique_ptr Renderer::CreateAsyncShaderCompiler() -{ - return std::make_unique(); -} - const GraphicsModManager& Renderer::GetGraphicsModManager() const { return m_graphics_mod_manager; diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index 17fe407618..fb88dfd1eb 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -64,100 +64,18 @@ struct EfbPokeData class Renderer { public: - Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, - AbstractTextureFormat backbuffer_format); + Renderer(); virtual ~Renderer(); - using ClearColor = std::array; - - virtual bool IsHeadless() const = 0; - virtual bool Initialize(); virtual void Shutdown(); - virtual void SetPipeline(const AbstractPipeline* pipeline) {} - virtual void SetScissorRect(const MathUtil::Rectangle& rc) {} - virtual void SetTexture(u32 index, const AbstractTexture* texture) {} - virtual void SetSamplerState(u32 index, const SamplerState& state) {} - virtual void SetComputeImageTexture(AbstractTexture* texture, bool read, bool write) {} - virtual void UnbindTexture(const AbstractTexture* texture) {} - virtual void SetViewport(float x, float y, float width, float height, float near_depth, - float far_depth) - { - } - virtual void SetFullscreen(bool enable_fullscreen) {} - virtual bool IsFullscreen() const { return false; } - virtual void BeginUtilityDrawing(); - virtual void EndUtilityDrawing(); - virtual std::unique_ptr CreateTexture(const TextureConfig& config, - std::string_view name = "") = 0; - virtual std::unique_ptr - CreateStagingTexture(StagingTextureType type, const TextureConfig& config) = 0; - virtual std::unique_ptr - CreateFramebuffer(AbstractTexture* color_attachment, AbstractTexture* depth_attachment) = 0; - - // Framebuffer operations. - virtual void SetFramebuffer(AbstractFramebuffer* framebuffer); - virtual void SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer); - virtual void SetAndClearFramebuffer(AbstractFramebuffer* framebuffer, - const ClearColor& color_value = {}, float depth_value = 0.0f); - - // Drawing with currently-bound pipeline state. - virtual void Draw(u32 base_vertex, u32 num_vertices) {} - virtual void DrawIndexed(u32 base_index, u32 num_indices, u32 base_vertex) {} - - // Dispatching compute shaders with currently-bound state. - virtual void DispatchComputeShader(const AbstractShader* shader, u32 groupsize_x, u32 groupsize_y, - u32 groupsize_z, u32 groups_x, u32 groups_y, u32 groups_z) - { - } - - // Binds the backbuffer for rendering. The buffer will be cleared immediately after binding. - // This is where any window size changes are detected, therefore m_backbuffer_width and/or - // m_backbuffer_height may change after this function returns. - virtual void BindBackbuffer(const ClearColor& clear_color = {}) {} - - // Presents the backbuffer to the window system, or "swaps buffers". - virtual void PresentBackbuffer() {} - - // Shader modules/objects. - virtual std::unique_ptr CreateShaderFromSource(ShaderStage stage, - std::string_view source, - std::string_view name = "") = 0; - virtual std::unique_ptr CreateShaderFromBinary(ShaderStage stage, - const void* data, size_t length, - std::string_view name = "") = 0; - virtual std::unique_ptr - CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) = 0; - virtual std::unique_ptr CreatePipeline(const AbstractPipelineConfig& config, - const void* cache_data = nullptr, - size_t cache_data_length = 0) = 0; - - AbstractFramebuffer* GetCurrentFramebuffer() const { return m_current_framebuffer; } - + void BeginUtilityDrawing(); + void EndUtilityDrawing(); // Ideal internal resolution - multiple of the native EFB resolution int GetTargetWidth() const { return m_target_width; } int GetTargetHeight() const { return m_target_height; } - // Sets viewport and scissor to the specified rectangle. rect is assumed to be in framebuffer - // coordinates, i.e. lower-left origin in OpenGL. - void SetViewportAndScissor(const MathUtil::Rectangle& rect, float min_depth = 0.0f, - float max_depth = 1.0f); - - // Scales a GPU texture using a copy shader. - virtual void ScaleTexture(AbstractFramebuffer* dst_framebuffer, - const MathUtil::Rectangle& dst_rect, - const AbstractTexture* src_texture, - const MathUtil::Rectangle& src_rect); - - // Converts an upper-left to lower-left if required by the backend, optionally - // clamping to the framebuffer size. - MathUtil::Rectangle ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, - u32 fb_width, u32 fb_height) const; - MathUtil::Rectangle - ConvertFramebufferRectangle(const MathUtil::Rectangle& rect, - const AbstractFramebuffer* framebuffer) const; - // EFB coordinate conversion functions // Use this to convert a whole native EFB rect to backbuffer coordinates MathUtil::Rectangle ConvertEFBRectangle(const MathUtil::Rectangle& rc) const; @@ -188,29 +106,12 @@ public: void BBoxWrite(u32 index, u16 value); void BBoxFlush(); - virtual void Flush() {} - virtual void WaitForGPUIdle() {} - // Finish up the current frame, print some stats void Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks); void UpdateWidescreenHeuristic(); bool IsGameWidescreen() const { return m_is_game_widescreen; } - // A simple presentation fallback, only used by video software - virtual void ShowImage(const AbstractTexture* source_texture, - const MathUtil::Rectangle& source_rc) - { - } - - // For opengl's glDrawBuffer - virtual void SelectLeftBuffer() {} - virtual void SelectRightBuffer() {} - virtual void SelectMainBuffer() {} - - // Called when the configuration changes, and backend structures need to be updated. - virtual void OnConfigChanged(u32 bits) {} - PixelFormat GetPrevPixelFormat() const { return m_prev_efb_format; } void StorePixelFormat(PixelFormat new_format) { m_prev_efb_format = new_format; } bool EFBHasAlphaChannel() const; @@ -218,30 +119,11 @@ public: bool UseVertexDepthRange() const; void DoState(PointerWrap& p); - virtual std::unique_ptr CreateAsyncShaderCompiler(); - - // Returns true if a layer-expanding geometry shader should be used when rendering the user - // interface and final XFB. - bool UseGeometryShaderForUI() const; - // Will forcibly reload all textures on the next swap void ForceReloadTextures(); const GraphicsModManager& GetGraphicsModManager() const; - // Bitmask containing information about which configuration has changed for the backend. - enum ConfigChangeBits : u32 - { - CONFIG_CHANGE_BIT_HOST_CONFIG = (1 << 0), - CONFIG_CHANGE_BIT_MULTISAMPLES = (1 << 1), - CONFIG_CHANGE_BIT_STEREO_MODE = (1 << 2), - CONFIG_CHANGE_BIT_TARGET_SIZE = (1 << 3), - CONFIG_CHANGE_BIT_ANISOTROPY = (1 << 4), - CONFIG_CHANGE_BIT_FORCE_TEXTURE_FILTERING = (1 << 5), - CONFIG_CHANGE_BIT_VSYNC = (1 << 6), - CONFIG_CHANGE_BIT_BBOX = (1 << 7) - }; - protected: std::tuple CalculateTargetScale(int x, int y) const; bool CalculateTargetSize(); @@ -251,11 +133,6 @@ protected: void CheckFifoRecording(); void RecordVideoMemory(); - virtual std::unique_ptr CreateBoundingBox() const = 0; - - AbstractFramebuffer* m_current_framebuffer = nullptr; - const AbstractPipeline* m_current_pipeline = nullptr; - bool m_is_game_widescreen = false; bool m_was_orthographically_anamorphic = false; diff --git a/Source/Core/VideoCommon/ShaderCache.cpp b/Source/Core/VideoCommon/ShaderCache.cpp index 1be1ad1167..b9876dc533 100644 --- a/Source/Core/VideoCommon/ShaderCache.cpp +++ b/Source/Core/VideoCommon/ShaderCache.cpp @@ -10,12 +10,12 @@ #include "Common/MsgHandler.h" #include "Core/ConfigManager.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/ConstantManager.h" #include "VideoCommon/DriverDetails.h" #include "VideoCommon/FramebufferManager.h" #include "VideoCommon/FramebufferShaderGen.h" #include "VideoCommon/Present.h" -#include "VideoCommon/RenderBase.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexManagerBase.h" @@ -45,7 +45,7 @@ bool ShaderCache::Initialize() if (!CompileSharedPipelines()) return false; - m_async_shader_compiler = g_renderer->CreateAsyncShaderCompiler(); + m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler(); return true; } @@ -122,7 +122,7 @@ const AbstractPipeline* ShaderCache::GetPipelineForUid(const GXPipelineUid& uid) std::unique_ptr pipeline; std::optional pipeline_config = GetGXPipelineConfig(uid); if (pipeline_config) - pipeline = g_renderer->CreatePipeline(*pipeline_config); + pipeline = g_gfx->CreatePipeline(*pipeline_config); if (g_ActiveConfig.bShaderCache && !exists_in_cache) AppendGXPipelineUID(uid); return InsertGXPipeline(uid, std::move(pipeline)); @@ -154,7 +154,7 @@ const AbstractPipeline* ShaderCache::GetUberPipelineForUid(const GXUberPipelineU std::unique_ptr pipeline; std::optional pipeline_config = GetGXPipelineConfig(uid); if (pipeline_config) - pipeline = g_renderer->CreatePipeline(*pipeline_config); + pipeline = g_gfx->CreatePipeline(*pipeline_config); return InsertGXUberPipeline(uid, std::move(pipeline)); } @@ -235,7 +235,7 @@ void ShaderCache::LoadShaderCache(T& cache, APIType api_type, const char* type, CacheReader(T& cache_) : cache(cache_) {} void Read(const K& key, const u8* value, u32 value_size) { - auto shader = g_renderer->CreateShaderFromBinary(stage, value, value_size); + auto shader = g_gfx->CreateShaderFromBinary(stage, value, value_size); if (shader) { auto& entry = cache.shader_map[key]; @@ -298,7 +298,7 @@ void ShaderCache::LoadPipelineCache(T& cache, LinearDiskCache& if (!config) return; - auto pipeline = g_renderer->CreatePipeline(*config, value, value_size); + auto pipeline = g_gfx->CreatePipeline(*config, value, value_size); if (!pipeline) { // If any of the pipelines fail to create, consider the cache stale. @@ -435,7 +435,7 @@ std::unique_ptr ShaderCache::CompileVertexShader(const VertexSha { const ShaderCode source_code = GenerateVertexShaderCode(m_api_type, m_host_config, uid.GetUidData()); - return g_renderer->CreateShaderFromSource(ShaderStage::Vertex, source_code.GetBuffer()); + return g_gfx->CreateShaderFromSource(ShaderStage::Vertex, source_code.GetBuffer()); } std::unique_ptr @@ -443,15 +443,15 @@ ShaderCache::CompileVertexUberShader(const UberShader::VertexShaderUid& uid) con { const ShaderCode source_code = UberShader::GenVertexShader(m_api_type, m_host_config, uid.GetUidData()); - return g_renderer->CreateShaderFromSource(ShaderStage::Vertex, source_code.GetBuffer(), - fmt::to_string(*uid.GetUidData())); + return g_gfx->CreateShaderFromSource(ShaderStage::Vertex, source_code.GetBuffer(), + fmt::to_string(*uid.GetUidData())); } std::unique_ptr ShaderCache::CompilePixelShader(const PixelShaderUid& uid) const { const ShaderCode source_code = GeneratePixelShaderCode(m_api_type, m_host_config, uid.GetUidData()); - return g_renderer->CreateShaderFromSource(ShaderStage::Pixel, source_code.GetBuffer()); + return g_gfx->CreateShaderFromSource(ShaderStage::Pixel, source_code.GetBuffer()); } std::unique_ptr @@ -459,8 +459,8 @@ ShaderCache::CompilePixelUberShader(const UberShader::PixelShaderUid& uid) const { const ShaderCode source_code = UberShader::GenPixelShader(m_api_type, m_host_config, uid.GetUidData()); - return g_renderer->CreateShaderFromSource(ShaderStage::Pixel, source_code.GetBuffer(), - fmt::to_string(*uid.GetUidData())); + return g_gfx->CreateShaderFromSource(ShaderStage::Pixel, source_code.GetBuffer(), + fmt::to_string(*uid.GetUidData())); } const AbstractShader* ShaderCache::InsertVertexShader(const VertexShaderUid& uid, @@ -556,8 +556,8 @@ const AbstractShader* ShaderCache::CreateGeometryShader(const GeometryShaderUid& const ShaderCode source_code = GenerateGeometryShaderCode(m_api_type, m_host_config, uid.GetUidData()); std::unique_ptr shader = - g_renderer->CreateShaderFromSource(ShaderStage::Geometry, source_code.GetBuffer(), - fmt::format("Geometry shader: {}", *uid.GetUidData())); + g_gfx->CreateShaderFromSource(ShaderStage::Geometry, source_code.GetBuffer(), + fmt::format("Geometry shader: {}", *uid.GetUidData())); auto& entry = m_gs_cache.shader_map[uid]; entry.pending = false; @@ -1159,7 +1159,7 @@ void ShaderCache::QueuePipelineCompile(const GXPipelineUid& uid, u32 priority) bool Compile() override { if (config) - pipeline = g_renderer->CreatePipeline(*config); + pipeline = g_gfx->CreatePipeline(*config); return true; } @@ -1234,7 +1234,7 @@ void ShaderCache::QueueUberPipelineCompile(const GXUberPipelineUid& uid, u32 pri bool Compile() override { if (config) - UberPipeline = g_renderer->CreatePipeline(*config); + UberPipeline = g_gfx->CreatePipeline(*config); return true; } @@ -1372,7 +1372,7 @@ ShaderCache::GetEFBCopyToVRAMPipeline(const TextureConversionShaderGen::TCShader return iter->second.get(); auto shader_code = TextureConversionShaderGen::GeneratePixelShader(m_api_type, uid.GetUidData()); - auto shader = g_renderer->CreateShaderFromSource( + auto shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, shader_code.GetBuffer(), fmt::format("EFB copy to VRAM pixel shader: {}", *uid.GetUidData())); if (!shader) @@ -1392,7 +1392,7 @@ ShaderCache::GetEFBCopyToVRAMPipeline(const TextureConversionShaderGen::TCShader config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = RenderState::GetRGBA8FramebufferState(); config.usage = AbstractPipelineUsage::Utility; - auto iiter = m_efb_copy_to_vram_pipelines.emplace(uid, g_renderer->CreatePipeline(config)); + auto iiter = m_efb_copy_to_vram_pipelines.emplace(uid, g_gfx->CreatePipeline(config)); return iiter.first->second.get(); } @@ -1404,7 +1404,7 @@ const AbstractPipeline* ShaderCache::GetEFBCopyToRAMPipeline(const EFBCopyParams const std::string shader_code = TextureConversionShaderTiled::GenerateEncodingShader(uid, m_api_type); - const auto shader = g_renderer->CreateShaderFromSource( + const auto shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, shader_code, fmt::format("EFB copy to RAM pixel shader: {}", uid)); if (!shader) { @@ -1420,19 +1420,19 @@ const AbstractPipeline* ShaderCache::GetEFBCopyToRAMPipeline(const EFBCopyParams config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = RenderState::GetColorFramebufferState(AbstractTextureFormat::BGRA8); config.usage = AbstractPipelineUsage::Utility; - auto iiter = m_efb_copy_to_ram_pipelines.emplace(uid, g_renderer->CreatePipeline(config)); + auto iiter = m_efb_copy_to_ram_pipelines.emplace(uid, g_gfx->CreatePipeline(config)); return iiter.first->second.get(); } bool ShaderCache::CompileSharedPipelines() { - m_screen_quad_vertex_shader = g_renderer->CreateShaderFromSource( + m_screen_quad_vertex_shader = g_gfx->CreateShaderFromSource( ShaderStage::Vertex, FramebufferShaderGen::GenerateScreenQuadVertexShader(), "Screen quad vertex shader"); - m_texture_copy_vertex_shader = g_renderer->CreateShaderFromSource( + m_texture_copy_vertex_shader = g_gfx->CreateShaderFromSource( ShaderStage::Vertex, FramebufferShaderGen::GenerateTextureCopyVertexShader(), "Texture copy vertex shader"); - m_efb_copy_vertex_shader = g_renderer->CreateShaderFromSource( + m_efb_copy_vertex_shader = g_gfx->CreateShaderFromSource( ShaderStage::Vertex, TextureConversionShaderGen::GenerateVertexShader(m_api_type).GetBuffer(), "EFB copy vertex shader"); if (!m_screen_quad_vertex_shader || !m_texture_copy_vertex_shader || !m_efb_copy_vertex_shader) @@ -1440,20 +1440,20 @@ bool ShaderCache::CompileSharedPipelines() if (UseGeometryShaderForEFBCopies()) { - m_texcoord_geometry_shader = g_renderer->CreateShaderFromSource( + m_texcoord_geometry_shader = g_gfx->CreateShaderFromSource( ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(1, 0), "Texcoord passthrough geometry shader"); - m_color_geometry_shader = g_renderer->CreateShaderFromSource( + m_color_geometry_shader = g_gfx->CreateShaderFromSource( ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(0, 1), "Color passthrough geometry shader"); if (!m_texcoord_geometry_shader || !m_color_geometry_shader) return false; } - m_texture_copy_pixel_shader = g_renderer->CreateShaderFromSource( + m_texture_copy_pixel_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, FramebufferShaderGen::GenerateTextureCopyPixelShader(), "Texture copy pixel shader"); - m_color_pixel_shader = g_renderer->CreateShaderFromSource( + m_color_pixel_shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, FramebufferShaderGen::GenerateColorPixelShader(), "Color pixel shader"); if (!m_texture_copy_pixel_shader || !m_color_pixel_shader) return false; @@ -1468,14 +1468,14 @@ bool ShaderCache::CompileSharedPipelines() config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = RenderState::GetRGBA8FramebufferState(); config.usage = AbstractPipelineUsage::Utility; - m_copy_rgba8_pipeline = g_renderer->CreatePipeline(config); + m_copy_rgba8_pipeline = g_gfx->CreatePipeline(config); if (!m_copy_rgba8_pipeline) return false; if (UseGeometryShaderForEFBCopies()) { config.geometry_shader = m_texcoord_geometry_shader.get(); - m_rgba8_stereo_copy_pipeline = g_renderer->CreatePipeline(config); + m_rgba8_stereo_copy_pipeline = g_gfx->CreatePipeline(config); if (!m_rgba8_stereo_copy_pipeline) return false; } @@ -1488,7 +1488,7 @@ bool ShaderCache::CompileSharedPipelines() for (size_t i = 0; i < NUM_PALETTE_CONVERSION_SHADERS; i++) { TLUTFormat format = static_cast(i); - auto shader = g_renderer->CreateShaderFromSource( + auto shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, TextureConversionShaderTiled::GeneratePaletteConversionShader(format, m_api_type), fmt::format("Palette conversion pixel shader: {}", format)); @@ -1496,7 +1496,7 @@ bool ShaderCache::CompileSharedPipelines() return false; config.pixel_shader = shader.get(); - m_palette_conversion_pipelines[i] = g_renderer->CreatePipeline(config); + m_palette_conversion_pipelines[i] = g_gfx->CreatePipeline(config); if (!m_palette_conversion_pipelines[i]) return false; } @@ -1527,7 +1527,7 @@ const AbstractPipeline* ShaderCache::GetTextureReinterpretPipeline(TextureFormat return nullptr; } - std::unique_ptr shader = g_renderer->CreateShaderFromSource( + std::unique_ptr shader = g_gfx->CreateShaderFromSource( ShaderStage::Pixel, shader_source, fmt::format("Texture reinterpret pixel shader: {} to {}", from_format, to_format)); if (!shader) @@ -1546,7 +1546,7 @@ const AbstractPipeline* ShaderCache::GetTextureReinterpretPipeline(TextureFormat config.blending_state = RenderState::GetNoBlendingBlendState(); config.framebuffer_state = RenderState::GetRGBA8FramebufferState(); config.usage = AbstractPipelineUsage::Utility; - auto iiter = m_texture_reinterpret_pipelines.emplace(key, g_renderer->CreatePipeline(config)); + auto iiter = m_texture_reinterpret_pipelines.emplace(key, g_gfx->CreatePipeline(config)); return iiter.first->second.get(); } @@ -1574,7 +1574,7 @@ ShaderCache::GetTextureDecodingShader(TextureFormat format, fmt::format("Texture decoding compute shader: {}", format); std::unique_ptr shader = - g_renderer->CreateShaderFromSource(ShaderStage::Compute, shader_source, name); + g_gfx->CreateShaderFromSource(ShaderStage::Compute, shader_source, name); if (!shader) { m_texture_decoding_shaders.emplace(key, nullptr); diff --git a/Source/Core/VideoCommon/TextureCacheBase.cpp b/Source/Core/VideoCommon/TextureCacheBase.cpp index 6102767e70..e991669950 100644 --- a/Source/Core/VideoCommon/TextureCacheBase.cpp +++ b/Source/Core/VideoCommon/TextureCacheBase.cpp @@ -34,6 +34,7 @@ #include "Core/System.h" #include "VideoCommon/AbstractFramebuffer.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/FramebufferManager.h" @@ -298,7 +299,7 @@ RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const decoded_entry->SetNotCopy(); decoded_entry->may_have_overlapping_textures = entry->may_have_overlapping_textures; - g_renderer->BeginUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); const u32 palette_size = entry->format == TextureFormat::I4 ? 32 : 512; u32 texel_buffer_offset; @@ -318,19 +319,19 @@ RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const uniforms.texel_buffer_offset = texel_buffer_offset; g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); - g_renderer->SetAndDiscardFramebuffer(decoded_entry->framebuffer.get()); - g_renderer->SetViewportAndScissor(decoded_entry->texture->GetRect()); - g_renderer->SetPipeline(pipeline); - g_renderer->SetTexture(1, entry->texture.get()); - g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); - g_renderer->Draw(0, 3); - g_renderer->EndUtilityDrawing(); + g_gfx->SetAndDiscardFramebuffer(decoded_entry->framebuffer.get()); + g_gfx->SetViewportAndScissor(decoded_entry->texture->GetRect()); + g_gfx->SetPipeline(pipeline); + g_gfx->SetTexture(1, entry->texture.get()); + g_gfx->SetSamplerState(1, RenderState::GetPointSamplerState()); + g_gfx->Draw(0, 3); + g_gfx->EndUtilityDrawing(); decoded_entry->texture->FinishedRendering(); } else { ERROR_LOG_FMT(VIDEO, "Texel buffer upload of {} bytes failed", palette_size); - g_renderer->EndUtilityDrawing(); + g_gfx->EndUtilityDrawing(); } textures_by_address.emplace(decoded_entry->addr, decoded_entry); @@ -369,14 +370,14 @@ RcTcacheEntry TextureCacheBase::ReinterpretEntry(const RcTcacheEntry& existing_e reinterpreted_entry->may_have_overlapping_textures = existing_entry->may_have_overlapping_textures; - g_renderer->BeginUtilityDrawing(); - g_renderer->SetAndDiscardFramebuffer(reinterpreted_entry->framebuffer.get()); - g_renderer->SetViewportAndScissor(reinterpreted_entry->texture->GetRect()); - g_renderer->SetPipeline(pipeline); - g_renderer->SetTexture(0, existing_entry->texture.get()); - g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); - g_renderer->Draw(0, 3); - g_renderer->EndUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); + g_gfx->SetAndDiscardFramebuffer(reinterpreted_entry->framebuffer.get()); + g_gfx->SetViewportAndScissor(reinterpreted_entry->texture->GetRect()); + g_gfx->SetPipeline(pipeline); + g_gfx->SetTexture(0, existing_entry->texture.get()); + g_gfx->SetSamplerState(1, RenderState::GetPointSamplerState()); + g_gfx->Draw(0, 3); + g_gfx->EndUtilityDrawing(); reinterpreted_entry->texture->FinishedRendering(); textures_by_address.emplace(reinterpreted_entry->addr, reinterpreted_entry); @@ -408,9 +409,8 @@ void TextureCacheBase::ScaleTextureCacheEntryTo(RcTcacheEntry& entry, u32 new_wi } // No need to convert the coordinates here since they'll be the same. - g_renderer->ScaleTexture(new_texture->framebuffer.get(), - new_texture->texture->GetConfig().GetRect(), entry->texture.get(), - entry->texture->GetConfig().GetRect()); + g_gfx->ScaleTexture(new_texture->framebuffer.get(), new_texture->texture->GetConfig().GetRect(), + entry->texture.get(), entry->texture->GetConfig().GetRect()); entry->texture.swap(new_texture->texture); entry->framebuffer.swap(new_texture->framebuffer); @@ -432,8 +432,7 @@ bool TextureCacheBase::CheckReadbackTexture(u32 width, u32 height, AbstractTextu TextureConfig staging_config(std::max(width, 128u), std::max(height, 128u), 1, 1, 1, format, 0); m_readback_texture.reset(); - m_readback_texture = - g_renderer->CreateStagingTexture(StagingTextureType::Readback, staging_config); + m_readback_texture = g_gfx->CreateStagingTexture(StagingTextureType::Readback, staging_config); return m_readback_texture != nullptr; } @@ -1081,7 +1080,7 @@ static void SetSamplerState(u32 index, float custom_tex_scale, bool custom_tex, state.tm0.anisotropic_filtering = false; } - g_renderer->SetSamplerState(index, state); + g_gfx->SetSamplerState(index, state); auto& system = Core::System::GetInstance(); auto& pixel_shader_manager = system.GetPixelShaderManager(); pixel_shader_manager.SetSamplerState(index, state.tm0.hex, state.tm1.hex); @@ -1096,7 +1095,7 @@ void TextureCacheBase::BindTextures(BitSet32 used_textures) const RcTcacheEntry& tentry = bound_textures[i]; if (used_textures[i] && tentry) { - g_renderer->SetTexture(i, tentry->texture.get()); + g_gfx->SetTexture(i, tentry->texture.get()); pixel_shader_manager.SetTexDims(i, tentry->native_width, tentry->native_height); const float custom_tex_scale = tentry->GetWidth() / float(tentry->native_width); @@ -2013,8 +2012,8 @@ void TextureCacheBase::StitchXFBCopy(RcTcacheEntry& stitched_entry) // We may have to scale if one of the copies is not internal resolution. if (srcrect.GetWidth() != dstrect.GetWidth() || srcrect.GetHeight() != dstrect.GetHeight()) { - g_renderer->ScaleTexture(stitched_entry->framebuffer.get(), dstrect, entry->texture.get(), - srcrect); + g_gfx->ScaleTexture(stitched_entry->framebuffer.get(), dstrect, entry->texture.get(), + srcrect); } else { @@ -2521,7 +2520,7 @@ std::unique_ptr TextureCacheBase::GetEFBCopyStagingTextu return ptr; } - std::unique_ptr tex = g_renderer->CreateStagingTexture( + std::unique_ptr tex = g_gfx->CreateStagingTexture( StagingTextureType::Readback, m_efb_encoding_texture->GetConfig()); if (!tex) WARN_LOG_FMT(VIDEO, "Failed to create EFB copy staging texture"); @@ -2614,7 +2613,7 @@ TextureCacheBase::AllocateTexture(const TextureConfig& config) return std::move(entry); } - std::unique_ptr texture = g_renderer->CreateTexture(config); + std::unique_ptr texture = g_gfx->CreateTexture(config); if (!texture) { WARN_LOG_FMT(VIDEO, "Failed to allocate a {}x{}x{} texture", config.width, config.height, @@ -2625,7 +2624,7 @@ TextureCacheBase::AllocateTexture(const TextureConfig& config) std::unique_ptr framebuffer; if (config.IsRenderTarget()) { - framebuffer = g_renderer->CreateFramebuffer(texture.get(), nullptr); + framebuffer = g_gfx->CreateFramebuffer(texture.get(), nullptr); if (!framebuffer) { WARN_LOG_FMT(VIDEO, "Failed to allocate a {}x{}x{} framebuffer", config.width, config.height, @@ -2745,12 +2744,11 @@ bool TextureCacheBase::CreateUtilityTextures() { constexpr TextureConfig encoding_texture_config( EFB_WIDTH * 4, 1024, 1, 1, 1, AbstractTextureFormat::BGRA8, AbstractTextureFlag_RenderTarget); - m_efb_encoding_texture = - g_renderer->CreateTexture(encoding_texture_config, "EFB encoding texture"); + m_efb_encoding_texture = g_gfx->CreateTexture(encoding_texture_config, "EFB encoding texture"); if (!m_efb_encoding_texture) return false; - m_efb_encoding_framebuffer = g_renderer->CreateFramebuffer(m_efb_encoding_texture.get(), nullptr); + m_efb_encoding_framebuffer = g_gfx->CreateFramebuffer(m_efb_encoding_texture.get(), nullptr); if (!m_efb_encoding_framebuffer) return false; @@ -2759,7 +2757,7 @@ bool TextureCacheBase::CreateUtilityTextures() constexpr TextureConfig decoding_texture_config( 1024, 1024, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage); m_decoding_texture = - g_renderer->CreateTexture(decoding_texture_config, "GPU texture decoding texture"); + g_gfx->CreateTexture(decoding_texture_config, "GPU texture decoding texture"); if (!m_decoding_texture) return false; } @@ -2788,14 +2786,14 @@ void TextureCacheBase::CopyEFBToCacheEntry(RcTcacheEntry& entry, bool is_depth_c } const auto scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect); - const auto framebuffer_rect = g_renderer->ConvertFramebufferRectangle( + const auto framebuffer_rect = g_gfx->ConvertFramebufferRectangle( scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer()); AbstractTexture* src_texture = is_depth_copy ? g_framebuffer_manager->ResolveEFBDepthTexture(framebuffer_rect) : g_framebuffer_manager->ResolveEFBColorTexture(framebuffer_rect); src_texture->FinishedRendering(); - g_renderer->BeginUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); // Fill uniform buffer. struct Uniforms @@ -2832,14 +2830,14 @@ void TextureCacheBase::CopyEFBToCacheEntry(RcTcacheEntry& entry, bool is_depth_c g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); // Use the copy pipeline to render the VRAM copy. - g_renderer->SetAndDiscardFramebuffer(entry->framebuffer.get()); - g_renderer->SetViewportAndScissor(entry->framebuffer->GetRect()); - g_renderer->SetPipeline(copy_pipeline); - g_renderer->SetTexture(0, src_texture); - g_renderer->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() : - RenderState::GetPointSamplerState()); - g_renderer->Draw(0, 3); - g_renderer->EndUtilityDrawing(); + g_gfx->SetAndDiscardFramebuffer(entry->framebuffer.get()); + g_gfx->SetViewportAndScissor(entry->framebuffer->GetRect()); + g_gfx->SetPipeline(copy_pipeline); + g_gfx->SetTexture(0, src_texture); + g_gfx->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() : + RenderState::GetPointSamplerState()); + g_gfx->Draw(0, 3); + g_gfx->EndUtilityDrawing(); entry->texture->FinishedRendering(); } @@ -2862,14 +2860,14 @@ void TextureCacheBase::CopyEFB(AbstractStagingTexture* dst, const EFBCopyParams& } const auto scaled_src_rect = g_renderer->ConvertEFBRectangle(src_rect); - const auto framebuffer_rect = g_renderer->ConvertFramebufferRectangle( + const auto framebuffer_rect = g_gfx->ConvertFramebufferRectangle( scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer()); AbstractTexture* src_texture = params.depth ? g_framebuffer_manager->ResolveEFBDepthTexture(framebuffer_rect) : g_framebuffer_manager->ResolveEFBColorTexture(framebuffer_rect); src_texture->FinishedRendering(); - g_renderer->BeginUtilityDrawing(); + g_gfx->BeginUtilityDrawing(); // Fill uniform buffer. struct Uniforms @@ -2909,15 +2907,15 @@ void TextureCacheBase::CopyEFB(AbstractStagingTexture* dst, const EFBCopyParams& const auto encode_rect = MathUtil::Rectangle(0, 0, render_width, render_height); // Render to GPU texture, and then copy to CPU-accessible texture. - g_renderer->SetAndDiscardFramebuffer(m_efb_encoding_framebuffer.get()); - g_renderer->SetViewportAndScissor(encode_rect); - g_renderer->SetPipeline(copy_pipeline); - g_renderer->SetTexture(0, src_texture); - g_renderer->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() : - RenderState::GetPointSamplerState()); - g_renderer->Draw(0, 3); + g_gfx->SetAndDiscardFramebuffer(m_efb_encoding_framebuffer.get()); + g_gfx->SetViewportAndScissor(encode_rect); + g_gfx->SetPipeline(copy_pipeline); + g_gfx->SetTexture(0, src_texture); + g_gfx->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() : + RenderState::GetPointSamplerState()); + g_gfx->Draw(0, 3); dst->CopyFromTexture(m_efb_encoding_texture.get(), encode_rect, 0, 0, encode_rect); - g_renderer->EndUtilityDrawing(); + g_gfx->EndUtilityDrawing(); // Flush if there's sufficient draws between this copy and the last. g_vertex_manager->OnEFBCopyToRAM(); @@ -2970,12 +2968,12 @@ bool TextureCacheBase::DecodeTextureOnGPU(RcTcacheEntry& entry, u32 dst_level, c aligned_height, src_offset, row_stride / bytes_per_buffer_elem, palette_offset}; g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); - g_renderer->SetComputeImageTexture(m_decoding_texture.get(), false, true); + g_gfx->SetComputeImageTexture(m_decoding_texture.get(), false, true); auto dispatch_groups = TextureConversionShaderTiled::GetDispatchCount(info, aligned_width, aligned_height); - g_renderer->DispatchComputeShader(shader, info->group_size_x, info->group_size_y, 1, - dispatch_groups.first, dispatch_groups.second, 1); + g_gfx->DispatchComputeShader(shader, info->group_size_x, info->group_size_y, 1, + dispatch_groups.first, dispatch_groups.second, 1); // Copy from decoding texture -> final texture // This is because we don't want to have to create compute view for every layer diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index 9bee673db4..f3d580b801 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -20,12 +20,12 @@ #include "Core/HW/Memmap.h" #include "Core/System.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/CPMemory.h" #include "VideoCommon/DataReader.h" #include "VideoCommon/IndexGenerator.h" #include "VideoCommon/NativeVertexFormat.h" -#include "VideoCommon/RenderBase.h" #include "VideoCommon/Statistics.h" #include "VideoCommon/VertexLoaderBase.h" #include "VideoCommon/VertexManagerBase.h" @@ -140,7 +140,7 @@ NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& d auto iter = s_native_vertex_map.find(decl); if (iter == s_native_vertex_map.end()) { - std::unique_ptr fmt = g_renderer->CreateNativeVertexFormat(decl); + std::unique_ptr fmt = g_gfx->CreateNativeVertexFormat(decl); auto ipair = s_native_vertex_map.emplace(decl, std::move(fmt)); iter = ipair.first; } diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 1ccfebad0c..5f6b8a310e 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -17,6 +17,7 @@ #include "Core/DolphinAnalytics.h" #include "Core/System.h" +#include "VideoCommon/AbstractGfx.h" #include "VideoCommon/BPMemory.h" #include "VideoCommon/BoundingBox.h" #include "VideoCommon/DataReader.h" @@ -329,7 +330,7 @@ void VertexManagerBase::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 ba g_renderer->BBoxFlush(); } - g_renderer->DrawIndexed(base_index, num_indices, base_vertex); + g_gfx->DrawIndexed(base_index, num_indices, base_vertex); } void VertexManagerBase::UploadUniforms() @@ -599,7 +600,7 @@ void VertexManagerBase::Flush() UpdatePipelineObject(); if (m_current_pipeline_object) { - g_renderer->SetPipeline(m_current_pipeline_object); + g_gfx->SetPipeline(m_current_pipeline_object); if (PerfQueryBase::ShouldEmulate()) g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); @@ -877,7 +878,7 @@ void VertexManagerBase::OnDraw() u32 diff = m_draw_counter - m_last_efb_copy_draw_counter; if (m_unflushed_efb_copy && diff > MINIMUM_DRAW_CALLS_PER_COMMAND_BUFFER_FOR_READBACK) { - g_renderer->Flush(); + g_gfx->Flush(); m_unflushed_efb_copy = false; m_last_efb_copy_draw_counter = m_draw_counter; } @@ -892,7 +893,7 @@ void VertexManagerBase::OnDraw() m_scheduled_command_buffer_kicks.end(), m_draw_counter)) { // Kick a command buffer on the background thread. - g_renderer->Flush(); + g_gfx->Flush(); m_unflushed_efb_copy = false; m_last_efb_copy_draw_counter = m_draw_counter; } @@ -927,7 +928,7 @@ void VertexManagerBase::OnEFBCopyToRAM() } m_unflushed_efb_copy = false; - g_renderer->Flush(); + g_gfx->Flush(); } void VertexManagerBase::OnEndFrame() diff --git a/Source/Core/VideoCommon/VideoBackendBase.cpp b/Source/Core/VideoCommon/VideoBackendBase.cpp index 167848b425..40fcd8b0f4 100644 --- a/Source/Core/VideoCommon/VideoBackendBase.cpp +++ b/Source/Core/VideoCommon/VideoBackendBase.cpp @@ -324,7 +324,9 @@ void VideoBackendBase::InitializeShared() // do not initialize again for the config window m_initialized = true; + g_renderer = std::make_unique(); g_presenter = std::make_unique(); + g_frame_dumper = std::make_unique(); auto& system = Core::System::GetInstance(); auto& command_processor = system.GetCommandProcessor(); @@ -337,7 +339,13 @@ void VideoBackendBase::InitializeShared() system.GetGeometryShaderManager().Init(); system.GetPixelShaderManager().Init(); TMEM::Init(); - g_frame_dumper = std::make_unique(); + + if (!g_renderer->Initialize() || !g_presenter->Initialize()) + { + PanicAlertFmtT("Failed to initialize renderer classes"); + Shutdown(); + return; + } g_Config.VerifyValidity(); UpdateActiveConfig();