summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
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/VideoCommon
parentdd2c8c49b37360f8b8838ccdb323a84eae00e065 (diff)
parentc211450b997effa6d91059fb0aaa564892297719 (diff)
Merge pull request #1550 from degasus/bbox
OGL: implement bounding box support with ssbo
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/BPStructs.cpp3
-rw-r--r--Source/Core/VideoCommon/Fifo.h1
-rw-r--r--Source/Core/VideoCommon/MainBase.cpp40
-rw-r--r--Source/Core/VideoCommon/PixelEngine.cpp2
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.cpp22
-rw-r--r--Source/Core/VideoCommon/PixelShaderGen.h2
-rw-r--r--Source/Core/VideoCommon/RenderBase.cpp2
-rw-r--r--Source/Core/VideoCommon/RenderBase.h3
-rw-r--r--Source/Core/VideoCommon/VertexLoader.cpp9
-rw-r--r--Source/Core/VideoCommon/VideoBackendBase.h2
-rw-r--r--Source/Core/VideoCommon/VideoConfig.h1
11 files changed, 81 insertions, 6 deletions
diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp
index 79c24778bd..c6b57c81ca 100644
--- a/Source/Core/VideoCommon/BPStructs.cpp
+++ b/Source/Core/VideoCommon/BPStructs.cpp
@@ -380,6 +380,9 @@ static void BPWritten(const BPCmd& bp)
BoundingBox::coords[offset] = bp.newvalue & 0x3ff;
BoundingBox::coords[offset + 1] = bp.newvalue >> 10;
BoundingBox::active = true;
+
+ g_renderer->BBoxWrite(offset, bp.newvalue & 0x3ff);
+ g_renderer->BBoxWrite(offset + 1, bp.newvalue >> 10);
}
return;
case BPMEM_TEXINVALIDATE:
diff --git a/Source/Core/VideoCommon/Fifo.h b/Source/Core/VideoCommon/Fifo.h
index 4418ac77af..3a441c187c 100644
--- a/Source/Core/VideoCommon/Fifo.h
+++ b/Source/Core/VideoCommon/Fifo.h
@@ -37,6 +37,7 @@ enum SyncGPUReason
SYNC_GPU_WRAPAROUND,
SYNC_GPU_EFB_POKE,
SYNC_GPU_PERFQUERY,
+ SYNC_GPU_BBOX,
SYNC_GPU_SWAP,
SYNC_GPU_AUX_SPACE,
};
diff --git a/Source/Core/VideoCommon/MainBase.cpp b/Source/Core/VideoCommon/MainBase.cpp
index d775cfe64c..40d2f57f20 100644
--- a/Source/Core/VideoCommon/MainBase.cpp
+++ b/Source/Core/VideoCommon/MainBase.cpp
@@ -1,6 +1,7 @@
#include "Common/Event.h"
#include "Core/ConfigManager.h"
+#include "VideoCommon/BoundingBox.h"
#include "VideoCommon/BPStructs.h"
#include "VideoCommon/CommandProcessor.h"
#include "VideoCommon/Fifo.h"
@@ -25,6 +26,11 @@ static Common::Event s_efbAccessReadyEvent;
static Common::Flag s_perfQueryRequested;
static Common::Event s_perfQueryReadyEvent;
+static Common::Flag s_BBoxRequested;
+static Common::Event s_BBoxReadyEvent;
+static int s_BBoxIndex;
+static u16 s_BBoxResult;
+
static volatile struct
{
u32 xfbAddr;
@@ -217,6 +223,39 @@ u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type)
return g_perf_query->GetQueryResult(type);
}
+u16 VideoBackendHardware::Video_GetBoundingBox(int index)
+{
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
+ return BoundingBox::coords[index];
+
+ SyncGPU(SYNC_GPU_BBOX);
+
+ if (SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread)
+ {
+ s_BBoxReadyEvent.Reset();
+ if (s_FifoShuttingDown.IsSet())
+ return 0;
+ s_BBoxIndex = index;
+ s_BBoxRequested.Set();
+ s_BBoxReadyEvent.Wait();
+ return s_BBoxResult;
+ }
+ else
+ {
+ return g_renderer->BBoxRead(index);
+ }
+}
+
+static void VideoFifo_CheckBBoxRequest()
+{
+ if (s_BBoxRequested.IsSet())
+ {
+ s_BBoxResult = g_renderer->BBoxRead(s_BBoxIndex);
+ s_BBoxRequested.Clear();
+ s_BBoxReadyEvent.Set();
+ }
+}
+
void VideoBackendHardware::InitializeShared()
{
VideoCommon_Init();
@@ -292,6 +331,7 @@ void VideoFifo_CheckAsyncRequest()
VideoFifo_CheckSwapRequest();
VideoFifo_CheckEFBAccess();
VideoFifo_CheckPerfQueryRequest();
+ VideoFifo_CheckBBoxRequest();
}
void VideoBackendHardware::Video_GatherPipeBursted()
diff --git a/Source/Core/VideoCommon/PixelEngine.cpp b/Source/Core/VideoCommon/PixelEngine.cpp
index 7fd8e12a39..f6bc26186a 100644
--- a/Source/Core/VideoCommon/PixelEngine.cpp
+++ b/Source/Core/VideoCommon/PixelEngine.cpp
@@ -233,7 +233,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
mmio->Register(base | (PE_BBOX_LEFT + 2 * i),
MMIO::ComplexRead<u16>([i](u32) {
BoundingBox::active = false;
- return BoundingBox::coords[i];
+ return g_video_backend->Video_GetBoundingBox(i);
}),
MMIO::InvalidWrite<u16>()
);
diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp
index 0f03fc013b..c0b45fdfda 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/PixelShaderGen.cpp
@@ -10,6 +10,7 @@
#include <xlocale.h>
#endif
+#include "VideoCommon/BoundingBox.h"
#include "VideoCommon/BPMemory.h"
#include "VideoCommon/ConstantManager.h"
#include "VideoCommon/LightingShaderGen.h"
@@ -264,6 +265,16 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
"\tfloat4 " I_DEPTHPARAMS";\n"
"};\n");
}
+
+ if (g_ActiveConfig.backend_info.bSupportsBBox)
+ {
+ out.Write(
+ "layout(std140, binding = 3) buffer BBox {\n"
+ "\tint4 bbox_data;\n"
+ "};\n"
+ );
+ }
+
const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED);
const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z);
@@ -551,6 +562,17 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
out.Write("\tocol0.a = float(" I_ALPHA".a) / 255.0;\n");
}
+ if (g_ActiveConfig.backend_info.bSupportsBBox && BoundingBox::active)
+ {
+ uid_data->bounding_box = true;
+ out.Write(
+ "\tif(bbox_data.x > int(gl_FragCoord.x)) atomicMin(bbox_data.x, int(gl_FragCoord.x));\n"
+ "\tif(bbox_data.y < int(gl_FragCoord.x)) atomicMax(bbox_data.y, int(gl_FragCoord.x));\n"
+ "\tif(bbox_data.z > int(gl_FragCoord.y)) atomicMin(bbox_data.z, int(gl_FragCoord.y));\n"
+ "\tif(bbox_data.w < int(gl_FragCoord.y)) atomicMax(bbox_data.w, int(gl_FragCoord.y));\n"
+ );
+ }
+
out.Write("}\n");
if (is_writing_shadercode)
diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h
index 2be3f59ba3..369f940619 100644
--- a/Source/Core/VideoCommon/PixelShaderGen.h
+++ b/Source/Core/VideoCommon/PixelShaderGen.h
@@ -61,7 +61,7 @@ struct pixel_shader_uid_data
u32 per_pixel_depth : 1;
u32 forced_early_z : 1;
u32 early_ztest : 1;
- u32 pad1 : 1;
+ u32 bounding_box : 1;
u32 texMtxInfo_n_projection : 8; // 8x1 bit
u32 tevindref_bi0 : 3;
diff --git a/Source/Core/VideoCommon/RenderBase.cpp b/Source/Core/VideoCommon/RenderBase.cpp
index 18b622b513..d93d43f490 100644
--- a/Source/Core/VideoCommon/RenderBase.cpp
+++ b/Source/Core/VideoCommon/RenderBase.cpp
@@ -132,7 +132,7 @@ int Renderer::EFBToScaledX(int x)
{
switch (g_ActiveConfig.iEFBScale)
{
- case SCALE_AUTO: // fractional
+ case SCALE_AUTO: // fractional
return FramebufferManagerBase::ScaleToVirtualXfbWidth(x, s_backbuffer_width);
default:
diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h
index 2350117369..746f75366c 100644
--- a/Source/Core/VideoCommon/RenderBase.h
+++ b/Source/Core/VideoCommon/RenderBase.h
@@ -104,6 +104,9 @@ public:
virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0;
+ virtual u16 BBoxRead(int index) = 0;
+ virtual void BBoxWrite(int index, u16 value) = 0;
+
// What's the real difference between these? Too similar names.
virtual void ResetAPIState() = 0;
virtual void RestoreAPIState() = 0;
diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp
index 4e6963124e..373dfae16b 100644
--- a/Source/Core/VideoCommon/VertexLoader.cpp
+++ b/Source/Core/VideoCommon/VertexLoader.cpp
@@ -171,7 +171,8 @@ void VertexLoader::CompileVertexTranslator()
#endif
// Get the pointer to this vertex's buffer data for the bounding box
- WriteCall(BoundingBox::SetVertexBufferPosition);
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
+ WriteCall(BoundingBox::SetVertexBufferPosition);
// Colors
const u64 col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
@@ -380,7 +381,8 @@ void VertexLoader::CompileVertexTranslator()
}
// Update the bounding box
- WriteCall(BoundingBox::Update);
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
+ WriteCall(BoundingBox::Update);
if (m_VtxDesc.PosMatIdx)
{
@@ -457,7 +459,8 @@ void VertexLoader::SetupRunVertices(const VAT& vat, int primitive, int const cou
colElements[i] = m_VtxAttr.color[i].Elements;
// Prepare bounding box
- BoundingBox::Prepare(vat, primitive, m_VtxDesc, m_native_vtx_decl);
+ if (!g_ActiveConfig.backend_info.bSupportsBBox)
+ BoundingBox::Prepare(vat, primitive, m_VtxDesc, m_native_vtx_decl);
}
void VertexLoader::ConvertVertices ( int count )
diff --git a/Source/Core/VideoCommon/VideoBackendBase.h b/Source/Core/VideoCommon/VideoBackendBase.h
index 7d62dda37b..7260fe6098 100644
--- a/Source/Core/VideoCommon/VideoBackendBase.h
+++ b/Source/Core/VideoCommon/VideoBackendBase.h
@@ -89,6 +89,7 @@ public:
virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0;
virtual u32 Video_GetQueryResult(PerfQueryType type) = 0;
+ virtual u16 Video_GetBoundingBox(int index) = 0;
virtual void Video_AddMessage(const std::string& msg, unsigned int milliseconds) = 0;
virtual void Video_ClearMessages() = 0;
@@ -137,6 +138,7 @@ class VideoBackendHardware : 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& pstr, unsigned int milliseconds) override;
void Video_ClearMessages() override;
diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h
index 9f2a8e81eb..44b0740728 100644
--- a/Source/Core/VideoCommon/VideoConfig.h
+++ b/Source/Core/VideoCommon/VideoConfig.h
@@ -138,6 +138,7 @@ struct VideoConfig final
bool bSupportsOversizedViewports;
bool bSupportsEarlyZ; // needed by PixelShaderGen, so must stay in VideoCommon
bool bSupportsBindingLayout; // Needed by ShaderGen, so must stay in VideoCommon
+ bool bSupportsBBox;
} backend_info;
// Utility