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
|
@ -34,6 +34,8 @@ public:
|
||||||
void RenderText(const std::string& text, int left, int top, u32 color) override;
|
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;
|
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 ResetAPIState() override;
|
||||||
void RestoreAPIState() override;
|
void RestoreAPIState() override;
|
||||||
|
|
|
@ -77,6 +77,7 @@ void InitBackendInfo()
|
||||||
g_Config.backend_info.bSupportsDualSourceBlend = true;
|
g_Config.backend_info.bSupportsDualSourceBlend = true;
|
||||||
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
g_Config.backend_info.bSupportsPrimitiveRestart = true;
|
||||||
g_Config.backend_info.bSupportsOversizedViewports = false;
|
g_Config.backend_info.bSupportsOversizedViewports = false;
|
||||||
|
g_Config.backend_info.bSupportsBBox = false; // TODO: not implemented
|
||||||
|
|
||||||
IDXGIFactory* factory;
|
IDXGIFactory* factory;
|
||||||
IDXGIAdapter* ad;
|
IDXGIAdapter* ad;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
|
@ -1,4 +1,5 @@
|
||||||
set(SRCS GLExtensions/GLExtensions.cpp
|
set(SRCS GLExtensions/GLExtensions.cpp
|
||||||
|
BoundingBox.cpp
|
||||||
FramebufferManager.cpp
|
FramebufferManager.cpp
|
||||||
GLUtil.cpp
|
GLUtil.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="BoundingBox.cpp" />
|
||||||
<ClCompile Include="FramebufferManager.cpp" />
|
<ClCompile Include="FramebufferManager.cpp" />
|
||||||
<ClCompile Include="GLExtensions\GLExtensions.cpp" />
|
<ClCompile Include="GLExtensions\GLExtensions.cpp" />
|
||||||
<ClCompile Include="GLInterface\GLInterface.cpp" />
|
<ClCompile Include="GLInterface\GLInterface.cpp" />
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
<ClCompile Include="VertexManager.cpp" />
|
<ClCompile Include="VertexManager.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="BoundingBox.h" />
|
||||||
<ClInclude Include="FramebufferManager.h" />
|
<ClInclude Include="FramebufferManager.h" />
|
||||||
<ClInclude Include="GLExtensions\ARB_blend_func_extended.h" />
|
<ClInclude Include="GLExtensions\ARB_blend_func_extended.h" />
|
||||||
<ClInclude Include="GLExtensions\ARB_buffer_storage.h" />
|
<ClInclude Include="GLExtensions\ARB_buffer_storage.h" />
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
<ClCompile Include="RasterFont.cpp">
|
<ClCompile Include="RasterFont.cpp">
|
||||||
<Filter>Logging</Filter>
|
<Filter>Logging</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="BoundingBox.cpp">
|
||||||
|
<Filter>Render</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="FramebufferManager.cpp">
|
<ClCompile Include="FramebufferManager.cpp">
|
||||||
<Filter>Render</Filter>
|
<Filter>Render</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -82,6 +85,9 @@
|
||||||
<ClInclude Include="RasterFont.h">
|
<ClInclude Include="RasterFont.h">
|
||||||
<Filter>Logging</Filter>
|
<Filter>Logging</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="BoundingBox.h">
|
||||||
|
<Filter>Render</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="FramebufferManager.h">
|
<ClInclude Include="FramebufferManager.h">
|
||||||
<Filter>Render</Filter>
|
<Filter>Render</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|
|
@ -485,6 +485,7 @@ void ProgramShaderCache::CreateHeader()
|
||||||
"%s\n" // msaa
|
"%s\n" // msaa
|
||||||
"%s\n" // sample shading
|
"%s\n" // sample shading
|
||||||
"%s\n" // Sampler binding
|
"%s\n" // Sampler binding
|
||||||
|
"%s\n" // storage buffer
|
||||||
|
|
||||||
// Precision defines for GLSL ES
|
// Precision defines for GLSL ES
|
||||||
"%s\n"
|
"%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.bSupportsMSAA && v < GLSL_150) ? "#extension GL_ARB_texture_multisample : enable" : ""
|
||||||
, (g_ogl_config.bSupportSampleShading) ? "#extension GL_ARB_sample_shading : 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.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 float;" : ""
|
||||||
, v>=GLSLES_300 ? "precision highp int;" : ""
|
, v>=GLSLES_300 ? "precision highp int;" : ""
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/Movie.h"
|
#include "Core/Movie.h"
|
||||||
|
|
||||||
|
#include "VideoBackends/OGL/BoundingBox.h"
|
||||||
#include "VideoBackends/OGL/FramebufferManager.h"
|
#include "VideoBackends/OGL/FramebufferManager.h"
|
||||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||||
#include "VideoBackends/OGL/GLUtil.h"
|
#include "VideoBackends/OGL/GLUtil.h"
|
||||||
|
@ -465,6 +466,7 @@ Renderer::Renderer()
|
||||||
g_Config.backend_info.bSupportsPrimitiveRestart = !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVERESTART) &&
|
g_Config.backend_info.bSupportsPrimitiveRestart = !DriverDetails::HasBug(DriverDetails::BUG_PRIMITIVERESTART) &&
|
||||||
((GLExtensions::Version() >= 310) || GLExtensions::Supports("GL_NV_primitive_restart"));
|
((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.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
|
// Desktop OpenGL supports the binding layout if it supports 420pack
|
||||||
// OpenGL ES 3.1 supports it implicitly without an extension
|
// 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;
|
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()
|
void Renderer::SetViewport()
|
||||||
{
|
{
|
||||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||||
|
|
|
@ -71,6 +71,9 @@ public:
|
||||||
|
|
||||||
u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) override;
|
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 ResetAPIState() override;
|
||||||
void RestoreAPIState() override;
|
void RestoreAPIState() override;
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,7 @@ Make AA apply instantly during gameplay if possible
|
||||||
#include "Core/Core.h"
|
#include "Core/Core.h"
|
||||||
#include "Core/Host.h"
|
#include "Core/Host.h"
|
||||||
|
|
||||||
|
#include "VideoBackends/OGL/BoundingBox.h"
|
||||||
#include "VideoBackends/OGL/FramebufferManager.h"
|
#include "VideoBackends/OGL/FramebufferManager.h"
|
||||||
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
#include "VideoBackends/OGL/GLInterfaceBase.h"
|
||||||
#include "VideoBackends/OGL/GLUtil.h"
|
#include "VideoBackends/OGL/GLUtil.h"
|
||||||
|
@ -205,6 +206,7 @@ void VideoBackend::Video_Prepare()
|
||||||
Renderer::Init();
|
Renderer::Init();
|
||||||
VertexLoaderManager::Init();
|
VertexLoaderManager::Init();
|
||||||
TextureConverter::Init();
|
TextureConverter::Init();
|
||||||
|
BoundingBox::Init();
|
||||||
|
|
||||||
// Notify the core that the video backend is ready
|
// Notify the core that the video backend is ready
|
||||||
Host_Message(WM_USER_CREATE);
|
Host_Message(WM_USER_CREATE);
|
||||||
|
@ -229,6 +231,7 @@ void VideoBackend::Video_Cleanup()
|
||||||
// The following calls are NOT Thread Safe
|
// The following calls are NOT Thread Safe
|
||||||
// And need to be called from the video thread
|
// And need to be called from the video thread
|
||||||
Renderer::Shutdown();
|
Renderer::Shutdown();
|
||||||
|
BoundingBox::Shutdown();
|
||||||
TextureConverter::Shutdown();
|
TextureConverter::Shutdown();
|
||||||
VertexLoaderManager::Shutdown();
|
VertexLoaderManager::Shutdown();
|
||||||
delete g_sampler_cache;
|
delete g_sampler_cache;
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "VideoBackends/Software/VideoBackend.h"
|
#include "VideoBackends/Software/VideoBackend.h"
|
||||||
#include "VideoBackends/Software/XFMemLoader.h"
|
#include "VideoBackends/Software/XFMemLoader.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/BoundingBox.h"
|
||||||
#include "VideoCommon/Fifo.h"
|
#include "VideoCommon/Fifo.h"
|
||||||
#include "VideoCommon/OnScreenDisplay.h"
|
#include "VideoCommon/OnScreenDisplay.h"
|
||||||
#include "VideoCommon/PixelEngine.h"
|
#include "VideoCommon/PixelEngine.h"
|
||||||
|
@ -283,6 +284,11 @@ u32 VideoSoftware::Video_GetQueryResult(PerfQueryType type)
|
||||||
return EfbInterface::perf_values[type];
|
return EfbInterface::perf_values[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u16 VideoSoftware::Video_GetBoundingBox(int index)
|
||||||
|
{
|
||||||
|
return BoundingBox::coords[index];
|
||||||
|
}
|
||||||
|
|
||||||
bool VideoSoftware::Video_Screenshot(const std::string& filename)
|
bool VideoSoftware::Video_Screenshot(const std::string& filename)
|
||||||
{
|
{
|
||||||
SWRenderer::SetScreenshot(filename.c_str());
|
SWRenderer::SetScreenshot(filename.c_str());
|
||||||
|
|
|
@ -32,6 +32,7 @@ class VideoSoftware : public VideoBackend
|
||||||
|
|
||||||
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override;
|
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override;
|
||||||
u32 Video_GetQueryResult(PerfQueryType type) 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_AddMessage(const std::string& msg, unsigned int milliseconds) override;
|
||||||
void Video_ClearMessages() override;
|
void Video_ClearMessages() override;
|
||||||
|
|
|
@ -380,6 +380,9 @@ static void BPWritten(const BPCmd& bp)
|
||||||
BoundingBox::coords[offset] = bp.newvalue & 0x3ff;
|
BoundingBox::coords[offset] = bp.newvalue & 0x3ff;
|
||||||
BoundingBox::coords[offset + 1] = bp.newvalue >> 10;
|
BoundingBox::coords[offset + 1] = bp.newvalue >> 10;
|
||||||
BoundingBox::active = true;
|
BoundingBox::active = true;
|
||||||
|
|
||||||
|
g_renderer->BBoxWrite(offset, bp.newvalue & 0x3ff);
|
||||||
|
g_renderer->BBoxWrite(offset + 1, bp.newvalue >> 10);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case BPMEM_TEXINVALIDATE:
|
case BPMEM_TEXINVALIDATE:
|
||||||
|
|
|
@ -37,6 +37,7 @@ enum SyncGPUReason
|
||||||
SYNC_GPU_WRAPAROUND,
|
SYNC_GPU_WRAPAROUND,
|
||||||
SYNC_GPU_EFB_POKE,
|
SYNC_GPU_EFB_POKE,
|
||||||
SYNC_GPU_PERFQUERY,
|
SYNC_GPU_PERFQUERY,
|
||||||
|
SYNC_GPU_BBOX,
|
||||||
SYNC_GPU_SWAP,
|
SYNC_GPU_SWAP,
|
||||||
SYNC_GPU_AUX_SPACE,
|
SYNC_GPU_AUX_SPACE,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Common/Event.h"
|
#include "Common/Event.h"
|
||||||
#include "Core/ConfigManager.h"
|
#include "Core/ConfigManager.h"
|
||||||
|
|
||||||
|
#include "VideoCommon/BoundingBox.h"
|
||||||
#include "VideoCommon/BPStructs.h"
|
#include "VideoCommon/BPStructs.h"
|
||||||
#include "VideoCommon/CommandProcessor.h"
|
#include "VideoCommon/CommandProcessor.h"
|
||||||
#include "VideoCommon/Fifo.h"
|
#include "VideoCommon/Fifo.h"
|
||||||
|
@ -25,6 +26,11 @@ static Common::Event s_efbAccessReadyEvent;
|
||||||
static Common::Flag s_perfQueryRequested;
|
static Common::Flag s_perfQueryRequested;
|
||||||
static Common::Event s_perfQueryReadyEvent;
|
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
|
static volatile struct
|
||||||
{
|
{
|
||||||
u32 xfbAddr;
|
u32 xfbAddr;
|
||||||
|
@ -217,6 +223,39 @@ u32 VideoBackendHardware::Video_GetQueryResult(PerfQueryType type)
|
||||||
return g_perf_query->GetQueryResult(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()
|
void VideoBackendHardware::InitializeShared()
|
||||||
{
|
{
|
||||||
VideoCommon_Init();
|
VideoCommon_Init();
|
||||||
|
@ -292,6 +331,7 @@ void VideoFifo_CheckAsyncRequest()
|
||||||
VideoFifo_CheckSwapRequest();
|
VideoFifo_CheckSwapRequest();
|
||||||
VideoFifo_CheckEFBAccess();
|
VideoFifo_CheckEFBAccess();
|
||||||
VideoFifo_CheckPerfQueryRequest();
|
VideoFifo_CheckPerfQueryRequest();
|
||||||
|
VideoFifo_CheckBBoxRequest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoBackendHardware::Video_GatherPipeBursted()
|
void VideoBackendHardware::Video_GatherPipeBursted()
|
||||||
|
|
|
@ -233,7 +233,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base)
|
||||||
mmio->Register(base | (PE_BBOX_LEFT + 2 * i),
|
mmio->Register(base | (PE_BBOX_LEFT + 2 * i),
|
||||||
MMIO::ComplexRead<u16>([i](u32) {
|
MMIO::ComplexRead<u16>([i](u32) {
|
||||||
BoundingBox::active = false;
|
BoundingBox::active = false;
|
||||||
return BoundingBox::coords[i];
|
return g_video_backend->Video_GetBoundingBox(i);
|
||||||
}),
|
}),
|
||||||
MMIO::InvalidWrite<u16>()
|
MMIO::InvalidWrite<u16>()
|
||||||
);
|
);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <xlocale.h>
|
#include <xlocale.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "VideoCommon/BoundingBox.h"
|
||||||
#include "VideoCommon/BPMemory.h"
|
#include "VideoCommon/BPMemory.h"
|
||||||
#include "VideoCommon/ConstantManager.h"
|
#include "VideoCommon/ConstantManager.h"
|
||||||
#include "VideoCommon/LightingShaderGen.h"
|
#include "VideoCommon/LightingShaderGen.h"
|
||||||
|
@ -264,6 +265,16 @@ static inline void GeneratePixelShader(T& out, DSTALPHA_MODE dstAlphaMode, API_T
|
||||||
"\tfloat4 " I_DEPTHPARAMS";\n"
|
"\tfloat4 " I_DEPTHPARAMS";\n"
|
||||||
"};\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 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);
|
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");
|
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");
|
out.Write("}\n");
|
||||||
|
|
||||||
if (is_writing_shadercode)
|
if (is_writing_shadercode)
|
||||||
|
|
|
@ -61,7 +61,7 @@ struct pixel_shader_uid_data
|
||||||
u32 per_pixel_depth : 1;
|
u32 per_pixel_depth : 1;
|
||||||
u32 forced_early_z : 1;
|
u32 forced_early_z : 1;
|
||||||
u32 early_ztest : 1;
|
u32 early_ztest : 1;
|
||||||
u32 pad1 : 1;
|
u32 bounding_box : 1;
|
||||||
|
|
||||||
u32 texMtxInfo_n_projection : 8; // 8x1 bit
|
u32 texMtxInfo_n_projection : 8; // 8x1 bit
|
||||||
u32 tevindref_bi0 : 3;
|
u32 tevindref_bi0 : 3;
|
||||||
|
|
|
@ -104,6 +104,9 @@ public:
|
||||||
|
|
||||||
virtual u32 AccessEFB(EFBAccessType type, u32 x, u32 y, u32 poke_data) = 0;
|
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.
|
// What's the real difference between these? Too similar names.
|
||||||
virtual void ResetAPIState() = 0;
|
virtual void ResetAPIState() = 0;
|
||||||
virtual void RestoreAPIState() = 0;
|
virtual void RestoreAPIState() = 0;
|
||||||
|
|
|
@ -171,6 +171,7 @@ void VertexLoader::CompileVertexTranslator()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Get the pointer to this vertex's buffer data for the bounding box
|
// Get the pointer to this vertex's buffer data for the bounding box
|
||||||
|
if (!g_ActiveConfig.backend_info.bSupportsBBox)
|
||||||
WriteCall(BoundingBox::SetVertexBufferPosition);
|
WriteCall(BoundingBox::SetVertexBufferPosition);
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
|
@ -380,6 +381,7 @@ void VertexLoader::CompileVertexTranslator()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the bounding box
|
// Update the bounding box
|
||||||
|
if (!g_ActiveConfig.backend_info.bSupportsBBox)
|
||||||
WriteCall(BoundingBox::Update);
|
WriteCall(BoundingBox::Update);
|
||||||
|
|
||||||
if (m_VtxDesc.PosMatIdx)
|
if (m_VtxDesc.PosMatIdx)
|
||||||
|
@ -457,6 +459,7 @@ void VertexLoader::SetupRunVertices(const VAT& vat, int primitive, int const cou
|
||||||
colElements[i] = m_VtxAttr.color[i].Elements;
|
colElements[i] = m_VtxAttr.color[i].Elements;
|
||||||
|
|
||||||
// Prepare bounding box
|
// Prepare bounding box
|
||||||
|
if (!g_ActiveConfig.backend_info.bSupportsBBox)
|
||||||
BoundingBox::Prepare(vat, primitive, m_VtxDesc, m_native_vtx_decl);
|
BoundingBox::Prepare(vat, primitive, m_VtxDesc, m_native_vtx_decl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ public:
|
||||||
|
|
||||||
virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0;
|
virtual u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) = 0;
|
||||||
virtual u32 Video_GetQueryResult(PerfQueryType type) = 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_AddMessage(const std::string& msg, unsigned int milliseconds) = 0;
|
||||||
virtual void Video_ClearMessages() = 0;
|
virtual void Video_ClearMessages() = 0;
|
||||||
|
@ -137,6 +138,7 @@ class VideoBackendHardware : public VideoBackend
|
||||||
|
|
||||||
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override;
|
u32 Video_AccessEFB(EFBAccessType, u32, u32, u32) override;
|
||||||
u32 Video_GetQueryResult(PerfQueryType type) 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_AddMessage(const std::string& pstr, unsigned int milliseconds) override;
|
||||||
void Video_ClearMessages() override;
|
void Video_ClearMessages() override;
|
||||||
|
|
|
@ -138,6 +138,7 @@ struct VideoConfig final
|
||||||
bool bSupportsOversizedViewports;
|
bool bSupportsOversizedViewports;
|
||||||
bool bSupportsEarlyZ; // needed by PixelShaderGen, so must stay in VideoCommon
|
bool bSupportsEarlyZ; // needed by PixelShaderGen, so must stay in VideoCommon
|
||||||
bool bSupportsBindingLayout; // Needed by ShaderGen, so must stay in VideoCommon
|
bool bSupportsBindingLayout; // Needed by ShaderGen, so must stay in VideoCommon
|
||||||
|
bool bSupportsBBox;
|
||||||
} backend_info;
|
} backend_info;
|
||||||
|
|
||||||
// Utility
|
// Utility
|
||||||
|
|
Loading…
Reference in New Issue