diff options
| author | comex <comexk@gmail.com> | 2014-11-19 20:25:23 -0500 |
|---|---|---|
| committer | comex <comexk@gmail.com> | 2014-11-19 20:25:23 -0500 |
| commit | fb50cb6d99062069a71db49d56d975df5c6eecb3 (patch) | |
| tree | b0a9615bcaa4d5d4efa65e590ff3b0e500391f6b /Source/Core/VideoBackends | |
| parent | dd2c8c49b37360f8b8838ccdb323a84eae00e065 (diff) | |
| parent | c211450b997effa6d91059fb0aaa564892297719 (diff) | |
Merge pull request #1550 from degasus/bbox
OGL: implement bounding box support with ssbo
Diffstat (limited to 'Source/Core/VideoBackends')
| -rw-r--r-- | Source/Core/VideoBackends/D3D/Render.h | 2 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/D3D/main.cpp | 1 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/BoundingBox.cpp | 54 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/BoundingBox.h | 20 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/OGL.vcxproj | 4 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/OGL.vcxproj.filters | 6 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/Render.cpp | 48 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/Render.h | 3 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/OGL/main.cpp | 3 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/SWmain.cpp | 6 | ||||
| -rw-r--r-- | Source/Core/VideoBackends/Software/VideoBackend.h | 1 |
13 files changed, 150 insertions, 1 deletions
diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 99e682d410..8b9fe9d87f 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -34,6 +34,8 @@ public: void RenderText(const std::string& text, int left, int top, u32 color) override; u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; + u16 BBoxRead(int index) override { return 0; }; + void BBoxWrite(int index, u16 value) override {}; void ResetAPIState() override; void RestoreAPIState() override; diff --git a/Source/Core/VideoBackends/D3D/main.cpp b/Source/Core/VideoBackends/D3D/main.cpp index e78d809e1b..296936d8a7 100644 --- a/Source/Core/VideoBackends/D3D/main.cpp +++ b/Source/Core/VideoBackends/D3D/main.cpp @@ -77,6 +77,7 @@ void InitBackendInfo() g_Config.backend_info.bSupportsDualSourceBlend = true; g_Config.backend_info.bSupportsPrimitiveRestart = true; g_Config.backend_info.bSupportsOversizedViewports = false; + g_Config.backend_info.bSupportsBBox = false; // TODO: not implemented IDXGIFactory* factory; IDXGIAdapter* ad; diff --git a/Source/Core/VideoBackends/OGL/BoundingBox.cpp b/Source/Core/VideoBackends/OGL/BoundingBox.cpp new file mode 100644 index 0000000000..91fedb2a2d --- /dev/null +++ b/Source/Core/VideoBackends/OGL/BoundingBox.cpp @@ -0,0 +1,54 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#include "VideoBackends/OGL/BoundingBox.h" +#include "VideoBackends/OGL/GLUtil.h" + +#include "VideoCommon/VideoConfig.h" + +static GLuint s_bbox_buffer_id; + +namespace OGL +{ + +void BoundingBox::Init() +{ + if (g_ActiveConfig.backend_info.bSupportsBBox) + { + 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, 3, s_bbox_buffer_id); + } +} + +void BoundingBox::Shutdown() +{ + if (g_ActiveConfig.backend_info.bSupportsBBox) + glDeleteBuffers(1, &s_bbox_buffer_id); +} + +void BoundingBox::Set(int index, int value) +{ + 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) +{ + int data = 0; + glBindBuffer(GL_SHADER_STORAGE_BUFFER, s_bbox_buffer_id); + void* ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, index * sizeof(int), sizeof(int), GL_MAP_READ_BIT); + if (ptr) + { + data = *(int*)ptr; + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + } + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); + return data; +} + +}; diff --git a/Source/Core/VideoBackends/OGL/BoundingBox.h b/Source/Core/VideoBackends/OGL/BoundingBox.h new file mode 100644 index 0000000000..76b86d0c4c --- /dev/null +++ b/Source/Core/VideoBackends/OGL/BoundingBox.h @@ -0,0 +1,20 @@ +// Copyright 2014 Dolphin Emulator Project +// Licensed under GPLv2+ +// Refer to the license.txt file included. + +#pragma once + +namespace OGL +{ + +class BoundingBox +{ +public: + static void Init(); + static void Shutdown(); + + static void Set(int index, int value); + static int Get(int index); +}; + +}; diff --git a/Source/Core/VideoBackends/OGL/CMakeLists.txt b/Source/Core/VideoBackends/OGL/CMakeLists.txt index 8233677fa9..03bbdb9b9c 100644 --- a/Source/Core/VideoBackends/OGL/CMakeLists.txt +++ b/Source/Core/VideoBackends/OGL/CMakeLists.txt @@ -1,4 +1,5 @@ set(SRCS GLExtensions/GLExtensions.cpp + BoundingBox.cpp FramebufferManager.cpp GLUtil.cpp main.cpp diff --git a/Source/Core/VideoBackends/OGL/OGL.vcxproj b/Source/Core/VideoBackends/OGL/OGL.vcxproj index bda0830146..1b60169220 100644 --- a/Source/Core/VideoBackends/OGL/OGL.vcxproj +++ b/Source/Core/VideoBackends/OGL/OGL.vcxproj @@ -35,6 +35,7 @@ </ImportGroup> <PropertyGroup Label="UserMacros" /> <ItemGroup> + <ClCompile Include="BoundingBox.cpp" /> <ClCompile Include="FramebufferManager.cpp" /> <ClCompile Include="GLExtensions\GLExtensions.cpp" /> <ClCompile Include="GLInterface\GLInterface.cpp" /> @@ -54,6 +55,7 @@ <ClCompile Include="VertexManager.cpp" /> </ItemGroup> <ItemGroup> + <ClInclude Include="BoundingBox.h" /> <ClInclude Include="FramebufferManager.h" /> <ClInclude Include="GLExtensions\ARB_blend_func_extended.h" /> <ClInclude Include="GLExtensions\ARB_buffer_storage.h" /> @@ -111,4 +113,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project>
\ No newline at end of file +</Project> diff --git a/Source/Core/VideoBackends/OGL/OGL.vcxproj.filters b/Source/Core/VideoBackends/OGL/OGL.vcxproj.filters index 901f30f9f6..8e65e8e2f5 100644 --- a/Source/Core/VideoBackends/OGL/OGL.vcxproj.filters +++ b/Source/Core/VideoBackends/OGL/OGL.vcxproj.filters @@ -36,6 +36,9 @@ <ClCompile Include="RasterFont.cpp"> <Filter>Logging</Filter> </ClCompile> + <ClCompile Include="BoundingBox.cpp"> + <Filter>Render</Filter> + </ClCompile> <ClCompile Include="FramebufferManager.cpp"> <Filter>Render</Filter> </ClCompile> @@ -82,6 +85,9 @@ <ClInclude Include="RasterFont.h"> <Filter>Logging</Filter> </ClInclude> + <ClInclude Include="BoundingBox.h"> + <Filter>Render</Filter> + </ClInclude> <ClInclude Include="FramebufferManager.h"> <Filter>Render</Filter> </ClInclude> diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index 1b0d8db5b8..f25f9c90cf 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -485,6 +485,7 @@ void ProgramShaderCache::CreateHeader() "%s\n" // msaa "%s\n" // sample shading "%s\n" // Sampler binding + "%s\n" // storage buffer // Precision defines for GLSL ES "%s\n" @@ -516,6 +517,7 @@ void ProgramShaderCache::CreateHeader() , (g_ogl_config.bSupportsMSAA && v < GLSL_150) ? "#extension GL_ARB_texture_multisample : enable" : "" , (g_ogl_config.bSupportSampleShading) ? "#extension GL_ARB_sample_shading : enable" : "" , g_ActiveConfig.backend_info.bSupportsBindingLayout ? "#define SAMPLER_BINDING(x) layout(binding = x)" : "#define SAMPLER_BINDING(x)" + , g_ActiveConfig.backend_info.bSupportsBBox ? "#extension GL_ARB_shader_storage_buffer_object : enable" : "" , v>=GLSLES_300 ? "precision highp float;" : "" , v>=GLSLES_300 ? "precision highp int;" : "" diff --git a/Source/Core/VideoBackends/OGL/Render.cpp b/Source/Core/VideoBackends/OGL/Render.cpp index 2b538f063c..502b7d31af 100644 --- a/Source/Core/VideoBackends/OGL/Render.cpp +++ b/Source/Core/VideoBackends/OGL/Render.cpp @@ -20,6 +20,7 @@ #include "Core/Core.h" #include "Core/Movie.h" +#include "VideoBackends/OGL/BoundingBox.h" #include "VideoBackends/OGL/FramebufferManager.h" #include "VideoBackends/OGL/GLInterfaceBase.h" #include "VideoBackends/OGL/GLUtil.h" @@ -465,6 +466,7 @@ Renderer::Renderer() g_Config.backend_info.bSupportsPrimitiveRestart = !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVERESTART) && ((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart")); g_Config.backend_info.bSupportsEarlyZ = GLExtensions::Supports("GL_ARB_shader_image_load_store"); + g_Config.backend_info.bSupportsBBox = GLExtensions::Supports("GL_ARB_shader_storage_buffer_object"); // Desktop OpenGL supports the binding layout if it supports 420pack // OpenGL ES 3.1 supports it implicitly without an extension @@ -1161,6 +1163,52 @@ u32 Renderer::AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) return 0; } +u16 Renderer::BBoxRead(int index) +{ + int swapped_index = index; + if (index >= 2) + swapped_index ^= 1; // swap 2 and 3 for top/bottom + + // Here we get the min/max value of the truncated position of the upscaled and swapped framebuffer. + // So we have to correct them to the unscaled EFB sizes. + int value = BoundingBox::Get(swapped_index); + + if (index < 2) + { + // left/right + value = value * EFB_WIDTH / s_target_width; + } + else + { + // up/down -- we have to swap up and down + value = value * EFB_HEIGHT / s_target_height; + value = EFB_HEIGHT - value - 1; + } + if (index & 1) + value++; // fix max values to describe the outer border + + return value; +} + +void Renderer::BBoxWrite(int index, u16 _value) +{ + int value = _value; // u16 isn't enough to multiply by the efb width + if (index & 1) + value--; + if (index < 2) + { + value = value * s_target_width / EFB_WIDTH; + } + else + { + index ^= 1; // swap 2 and 3 for top/bottom + value = EFB_HEIGHT - value - 1; + value = value * s_target_height / EFB_HEIGHT; + } + + BoundingBox::Set(index, value); +} + void Renderer::SetViewport() { // reversed gxsetviewport(xorig, yorig, width, height, nearz, farz) diff --git a/Source/Core/VideoBackends/OGL/Render.h b/Source/Core/VideoBackends/OGL/Render.h index 0c2534b18f..f35487a373 100644 --- a/Source/Core/VideoBackends/OGL/Render.h +++ b/Source/Core/VideoBackends/OGL/Render.h @@ -71,6 +71,9 @@ public: u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override; + u16 BBoxRead(int index) override; + void BBoxWrite(int index, u16 value) override; + void ResetAPIState() override; void RestoreAPIState() override; diff --git a/Source/Core/VideoBackends/OGL/main.cpp b/Source/Core/VideoBackends/OGL/main.cpp index 810509b0a9..eb01d3355a 100644 --- a/Source/Core/VideoBackends/OGL/main.cpp +++ b/Source/Core/VideoBackends/OGL/main.cpp @@ -48,6 +48,7 @@ Make AA apply instantly during gameplay if possible #include "Core/Core.h" #include "Core/Host.h" +#include "VideoBackends/OGL/BoundingBox.h" #include "VideoBackends/OGL/FramebufferManager.h" #include "VideoBackends/OGL/GLInterfaceBase.h" #include "VideoBackends/OGL/GLUtil.h" @@ -205,6 +206,7 @@ void VideoBackend::Video_Prepare() Renderer::Init(); VertexLoaderManager::Init(); TextureConverter::Init(); + BoundingBox::Init(); // Notify the core that the video backend is ready Host_Message(WM_USER_CREATE); @@ -229,6 +231,7 @@ void VideoBackend::Video_Cleanup() // The following calls are NOT Thread Safe // And need to be called from the video thread Renderer::Shutdown(); + BoundingBox::Shutdown(); TextureConverter::Shutdown(); VertexLoaderManager::Shutdown(); delete g_sampler_cache; diff --git a/Source/Core/VideoBackends/Software/SWmain.cpp b/Source/Core/VideoBackends/Software/SWmain.cpp index 9063cece5e..8f7c06c5a8 100644 --- a/Source/Core/VideoBackends/Software/SWmain.cpp +++ b/Source/Core/VideoBackends/Software/SWmain.cpp @@ -33,6 +33,7 @@ #include "VideoBackends/Software/VideoBackend.h" #include "VideoBackends/Software/XFMemLoader.h" +#include "VideoCommon/BoundingBox.h" #include "VideoCommon/Fifo.h" #include "VideoCommon/OnScreenDisplay.h" #include "VideoCommon/PixelEngine.h" @@ -283,6 +284,11 @@ u32 VideoSoftware::Video_GetQueryResult(PerfQueryType type) return EfbInterface::perf_values[type]; } +u16 VideoSoftware::Video_GetBoundingBox(int index) +{ + return BoundingBox::coords[index]; +} + bool VideoSoftware::Video_Screenshot(const std::string& filename) { SWRenderer::SetScreenshot(filename.c_str()); diff --git a/Source/Core/VideoBackends/Software/VideoBackend.h b/Source/Core/VideoBackends/Software/VideoBackend.h index eb4d4807c2..0edb3bd4df 100644 --- a/Source/Core/VideoBackends/Software/VideoBackend.h +++ b/Source/Core/VideoBackends/Software/VideoBackend.h @@ -32,6 +32,7 @@ class VideoSoftware : public VideoBackend u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override; u32 Video_GetQueryResult(PerfQueryType type) override; + u16 Video_GetBoundingBox(int index) override; void Video_AddMessage(const std::string& msg, unsigned int milliseconds) override; void Video_ClearMessages() override; |
