summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/RenderBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/RenderBase.cpp')
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp174
1 files changed, 41 insertions, 133 deletions
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index 86725f534e..ec5f25267f 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -38,6 +38,7 @@
#include "Core/System.h"
#include "VideoCommon/AbstractFramebuffer.h"
+#include "VideoCommon/AbstractGfx.h"
#include "VideoCommon/AbstractTexture.h"
#include "VideoCommon/BoundingBox.h"
#include "VideoCommon/CommandProcessor.h"
@@ -59,17 +60,12 @@
std::unique_ptr<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)
+bool Renderer::EFBHasAlphaChannel() const
{
- m_current_framebuffer = framebuffer;
+ return m_prev_efb_format == PixelFormat::RGBA6_Z24;
}
-void Renderer::SetAndDiscardFramebuffer(AbstractFramebuffer* framebuffer)
+void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool color_enable, bool alpha_enable,
+ bool z_enable, u32 color, u32 z)
{
- m_current_framebuffer = framebuffer;
-}
+ g_framebuffer_manager->FlushEFBPokes();
+ g_framebuffer_manager->FlagPeekCacheAsOutOfDate();
-void Renderer::SetAndClearFramebuffer(AbstractFramebuffer* framebuffer,
- const ClearColor& color_value, float depth_value)
-{
- m_current_framebuffer = framebuffer;
-}
+ // Native -> EFB coordinates
+ MathUtil::Rectangle<int> target_rc = Renderer::ConvertEFBRectangle(rc);
+ target_rc.ClampUL(0, 0, m_target_width, m_target_height);
-bool Renderer::EFBHasAlphaChannel() const
-{
- return m_prev_efb_format == PixelFormat::RGBA6_Z24;
-}
+ // 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;
+ }
-void Renderer::ClearScreen(const MathUtil::Rectangle<int>& rc, bool colorEnable, bool alphaEnable,
- bool zEnable, u32 color, u32 z)
-{
- g_framebuffer_manager->ClearEFB(rc, colorEnable, alphaEnable, zEnable, color, z);
+ 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;