From c211450b997effa6d91059fb0aaa564892297719 Mon Sep 17 00:00:00 2001 From: degasus Date: Thu, 13 Nov 2014 23:26:49 +0100 Subject: [PATCH] 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. --- Source/Core/VideoBackends/D3D/Render.h | 2 + Source/Core/VideoBackends/D3D/main.cpp | 1 + Source/Core/VideoBackends/OGL/BoundingBox.cpp | 54 +++++++++++++++++++ Source/Core/VideoBackends/OGL/BoundingBox.h | 20 +++++++ Source/Core/VideoBackends/OGL/CMakeLists.txt | 1 + Source/Core/VideoBackends/OGL/OGL.vcxproj | 4 +- .../VideoBackends/OGL/OGL.vcxproj.filters | 6 +++ .../VideoBackends/OGL/ProgramShaderCache.cpp | 2 + Source/Core/VideoBackends/OGL/Render.cpp | 48 +++++++++++++++++ Source/Core/VideoBackends/OGL/Render.h | 3 ++ Source/Core/VideoBackends/OGL/main.cpp | 3 ++ Source/Core/VideoBackends/Software/SWmain.cpp | 6 +++ .../VideoBackends/Software/VideoBackend.h | 1 + Source/Core/VideoCommon/BPStructs.cpp | 3 ++ Source/Core/VideoCommon/Fifo.h | 1 + Source/Core/VideoCommon/MainBase.cpp | 40 ++++++++++++++ Source/Core/VideoCommon/PixelEngine.cpp | 2 +- Source/Core/VideoCommon/PixelShaderGen.cpp | 22 ++++++++ Source/Core/VideoCommon/PixelShaderGen.h | 2 +- Source/Core/VideoCommon/RenderBase.cpp | 2 +- Source/Core/VideoCommon/RenderBase.h | 3 ++ Source/Core/VideoCommon/VertexLoader.cpp | 9 ++-- Source/Core/VideoCommon/VideoBackendBase.h | 2 + Source/Core/VideoCommon/VideoConfig.h | 1 + 24 files changed, 231 insertions(+), 7 deletions(-) create mode 100644 Source/Core/VideoBackends/OGL/BoundingBox.cpp create mode 100644 Source/Core/VideoBackends/OGL/BoundingBox.h 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 @@ + @@ -54,6 +55,7 @@ + @@ -111,4 +113,4 @@ - \ No newline at end of file + 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 @@ Logging + + Render + Render @@ -82,6 +85,9 @@ Logging + + Render + Render 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; 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([i](u32) { BoundingBox::active = false; - return BoundingBox::coords[i]; + return g_video_backend->Video_GetBoundingBox(i); }), MMIO::InvalidWrite() ); 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 #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