Split AbstractGfx out of Renderer

Almost all the virtual functions in Renderer are part of dolphin's
"graphics api abstraction layer", which has slowly formed over the
last decade or two.

Most of the work was done previously with the introduction of the
various "AbstractX" classes, associated with texture cache cleanups
and implementation of newer graphics APIs (Direct3D 12, Vulkan, Metal).
We are simply taking the last step and yeeting these functions out
of Renderer.

This "AbstractGfx" class is now completely agnostic of any details
from the flipper/hollywood GPU we are emulating, though somewhat
specialized.

(Will not build, this commit only contains changes outside VideoBackends)
This commit is contained in:
Scott Mansell 2023-01-27 11:34:59 +13:00
parent e57eb04ed3
commit 8a23629345
21 changed files with 645 additions and 531 deletions

View File

@ -618,6 +618,7 @@
<ClInclude Include="VideoBackends\Vulkan\VulkanContext.h" /> <ClInclude Include="VideoBackends\Vulkan\VulkanContext.h" />
<ClInclude Include="VideoBackends\Vulkan\VulkanLoader.h" /> <ClInclude Include="VideoBackends\Vulkan\VulkanLoader.h" />
<ClInclude Include="VideoCommon\AbstractFramebuffer.h" /> <ClInclude Include="VideoCommon\AbstractFramebuffer.h" />
<ClInclude Include="VideoCommon\AbstractGfx.h" />
<ClInclude Include="VideoCommon\AbstractPipeline.h" /> <ClInclude Include="VideoCommon\AbstractPipeline.h" />
<ClInclude Include="VideoCommon\AbstractShader.h" /> <ClInclude Include="VideoCommon\AbstractShader.h" />
<ClInclude Include="VideoCommon\AbstractStagingTexture.h" /> <ClInclude Include="VideoCommon\AbstractStagingTexture.h" />
@ -1219,6 +1220,7 @@
<ClCompile Include="VideoBackends\Vulkan\VulkanContext.cpp" /> <ClCompile Include="VideoBackends\Vulkan\VulkanContext.cpp" />
<ClCompile Include="VideoBackends\Vulkan\VulkanLoader.cpp" /> <ClCompile Include="VideoBackends\Vulkan\VulkanLoader.cpp" />
<ClCompile Include="VideoCommon\AbstractFramebuffer.cpp" /> <ClCompile Include="VideoCommon\AbstractFramebuffer.cpp" />
<ClCompile Include="VideoCommon\AbstractGfx.cpp" />
<ClCompile Include="VideoCommon\AbstractStagingTexture.cpp" /> <ClCompile Include="VideoCommon\AbstractStagingTexture.cpp" />
<ClCompile Include="VideoCommon\AbstractTexture.cpp" /> <ClCompile Include="VideoCommon\AbstractTexture.cpp" />
<ClCompile Include="VideoCommon\AsyncRequests.cpp" /> <ClCompile Include="VideoCommon\AsyncRequests.cpp" />

View File

@ -36,9 +36,9 @@
#include "UICommon/DiscordPresence.h" #include "UICommon/DiscordPresence.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/Fifo.cpp" #include "VideoCommon/Fifo.cpp"
#include "VideoCommon/Present.h" #include "VideoCommon/Present.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/VideoConfig.h" #include "VideoCommon/VideoConfig.h"
static thread_local bool tls_is_host_thread = false; static thread_local bool tls_is_host_thread = false;
@ -150,11 +150,11 @@ bool Host::GetRenderFullFocus()
void Host::SetRenderFocus(bool focus) void Host::SetRenderFocus(bool focus)
{ {
m_render_focus = 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] { RunWithGPUThreadInactive([focus] {
if (!Config::Get(Config::MAIN_RENDER_TO_MAIN)) 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; m_render_fullscreen = fullscreen;
if (g_renderer && g_renderer->IsFullscreen() != fullscreen && if (g_gfx && g_gfx->IsFullscreen() != fullscreen && g_ActiveConfig.ExclusiveFullscreenEnabled())
g_ActiveConfig.ExclusiveFullscreenEnabled())
{ {
RunWithGPUThreadInactive([fullscreen] { g_renderer->SetFullscreen(fullscreen); }); RunWithGPUThreadInactive([fullscreen] { g_gfx->SetFullscreen(fullscreen); });
} }
} }

View File

@ -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<int>& rc,
const MathUtil::Rectangle<int>& 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<int>& rect, float min_depth,
float max_depth)
{
SetViewport(static_cast<float>(rect.left), static_cast<float>(rect.top),
static_cast<float>(rect.GetWidth()), static_cast<float>(rect.GetHeight()), min_depth,
max_depth);
SetScissorRect(rect);
}
void AbstractGfx::ScaleTexture(AbstractFramebuffer* dst_framebuffer,
const MathUtil::Rectangle<int>& dst_rect,
const AbstractTexture* src_texture,
const MathUtil::Rectangle<int>& 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<float, 4> 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<u32>(dst_rect.GetWidth()) == dst_framebuffer->GetWidth() &&
static_cast<u32>(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<int>
AbstractGfx::ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect,
const AbstractFramebuffer* framebuffer) const
{
return ConvertFramebufferRectangle(rect, framebuffer->GetWidth(), framebuffer->GetHeight());
}
MathUtil::Rectangle<int>
AbstractGfx::ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect, u32 fb_width,
u32 fb_height) const
{
MathUtil::Rectangle<int> 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<VideoCommon::AsyncShaderCompiler> AbstractGfx::CreateAsyncShaderCompiler()
{
return std::make_unique<VideoCommon::AsyncShaderCompiler>();
}
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;
}

View File

@ -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 <array>
#include <memory>
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<float, 4>;
class AbstractGfx
{
public:
virtual bool IsHeadless() const = 0;
virtual void SetPipeline(const AbstractPipeline* pipeline) {}
virtual void SetScissorRect(const MathUtil::Rectangle<int>& 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<AbstractTexture> CreateTexture(const TextureConfig& config,
std::string_view name = "") = 0;
virtual std::unique_ptr<AbstractStagingTexture>
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) = 0;
virtual std::unique_ptr<AbstractFramebuffer>
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<int>& rc,
const MathUtil::Rectangle<int>& 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<AbstractShader> CreateShaderFromSource(ShaderStage stage,
std::string_view source,
std::string_view name = "") = 0;
virtual std::unique_ptr<AbstractShader> CreateShaderFromBinary(ShaderStage stage,
const void* data, size_t length,
std::string_view name = "") = 0;
virtual std::unique_ptr<NativeVertexFormat>
CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) = 0;
virtual std::unique_ptr<AbstractPipeline> 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<int>& 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<int>& dst_rect,
const AbstractTexture* src_texture,
const MathUtil::Rectangle<int>& src_rect);
// Converts an upper-left to lower-left if required by the backend, optionally
// clamping to the framebuffer size.
MathUtil::Rectangle<int> ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect,
u32 fb_width, u32 fb_height) const;
MathUtil::Rectangle<int>
ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& 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<int>& source_rc)
{
}
virtual std::unique_ptr<VideoCommon::AsyncShaderCompiler> 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<AbstractGfx> g_gfx;

View File

@ -8,8 +8,8 @@
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/Image.h" #include "Common/Image.h"
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/AbstractStagingTexture.h"
#include "VideoCommon/RenderBase.h"
AbstractTexture::AbstractTexture(const TextureConfig& c) : m_config(c) 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, TextureConfig readback_texture_config(level_width, level_height, 1, 1, 1,
AbstractTextureFormat::RGBA8, 0); AbstractTextureFormat::RGBA8, 0);
auto readback_texture = auto readback_texture =
g_renderer->CreateStagingTexture(StagingTextureType::Readback, readback_texture_config); g_gfx->CreateStagingTexture(StagingTextureType::Readback, readback_texture_config);
if (!readback_texture) if (!readback_texture)
return false; return false;

View File

@ -12,6 +12,7 @@
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/RenderBase.h" #include "VideoCommon/RenderBase.h"
@ -198,9 +199,8 @@ void SetScissorAndViewport()
auto native_rc = ComputeScissorRects().Best(); auto native_rc = ComputeScissorRects().Best();
auto target_rc = g_renderer->ConvertEFBRectangle(native_rc.rect); auto target_rc = g_renderer->ConvertEFBRectangle(native_rc.rect);
auto converted_rc = auto converted_rc = g_gfx->ConvertFramebufferRectangle(target_rc, g_gfx->GetCurrentFramebuffer());
g_renderer->ConvertFramebufferRectangle(target_rc, g_renderer->GetCurrentFramebuffer()); g_gfx->SetScissorRect(converted_rc);
g_renderer->SetScissorRect(converted_rc);
float raw_x = (xfmem.viewport.xOrig - native_rc.x_off) - xfmem.viewport.wd; 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; float raw_y = (xfmem.viewport.yOrig - native_rc.y_off) + xfmem.viewport.ht;
@ -280,9 +280,9 @@ void SetScissorAndViewport()
// Lower-left flip. // Lower-left flip.
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin) if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
y = static_cast<float>(g_renderer->GetCurrentFramebuffer()->GetHeight()) - y - height; y = static_cast<float>(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() void SetDepthMode()

View File

@ -4,6 +4,7 @@
#pragma once #pragma once
#include <array> #include <array>
#include <memory>
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
@ -49,3 +50,5 @@ private:
std::array<bool, NUM_BBOX_VALUES> m_dirty = {}; std::array<bool, NUM_BBOX_VALUES> m_dirty = {};
bool m_is_valid = true; bool m_is_valid = true;
}; };
extern std::unique_ptr<BoundingBox> g_bounding_box;

View File

