summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends
diff options
context:
space:
mode:
authorcomex <comexk@gmail.com>2014-11-19 20:25:23 -0500
committercomex <comexk@gmail.com>2014-11-19 20:25:23 -0500
commitfb50cb6d99062069a71db49d56d975df5c6eecb3 (patch)
treeb0a9615bcaa4d5d4efa65e590ff3b0e500391f6b /Source/Core/VideoBackends
parentdd2c8c49b37360f8b8838ccdb323a84eae00e065 (diff)
parentc211450b997effa6d91059fb0aaa564892297719 (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.h2
-rw-r--r--Source/Core/VideoBackends/D3D/main.cpp1
-rw-r--r--Source/Core/VideoBackends/OGL/BoundingBox.cpp54
-rw-r--r--Source/Core/VideoBackends/OGL/BoundingBox.h20
-rw-r--r--Source/Core/VideoBackends/OGL/CMakeLists.txt1
-rw-r--r--Source/Core/VideoBackends/OGL/OGL.vcxproj4
-rw-r--r--Source/Core/VideoBackends/OGL/OGL.vcxproj.filters6
-rw-r--r--Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp2
-rw-r--r--Source/Core/VideoBackends/OGL/Render.cpp48
-rw-r--r--Source/Core/VideoBackends/OGL/Render.h3
-rw-r--r--Source/Core/VideoBackends/OGL/main.cpp3
-rw-r--r--Source/Core/VideoBackends/Software/SWmain.cpp6
-rw-r--r--Source/Core/VideoBackends/Software/VideoBackend.h1
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;