diff options
| author | Tilka <tilkax@gmail.com> | 2019-02-26 04:21:05 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-02-26 04:21:05 +0000 |
| commit | 6ce7f44b8a0bb3b95d3f12ebffbef7a71a443fdd (patch) | |
| tree | 98380ce3a3284c52597a6fba86589c847219ecd5 /Source/Core/VideoBackends/OGL/BoundingBox.cpp | |
| parent | 19673ce79af814ca3b77d7f8ea60458e564bfa51 (diff) | |
| parent | f039149198657c1891e1c6462ed30c31ed4b8486 (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.cpp | 172 |
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 |