@ -1,6 +1,8 @@
add_library(videocommon add_library(videocommon
AbstractFramebuffer.cpp AbstractFramebuffer.cpp
AbstractFramebuffer.h AbstractFramebuffer.h
AbstractGfx.cpp
AbstractGfx.h
AbstractShader.h AbstractShader.h
AbstractStagingTexture.cpp AbstractStagingTexture.cpp
AbstractStagingTexture.h AbstractStagingTexture.h

View File

@ -11,6 +11,7 @@
#include "Core/Config/MainSettings.h" #include "Core/Config/MainSettings.h"
#include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/AbstractStagingTexture.h"
#include "VideoCommon/AbstractTexture.h" #include "VideoCommon/AbstractTexture.h"
#include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/OnScreenDisplay.h"
@ -51,7 +52,7 @@ void FrameDumper::DumpCurrentFrame(const AbstractTexture* src_texture,
if (!CheckFrameDumpRenderTexture(target_width, target_height)) if (!CheckFrameDumpRenderTexture(target_width, target_height))
return; return;
g_renderer->ScaleTexture(m_frame_dump_render_framebuffer.get(), g_gfx->ScaleTexture(m_frame_dump_render_framebuffer.get(),
m_frame_dump_render_framebuffer->GetRect(), src_texture, src_rect); m_frame_dump_render_framebuffer->GetRect(), src_texture, src_rect);
src_texture = m_frame_dump_render_texture.get(); src_texture = m_frame_dump_render_texture.get();
copy_rect = src_texture->GetRect(); 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. // 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_framebuffer.reset();
m_frame_dump_render_texture.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, TextureConfig(target_width, target_height, 1, 1, 1, AbstractTextureFormat::RGBA8,
AbstractTextureFlag_RenderTarget), AbstractTextureFlag_RenderTarget),
"Frame dump render texture"); "Frame dump render texture");
@ -89,7 +90,7 @@ bool FrameDumper::CheckFrameDumpRenderTexture(u32 target_width, u32 target_heigh
return false; return false;
} }
m_frame_dump_render_framebuffer = 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); ASSERT(m_frame_dump_render_framebuffer);
return true; return true;
} }
@ -101,7 +102,7 @@ bool FrameDumper::CheckFrameDumpReadbackTexture(u32 target_width, u32 target_hei
return true; return true;
rbtex.reset(); rbtex.reset();
rbtex = g_renderer->CreateStagingTexture( rbtex = g_gfx->CreateStagingTexture(
StagingTextureType::Readback, StagingTextureType::Readback,
TextureConfig(target_width, target_height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0)); TextureConfig(target_width, target_height, 1, 1, 1, AbstractTextureFormat::RGBA8, 0));
if (!rbtex) if (!rbtex)

View File

@ -11,6 +11,7 @@
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "Core/Config/GraphicsSettings.h" #include "Core/Config/GraphicsSettings.h"
#include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractPipeline.h"
#include "VideoCommon/AbstractShader.h" #include "VideoCommon/AbstractShader.h"
#include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/AbstractStagingTexture.h"
@ -171,17 +172,17 @@ bool FramebufferManager::CreateEFBFramebuffer()
const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig(); const TextureConfig efb_depth_texture_config = GetEFBDepthTextureConfig();
// We need a second texture to swap with for changing pixel formats // 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_color_texture = g_gfx->CreateTexture(efb_color_texture_config, "EFB color texture");
m_efb_depth_texture = g_renderer->CreateTexture(efb_depth_texture_config, "EFB depth texture"); m_efb_depth_texture = g_gfx->CreateTexture(efb_depth_texture_config, "EFB depth texture");
m_efb_convert_color_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) if (!m_efb_color_texture || !m_efb_depth_texture || !m_efb_convert_color_texture)
return false; return false;
m_efb_framebuffer = 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 = 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) if (!m_efb_framebuffer || !m_efb_convert_framebuffer)
return false; return false;
@ -191,7 +192,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
u32 flags = 0; u32 flags = 0;
if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve) if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
flags |= AbstractTextureFlag_RenderTarget; 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, 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_texture_config.layers, 1, efb_color_texture_config.format, flags),
"EFB color resolve texture"); "EFB color resolve texture");
@ -201,7 +202,7 @@ bool FramebufferManager::CreateEFBFramebuffer()
if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve) if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
{ {
m_efb_color_resolve_framebuffer = 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) if (!m_efb_color_resolve_framebuffer)
return false; 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). // We also need one to convert the D24S8 to R32F if that is being used (Adreno).
if (g_ActiveConfig.MultisamplingEnabled() || GetEFBDepthFormat() != AbstractTextureFormat::R32F) 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, TextureConfig(efb_depth_texture_config.width, efb_depth_texture_config.height, 1,
efb_depth_texture_config.layers, 1, GetEFBDepthCopyFormat(), efb_depth_texture_config.layers, 1, GetEFBDepthCopyFormat(),
AbstractTextureFlag_RenderTarget), AbstractTextureFlag_RenderTarget),
@ -219,15 +220,15 @@ bool FramebufferManager::CreateEFBFramebuffer()
return false; return false;
m_efb_depth_resolve_framebuffer = 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) if (!m_efb_depth_resolve_framebuffer)
return false; return false;
} }
// Clear the renderable textures out. // Clear the renderable textures out.
g_renderer->SetAndClearFramebuffer( g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}}, g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f :
g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f); 0.0f);
return true; return true;
} }
@ -245,7 +246,7 @@ void FramebufferManager::DestroyEFBFramebuffer()
void FramebufferManager::BindEFBFramebuffer() void FramebufferManager::BindEFBFramebuffer()
{ {
g_renderer->SetFramebuffer(m_efb_framebuffer.get()); g_gfx->SetFramebuffer(m_efb_framebuffer.get());
} }
AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rectangle<int>& region) AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rectangle<int>& region)
@ -270,15 +271,15 @@ AbstractTexture* FramebufferManager::ResolveEFBColorTexture(const MathUtil::Rect
else else
{ {
m_efb_color_texture->FinishedRendering(); m_efb_color_texture->FinishedRendering();
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
g_renderer->SetAndDiscardFramebuffer(m_efb_color_resolve_framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(m_efb_color_resolve_framebuffer.get());
g_renderer->SetPipeline(m_efb_color_resolve_pipeline.get()); g_gfx->SetPipeline(m_efb_color_resolve_pipeline.get());
g_renderer->SetTexture(0, m_efb_color_texture.get()); g_gfx->SetTexture(0, m_efb_color_texture.get());
g_renderer->SetSamplerState(0, RenderState::GetPointSamplerState()); g_gfx->SetSamplerState(0, RenderState::GetPointSamplerState());
g_renderer->SetViewportAndScissor(clamped_region); g_gfx->SetViewportAndScissor(clamped_region);
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
m_efb_resolve_color_texture->FinishedRendering(); m_efb_resolve_color_texture->FinishedRendering();
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
} }
m_efb_resolve_color_texture->FinishedRendering(); m_efb_resolve_color_texture->FinishedRendering();
return m_efb_resolve_color_texture.get(); return m_efb_resolve_color_texture.get();
@ -298,16 +299,16 @@ AbstractTexture* FramebufferManager::ResolveEFBDepthTexture(const MathUtil::Rect
clamped_region.ClampUL(0, 0, GetEFBWidth(), GetEFBHeight()); clamped_region.ClampUL(0, 0, GetEFBWidth(), GetEFBHeight());
m_efb_depth_texture->FinishedRendering(); m_efb_depth_texture->FinishedRendering();
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
g_renderer->SetAndDiscardFramebuffer(m_efb_depth_resolve_framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(m_efb_depth_resolve_framebuffer.get());
g_renderer->SetPipeline(IsEFBMultisampled() ? m_efb_depth_resolve_pipeline.get() : g_gfx->SetPipeline(IsEFBMultisampled() ? m_efb_depth_resolve_pipeline.get() :
m_efb_depth_cache.copy_pipeline.get()); m_efb_depth_cache.copy_pipeline.get());
g_renderer->SetTexture(0, m_efb_depth_texture.get()); g_gfx->SetTexture(0, m_efb_depth_texture.get());
g_renderer->SetSamplerState(0, RenderState::GetPointSamplerState()); g_gfx->SetSamplerState(0, RenderState::GetPointSamplerState());
g_renderer->SetViewportAndScissor(clamped_region); g_gfx->SetViewportAndScissor(clamped_region);
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
m_efb_depth_resolve_texture->FinishedRendering(); m_efb_depth_resolve_texture->FinishedRendering();
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
return m_efb_depth_resolve_texture.get(); 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 // 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. // future (e.g. on mobile/tilers), it may be worth discarding only the color buffer.
m_efb_color_texture->FinishedRendering(); m_efb_color_texture->FinishedRendering();
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
g_renderer->SetFramebuffer(m_efb_convert_framebuffer.get()); g_gfx->SetFramebuffer(m_efb_convert_framebuffer.get());
g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect()); g_gfx->SetViewportAndScissor(m_efb_framebuffer->GetRect());
g_renderer->SetPipeline(m_format_conversion_pipelines[static_cast<u32>(convtype)].get()); g_gfx->SetPipeline(m_format_conversion_pipelines[static_cast<u32>(convtype)].get());
g_renderer->SetTexture(0, m_efb_color_texture.get()); g_gfx->SetTexture(0, m_efb_color_texture.get());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
// And swap the framebuffers around, so we do new drawing to the converted framebuffer. // 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_color_texture, m_efb_convert_color_texture);
std::swap(m_efb_framebuffer, m_efb_convert_framebuffer); std::swap(m_efb_framebuffer, m_efb_convert_framebuffer);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
InvalidatePeekCache(true); InvalidatePeekCache(true);
return true; return true;
} }
@ -342,7 +343,7 @@ bool FramebufferManager::CompileConversionPipelines()
for (u32 i = 0; i < NUM_EFB_REINTERPRET_TYPES; i++) for (u32 i = 0; i < NUM_EFB_REINTERPRET_TYPES; i++)
{ {
EFBReinterpretType convtype = static_cast<EFBReinterpretType>(i); EFBReinterpretType convtype = static_cast<EFBReinterpretType>(i);
std::unique_ptr<AbstractShader> pixel_shader = g_renderer->CreateShaderFromSource( std::unique_ptr<AbstractShader> pixel_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, ShaderStage::Pixel,
FramebufferShaderGen::GenerateFormatConversionShader(convtype, GetEFBSamples()), FramebufferShaderGen::GenerateFormatConversionShader(convtype, GetEFBSamples()),
fmt::format("Framebuffer conversion pixel shader {}", convtype)); fmt::format("Framebuffer conversion pixel shader {}", convtype));
@ -358,7 +359,7 @@ bool FramebufferManager::CompileConversionPipelines()
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = GetEFBFramebufferState(); config.framebuffer_state = GetEFBFramebufferState();
config.usage = AbstractPipelineUsage::Utility; 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]) if (!m_format_conversion_pipelines[i])
return false; return false;
} }
@ -493,7 +494,7 @@ void FramebufferManager::RefreshPeekCache()
if (flush_command_buffer) if (flush_command_buffer)
{ {
g_renderer->Flush(); g_gfx->Flush();
} }
} }
@ -562,33 +563,33 @@ bool FramebufferManager::CompileReadbackPipelines()
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = RenderState::GetColorFramebufferState(GetEFBColorFormat()); config.framebuffer_state = RenderState::GetColorFramebufferState(GetEFBColorFormat());
config.usage = AbstractPipelineUsage::Utility; 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) if (!m_efb_color_cache.copy_pipeline)
return false; return false;
// same for depth, except different format // same for depth, except different format
config.framebuffer_state.color_texture_format = GetEFBDepthCopyFormat(); 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) if (!m_efb_depth_cache.copy_pipeline)
return false; return false;
if (IsEFBMultisampled()) if (IsEFBMultisampled())
{ {
auto depth_resolve_shader = g_renderer->CreateShaderFromSource( auto depth_resolve_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, FramebufferShaderGen::GenerateResolveDepthPixelShader(GetEFBSamples()), ShaderStage::Pixel, FramebufferShaderGen::GenerateResolveDepthPixelShader(GetEFBSamples()),
"Depth resolve pixel shader"); "Depth resolve pixel shader");
if (!depth_resolve_shader) if (!depth_resolve_shader)
return false; return false;
config.pixel_shader = depth_resolve_shader.get(); 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) if (!m_efb_depth_resolve_pipeline)
return false; return false;
if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve) if (!g_ActiveConfig.backend_info.bSupportsPartialMultisampleResolve)
{ {
config.framebuffer_state.color_texture_format = GetEFBColorFormat(); config.framebuffer_state.color_texture_format = GetEFBColorFormat();
auto color_resolve_shader = g_renderer->CreateShaderFromSource( auto color_resolve_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, ShaderStage::Pixel,
FramebufferShaderGen::GenerateResolveColorPixelShader(GetEFBSamples()), FramebufferShaderGen::GenerateResolveColorPixelShader(GetEFBSamples()),
"Color resolve pixel shader"); "Color resolve pixel shader");
@ -596,14 +597,14 @@ bool FramebufferManager::CompileReadbackPipelines()
return false; return false;
config.pixel_shader = color_resolve_shader.get(); 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) if (!m_efb_color_resolve_pipeline)
return false; return false;
} }
} }
// EFB restore pipeline // EFB restore pipeline
auto restore_shader = g_renderer->CreateShaderFromSource( auto restore_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, FramebufferShaderGen::GenerateEFBRestorePixelShader(), ShaderStage::Pixel, FramebufferShaderGen::GenerateEFBRestorePixelShader(),
"EFB restore pixel shader"); "EFB restore pixel shader");
if (!restore_shader) if (!restore_shader)
@ -614,7 +615,7 @@ bool FramebufferManager::CompileReadbackPipelines()
config.framebuffer_state.per_sample_shading = false; config.framebuffer_state.per_sample_shading = false;
config.vertex_shader = g_shader_cache->GetScreenQuadVertexShader(); config.vertex_shader = g_shader_cache->GetScreenQuadVertexShader();
config.pixel_shader = restore_shader.get(); 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) if (!m_efb_restore_pipeline)
return false; return false;
@ -635,12 +636,12 @@ bool FramebufferManager::CreateReadbackFramebuffer()
const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH, const TextureConfig color_config(IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_WIDTH,
IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1,
1, 1, GetEFBColorFormat(), AbstractTextureFlag_RenderTarget); 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) if (!m_efb_color_cache.texture)
return false; return false;
m_efb_color_cache.framebuffer = 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) if (!m_efb_color_cache.framebuffer)
return false; return false;
} }
@ -657,21 +658,21 @@ bool FramebufferManager::CreateReadbackFramebuffer()
IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1, IsUsingTiledEFBCache() ? m_efb_cache_tile_size : EFB_HEIGHT, 1,
1, 1, GetEFBDepthCopyFormat(), 1, 1, GetEFBDepthCopyFormat(),
AbstractTextureFlag_RenderTarget); 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) if (!m_efb_depth_cache.texture)
return false; return false;
m_efb_depth_cache.framebuffer = 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) if (!m_efb_depth_cache.framebuffer)
return false; return false;
} }
// Staging texture use the full EFB dimensions, as this is the buffer for the whole cache. // 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, StagingTextureType::Mutable,
TextureConfig(EFB_WIDTH, EFB_HEIGHT, 1, 1, 1, GetEFBColorFormat(), 0)); 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, StagingTextureType::Mutable,
TextureConfig(EFB_WIDTH, EFB_HEIGHT, 1, 1, 1, GetEFBDepthCopyFormat(), 0)); TextureConfig(EFB_WIDTH, EFB_HEIGHT, 1, 1, 1, GetEFBDepthCopyFormat(), 0));
if (!m_efb_color_cache.readback_texture || !m_efb_depth_cache.readback_texture) 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. // TODO: This won't produce correct results at IRs above 2x. More samples are required.
// This is the same issue as with EFB copies. // This is the same issue as with EFB copies.
src_texture->FinishedRendering(); src_texture->FinishedRendering();
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
const float rcp_src_width = 1.0f / m_efb_framebuffer->GetWidth(); const float rcp_src_width = 1.0f / m_efb_framebuffer->GetWidth();
const float rcp_src_height = 1.0f / m_efb_framebuffer->GetHeight(); 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 // 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. // 64, because 528 is not evenly divisible by 64.
g_renderer->SetAndDiscardFramebuffer(data.framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(data.framebuffer.get());
g_renderer->SetViewportAndScissor( g_gfx->SetViewportAndScissor(MathUtil::Rectangle<int>(0, 0, rect.GetWidth(), rect.GetHeight()));
MathUtil::Rectangle<int>(0, 0, rect.GetWidth(), rect.GetHeight())); g_gfx->SetPipeline(data.copy_pipeline.get());
g_renderer->SetPipeline(data.copy_pipeline.get()); g_gfx->SetTexture(0, src_texture);
g_renderer->SetTexture(0, src_texture); g_gfx->SetSamplerState(0, depth ? RenderState::GetPointSamplerState() :
g_renderer->SetSamplerState(0, depth ? RenderState::GetPointSamplerState() :
RenderState::GetLinearSamplerState()); RenderState::GetLinearSamplerState());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
// Copy from EFB or copy texture to staging texture. // Copy from EFB or copy texture to staging texture.
// No need to call FinishedRendering() here because CopyFromTexture() transitions. // 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<int>(0, 0, rect.GetWidth(), rect.GetHeight()), 0, 0, data.texture.get(), MathUtil::Rectangle<int>(0, 0, rect.GetWidth(), rect.GetHeight()), 0, 0,
rect); rect);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
} }
else else
{ {
@ -790,7 +790,7 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle<int>& rc, bool clear
{ {
FlushEFBPokes(); FlushEFBPokes();
FlagPeekCacheAsOutOfDate(); FlagPeekCacheAsOutOfDate();
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
// Set up uniforms. // Set up uniforms.
struct Uniforms struct Uniforms
@ -809,17 +809,17 @@ void FramebufferManager::ClearEFB(const MathUtil::Rectangle<int>& rc, bool clear
uniforms.clear_depth = 1.0f - uniforms.clear_depth; uniforms.clear_depth = 1.0f - uniforms.clear_depth;
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
const auto target_rc = g_renderer->ConvertFramebufferRectangle( const auto target_rc = g_gfx->ConvertFramebufferRectangle(g_renderer->ConvertEFBRectangle(rc),
g_renderer->ConvertEFBRectangle(rc), m_efb_framebuffer.get()); m_efb_framebuffer.get());
g_renderer->SetPipeline(m_efb_clear_pipelines[clear_color][clear_alpha][clear_z].get()); g_gfx->SetPipeline(m_efb_clear_pipelines[clear_color][clear_alpha][clear_z].get());
g_renderer->SetViewportAndScissor(target_rc); g_gfx->SetViewportAndScissor(target_rc);
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
} }
bool FramebufferManager::CompileClearPipelines() bool FramebufferManager::CompileClearPipelines()
{ {
auto vertex_shader = g_renderer->CreateShaderFromSource( auto vertex_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Vertex, FramebufferShaderGen::GenerateClearVertexShader(), ShaderStage::Vertex, FramebufferShaderGen::GenerateClearVertexShader(),
"Clear vertex shader"); "Clear vertex shader");
if (!vertex_shader) if (!vertex_shader)
@ -848,7 +848,7 @@ bool FramebufferManager::CompileClearPipelines()
config.depth_state.updateenable = depth_enable != 0; config.depth_state.updateenable = depth_enable != 0;
m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable] = 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]) if (!m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable])
return false; return false;
} }
@ -957,17 +957,17 @@ void FramebufferManager::DrawPokeVertices(const EFBPokeVertex* vertices, u32 ver
const AbstractPipeline* pipeline) const AbstractPipeline* pipeline)
{ {
// Copy to vertex buffer. // Copy to vertex buffer.
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
u32 base_vertex, base_index; u32 base_vertex, base_index;
g_vertex_manager->UploadUtilityVertices(vertices, sizeof(EFBPokeVertex), g_vertex_manager->UploadUtilityVertices(vertices, sizeof(EFBPokeVertex),
static_cast<u32>(vertex_count), nullptr, 0, &base_vertex, static_cast<u32>(vertex_count), nullptr, 0, &base_vertex,
&base_index); &base_index);
// Now we can draw. // Now we can draw.
g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect()); g_gfx->SetViewportAndScissor(m_efb_framebuffer->GetRect());
g_renderer->SetPipeline(pipeline); g_gfx->SetPipeline(pipeline);
g_renderer->Draw(base_vertex, vertex_count); g_gfx->Draw(base_vertex, vertex_count);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
} }
bool FramebufferManager::CompilePokePipelines() bool FramebufferManager::CompilePokePipelines()
@ -985,11 +985,11 @@ bool FramebufferManager::CompilePokePipelines()
vtx_decl.colors[0].offset = offsetof(EFBPokeVertex, color); vtx_decl.colors[0].offset = offsetof(EFBPokeVertex, color);
vtx_decl.stride = sizeof(EFBPokeVertex); 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) if (!m_poke_vertex_format)
return false; return false;
auto poke_vertex_shader = g_renderer->CreateShaderFromSource( auto poke_vertex_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Vertex, FramebufferShaderGen::GenerateEFBPokeVertexShader(), ShaderStage::Vertex, FramebufferShaderGen::GenerateEFBPokeVertexShader(),
"EFB poke vertex shader"); "EFB poke vertex shader");
if (!poke_vertex_shader) if (!poke_vertex_shader)
@ -1007,14 +1007,14 @@ bool FramebufferManager::CompilePokePipelines()
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = GetEFBFramebufferState(); config.framebuffer_state = GetEFBFramebufferState();
config.usage = AbstractPipelineUsage::Utility; 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) if (!m_color_poke_pipeline)
return false; return false;
// Turn off color writes, depth writes on for depth pokes. // Turn off color writes, depth writes on for depth pokes.
config.depth_state = RenderState::GetAlwaysWriteDepthState(); config.depth_state = RenderState::GetAlwaysWriteDepthState();
config.blending_state = RenderState::GetNoColorWriteBlendState(); 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) if (!m_depth_poke_pipeline)
return false; return false;
@ -1077,9 +1077,9 @@ void FramebufferManager::DoLoadState(PointerWrap& p)
color_tex->texture->GetLayers() != m_efb_color_texture->GetLayers()) color_tex->texture->GetLayers() != m_efb_color_texture->GetLayers())
{ {
WARN_LOG_FMT(VIDEO, "Failed to deserialize EFB contents. Clearing instead."); WARN_LOG_FMT(VIDEO, "Failed to deserialize EFB contents. Clearing instead.");
g_renderer->SetAndClearFramebuffer( g_gfx->SetAndClearFramebuffer(m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}},
m_efb_framebuffer.get(), {{0.0f, 0.0f, 0.0f, 0.0f}}, g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f :
g_ActiveConfig.backend_info.bSupportsReversedDepthRange ? 1.0f : 0.0f); 0.0f);
return; return;
} }
@ -1089,15 +1089,15 @@ void FramebufferManager::DoLoadState(PointerWrap& p)
color_tex->texture->GetHeight() != m_efb_color_texture->GetHeight(); color_tex->texture->GetHeight() != m_efb_color_texture->GetHeight();
// Draw the deserialized textures over the EFB. // Draw the deserialized textures over the EFB.
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
g_renderer->SetAndDiscardFramebuffer(m_efb_framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(m_efb_framebuffer.get());
g_renderer->SetViewportAndScissor(m_efb_framebuffer->GetRect()); g_gfx->SetViewportAndScissor(m_efb_framebuffer->GetRect());
g_renderer->SetPipeline(m_efb_restore_pipeline.get()); g_gfx->SetPipeline(m_efb_restore_pipeline.get());
g_renderer->SetTexture(0, color_tex->texture.get()); g_gfx->SetTexture(0, color_tex->texture.get());
g_renderer->SetTexture(1, depth_tex->texture.get()); g_gfx->SetTexture(1, depth_tex->texture.get());
g_renderer->SetSamplerState(0, rescale ? RenderState::GetLinearSamplerState() : g_gfx->SetSamplerState(0, rescale ? RenderState::GetLinearSamplerState() :
RenderState::GetPointSamplerState()); RenderState::GetPointSamplerState());
g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); g_gfx->SetSamplerState(1, RenderState::GetPointSamplerState());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
} }

