2014-11-13 15:26:49 -07:00
|
|
|
// Copyright 2014 Dolphin Emulator Project
|
2021-07-04 19:22:19 -06:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2014-11-13 15:26:49 -07:00
|
|
|
|
2020-09-15 06:00:24 -06:00
|
|
|
#include "VideoBackends/OGL/OGLBoundingBox.h"
|
2014-11-13 15:26:49 -07:00
|
|
|
|
2023-01-26 17:21:09 -07:00
|
|
|
#include "VideoBackends/OGL/OGLGfx.h"
|
2016-05-11 06:19:59 -06:00
|
|
|
#include "VideoCommon/DriverDetails.h"
|
2014-11-13 15:26:49 -07:00
|
|
|
|
|
|
|
namespace OGL
|
|
|
|
{
|
2021-06-09 05:42:21 -06:00
|
|
|
OGLBoundingBox::~OGLBoundingBox()
|
2014-11-13 15:26:49 -07:00
|
|
|
{
|
2021-06-09 05:42:21 -06:00
|
|
|
if (m_buffer_id)
|
|
|
|
glDeleteBuffers(1, &m_buffer_id);
|
2014-11-13 15:26:49 -07:00
|
|
|
}
|
|
|
|
|
2021-06-09 05:42:21 -06:00
|
|
|
bool OGLBoundingBox::Initialize()
|
2014-11-13 15:26:49 -07:00
|
|
|
{
|
2021-06-09 05:42:21 -06:00
|
|
|
const BBoxType initial_values[NUM_BBOX_VALUES] = {0, 0, 0, 0};
|
2021-04-17 11:14:52 -06:00
|
|
|
|
2021-06-09 05:42:21 -06:00
|
|
|
glGenBuffers(1, &m_buffer_id);
|
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer_id);
|
|
|
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(initial_values), initial_values, GL_DYNAMIC_DRAW);
|
|
|
|
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, m_buffer_id);
|
2021-04-17 11:14:52 -06:00
|
|
|
|
2021-06-09 05:42:21 -06:00
|
|
|
return true;
|
2014-11-13 15:26:49 -07:00
|
|
|
}
|
|
|
|
|
2021-06-09 05:42:21 -06:00
|
|
|
std::vector<BBoxType> OGLBoundingBox::Read(u32 index, u32 length)
|
2014-11-13 15:26:49 -07:00
|
|
|
{
|
2021-06-09 05:42:21 -06:00
|
|
|
std::vector<BBoxType> values(length);
|
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer_id);
|
2021-05-29 00:50:33 -06:00
|
|
|
|
|
|
|
// Using glMapBufferRange to read back the contents of the SSBO is extremely slow
|
|
|
|
// on nVidia drivers. This is more noticeable at higher internal resolutions.
|
|
|
|
// Using glGetBufferSubData instead does not seem to exhibit this slowdown.
|
2019-02-14 18:59:50 -07:00
|
|
|
if (!DriverDetails::HasBug(DriverDetails::BUG_SLOW_GETBUFFERSUBDATA) &&
|
2023-01-26 17:21:09 -07:00
|
|
|
!static_cast<OGLGfx*>(g_gfx.get())->IsGLES())
|
2016-05-11 06:19:59 -06:00
|
|
|
{
|
2021-05-29 00:50:33 -06:00
|
|
|
// We also need to ensure the the CPU does not receive stale values which have been updated by
|
|
|
|
// the GPU. Apparently the buffer here is not coherent on NVIDIA drivers. Not sure if this is a
|
|
|
|
// driver bug/spec violation or not, one would think that glGetBufferSubData() would invalidate
|
|
|
|
// any caches as needed, but this path is only used on NVIDIA anyway, so it's fine. A point to
|
|
|
|
// note is that according to ARB_debug_report, it's moved from video to host memory, which would
|
|
|
|
// explain why it needs the cache invalidate.
|
|
|
|
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
|
|
|
|
2021-06-09 05:42:21 -06:00
|
|
|
glGetBufferSubData(GL_SHADER_STORAGE_BUFFER, sizeof(BBoxType) * index,
|
|
|
|
sizeof(BBoxType) * length, values.data());
|
2016-05-11 06:19:59 -06:00
|
|
|
}
|
|
|
|
else
|
2014-11-13 15:26:49 -07:00
|
|
|
{
|
2019-02-14 18:59:50 -07:00
|
|
|
// Using glMapBufferRange is faster on AMD cards by a measurable margin.
|
2021-06-09 05:42:21 -06:00
|
|
|
void* ptr = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, 0, sizeof(BBoxType) * NUM_BBOX_VALUES,
|
2019-02-14 18:59:50 -07:00
|
|
|
GL_MAP_READ_BIT);
|
|
|
|
if (ptr)
|
2016-05-11 06:19:59 -06:00
|
|
|
{
|
2021-06-09 05:42:21 -06:00
|
|
|
std::memcpy(values.data(), reinterpret_cast<const u8*>(ptr) + sizeof(BBoxType) * index,
|
|
|
|
sizeof(BBoxType) * length);
|
2021-04-17 11:14:52 -06:00
|
|
|
|
2019-02-14 18:59:50 -07:00
|
|
|
glUnmapBuffer(GL_SHADER_STORAGE_BUFFER);
|
2016-05-11 06:19:59 -06:00
|
|
|
}
|
2014-11-13 15:26:49 -07:00
|
|
|
}
|
2021-06-09 05:42:21 -06:00
|
|
|
|
2019-02-14 18:59:50 -07:00
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
2021-06-09 05:42:21 -06:00
|
|
|
return values;
|
2021-04-17 11:14:52 -06:00
|
|
|
}
|
|
|
|
|
2023-12-09 12:54:17 -07:00
|
|
|
void OGLBoundingBox::Write(u32 index, std::span<const BBoxType> values)
|
2021-04-17 11:14:52 -06:00
|
|
|
{
|
2021-06-09 05:42:21 -06:00
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, m_buffer_id);
|
|
|
|
glBufferSubData(GL_SHADER_STORAGE_BUFFER, sizeof(BBoxType) * index,
|
|
|
|
sizeof(BBoxType) * values.size(), values.data());
|
|
|
|
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
|
2021-04-17 11:14:52 -06:00
|
|
|
}
|
|
|
|
|
2021-06-09 05:42:21 -06:00
|
|
|
} // namespace OGL
|