mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-23 06:09:50 -06:00
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:
@ -38,6 +38,7 @@
|
||||
#include "Core/System.h"
|
||||
|
||||
#include "VideoCommon/AbstractFramebuffer.h"
|
||||
#include "VideoCommon/AbstractGfx.h"
|
||||
#include "VideoCommon/AbstractTexture.h"
|
||||
#include "VideoCommon/BoundingBox.h"
|
||||
#include "VideoCommon/CommandProcessor.h"
|
||||
@ -59,17 +60,12 @@
|
||||
|
||||
std::unique_ptr<Renderer> g_renderer;
|
||||
|
||||
Renderer::Renderer(int backbuffer_width, int backbuffer_height, float backbuffer_scale,
|
||||
AbstractTextureFormat backbuffer_format)
|
||||
: m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT}
|
||||
Renderer::Renderer() : m_last_xfb_width{MAX_XFB_WIDTH}, m_last_xfb_height{MAX_XFB_HEIGHT}
|
||||
{
|
||||
UpdateActiveConfig();
|
||||
FreeLook::UpdateActiveConfig();
|
||||
CalculateTargetSize();
|
||||
|
||||
g_presenter->SetBackbuffer(backbuffer_width, backbuffer_height, backbuffer_scale,
|
||||
backbuffer_format);
|
||||
|
||||
m_is_game_widescreen = SConfig::GetInstance().bWii && Config::Get(Config::SYSCONF_WIDESCREEN);
|
||||
g_freelook_camera.SetControlType(FreeLook::GetActiveConfig().camera_config.control_type);
|
||||
}
|
||||
@ -78,13 +74,6 @@ Renderer::~Renderer() = default;
|
||||
|
||||
bool Renderer::Initialize()
|
||||
{
|
||||
m_bounding_box = CreateBoundingBox();
|
||||
if (g_ActiveConfig.backend_info.bSupportsBBox && !m_bounding_box->Initialize())
|
||||
{
|
||||
PanicAlertFmt("Failed to initialize bounding box.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (g_ActiveConfig.bGraphicMods)
|
||||
{
|
||||
// If a config change occurred in a previous session,
|
||||
@ -101,12 +90,12 @@ bool Renderer::Initialize()
|
||||
m_graphics_mod_manager.Load(*g_ActiveConfig.graphics_mod_config);
|
||||
}
|
||||
|
||||
return g_presenter->Initialize();
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::Shutdown()
|
||||
{
|
||||
m_bounding_box.reset();
|
||||
g_bounding_box.reset();
|
||||
}
|
||||
|
||||
void Renderer::BeginUtilityDrawing()
|
||||
@ -121,31 +110,38 @@ void Renderer::EndUtilityDrawing()
|
||||
BPFunctions::SetScissorAndViewport();
|
||||
}
|
||||
|
||||
void Renderer::SetFramebuffer(AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
m_current_framebuffer = framebuffer;
|
||||
}
|
||||
|
||||
void Renderer::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer)
|
||||
{
|
||||
m_current_framebuffer = framebuffer;
|
||||
}
|
||||
|
||||
void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer,
|
||||
const ClearColor& color_value, float depth_value)
|
||||
{
|
||||
m_current_framebuffer = framebuffer;
|
||||
}
|
||||
|
||||
bool Renderer::EFBHasAlphaChannel() const
|
||||
{
|
||||
return m_prev_efb_format == PixelFormat::RGBA6_Z24;
|
||||
}
|
||||
|
||||
void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool colorEnable, bool alphaEnable,
|
||||
bool zEnable, u32 color, u32 z)
|
||||
void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool color_enable, bool alpha_enable,
|
||||
bool z_enable, u32 color, u32 z)
|
||||
{
|
||||
g_framebuffer_manager->ClearEFB(rc, colorEnable, alphaEnable, zEnable, color, z);
|
||||
g_framebuffer_manager->FlushEFBPokes();
|
||||
g_framebuffer_manager->FlagPeekCacheAsOutOfDate();
|
||||
|
||||
// Native -> EFB coordinates
|
||||
MathUtil::Rectangle<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)
|
||||
@ -155,17 +151,17 @@ void Renderer::ReinterpretPixelData(EFBReinterpretType convtype)
|
||||
|
||||
bool Renderer::IsBBoxEnabled() const
|
||||
{
|
||||
return m_bounding_box->IsEnabled();
|
||||
return g_bounding_box->IsEnabled();
|
||||
}
|
||||
|
||||
void Renderer::BBoxEnable(PixelShaderManager& pixel_shader_manager)
|
||||
{
|
||||
m_bounding_box->Enable(pixel_shader_manager);
|
||||
g_bounding_box->Enable(pixel_shader_manager);
|
||||
}
|
||||
|
||||
void Renderer::BBoxDisable(PixelShaderManager& pixel_shader_manager)
|
||||
{
|
||||
m_bounding_box->Disable(pixel_shader_manager);
|
||||
g_bounding_box->Disable(pixel_shader_manager);
|
||||
}
|
||||
|
||||
u16 Renderer::BBoxRead(u32 index)
|
||||
@ -173,7 +169,7 @@ u16 Renderer::BBoxRead(u32 index)
|
||||
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
|
||||
return m_bounding_box_fallback[index];
|
||||
|
||||
return m_bounding_box->Get(index);
|
||||
return g_bounding_box->Get(index);
|
||||
}
|
||||
|
||||
void Renderer::BBoxWrite(u32 index, u16 value)
|
||||
@ -184,7 +180,7 @@ void Renderer::BBoxWrite(u32 index, u16 value)
|
||||
return;
|
||||
}
|
||||
|
||||
m_bounding_box->Set(index, value);
|
||||
g_bounding_box->Set(index, value);
|
||||
}
|
||||
|
||||
void Renderer::BBoxFlush()
|
||||
@ -192,7 +188,7 @@ void Renderer::BBoxFlush()
|
||||
if (!g_ActiveConfig.bBBoxEnable || !g_ActiveConfig.backend_info.bSupportsBBox)
|
||||
return;
|
||||
|
||||
m_bounding_box->Flush();
|
||||
g_bounding_box->Flush();
|
||||
}
|
||||
|
||||
u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data)
|
||||
@ -436,13 +432,13 @@ void Renderer::CheckForConfigChanges()
|
||||
return;
|
||||
|
||||
// Notify the backend of the changes, if any.
|
||||
OnConfigChanged(changed_bits);
|
||||
g_gfx->OnConfigChanged(changed_bits);
|
||||
|
||||
// If there's any shader changes, wait for the GPU to finish before destroying anything.
|
||||
if (changed_bits & (CONFIG_CHANGE_BIT_HOST_CONFIG | CONFIG_CHANGE_BIT_MULTISAMPLES))
|
||||
{
|
||||
WaitForGPUIdle();
|
||||
SetPipeline(nullptr);
|
||||
g_gfx->WaitForGPUIdle();
|
||||
g_gfx->SetPipeline(nullptr);
|
||||
}
|
||||
|
||||
// Framebuffer changed?
|
||||
@ -469,81 +465,6 @@ void Renderer::CheckForConfigChanges()
|
||||
}
|
||||
}
|
||||
|
||||
bool Renderer::IsHeadless() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Renderer::SetViewportAndScissor(const MathUtil::Rectangle<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> result;
|
||||
@ -590,14 +511,6 @@ void Renderer::RecordVideoMemory()
|
||||
texMem);
|
||||
}
|
||||
|
||||
bool Renderer::UseGeometryShaderForUI() const
|
||||
{
|
||||
// OpenGL doesn't render to a 2-layer backbuffer like D3D/Vulkan for quad-buffered stereo,
|
||||
// instead drawing twice and the eye selected by glDrawBuffer() (see Presenter::RenderXFBToScreen)
|
||||
return g_ActiveConfig.stereo_mode == StereoMode::QuadBuffer &&
|
||||
g_ActiveConfig.backend_info.api_type != APIType::OpenGL;
|
||||
}
|
||||
|
||||
void Renderer::ForceReloadTextures()
|
||||
{
|
||||
m_force_reload_textures.Set();
|
||||
@ -756,7 +669,7 @@ void Renderer::Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u6
|
||||
}
|
||||
else
|
||||
{
|
||||
Flush();
|
||||
g_gfx->Flush();
|
||||
}
|
||||
|
||||
// Update our last xfb values
|
||||
@ -768,7 +681,7 @@ void Renderer::Swap(u32 xfb_addr, u32 fb_width, u32 fb_stride, u32 fb_height, u6
|
||||
}
|
||||
else
|
||||
{
|
||||
Flush();
|
||||
g_gfx->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
@ -803,7 +716,7 @@ void Renderer::DoState(PointerWrap& p)
|
||||
p.Do(m_last_xfb_height);
|
||||
p.DoArray(m_bounding_box_fallback);
|
||||
|
||||
m_bounding_box->DoState(p);
|
||||
g_bounding_box->DoState(p);
|
||||
|
||||
if (p.IsReadMode())
|
||||
{
|
||||
@ -821,11 +734,6 @@ void Renderer::DoState(PointerWrap& p)
|
||||
#endif
|
||||
}
|
||||
|
||||
std::unique_ptr<VideoCommon::AsyncShaderCompiler> Renderer::CreateAsyncShaderCompiler()
|
||||
{
|
||||
return std::make_unique<VideoCommon::AsyncShaderCompiler>();
|
||||
}
|
||||
|
||||
const GraphicsModManager& Renderer::GetGraphicsModManager() const
|
||||
{
|
||||
return m_graphics_mod_manager;
|
||||
|
Reference in New Issue
Block a user