View File

@ -10,6 +10,7 @@
#include "Core/Config/NetplaySettings.h" #include "Core/Config/NetplaySettings.h"
#include "Core/Movie.h" #include "Core/Movie.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractPipeline.h"
#include "VideoCommon/AbstractShader.h" #include "VideoCommon/AbstractShader.h"
#include "VideoCommon/FramebufferShaderGen.h" #include "VideoCommon/FramebufferShaderGen.h"
@ -18,7 +19,6 @@
#include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/OnScreenDisplay.h"
#include "VideoCommon/PerformanceMetrics.h" #include "VideoCommon/PerformanceMetrics.h"
#include "VideoCommon/Present.h" #include "VideoCommon/Present.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/Statistics.h" #include "VideoCommon/Statistics.h"
#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexManagerBase.h"
#include "VideoCommon/VideoConfig.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.texcoords[0] = {ComponentFormat::Float, 2, offsetof(ImDrawVert, uv), true, false};
vdecl.colors[0] = {ComponentFormat::UByte, 4, offsetof(ImDrawVert, col), true, false}; vdecl.colors[0] = {ComponentFormat::UByte, 4, offsetof(ImDrawVert, col), true, false};
vdecl.stride = sizeof(ImDrawVert); 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) if (!m_imgui_vertex_format)
{ {
PanicAlertFmt("Failed to create 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, TextureConfig font_tex_config(font_tex_width, font_tex_height, 1, 1, 1,
AbstractTextureFormat::RGBA8, 0); AbstractTextureFormat::RGBA8, 0);
std::unique_ptr<AbstractTexture> font_tex = std::unique_ptr<AbstractTexture> font_tex =
g_renderer->CreateTexture(font_tex_config, "ImGui font texture"); g_gfx->CreateTexture(font_tex_config, "ImGui font texture");
if (!font_tex) if (!font_tex)
{ {
PanicAlertFmt("Failed to create ImGui texture"); PanicAlertFmt("Failed to create ImGui texture");
@ -120,10 +120,10 @@ bool OnScreenUI::RecompileImGuiPipeline()
return true; return true;
} }
std::unique_ptr<AbstractShader> vertex_shader = g_renderer->CreateShaderFromSource( std::unique_ptr<AbstractShader> vertex_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Vertex, FramebufferShaderGen::GenerateImGuiVertexShader(), ShaderStage::Vertex, FramebufferShaderGen::GenerateImGuiVertexShader(),
"ImGui vertex shader"); "ImGui vertex shader");
std::unique_ptr<AbstractShader> pixel_shader = g_renderer->CreateShaderFromSource( std::unique_ptr<AbstractShader> pixel_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, FramebufferShaderGen::GenerateImGuiPixelShader(), "ImGui pixel shader"); ShaderStage::Pixel, FramebufferShaderGen::GenerateImGuiPixelShader(), "ImGui pixel shader");
if (!vertex_shader || !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. // GS is used to render the UI to both eyes in stereo modes.
std::unique_ptr<AbstractShader> geometry_shader; std::unique_ptr<AbstractShader> 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), ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(1, 1),
"ImGui passthrough geometry shader"); "ImGui passthrough geometry shader");
if (!geometry_shader) if (!geometry_shader)
@ -163,7 +163,7 @@ bool OnScreenUI::RecompileImGuiPipeline()
pconfig.framebuffer_state.samples = 1; pconfig.framebuffer_state.samples = 1;
pconfig.framebuffer_state.per_sample_shading = false; pconfig.framebuffer_state.per_sample_shading = false;
pconfig.usage = AbstractPipelineUsage::Utility; pconfig.usage = AbstractPipelineUsage::Utility;
m_imgui_pipeline = g_renderer->CreatePipeline(pconfig); m_imgui_pipeline = g_gfx->CreatePipeline(pconfig);
if (!m_imgui_pipeline) if (!m_imgui_pipeline)
{ {
PanicAlertFmt("Failed to create imgui pipeline"); PanicAlertFmt("Failed to create imgui pipeline");
@ -204,7 +204,7 @@ void OnScreenUI::DrawImGui()
if (!draw_data) if (!draw_data)
return; return;
g_renderer->SetViewport(0.0f, 0.0f, static_cast<float>(m_backbuffer_width), g_gfx->SetViewport(0.0f, 0.0f, static_cast<float>(m_backbuffer_width),
static_cast<float>(m_backbuffer_height), 0.0f, 1.0f); static_cast<float>(m_backbuffer_height), 0.0f, 1.0f);
// Uniform buffer for draws. // Uniform buffer for draws.
@ -216,8 +216,8 @@ void OnScreenUI::DrawImGui()
ImGuiUbo ubo = {{1.0f / m_backbuffer_width * 2.0f, 1.0f / m_backbuffer_height * 2.0f}}; ImGuiUbo ubo = {{1.0f / m_backbuffer_width * 2.0f, 1.0f / m_backbuffer_height * 2.0f}};
// Set up common state for drawing. // Set up common state for drawing.
g_renderer->SetPipeline(m_imgui_pipeline.get()); g_gfx->SetPipeline(m_imgui_pipeline.get());
g_renderer->SetSamplerState(0, RenderState::GetPointSamplerState()); g_gfx->SetSamplerState(0, RenderState::GetPointSamplerState());
g_vertex_manager->UploadUtilityUniforms(&ubo, sizeof(ubo)); g_vertex_manager->UploadUtilityUniforms(&ubo, sizeof(ubo));
for (int i = 0; i < draw_data->CmdListsCount; i++) for (int i = 0; i < draw_data->CmdListsCount; i++)
@ -239,13 +239,13 @@ void OnScreenUI::DrawImGui()
continue; continue;
} }
g_renderer->SetScissorRect(g_renderer->ConvertFramebufferRectangle( g_gfx->SetScissorRect(g_gfx->ConvertFramebufferRectangle(
MathUtil::Rectangle<int>( MathUtil::Rectangle<int>(
static_cast<int>(cmd.ClipRect.x), static_cast<int>(cmd.ClipRect.y), static_cast<int>(cmd.ClipRect.x), static_cast<int>(cmd.ClipRect.y),
static_cast<int>(cmd.ClipRect.z), static_cast<int>(cmd.ClipRect.w)), static_cast<int>(cmd.ClipRect.z), static_cast<int>(cmd.ClipRect.w)),
g_renderer->GetCurrentFramebuffer())); g_gfx->GetCurrentFramebuffer()));
g_renderer->SetTexture(0, reinterpret_cast<const AbstractTexture*>(cmd.TextureId)); g_gfx->SetTexture(0, reinterpret_cast<const AbstractTexture*>(cmd.TextureId));
g_renderer->DrawIndexed(base_index, cmd.ElemCount, base_vertex); g_gfx->DrawIndexed(base_index, cmd.ElemCount, base_vertex);
base_index += cmd.ElemCount; 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 // 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 // capture whenever any ImGui windows are open. We'll reset the scissor rectangle to the entire
// viewport here to avoid this problem. // viewport here to avoid this problem.
g_renderer->SetScissorRect(g_renderer->ConvertFramebufferRectangle( g_gfx->SetScissorRect(g_gfx->ConvertFramebufferRectangle(
MathUtil::Rectangle<int>(0, 0, m_backbuffer_width, m_backbuffer_height), MathUtil::Rectangle<int>(0, 0, m_backbuffer_width, m_backbuffer_height),
g_renderer->GetCurrentFramebuffer())); g_gfx->GetCurrentFramebuffer()));
} }
// Create On-Screen-Messages // Create On-Screen-Messages

