summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/OGL/BoundingBox.cpp
diff options
context:
space:
mode:
authorTilka <tilkax@gmail.com>2019-02-26 04:21:05 +0000
committerGitHub <noreply@github.com>2019-02-26 04:21:05 +0000
commit6ce7f44b8a0bb3b95d3f12ebffbef7a71a443fdd (patch)
tree98380ce3a3284c52597a6fba86589c847219ecd5 /Source/Core/VideoBackends/OGL/BoundingBox.cpp
parent19673ce79af814ca3b77d7f8ea60458e564bfa51 (diff)
parentf039149198657c1891e1c6462ed30c31ed4b8486 (diff)
Merge pull request #7753 from stenzek/videocommon-all-the-things
Move a significant amount of video backend logic to VideoCommon
Diffstat (limited to 'Source/Core/VideoBackends/OGL/BoundingBox.cpp')
-rw-r--r--Source/Core/VideoBackends/OGL/BoundingBox.cpp172
1 files changed, 37 insertions, 135 deletions
diff --git a/Source/Core/VideoBackends/OGL/BoundingBox.cpp b/Source/Core/VideoBackends/OGL/BoundingBox.cpp
index c50f831524..18ef7802cc 100644
--- a/Source/Core/VideoBackends/OGL/BoundingBox.cpp
+++ b/Source/Core/VideoBackends/OGL/BoundingBox.cpp
@@ -2,175 +2,77 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
-#include <algorithm>
-#include <array>
#include <cstring>
#include "Common/GL/GLUtil.h"
#include "VideoBackends/OGL/BoundingBox.h"
-#include "VideoBackends/OGL/FramebufferManager.h"
+#include "VideoBackends/OGL/Render.h"
#include "VideoCommon/DriverDetails.h"
#include "VideoCommon/VideoConfig.h"
static GLuint s_bbox_buffer_id;
-static GLuint s_pbo;
-
-static std::array<int, 4> s_stencil_bounds;
-static bool s_stencil_updated;
-static bool s_stencil_cleared;
-
-static int s_target_width;
-static int s_target_height;
namespace OGL
{
-void BoundingBox::SetTargetSizeChanged(int target_width, int target_height)
+void BoundingBox::Init()
{
- if (g_ActiveConfig.BBoxUseFragmentShaderImplementation())
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
return;
- s_target_width = target_width;
- s_target_height = target_height;
- s_stencil_updated = false;
-
- glBindBuffer(GL_PIXEL_PACK_BUFFER, s_pbo);
- glBufferData(GL_PIXEL_PACK_BUFFER, s_target_width * s_target_height, nullptr, GL_STREAM_READ);
- glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
-}
-
-void BoundingBox::Init(int target_width, int target_height)
-{
- if (g_ActiveConfig.BBoxUseFragmentShaderImplementation())
- {
- int initial_values[4] = {0, 0, 0, 0};
- glGenBuffers(1, &s_bbox_buffer_id);
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, s_bbox_buffer_id);
- glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(s32), initial_values, GL_DYNAMIC_DRAW);
- glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, s_bbox_buffer_id);
- }
- else
- {
- s_stencil_bounds = {{0, 0, 0, 0}};
- glGenBuffers(1, &s_pbo);
- SetTargetSizeChanged(target_width, target_height);
- }
+ int initial_values[4] = {0, 0, 0, 0};
+ glGenBuffers(1, &s_bbox_buffer_id);
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, s_bbox_buffer_id);
+ glBufferData(GL_SHADER_STORAGE_BUFFER, 4 * sizeof(s32), initial_values, GL_DYNAMIC_DRAW);
+ glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, s_bbox_buffer_id);
}
void BoundingBox::Shutdown()
{
- if (g_ActiveConfig.BBoxUseFragmentShaderImplementation())
- {
- glDeleteBuffers(1, &s_bbox_buffer_id);
- }
- else
- {
- glDeleteBuffers(1, &s_pbo);
- }
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
+ return;
+
+ glDeleteBuffers(1, &s_bbox_buffer_id);
}
void BoundingBox::Set(int index, int value)
{
- if (g_ActiveConfig.BBoxUseFragmentShaderImplementation())
- {
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, s_bbox_buffer_id);
- glBufferSubData(GL_SHADER_STORAGE_BUFFER, index * sizeof(int), sizeof(int), &value);
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
- }
- else
- {
- s_stencil_bounds[index] = value;
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
+ return;
- if (!s_stencil_cleared)
- {
- // Assumes that the EFB framebuffer is currently bound
- glClearStencil(0);
- glClear(GL_STENCIL_BUFFER_BIT);
- s_stencil_updated = false;
- s_stencil_cleared = true;
- }
- }
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, s_bbox_buffer_id);
+ glBufferSubData(GL_SHADER_STORAGE_BUFFER, index * sizeof(int), sizeof(int), &value);
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
}
int BoundingBox::Get(int index)
{
- if (g_ActiveConfig.BBoxUseFragmentShaderImplementation())
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
+ return 0;
+
+ int data = 0;
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, s_bbox_buffer_id);
+ if (!DriverDetails::HasBug(DriverDetails::BUG_SLOW_GETBUFFERSUBDATA) &&
+ !static_cast<Renderer*>(g_renderer.get())->IsGLES())
{
- int data = 0;
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, s_bbox_buffer_id);
- if (!DriverDetails::HasBug(DriverDetails::BUG_SLOW_GETBUFFERSUBDATA) &&
- !static_cast<Renderer*>(g_renderer.get())->IsGLES())
- {
- // Using glMapBufferRange to read back the contents of the SSBO is extremely slow
- // on nVidia drivers. This is more noticeable at higher internal resolutions.
- // Using glGetBufferSubData instead does not seem to exhibit this slowdown.
- glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, index * sizeof(int), sizeof(int), &data);
- }
- else
- {
- // Using glMapBufferRange is faster on AMD cards by a measurable margin.
- void* ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, index * sizeof(int), sizeof(int),
- GL_MAP_READ_BIT);
- if (ptr)
- {
- memcpy(&data, ptr, sizeof(int));
- glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
- }
- }
- glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
- return data;
+ // Using glMapBufferRange to read back the contents of the SSBO is extremely slow
+ // on nVidia drivers. This is more noticeable at higher internal resolutions.
+ // Using glGetBufferSubData instead does not seem to exhibit this slowdown.
+ glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, index * sizeof(int), sizeof(int), &data);
}
else
{
- if (s_stencil_updated)
+ // Using glMapBufferRange is faster on AMD cards by a measurable margin.
+ void* ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, index * sizeof(int), sizeof(int),
+ GL_MAP_READ_BIT);
+ if (ptr)
{
- s_stencil_updated = false;
-
- FramebufferManager::ResolveEFBStencilTexture();
- glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetResolvedFramebuffer());
- glBindBuffer(GL_PIXEL_PACK_BUFFER, s_pbo);
- glPixelStorei(GL_PACK_ALIGNMENT, 1);
- glReadPixels(0, 0, s_target_width, s_target_height, GL_STENCIL_INDEX, GL_UNSIGNED_BYTE, 0);
- glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferManager::GetEFBFramebuffer());
-
- // Eke every bit of performance out of the compiler that we can
- std::array<int, 4> bounds = s_stencil_bounds;
-
- u8* data = static_cast<u8*>(glMapBufferRange(
- GL_PIXEL_PACK_BUFFER, 0, s_target_height * s_target_width, GL_MAP_READ_BIT));
-
- for (int row = 0; row < s_target_height; row++)
- {
- for (int col = 0; col < s_target_width; col++)
- {
- if (data[row * s_target_width + col] == 0)
- continue;
- bounds[0] = std::min(bounds[0], col);
- bounds[1] = std::max(bounds[1], col);
- bounds[2] = std::min(bounds[2], row);
- bounds[3] = std::max(bounds[3], row);
- }
- }
-
- s_stencil_bounds = bounds;
-
- glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
- glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
+ memcpy(&data, ptr, sizeof(int));
+ glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
}
-
- return s_stencil_bounds[index];
}
+ glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
+ return data;
}
-
-void BoundingBox::StencilWasUpdated()
-{
- s_stencil_updated = true;
- s_stencil_cleared = false;
-}
-
-bool BoundingBox::NeedsStencilBuffer()
-{
- return g_ActiveConfig.bBBoxEnable && !g_ActiveConfig.BBoxUseFragmentShaderImplementation();
-}
-};
+}; // namespace OGL