summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authordegasus <wickmarkus@web.de>2014-11-13 23:26:49 +0100
committerdegasus <wickmarkus@web.de>2014-11-17 21:20:32 +0100
commitc211450b997effa6d91059fb0aaa564892297719 (patch)
treefabbfdf698d6e499c53dec988d4b7ba2ef6556bc /Source/Core/VideoCommon
parentdced84d4404b1f0346297c5941bfdf94cfdef4d5 (diff)
OGL: implement bounding box support with ssbo
This implemention tries to be as accurate as the old SW implemention, but it will remove the dependcy of our vertexloader on videosw.
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