View File

@ -20,12 +20,12 @@
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractPipeline.h" #include "VideoCommon/AbstractPipeline.h"
#include "VideoCommon/AbstractShader.h" #include "VideoCommon/AbstractShader.h"
#include "VideoCommon/AbstractTexture.h" #include "VideoCommon/AbstractTexture.h"
#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/Present.h" #include "VideoCommon/Present.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/ShaderCache.h" #include "VideoCommon/ShaderCache.h"
#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexManagerBase.h"
#include "VideoCommon/VideoCommon.h" #include "VideoCommon/VideoCommon.h"
@ -417,9 +417,9 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst,
const MathUtil::Rectangle<int>& src, const MathUtil::Rectangle<int>& src,
const AbstractTexture* src_tex, int src_layer) 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(); RecompilePipeline();
} }
@ -430,12 +430,12 @@ void PostProcessing::BlitFromTexture(const MathUtil::Rectangle<int>& dst,
g_vertex_manager->UploadUtilityUniforms(m_uniform_staging_buffer.data(), g_vertex_manager->UploadUtilityUniforms(m_uniform_staging_buffer.data(),
static_cast<u32>(m_uniform_staging_buffer.size())); static_cast<u32>(m_uniform_staging_buffer.size()));
g_renderer->SetViewportAndScissor( g_gfx->SetViewportAndScissor(
g_renderer->ConvertFramebufferRectangle(dst, g_renderer->GetCurrentFramebuffer())); g_gfx->ConvertFramebufferRectangle(dst, g_gfx->GetCurrentFramebuffer()));
g_renderer->SetPipeline(m_pipeline.get()); g_gfx->SetPipeline(m_pipeline.get());
g_renderer->SetTexture(0, src_tex); g_gfx->SetTexture(0, src_tex);
g_renderer->SetSamplerState(0, RenderState::GetLinearSamplerState()); g_gfx->SetSamplerState(0, RenderState::GetLinearSamplerState());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
} }
std::string PostProcessing::GetUniformBufferHeader() const std::string PostProcessing::GetUniformBufferHeader() const
@ -598,8 +598,8 @@ bool PostProcessing::CompileVertexShader()
ss << "}\n"; ss << "}\n";
m_vertex_shader = g_renderer->CreateShaderFromSource(ShaderStage::Vertex, ss.str(), m_vertex_shader =
"Post-processing vertex shader"); g_gfx->CreateShaderFromSource(ShaderStage::Vertex, ss.str(), "Post-processing vertex shader");
if (!m_vertex_shader) if (!m_vertex_shader)
{ {
PanicAlertFmt("Failed to compile post-processing vertex shader"); PanicAlertFmt("Failed to compile post-processing vertex shader");
@ -688,7 +688,7 @@ bool PostProcessing::CompilePixelShader()
// Generate GLSL and compile the new shader. // Generate GLSL and compile the new shader.
m_config.LoadShader(g_ActiveConfig.sPostProcessingShader); 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(), ShaderStage::Pixel, GetHeader() + m_config.GetShaderCode() + GetFooter(),
fmt::format("Post-processing pixel shader: {}", m_config.GetShader())); fmt::format("Post-processing pixel shader: {}", m_config.GetShader()));
if (!m_pixel_shader) if (!m_pixel_shader)
@ -697,7 +697,7 @@ bool PostProcessing::CompilePixelShader()
// Use default shader. // Use default shader.
m_config.LoadDefaultShader(); m_config.LoadDefaultShader();
m_pixel_shader = g_renderer->CreateShaderFromSource( m_pixel_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, GetHeader() + m_config.GetShaderCode() + GetFooter(), ShaderStage::Pixel, GetHeader() + m_config.GetShaderCode() + GetFooter(),
"Default post-processing pixel shader"); "Default post-processing pixel shader");
if (!m_pixel_shader) if (!m_pixel_shader)
@ -716,14 +716,14 @@ bool PostProcessing::CompilePipeline()
AbstractPipelineConfig config = {}; AbstractPipelineConfig config = {};
config.vertex_shader = m_vertex_shader.get(); config.vertex_shader = m_vertex_shader.get();
config.geometry_shader = 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.pixel_shader = m_pixel_shader.get();
config.rasterization_state = RenderState::GetNoCullRasterizationState(PrimitiveType::Triangles); config.rasterization_state = RenderState::GetNoCullRasterizationState(PrimitiveType::Triangles);
config.depth_state = RenderState::GetNoDepthTestingDepthState(); config.depth_state = RenderState::GetNoDepthTestingDepthState();
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = RenderState::GetColorFramebufferState(m_framebuffer_format); config.framebuffer_state = RenderState::GetColorFramebufferState(m_framebuffer_format);
config.usage = AbstractPipelineUsage::Utility; config.usage = AbstractPipelineUsage::Utility;
m_pipeline = g_renderer->CreatePipeline(config); m_pipeline = g_gfx->CreatePipeline(config);
if (!m_pipeline) if (!m_pipeline)
return false; return false;

View File

