mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-02 14:19:02 +00:00
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.
This commit is contained in:
parent
dced84d440
commit
c211450b99
24 changed files with 231 additions and 7 deletions
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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>()
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue