summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/FramebufferManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/FramebufferManager.cpp')
-rw-r--r--Source/Core/VideoCommon/FramebufferManager.cpp61
1 files changed, 33 insertions, 28 deletions
diff --git a/Source/Core/VideoCommon/FramebufferManager.cpp b/Source/Core/VideoCommon/FramebufferManager.cpp
index 3032de574f..5696ebb2b8 100644
--- a/Source/Core/VideoCommon/FramebufferManager.cpp
+++ b/Source/Core/VideoCommon/FramebufferManager.cpp
@@ -16,6 +16,7 @@
#include "VideoCommon/AbstractShader.h"
#include "VideoCommon/AbstractStagingTexture.h"
#include "VideoCommon/AbstractTexture.h"
+#include "VideoCommon/BPFunctions.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/FramebufferShaderGen.h"
#include "VideoCommon/RenderBase.h"
@@ -787,36 +788,34 @@ void FramebufferManager::PopulateEFBCache(bool depth, u32 tile_index, bool async
data.tiles[tile_index].present = true;
}
-void FramebufferManager::ClearEFB(const MathUtil::Rectangle<int>& rc, bool clear_color,
- bool clear_alpha, bool clear_z, u32 color, u32 z)
+void FramebufferManager::ClearEFB(const MathUtil::Rectangle<int>& rc, bool color_enable,
+ bool alpha_enable, bool z_enable, u32 color, u32 z)
{
FlushEFBPokes();
FlagPeekCacheAsOutOfDate();
- g_gfx->BeginUtilityDrawing();
- // Set up uniforms.
- struct Uniforms
+ // Native -> EFB coordinates
+ MathUtil::Rectangle<int> target_rc = g_renderer->ConvertEFBRectangle(rc);
+ target_rc = g_gfx->ConvertFramebufferRectangle(target_rc, m_efb_framebuffer.get());
+ target_rc.ClampUL(0, 0, g_renderer->GetTargetWidth(), g_renderer->GetTargetHeight());
+
+ // 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)
{
- float clear_color[4];
- float clear_depth;
- float padding1, padding2, padding3;
- };
- static_assert(std::is_standard_layout<Uniforms>::value);
- Uniforms uniforms = {{static_cast<float>((color >> 16) & 0xFF) / 255.0f,
- static_cast<float>((color >> 8) & 0xFF) / 255.0f,
- static_cast<float>((color >> 0) & 0xFF) / 255.0f,
- static_cast<float>((color >> 24) & 0xFF) / 255.0f},
- static_cast<float>(z & 0xFFFFFF) / 16777216.0f};
- if (!g_ActiveConfig.backend_info.bSupportsReversedDepthRange)
- uniforms.clear_depth = 1.0f - uniforms.clear_depth;
- g_vertex_manager->UploadUtilityUniforms(&uniforms, sizeof(uniforms));
-
- const auto target_rc = g_gfx->ConvertFramebufferRectangle(g_renderer->ConvertEFBRectangle(rc),
- m_efb_framebuffer.get());
- g_gfx->SetPipeline(m_efb_clear_pipelines[clear_color][clear_alpha][clear_z].get());
- g_gfx->SetViewportAndScissor(target_rc);
- g_gfx->Draw(0, 3);
- g_gfx->EndUtilityDrawing();
+ // Force alpha writes, and clear the alpha channel.
+ alpha_enable = true;
+ color &= 0x00FFFFFF;
+ }
+
+ g_gfx->ClearRegion(target_rc, color_enable, alpha_enable, z_enable, color, z);
+
+ // Scissor rect must be restored.
+ BPFunctions::SetScissorAndViewport();
}
bool FramebufferManager::CompileClearPipelines()
@@ -849,9 +848,9 @@ bool FramebufferManager::CompileClearPipelines()
config.depth_state.testenable = depth_enable != 0;
config.depth_state.updateenable = depth_enable != 0;
- m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable] =
+ m_clear_pipelines[color_enable][alpha_enable][depth_enable] =
g_gfx->CreatePipeline(config);
- if (!m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable])
+ if (!m_clear_pipelines[color_enable][alpha_enable][depth_enable])
return false;
}
}
@@ -868,12 +867,18 @@ void FramebufferManager::DestroyClearPipelines()
{
for (u32 depth_enable = 0; depth_enable < 2; depth_enable++)
{
- m_efb_clear_pipelines[color_enable][alpha_enable][depth_enable].reset();
+ m_clear_pipelines[color_enable][alpha_enable][depth_enable].reset();
}
}
}
}
+AbstractPipeline* FramebufferManager::GetClearPipeline(bool colorEnable, bool alphaEnable,
+ bool zEnable) const
+{
+ return m_clear_pipelines[colorEnable][alphaEnable][zEnable].get();
+}
+
void FramebufferManager::PokeEFBColor(u32 x, u32 y, u32 color)
{
// Flush if we exceeded the number of vertices per batch.