@ -8,6 +8,7 @@
#include "InputCommon/ControllerInterface/ControllerInterface.h" #include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/FrameDumper.h" #include "VideoCommon/FrameDumper.h"
#include "VideoCommon/OnScreenUI.h" #include "VideoCommon/OnScreenUI.h"
#include "VideoCommon/PostProcessing.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)) if (!m_onscreen_ui->Initialize(m_backbuffer_width, m_backbuffer_height, m_backbuffer_scale))
return false; return false;
if (!g_gfx->IsHeadless())
SetBackbuffer(g_gfx->GetSurfaceInfo());
return true; return true;
} }
@ -57,13 +61,12 @@ void Presenter::SetBackbuffer(int backbuffer_width, int backbuffer_height)
UpdateDrawRectangle(); UpdateDrawRectangle();
} }
void Presenter::SetBackbuffer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, void Presenter::SetBackbuffer(SurfaceInfo info)
AbstractTextureFormat backbuffer_format)
{ {
m_backbuffer_width = backbuffer_width; m_backbuffer_width = info.width;
m_backbuffer_height = backbuffer_height; m_backbuffer_height = info.height;
m_backbuffer_scale = backbuffer_scale; m_backbuffer_scale = info.scale;
m_backbuffer_format = backbuffer_format; m_backbuffer_format = info.format;
UpdateDrawRectangle(); UpdateDrawRectangle();
} }
@ -74,14 +77,14 @@ void Presenter::CheckForConfigChanges(u32 changed_bits)
if (m_post_processor->GetConfig()->GetShader() != g_ActiveConfig.sPostProcessingShader) if (m_post_processor->GetConfig()->GetShader() != g_ActiveConfig.sPostProcessingShader)
{ {
// The existing shader must not be in use when it's destroyed // The existing shader must not be in use when it's destroyed
g_renderer->WaitForGPUIdle(); g_gfx->WaitForGPUIdle();
m_post_processor->RecompileShader(); m_post_processor->RecompileShader();
} }
// Stereo mode change requires recompiling our post processing pipeline and imgui pipelines for // Stereo mode change requires recompiling our post processing pipeline and imgui pipelines for
// rendering the UI. // 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_onscreen_ui->RecompileImGuiPipeline();
m_post_processor->RecompilePipeline(); m_post_processor->RecompilePipeline();
@ -90,24 +93,24 @@ void Presenter::CheckForConfigChanges(u32 changed_bits)
void Presenter::BeginUIFrame() void Presenter::BeginUIFrame()
{ {
if (g_renderer->IsHeadless()) if (g_gfx->IsHeadless())
return; return;
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
g_renderer->BindBackbuffer({0.0f, 0.0f, 0.0f, 1.0f}); g_gfx->BindBackbuffer({0.0f, 0.0f, 0.0f, 1.0f});
} }
void Presenter::EndUIFrame() void Presenter::EndUIFrame()
{ {
m_onscreen_ui->Finalize(); m_onscreen_ui->Finalize();
if (g_renderer->IsHeadless()) if (g_gfx->IsHeadless())
{ {
m_onscreen_ui->DrawImGui(); m_onscreen_ui->DrawImGui();
std::lock_guard<std::mutex> guard(m_swap_mutex); std::lock_guard<std::mutex> guard(m_swap_mutex);
g_renderer->PresentBackbuffer(); g_gfx->PresentBackbuffer();
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
} }
m_onscreen_ui->BeginImGuiFrame(m_backbuffer_width, m_backbuffer_height); m_onscreen_ui->BeginImGuiFrame(m_backbuffer_width, m_backbuffer_height);
@ -392,7 +395,7 @@ void Presenter::RenderXFBToScreen(const MathUtil::Rectangle<int>& target_rc,
{ {
if (!g_ActiveConfig.backend_info.bSupportsPostProcessing) if (!g_ActiveConfig.backend_info.bSupportsPostProcessing)
{ {
g_renderer->ShowImage(source_texture, source_rc); g_gfx->ShowImage(source_texture, source_rc);
return; return;
} }
@ -400,13 +403,13 @@ void Presenter::RenderXFBToScreen(const MathUtil::Rectangle<int>& target_rc,
g_ActiveConfig.backend_info.bUsesExplictQuadBuffering) g_ActiveConfig.backend_info.bUsesExplictQuadBuffering)
{ {
// Quad-buffered stereo is annoying on GL. // Quad-buffered stereo is annoying on GL.
g_renderer->SelectLeftBuffer(); g_gfx->SelectLeftBuffer();
m_post_processor->BlitFromTexture(target_rc, source_rc, source_texture, 0); 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); 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 || else if (g_ActiveConfig.stereo_mode == StereoMode::SBS ||
g_ActiveConfig.stereo_mode == StereoMode::TAB) g_ActiveConfig.stereo_mode == StereoMode::TAB)
@ -436,7 +439,7 @@ bool Presenter::SubmitXFB(RcTcacheEntry xfb_entry, MathUtil::Rectangle<int>& xfb
if (g_frame_dumper->IsFrameDumping()) if (g_frame_dumper->IsFrameDumping())
{ {
MathUtil::Rectangle<int> target_rect; MathUtil::Rectangle<int> target_rect;
if (!g_ActiveConfig.bInternalResolutionFrameDumps && !g_renderer->IsHeadless()) if (!g_ActiveConfig.bInternalResolutionFrameDumps && !g_gfx->IsHeadless())
{ {
target_rect = GetTargetRectangle(); target_rect = GetTargetRectangle();
} }
@ -469,10 +472,10 @@ void Presenter::Present()
m_onscreen_ui->Finalize(); m_onscreen_ui->Finalize();
// Render the XFB to the screen. // Render the XFB to the screen.
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
if (!g_renderer->IsHeadless()) 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(); UpdateDrawRectangle();
@ -488,7 +491,7 @@ void Presenter::Present()
// Present to the window system. // Present to the window system.
{ {
std::lock_guard<std::mutex> guard(m_swap_mutex); std::lock_guard<std::mutex> guard(m_swap_mutex);
g_renderer->PresentBackbuffer(); g_gfx->PresentBackbuffer();
} }
// Update the window size based on the frame that was just rendered. // 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); m_onscreen_ui->BeginImGuiFrame(m_backbuffer_width, m_backbuffer_height);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
} }
void Presenter::SetKeyMap(std::span<std::array<int, 2>> key_map) void Presenter::SetKeyMap(std::span<std::array<int, 2>> key_map)

View File

@ -16,6 +16,7 @@
#include <tuple> #include <tuple>
class AbstractTexture; class AbstractTexture;
struct SurfaceInfo;
namespace VideoCommon namespace VideoCommon
{ {
@ -51,8 +52,7 @@ public:
AbstractTextureFormat GetBackbufferFormat() const { return m_backbuffer_format; } AbstractTextureFormat GetBackbufferFormat() const { return m_backbuffer_format; }
void SetWindowSize(int width, int height); void SetWindowSize(int width, int height);
void SetBackbuffer(int backbuffer_width, int backbuffer_height); void SetBackbuffer(int backbuffer_width, int backbuffer_height);
void SetBackbuffer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, void SetBackbuffer(SurfaceInfo info);
AbstractTextureFormat backbuffer_format);
void UpdateDrawRectangle(); void UpdateDrawRectangle();

View File

@ -38,6 +38,7 @@
#include "Core/System.h" #include "Core/System.h"
#include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractTexture.h" #include "VideoCommon/AbstractTexture.h"
#include "VideoCommon/BoundingBox.h" #include "VideoCommon/BoundingBox.h"
#include "VideoCommon/CommandProcessor.h" #include "VideoCommon/CommandProcessor.h"
@ -59,17 +60,12 @@
std::unique_ptr<Renderer> g_renderer; std::unique_ptr<Renderer> g_renderer;
Renderer::Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, Renderer::Renderer() : m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT}
AbstractTextureFormat backbuffer_format)
: m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT}
{ {
UpdateActiveConfig(); UpdateActiveConfig();
FreeLook::UpdateActiveConfig(); FreeLook::UpdateActiveConfig();
CalculateTargetSize(); CalculateTargetSize();
g_presenter->SetBackbuffer(backbuffer_width, backbuffer_height, backbuffer_scale,
backbuffer_format);
m_is_game_widescreen = SConfig::GetInstance().bWii && Config::Get(Config::SYSCONF_WIDESCREEN); m_is_game_widescreen = SConfig::GetInstance().bWii && Config::Get(Config::SYSCONF_WIDESCREEN);
g_freelook_camera.SetControlType(FreeLook::GetActiveConfig().camera_config.control_type); g_freelook_camera.SetControlType(FreeLook::GetActiveConfig().camera_config.control_type);
} }
@ -78,13 +74,6 @@ Renderer::~Renderer() = default;
bool Renderer::Initialize() 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 (g_ActiveConfig.bGraphicMods)
{ {
// If a config change occurred in a previous session, // 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); m_graphics_mod_manager.Load(*g_ActiveConfig.graphics_mod_config);
} }
return g_presenter->Initialize(); return true;
} }
void Renderer::Shutdown() void Renderer::Shutdown()
{ {
m_bounding_box.reset(); g_bounding_box.reset();
} }
void Renderer::BeginUtilityDrawing() void Renderer::BeginUtilityDrawing()
@ -121,31 +110,38 @@ void Renderer::EndUtilityDrawing()
BPFunctions::SetScissorAndViewport(); 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 bool Renderer::EFBHasAlphaChannel() const
{ {
return m_prev_efb_format == PixelFormat::RGBA6_Z24; return m_prev_efb_format == PixelFormat::RGBA6_Z24;
} }
void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool colorEnable, bool alphaEnable, void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool color_enable, bool alpha_enable,
bool zEnable, u32 color, u32 z) 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<int> 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) void Renderer::ReinterpretPixelData(EFBReinterpretType convtype)
@ -155,17 +151,17 @@ void Renderer::ReinterpretPixelData(EFBReinterpretType convtype)
bool Renderer::IsBBoxEnabled() const bool Renderer::IsBBoxEnabled() const
{ {
return m_bounding_box->IsEnabled(); return g_bounding_box->IsEnabled();
} }
void Renderer::BBoxEnable(PixelShaderManager& pixel_shader_manager) 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) 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) u16 Renderer::BBoxRead(u32 index)
@ -173,7 +169,7 @@ u16 Renderer::BBoxRead(u32 index)
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
return m_bounding_box_fallback[index]; 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) void Renderer::BBoxWrite(u32 index, u16 value)
@ -184,7 +180,7 @@ void Renderer::BBoxWrite(u32 index, u16 value)
return; return;
} }
m_bounding_box->Set(index, value); g_bounding_box->Set(index, value);
} }
void Renderer::BBoxFlush() void Renderer::BBoxFlush()
@ -192,7 +188,7 @@ void Renderer::BBoxFlush()
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox) if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
return; return;
m_bounding_box->Flush(); g_bounding_box->Flush();
} }
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
@ -436,13 +432,13 @@ void Renderer::CheckForConfigChanges()
return; return;
// Notify the backend of the changes, if any. // 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 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)) if (changed_bits & (CONFIG_CHANGE_BIT_HOST_CONFIG | CONFIG_CHANGE_BIT_MULTISAMPLES))
{ {
WaitForGPUIdle(); g_gfx->WaitForGPUIdle();
SetPipeline(nullptr); g_gfx->SetPipeline(nullptr);
} }
// Framebuffer changed? // Framebuffer changed?
@ -469,81 +465,6 @@ void Renderer::CheckForConfigChanges()
} }
} }
bool Renderer::IsHeadless() const
{
return true;
}
void Renderer::SetViewportAndScissor(const MathUtil::Rectangle<int>& rect, float min_depth,
float max_depth)
{
SetViewport(static_cast<float>(rect.left), static_cast<float>(rect.top),
static_cast<float>(rect.GetWidth()), static_cast<float>(rect.GetHeight()), min_depth,
max_depth);
SetScissorRect(rect);
}
void Renderer::ScaleTexture(AbstractFramebuffer* dst_framebuffer,
const MathUtil::Rectangle<int>& dst_rect,
const AbstractTexture* src_texture,
const MathUtil::Rectangle<int>& 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<float, 4> 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<u32>(dst_rect.GetWidth()) == dst_framebuffer->GetWidth() &&
static_cast<u32>(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<int>
Renderer::ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect,
const AbstractFramebuffer* framebuffer) const
{
return ConvertFramebufferRectangle(rect, framebuffer->GetWidth(), framebuffer->GetHeight());
}
MathUtil::Rectangle<int> Renderer::ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect,
u32 fb_width, u32 fb_height) const
{
MathUtil::Rectangle<int> ret = rect;
if (g_ActiveConfig.backend_info.bUsesLowerLeftOrigin)
{
ret.top = fb_height - rect.bottom;
ret.bottom = fb_height - rect.top;
}
return ret;
}
MathUtil::Rectangle<int> Renderer::ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const MathUtil::Rectangle<int> Renderer::ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const
{ {
MathUtil::Rectangle<int> result; MathUtil::Rectangle<int> result;
@ -590,14 +511,6 @@ void Renderer::RecordVideoMemory()
texMem); 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() void Renderer::ForceReloadTextures()
{ {
m_force_reload_textures.Set(); 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 else
{ {
Flush(); g_gfx->Flush();
} }
// Update our last xfb values // 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 else
{ {
Flush(); g_gfx->Flush();
} }
} }
@ -803,7 +716,7 @@ void Renderer::DoState(PointerWrap& p)
p.Do(m_last_xfb_height); p.Do(m_last_xfb_height);
p.DoArray(m_bounding_box_fallback); p.DoArray(m_bounding_box_fallback);
m_bounding_box->DoState(p); g_bounding_box->DoState(p);
if (p.IsReadMode()) if (p.IsReadMode())
{ {
@ -821,11 +734,6 @@ void Renderer::DoState(PointerWrap& p)
#endif #endif
} }
std::unique_ptr<VideoCommon::AsyncShaderCompiler> Renderer::CreateAsyncShaderCompiler()
{
return std::make_unique<VideoCommon::AsyncShaderCompiler>();
}
const GraphicsModManager& Renderer::GetGraphicsModManager() const const GraphicsModManager& Renderer::GetGraphicsModManager() const
{ {
return m_graphics_mod_manager; return m_graphics_mod_manager;

View File

@ -64,100 +64,18 @@ struct EfbPokeData
class Renderer class Renderer
{ {
public: public:
Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale, Renderer();
AbstractTextureFormat backbuffer_format);
virtual ~Renderer(); virtual ~Renderer();
using ClearColor = std::array<float, 4>;
virtual bool IsHeadless() const = 0;
virtual bool Initialize(); virtual bool Initialize();
virtual void Shutdown(); virtual void Shutdown();
virtual void SetPipeline(const AbstractPipeline* pipeline) {} void BeginUtilityDrawing();
virtual void SetScissorRect(const MathUtil::Rectangle<int>& rc) {} void EndUtilityDrawing();
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<AbstractTexture> CreateTexture(const TextureConfig& config,
std::string_view name = "") = 0;
virtual std::unique_ptr<AbstractStagingTexture>
CreateStagingTexture(StagingTextureType type, const TextureConfig& config) = 0;
virtual std::unique_ptr<AbstractFramebuffer>
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<AbstractShader> CreateShaderFromSource(ShaderStage stage,
std::string_view source,
std::string_view name = "") = 0;
virtual std::unique_ptr<AbstractShader> CreateShaderFromBinary(ShaderStage stage,
const void* data, size_t length,
std::string_view name = "") = 0;
virtual std::unique_ptr<NativeVertexFormat>
CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl) = 0;
virtual std::unique_ptr<AbstractPipeline> CreatePipeline(const AbstractPipelineConfig& config,
const void* cache_data = nullptr,
size_t cache_data_length = 0) = 0;
AbstractFramebuffer* GetCurrentFramebuffer() const { return m_current_framebuffer; }
// Ideal internal resolution - multiple of the native EFB resolution // Ideal internal resolution - multiple of the native EFB resolution
int GetTargetWidth() const { return m_target_width; } int GetTargetWidth() const { return m_target_width; }
int GetTargetHeight() const { return m_target_height; } 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<int>& 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<int>& dst_rect,
const AbstractTexture* src_texture,
const MathUtil::Rectangle<int>& src_rect);
// Converts an upper-left to lower-left if required by the backend, optionally
// clamping to the framebuffer size.
MathUtil::Rectangle<int> ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect,
u32 fb_width, u32 fb_height) const;
MathUtil::Rectangle<int>
ConvertFramebufferRectangle(const MathUtil::Rectangle<int>& rect,
const AbstractFramebuffer* framebuffer) const;
// EFB coordinate conversion functions // EFB coordinate conversion functions
// Use this to convert a whole native EFB rect to backbuffer coordinates // Use this to convert a whole native EFB rect to backbuffer coordinates
MathUtil::Rectangle<int> ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const; MathUtil::Rectangle<int> ConvertEFBRectangle(const MathUtil::Rectangle<int>& rc) const;
@ -188,29 +106,12 @@ public:
void BBoxWrite(u32 index, u16 value); void BBoxWrite(u32 index, u16 value);
void BBoxFlush(); void BBoxFlush();
virtual void Flush() {}
virtual void WaitForGPUIdle() {}
// Finish up the current frame, print some stats // 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 Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u64 ticks);
void UpdateWidescreenHeuristic(); void UpdateWidescreenHeuristic();
bool IsGameWidescreen() const { return m_is_game_widescreen; } 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<int>& 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; } PixelFormat GetPrevPixelFormat() const { return m_prev_efb_format; }
void StorePixelFormat(PixelFormat new_format) { m_prev_efb_format = new_format; } void StorePixelFormat(PixelFormat new_format) { m_prev_efb_format = new_format; }
bool EFBHasAlphaChannel() const; bool EFBHasAlphaChannel() const;
@ -218,30 +119,11 @@ public:
bool UseVertexDepthRange() const; bool UseVertexDepthRange() const;
void DoState(PointerWrap& p); void DoState(PointerWrap& p);
virtual std::unique_ptr<VideoCommon::AsyncShaderCompiler> 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 // Will forcibly reload all textures on the next swap
void ForceReloadTextures(); void ForceReloadTextures();
const GraphicsModManager& GetGraphicsModManager() const; 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: protected:
std::tuple<int, int> CalculateTargetScale(int x, int y) const; std::tuple<int, int> CalculateTargetScale(int x, int y) const;
bool CalculateTargetSize(); bool CalculateTargetSize();
@ -251,11 +133,6 @@ protected:
void CheckFifoRecording(); void CheckFifoRecording();
void RecordVideoMemory(); void RecordVideoMemory();
virtual std::unique_ptr<BoundingBox> CreateBoundingBox() const = 0;
AbstractFramebuffer* m_current_framebuffer = nullptr;
const AbstractPipeline* m_current_pipeline = nullptr;
bool m_is_game_widescreen = false; bool m_is_game_widescreen = false;
bool m_was_orthographically_anamorphic = false; bool m_was_orthographically_anamorphic = false;

View File

@ -10,12 +10,12 @@
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/ConstantManager.h" #include "VideoCommon/ConstantManager.h"
#include "VideoCommon/DriverDetails.h" #include "VideoCommon/DriverDetails.h"
#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/FramebufferManager.h"
#include "VideoCommon/FramebufferShaderGen.h" #include "VideoCommon/FramebufferShaderGen.h"
#include "VideoCommon/Present.h" #include "VideoCommon/Present.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/Statistics.h" #include "VideoCommon/Statistics.h"
#include "VideoCommon/VertexLoaderManager.h" #include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexManagerBase.h"
@ -45,7 +45,7 @@ bool ShaderCache::Initialize()
if (!CompileSharedPipelines()) if (!CompileSharedPipelines())
return false; return false;
m_async_shader_compiler = g_renderer->CreateAsyncShaderCompiler(); m_async_shader_compiler = g_gfx->CreateAsyncShaderCompiler();
return true; return true;
} }
@ -122,7 +122,7 @@ const AbstractPipeline* ShaderCache::GetPipelineForUid(const GXPipelineUid& uid)
std::unique_ptr<AbstractPipeline> pipeline; std::unique_ptr<AbstractPipeline> pipeline;
std::optional<AbstractPipelineConfig> pipeline_config = GetGXPipelineConfig(uid); std::optional<AbstractPipelineConfig> pipeline_config = GetGXPipelineConfig(uid);
if (pipeline_config) if (pipeline_config)
pipeline = g_renderer->CreatePipeline(*pipeline_config); pipeline = g_gfx->CreatePipeline(*pipeline_config);
if (g_ActiveConfig.bShaderCache && !exists_in_cache) if (g_ActiveConfig.bShaderCache && !exists_in_cache)
AppendGXPipelineUID(uid); AppendGXPipelineUID(uid);
return InsertGXPipeline(uid, std::move(pipeline)); return InsertGXPipeline(uid, std::move(pipeline));
@ -154,7 +154,7 @@ const AbstractPipeline* ShaderCache::GetUberPipelineForUid(const GXUberPipelineU
std::unique_ptr<AbstractPipeline> pipeline; std::unique_ptr<AbstractPipeline> pipeline;
std::optional<AbstractPipelineConfig> pipeline_config = GetGXPipelineConfig(uid); std::optional<AbstractPipelineConfig> pipeline_config = GetGXPipelineConfig(uid);
if (pipeline_config) if (pipeline_config)
pipeline = g_renderer->CreatePipeline(*pipeline_config); pipeline = g_gfx->CreatePipeline(*pipeline_config);
return InsertGXUberPipeline(uid, std::move(pipeline)); 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_) {} CacheReader(T& cache_) : cache(cache_) {}
void Read(const K& key, const u8* value, u32 value_size) 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) if (shader)
{ {
auto& entry = cache.shader_map[key]; auto& entry = cache.shader_map[key];
@ -298,7 +298,7 @@ void ShaderCache::LoadPipelineCache(T& cache, LinearDiskCache<DiskKeyType, u8>&
if (!config) if (!config)
return; return;
auto pipeline = g_renderer->CreatePipeline(*config, value, value_size); auto pipeline = g_gfx->CreatePipeline(*config, value, value_size);
if (!pipeline) if (!pipeline)
{ {
// If any of the pipelines fail to create, consider the cache stale. // If any of the pipelines fail to create, consider the cache stale.
@ -435,7 +435,7 @@ std::unique_ptr<AbstractShader> ShaderCache::CompileVertexShader(const VertexSha
{ {
const ShaderCode source_code = const ShaderCode source_code =
GenerateVertexShaderCode(m_api_type, m_host_config, uid.GetUidData()); 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<AbstractShader> std::unique_ptr<AbstractShader>
@ -443,7 +443,7 @@ ShaderCache::CompileVertexUberShader(const UberShader::VertexShaderUid& uid) con
{ {
const ShaderCode source_code = const ShaderCode source_code =
UberShader::GenVertexShader(m_api_type, m_host_config, uid.GetUidData()); UberShader::GenVertexShader(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(),
fmt::to_string(*uid.GetUidData())); fmt::to_string(*uid.GetUidData()));
} }
@ -451,7 +451,7 @@ std::unique_ptr<AbstractShader> ShaderCache::CompilePixelShader(const PixelShade
{ {
const ShaderCode source_code = const ShaderCode source_code =
GeneratePixelShaderCode(m_api_type, m_host_config, uid.GetUidData()); 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<AbstractShader> std::unique_ptr<AbstractShader>
@ -459,7 +459,7 @@ ShaderCache::CompilePixelUberShader(const UberShader::PixelShaderUid& uid) const
{ {
const ShaderCode source_code = const ShaderCode source_code =
UberShader::GenPixelShader(m_api_type, m_host_config, uid.GetUidData()); UberShader::GenPixelShader(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(),
fmt::to_string(*uid.GetUidData())); fmt::to_string(*uid.GetUidData()));
} }
@ -556,7 +556,7 @@ const AbstractShader* ShaderCache::CreateGeometryShader(const GeometryShaderUid&
const ShaderCode source_code = const ShaderCode source_code =
GenerateGeometryShaderCode(m_api_type, m_host_config, uid.GetUidData()); GenerateGeometryShaderCode(m_api_type, m_host_config, uid.GetUidData());
std::unique_ptr<AbstractShader> shader = std::unique_ptr<AbstractShader> shader =
g_renderer->CreateShaderFromSource(ShaderStage::Geometry, source_code.GetBuffer(), g_gfx->CreateShaderFromSource(ShaderStage::Geometry, source_code.GetBuffer(),
fmt::format("Geometry shader: {}", *uid.GetUidData())); fmt::format("Geometry shader: {}", *uid.GetUidData()));
auto& entry = m_gs_cache.shader_map[uid]; auto& entry = m_gs_cache.shader_map[uid];
@ -1159,7 +1159,7 @@ void ShaderCache::QueuePipelineCompile(const GXPipelineUid& uid, u32 priority)
bool Compile() override bool Compile() override
{ {
if (config) if (config)
pipeline = g_renderer->CreatePipeline(*config); pipeline = g_gfx->CreatePipeline(*config);
return true; return true;
} }
@ -1234,7 +1234,7 @@ void ShaderCache::QueueUberPipelineCompile(const GXUberPipelineUid& uid, u32 pri
bool Compile() override bool Compile() override
{ {
if (config) if (config)
UberPipeline = g_renderer->CreatePipeline(*config); UberPipeline = g_gfx->CreatePipeline(*config);
return true; return true;
} }
@ -1372,7 +1372,7 @@ ShaderCache::GetEFBCopyToVRAMPipeline(const TextureConversionShaderGen::TCShader
return iter->second.get(); return iter->second.get();
auto shader_code = TextureConversionShaderGen::GeneratePixelShader(m_api_type, uid.GetUidData()); 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(), ShaderStage::Pixel, shader_code.GetBuffer(),
fmt::format("EFB copy to VRAM pixel shader: {}", *uid.GetUidData())); fmt::format("EFB copy to VRAM pixel shader: {}", *uid.GetUidData()));
if (!shader) if (!shader)
@ -1392,7 +1392,7 @@ ShaderCache::GetEFBCopyToVRAMPipeline(const TextureConversionShaderGen::TCShader
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = RenderState::GetRGBA8FramebufferState(); config.framebuffer_state = RenderState::GetRGBA8FramebufferState();
config.usage = AbstractPipelineUsage::Utility; 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(); return iiter.first->second.get();
} }
@ -1404,7 +1404,7 @@ const AbstractPipeline* ShaderCache::GetEFBCopyToRAMPipeline(const EFBCopyParams
const std::string shader_code = const std::string shader_code =
TextureConversionShaderTiled::GenerateEncodingShader(uid, m_api_type); 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)); ShaderStage::Pixel, shader_code, fmt::format("EFB copy to RAM pixel shader: {}", uid));
if (!shader) if (!shader)
{ {
@ -1420,19 +1420,19 @@ const AbstractPipeline* ShaderCache::GetEFBCopyToRAMPipeline(const EFBCopyParams
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = RenderState::GetColorFramebufferState(AbstractTextureFormat::BGRA8); config.framebuffer_state = RenderState::GetColorFramebufferState(AbstractTextureFormat::BGRA8);
config.usage = AbstractPipelineUsage::Utility; 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(); return iiter.first->second.get();
} }
bool ShaderCache::CompileSharedPipelines() bool ShaderCache::CompileSharedPipelines()
{ {
m_screen_quad_vertex_shader = g_renderer->CreateShaderFromSource( m_screen_quad_vertex_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Vertex, FramebufferShaderGen::GenerateScreenQuadVertexShader(), ShaderStage::Vertex, FramebufferShaderGen::GenerateScreenQuadVertexShader(),
"Screen quad vertex shader"); "Screen quad vertex shader");
m_texture_copy_vertex_shader = g_renderer->CreateShaderFromSource( m_texture_copy_vertex_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Vertex, FramebufferShaderGen::GenerateTextureCopyVertexShader(), ShaderStage::Vertex, FramebufferShaderGen::GenerateTextureCopyVertexShader(),
"Texture copy vertex shader"); "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(), ShaderStage::Vertex, TextureConversionShaderGen::GenerateVertexShader(m_api_type).GetBuffer(),
"EFB copy vertex shader"); "EFB copy vertex shader");
if (!m_screen_quad_vertex_shader || !m_texture_copy_vertex_shader || !m_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()) if (UseGeometryShaderForEFBCopies())
{ {
m_texcoord_geometry_shader = g_renderer->CreateShaderFromSource( m_texcoord_geometry_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(1, 0), ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(1, 0),
"Texcoord passthrough geometry shader"); "Texcoord passthrough geometry shader");
m_color_geometry_shader = g_renderer->CreateShaderFromSource( m_color_geometry_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(0, 1), ShaderStage::Geometry, FramebufferShaderGen::GeneratePassthroughGeometryShader(0, 1),
"Color passthrough geometry shader"); "Color passthrough geometry shader");
if (!m_texcoord_geometry_shader || !m_color_geometry_shader) if (!m_texcoord_geometry_shader || !m_color_geometry_shader)
return false; return false;
} }
m_texture_copy_pixel_shader = g_renderer->CreateShaderFromSource( m_texture_copy_pixel_shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, FramebufferShaderGen::GenerateTextureCopyPixelShader(), ShaderStage::Pixel, FramebufferShaderGen::GenerateTextureCopyPixelShader(),
"Texture copy pixel shader"); "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"); ShaderStage::Pixel, FramebufferShaderGen::GenerateColorPixelShader(), "Color pixel shader");
if (!m_texture_copy_pixel_shader || !m_color_pixel_shader) if (!m_texture_copy_pixel_shader || !m_color_pixel_shader)
return false; return false;
@ -1468,14 +1468,14 @@ bool ShaderCache::CompileSharedPipelines()
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = RenderState::GetRGBA8FramebufferState(); config.framebuffer_state = RenderState::GetRGBA8FramebufferState();
config.usage = AbstractPipelineUsage::Utility; 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) if (!m_copy_rgba8_pipeline)
return false; return false;
if (UseGeometryShaderForEFBCopies()) if (UseGeometryShaderForEFBCopies())
{ {
config.geometry_shader = m_texcoord_geometry_shader.get(); 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) if (!m_rgba8_stereo_copy_pipeline)
return false; return false;
} }
@ -1488,7 +1488,7 @@ bool ShaderCache::CompileSharedPipelines()
for (size_t i = 0; i < NUM_PALETTE_CONVERSION_SHADERS; i++) for (size_t i = 0; i < NUM_PALETTE_CONVERSION_SHADERS; i++)
{ {
TLUTFormat format = static_cast<TLUTFormat>(i); TLUTFormat format = static_cast<TLUTFormat>(i);
auto shader = g_renderer->CreateShaderFromSource( auto shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, ShaderStage::Pixel,
TextureConversionShaderTiled::GeneratePaletteConversionShader(format, m_api_type), TextureConversionShaderTiled::GeneratePaletteConversionShader(format, m_api_type),
fmt::format("Palette conversion pixel shader: {}", format)); fmt::format("Palette conversion pixel shader: {}", format));
@ -1496,7 +1496,7 @@ bool ShaderCache::CompileSharedPipelines()
return false; return false;
config.pixel_shader = shader.get(); 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]) if (!m_palette_conversion_pipelines[i])
return false; return false;
} }
@ -1527,7 +1527,7 @@ const AbstractPipeline* ShaderCache::GetTextureReinterpretPipeline(TextureFormat
return nullptr; return nullptr;
} }
std::unique_ptr<AbstractShader> shader = g_renderer->CreateShaderFromSource( std::unique_ptr<AbstractShader> shader = g_gfx->CreateShaderFromSource(
ShaderStage::Pixel, shader_source, ShaderStage::Pixel, shader_source,
fmt::format("Texture reinterpret pixel shader: {} to {}", from_format, to_format)); fmt::format("Texture reinterpret pixel shader: {} to {}", from_format, to_format));
if (!shader) if (!shader)
@ -1546,7 +1546,7 @@ const AbstractPipeline* ShaderCache::GetTextureReinterpretPipeline(TextureFormat
config.blending_state = RenderState::GetNoBlendingBlendState(); config.blending_state = RenderState::GetNoBlendingBlendState();
config.framebuffer_state = RenderState::GetRGBA8FramebufferState(); config.framebuffer_state = RenderState::GetRGBA8FramebufferState();
config.usage = AbstractPipelineUsage::Utility; 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(); return iiter.first->second.get();
} }
@ -1574,7 +1574,7 @@ ShaderCache::GetTextureDecodingShader(TextureFormat format,
fmt::format("Texture decoding compute shader: {}", format); fmt::format("Texture decoding compute shader: {}", format);
std::unique_ptr<AbstractShader> shader = std::unique_ptr<AbstractShader> shader =
g_renderer->CreateShaderFromSource(ShaderStage::Compute, shader_source, name); g_gfx->CreateShaderFromSource(ShaderStage::Compute, shader_source, name);
if (!shader) if (!shader)
{ {
m_texture_decoding_shaders.emplace(key, nullptr); m_texture_decoding_shaders.emplace(key, nullptr);

View File

@ -34,6 +34,7 @@
#include "Core/System.h" #include "Core/System.h"
#include "VideoCommon/AbstractFramebuffer.h" #include "VideoCommon/AbstractFramebuffer.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractStagingTexture.h" #include "VideoCommon/AbstractStagingTexture.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/FramebufferManager.h" #include "VideoCommon/FramebufferManager.h"
@ -298,7 +299,7 @@ RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const
decoded_entry->SetNotCopy(); decoded_entry->SetNotCopy();
decoded_entry->may_have_overlapping_textures = entry->may_have_overlapping_textures; 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; const u32 palette_size = entry->format == TextureFormat::I4 ? 32 : 512;
u32 texel_buffer_offset; u32 texel_buffer_offset;
@ -318,19 +319,19 @@ RcTcacheEntry TextureCacheBase::ApplyPaletteToEntry(RcTcacheEntry& entry, const
uniforms.texel_buffer_offset = texel_buffer_offset; uniforms.texel_buffer_offset = texel_buffer_offset;
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
g_renderer->SetAndDiscardFramebuffer(decoded_entry->framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(decoded_entry->framebuffer.get());
g_renderer->SetViewportAndScissor(decoded_entry->texture->GetRect()); g_gfx->SetViewportAndScissor(decoded_entry->texture->GetRect());
g_renderer->SetPipeline(pipeline); g_gfx->SetPipeline(pipeline);
g_renderer->SetTexture(1, entry->texture.get()); g_gfx->SetTexture(1, entry->texture.get());
g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); g_gfx->SetSamplerState(1, RenderState::GetPointSamplerState());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
decoded_entry->texture->FinishedRendering(); decoded_entry->texture->FinishedRendering();
} }
else else
{ {
ERROR_LOG_FMT(VIDEO, "Texel buffer upload of {} bytes failed", palette_size); 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); 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 = reinterpreted_entry->may_have_overlapping_textures =
existing_entry->may_have_overlapping_textures; existing_entry->may_have_overlapping_textures;
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
g_renderer->SetAndDiscardFramebuffer(reinterpreted_entry->framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(reinterpreted_entry->framebuffer.get());
g_renderer->SetViewportAndScissor(reinterpreted_entry->texture->GetRect()); g_gfx->SetViewportAndScissor(reinterpreted_entry->texture->GetRect());
g_renderer->SetPipeline(pipeline); g_gfx->SetPipeline(pipeline);
g_renderer->SetTexture(0, existing_entry->texture.get()); g_gfx->SetTexture(0, existing_entry->texture.get());
g_renderer->SetSamplerState(1, RenderState::GetPointSamplerState()); g_gfx->SetSamplerState(1, RenderState::GetPointSamplerState());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
reinterpreted_entry->texture->FinishedRendering(); reinterpreted_entry->texture->FinishedRendering();
textures_by_address.emplace(reinterpreted_entry->addr, reinterpreted_entry); 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. // No need to convert the coordinates here since they'll be the same.
g_renderer->ScaleTexture(new_texture->framebuffer.get(), g_gfx->ScaleTexture(new_texture->framebuffer.get(), new_texture->texture->GetConfig().GetRect(),
new_texture->texture->GetConfig().GetRect(), entry->texture.get(), entry->texture.get(), entry->texture->GetConfig().GetRect());
entry->texture->GetConfig().GetRect());
entry->texture.swap(new_texture->texture); entry->texture.swap(new_texture->texture);
entry->framebuffer.swap(new_texture->framebuffer); 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); TextureConfig staging_config(std::max(width, 128u), std::max(height, 128u), 1, 1, 1, format, 0);
m_readback_texture.reset(); m_readback_texture.reset();
m_readback_texture = m_readback_texture = g_gfx->CreateStagingTexture(StagingTextureType::Readback, staging_config);
g_renderer->CreateStagingTexture(StagingTextureType::Readback, staging_config);
return m_readback_texture != nullptr; 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; state.tm0.anisotropic_filtering = false;
} }
g_renderer->SetSamplerState(index, state); g_gfx->SetSamplerState(index, state);
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& pixel_shader_manager = system.GetPixelShaderManager(); auto& pixel_shader_manager = system.GetPixelShaderManager();
pixel_shader_manager.SetSamplerState(index, state.tm0.hex, state.tm1.hex); 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]; const RcTcacheEntry& tentry = bound_textures[i];
if (used_textures[i] && tentry) 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); pixel_shader_manager.SetTexDims(i, tentry->native_width, tentry->native_height);
const float custom_tex_scale = tentry->GetWidth() / float(tentry->native_width); const float custom_tex_scale = tentry->GetWidth() / float(tentry->native_width);
@ -2013,7 +2012,7 @@ void TextureCacheBase::StitchXFBCopy(RcTcacheEntry& stitched_entry)
// We may have to scale if one of the copies is not internal resolution. // We may have to scale if one of the copies is not internal resolution.
if (srcrect.GetWidth() != dstrect.GetWidth() || srcrect.GetHeight() != dstrect.GetHeight()) if (srcrect.GetWidth() != dstrect.GetWidth() || srcrect.GetHeight() != dstrect.GetHeight())
{ {
g_renderer->ScaleTexture(stitched_entry->framebuffer.get(), dstrect, entry->texture.get(), g_gfx->ScaleTexture(stitched_entry->framebuffer.get(), dstrect, entry->texture.get(),
srcrect); srcrect);
} }
else else
@ -2521,7 +2520,7 @@ std::unique_ptr<AbstractStagingTexture> TextureCacheBase::GetEFBCopyStagingTextu
return ptr; return ptr;
} }
std::unique_ptr<AbstractStagingTexture> tex = g_renderer->CreateStagingTexture( std::unique_ptr<AbstractStagingTexture> tex = g_gfx->CreateStagingTexture(
StagingTextureType::Readback, m_efb_encoding_texture->GetConfig()); StagingTextureType::Readback, m_efb_encoding_texture->GetConfig());
if (!tex) if (!tex)
WARN_LOG_FMT(VIDEO, "Failed to create EFB copy staging texture"); WARN_LOG_FMT(VIDEO, "Failed to create EFB copy staging texture");
@ -2614,7 +2613,7 @@ TextureCacheBase::AllocateTexture(const TextureConfig& config)
return std::move(entry); return std::move(entry);
} }
std::unique_ptr<AbstractTexture> texture = g_renderer->CreateTexture(config); std::unique_ptr<AbstractTexture> texture = g_gfx->CreateTexture(config);
if (!texture) if (!texture)
{ {
WARN_LOG_FMT(VIDEO, "Failed to allocate a {}x{}x{} texture", config.width, config.height, 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<AbstractFramebuffer> framebuffer; std::unique_ptr<AbstractFramebuffer> framebuffer;
if (config.IsRenderTarget()) if (config.IsRenderTarget())
{ {
framebuffer = g_renderer->CreateFramebuffer(texture.get(), nullptr); framebuffer = g_gfx->CreateFramebuffer(texture.get(), nullptr);
if (!framebuffer) if (!framebuffer)
{ {
WARN_LOG_FMT(VIDEO, "Failed to allocate a {}x{}x{} framebuffer", config.width, config.height, 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( constexpr TextureConfig encoding_texture_config(
EFB_WIDTH * 4, 1024, 1, 1, 1, AbstractTextureFormat::BGRA8, AbstractTextureFlag_RenderTarget); EFB_WIDTH * 4, 1024, 1, 1, 1, AbstractTextureFormat::BGRA8, AbstractTextureFlag_RenderTarget);
m_efb_encoding_texture = m_efb_encoding_texture = g_gfx->CreateTexture(encoding_texture_config, "EFB encoding texture");
g_renderer->CreateTexture(encoding_texture_config, "EFB encoding texture");
if (!m_efb_encoding_texture) if (!m_efb_encoding_texture)
return false; 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) if (!m_efb_encoding_framebuffer)
return false; return false;
@ -2759,7 +2757,7 @@ bool TextureCacheBase::CreateUtilityTextures()
constexpr TextureConfig decoding_texture_config( constexpr TextureConfig decoding_texture_config(
1024, 1024, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage); 1024, 1024, 1, 1, 1, AbstractTextureFormat::RGBA8, AbstractTextureFlag_ComputeImage);
m_decoding_texture = 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) if (!m_decoding_texture)
return false; 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 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()); scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer());
AbstractTexture* src_texture = AbstractTexture* src_texture =
is_depth_copy ? g_framebuffer_manager->ResolveEFBDepthTexture(framebuffer_rect) : is_depth_copy ? g_framebuffer_manager->ResolveEFBDepthTexture(framebuffer_rect) :
g_framebuffer_manager->ResolveEFBColorTexture(framebuffer_rect); g_framebuffer_manager->ResolveEFBColorTexture(framebuffer_rect);
src_texture->FinishedRendering(); src_texture->FinishedRendering();
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
// Fill uniform buffer. // Fill uniform buffer.
struct Uniforms struct Uniforms
@ -2832,14 +2830,14 @@ void TextureCacheBase::CopyEFBToCacheEntry(RcTcacheEntry& entry, bool is_depth_c
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
// Use the copy pipeline to render the VRAM copy. // Use the copy pipeline to render the VRAM copy.
g_renderer->SetAndDiscardFramebuffer(entry->framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(entry->framebuffer.get());
g_renderer->SetViewportAndScissor(entry->framebuffer->GetRect()); g_gfx->SetViewportAndScissor(entry->framebuffer->GetRect());
g_renderer->SetPipeline(copy_pipeline); g_gfx->SetPipeline(copy_pipeline);
g_renderer->SetTexture(0, src_texture); g_gfx->SetTexture(0, src_texture);
g_renderer->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() : g_gfx->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() :
RenderState::GetPointSamplerState()); RenderState::GetPointSamplerState());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
g_renderer->EndUtilityDrawing(); g_gfx->EndUtilityDrawing();
entry->texture->FinishedRendering(); 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 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()); scaled_src_rect, g_framebuffer_manager->GetEFBFramebuffer());
AbstractTexture* src_texture = AbstractTexture* src_texture =
params.depth ? g_framebuffer_manager->ResolveEFBDepthTexture(framebuffer_rect) : params.depth ? g_framebuffer_manager->ResolveEFBDepthTexture(framebuffer_rect) :
g_framebuffer_manager->ResolveEFBColorTexture(framebuffer_rect); g_framebuffer_manager->ResolveEFBColorTexture(framebuffer_rect);
src_texture->FinishedRendering(); src_texture->FinishedRendering();
g_renderer->BeginUtilityDrawing(); g_gfx->BeginUtilityDrawing();
// Fill uniform buffer. // Fill uniform buffer.
struct Uniforms struct Uniforms
@ -2909,15 +2907,15 @@ void TextureCacheBase::CopyEFB(AbstractStagingTexture* dst, const EFBCopyParams&
const auto encode_rect = MathUtil::Rectangle<int>(0, 0, render_width, render_height); const auto encode_rect = MathUtil::Rectangle<int>(0, 0, render_width, render_height);
// Render to GPU texture, and then copy to CPU-accessible texture. // Render to GPU texture, and then copy to CPU-accessible texture.
g_renderer->SetAndDiscardFramebuffer(m_efb_encoding_framebuffer.get()); g_gfx->SetAndDiscardFramebuffer(m_efb_encoding_framebuffer.get());
g_renderer->SetViewportAndScissor(encode_rect); g_gfx->SetViewportAndScissor(encode_rect);
g_renderer->SetPipeline(copy_pipeline); g_gfx->SetPipeline(copy_pipeline);
g_renderer->SetTexture(0, src_texture); g_gfx->SetTexture(0, src_texture);
g_renderer->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() : g_gfx->SetSamplerState(0, linear_filter ? RenderState::GetLinearSamplerState() :
RenderState::GetPointSamplerState()); RenderState::GetPointSamplerState());
g_renderer->Draw(0, 3); g_gfx->Draw(0, 3);
dst->CopyFromTexture(m_efb_encoding_texture.get(), encode_rect, 0, 0, encode_rect); 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. // Flush if there's sufficient draws between this copy and the last.
g_vertex_manager->OnEFBCopyToRAM(); g_vertex_manager->OnEFBCopyToRAM();
@ -2970,11 +2968,11 @@ bool TextureCacheBase::DecodeTextureOnGPU(RcTcacheEntry& entry, u32 dst_level, c
aligned_height, src_offset, row_stride / bytes_per_buffer_elem, aligned_height, src_offset, row_stride / bytes_per_buffer_elem,
palette_offset}; palette_offset};
g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms)); 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 = auto dispatch_groups =
TextureConversionShaderTiled::GetDispatchCount(info, aligned_width, aligned_height); TextureConversionShaderTiled::GetDispatchCount(info, aligned_width, aligned_height);
g_renderer->DispatchComputeShader(shader, info->group_size_x, info->group_size_y, 1, g_gfx->DispatchComputeShader(shader, info->group_size_x, info->group_size_y, 1,
dispatch_groups.first, dispatch_groups.second, 1); dispatch_groups.first, dispatch_groups.second, 1);
// Copy from decoding texture -> final texture // Copy from decoding texture -> final texture

View File

@ -20,12 +20,12 @@
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
#include "Core/System.h" #include "Core/System.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/CPMemory.h" #include "VideoCommon/CPMemory.h"
#include "VideoCommon/DataReader.h" #include "VideoCommon/DataReader.h"
#include "VideoCommon/IndexGenerator.h" #include "VideoCommon/IndexGenerator.h"
#include "VideoCommon/NativeVertexFormat.h" #include "VideoCommon/NativeVertexFormat.h"
#include "VideoCommon/RenderBase.h"
#include "VideoCommon/Statistics.h" #include "VideoCommon/Statistics.h"
#include "VideoCommon/VertexLoaderBase.h" #include "VideoCommon/VertexLoaderBase.h"
#include "VideoCommon/VertexManagerBase.h" #include "VideoCommon/VertexManagerBase.h"
@ -140,7 +140,7 @@ NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& d
auto iter = s_native_vertex_map.find(decl); auto iter = s_native_vertex_map.find(decl);
if (iter == s_native_vertex_map.end()) if (iter == s_native_vertex_map.end())
{ {
std::unique_ptr<NativeVertexFormat> fmt = g_renderer->CreateNativeVertexFormat(decl); std::unique_ptr<NativeVertexFormat> fmt = g_gfx->CreateNativeVertexFormat(decl);
auto ipair = s_native_vertex_map.emplace(decl, std::move(fmt)); auto ipair = s_native_vertex_map.emplace(decl, std::move(fmt));
iter = ipair.first; iter = ipair.first;
} }

View File

@ -17,6 +17,7 @@
#include "Core/DolphinAnalytics.h" #include "Core/DolphinAnalytics.h"
#include "Core/System.h" #include "Core/System.h"
#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/BPMemory.h" #include "VideoCommon/BPMemory.h"
#include "VideoCommon/BoundingBox.h" #include "VideoCommon/BoundingBox.h"
#include "VideoCommon/DataReader.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->BBoxFlush();
} }
g_renderer->DrawIndexed(base_index, num_indices, base_vertex); g_gfx->DrawIndexed(base_index, num_indices, base_vertex);
} }
void VertexManagerBase::UploadUniforms() void VertexManagerBase::UploadUniforms()
@ -599,7 +600,7 @@ void VertexManagerBase::Flush()
UpdatePipelineObject(); UpdatePipelineObject();
if (m_current_pipeline_object) if (m_current_pipeline_object)
{ {
g_renderer->SetPipeline(m_current_pipeline_object); g_gfx->SetPipeline(m_current_pipeline_object);
if (PerfQueryBase::ShouldEmulate()) if (PerfQueryBase::ShouldEmulate())
g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); 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; 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) 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_unflushed_efb_copy = false;
m_last_efb_copy_draw_counter = m_draw_counter; 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)) m_scheduled_command_buffer_kicks.end(), m_draw_counter))
{ {
// Kick a command buffer on the background thread. // Kick a command buffer on the background thread.
g_renderer->Flush(); g_gfx->Flush();
m_unflushed_efb_copy = false; m_unflushed_efb_copy = false;
m_last_efb_copy_draw_counter = m_draw_counter; m_last_efb_copy_draw_counter = m_draw_counter;
} }
@ -927,7 +928,7 @@ void VertexManagerBase::OnEFBCopyToRAM()
} }
m_unflushed_efb_copy = false; m_unflushed_efb_copy = false;
g_renderer->Flush(); g_gfx->Flush();
} }
void VertexManagerBase::OnEndFrame() void VertexManagerBase::OnEndFrame()

View File

@ -324,7 +324,9 @@ void VideoBackendBase::InitializeShared()
// do not initialize again for the config window // do not initialize again for the config window
m_initialized = true; m_initialized = true;
g_renderer = std::make_unique<Renderer>();
g_presenter = std::make_unique<VideoCommon::Presenter>(); g_presenter = std::make_unique<VideoCommon::Presenter>();
g_frame_dumper = std::make_unique<FrameDumper>();
auto& system = Core::System::GetInstance(); auto& system = Core::System::GetInstance();
auto& command_processor = system.GetCommandProcessor(); auto& command_processor = system.GetCommandProcessor();
@ -337,7 +339,13 @@ void VideoBackendBase::InitializeShared()
system.GetGeometryShaderManager().Init(); system.GetGeometryShaderManager().Init();
system.GetPixelShaderManager().Init(); system.GetPixelShaderManager().Init();
TMEM::Init(); TMEM::Init();
g_frame_dumper = std::make_unique<FrameDumper>();
if (!g_renderer->Initialize() || !g_presenter->Initialize())
{
PanicAlertFmtT("Failed to initialize renderer classes");
Shutdown();
return;
}
g_Config.VerifyValidity(); g_Config.VerifyValidity();
UpdateActiveConfig(); UpdateActiveConfig();