2018-08-29 00:27:03 +02:00
|
|
|
// Copyright 2018 yuzu Emulator Project
|
|
|
|
// Licensed under GPLv2 or any later version
|
|
|
|
// Refer to the license.txt file included.
|
|
|
|
|
2018-09-06 20:57:40 +02:00
|
|
|
#include <memory>
|
|
|
|
|
2019-06-20 08:22:25 +02:00
|
|
|
#include <glad/glad.h>
|
|
|
|
|
2019-05-28 01:50:11 +02:00
|
|
|
#include "common/assert.h"
|
2019-07-20 18:54:31 +02:00
|
|
|
#include "common/microprofile.h"
|
2019-11-02 08:08:31 +01:00
|
|
|
#include "video_core/engines/maxwell_3d.h"
|
2019-08-29 23:58:34 +02:00
|
|
|
#include "video_core/rasterizer_interface.h"
|
2018-08-29 00:27:03 +02:00
|
|
|
#include "video_core/renderer_opengl/gl_buffer_cache.h"
|
2019-11-02 08:08:31 +01:00
|
|
|
#include "video_core/renderer_opengl/gl_device.h"
|
2018-11-08 12:08:00 +01:00
|
|
|
#include "video_core/renderer_opengl/gl_rasterizer.h"
|
2019-05-28 01:50:11 +02:00
|
|
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
2018-08-29 00:27:03 +02:00
|
|
|
|
|
|
|
namespace OpenGL {
|
|
|
|
|
2019-11-02 08:08:31 +01:00
|
|
|
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
|
|
|
|
|
2019-07-20 18:54:31 +02:00
|
|
|
MICROPROFILE_DEFINE(OpenGL_Buffer_Download, "OpenGL", "Buffer Download", MP_RGB(192, 192, 128));
|
|
|
|
|
2020-04-05 23:23:49 +02:00
|
|
|
CachedBufferBlock::CachedBufferBlock(VAddr cpu_addr, const std::size_t size)
|
|
|
|
: VideoCommon::BufferBlock{cpu_addr, size} {
|
2019-07-19 16:50:40 +02:00
|
|
|
gl_buffer.Create();
|
|
|
|
glNamedBufferData(gl_buffer.handle, static_cast<GLsizeiptr>(size), nullptr, GL_DYNAMIC_DRAW);
|
|
|
|
}
|
|
|
|
|
|
|
|
CachedBufferBlock::~CachedBufferBlock() = default;
|
|
|
|
|
2019-06-20 08:22:25 +02:00
|
|
|
OGLBufferCache::OGLBufferCache(RasterizerOpenGL& rasterizer, Core::System& system,
|
2019-11-02 08:08:31 +01:00
|
|
|
const Device& device, std::size_t stream_size)
|
|
|
|
: GenericBufferCache{rasterizer, system, std::make_unique<OGLStreamBuffer>(stream_size, true)} {
|
|
|
|
if (!device.HasFastBufferSubData()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static constexpr auto size = static_cast<GLsizeiptr>(Maxwell::MaxConstBufferSize);
|
|
|
|
glCreateBuffers(static_cast<GLsizei>(std::size(cbufs)), std::data(cbufs));
|
|
|
|
for (const GLuint cbuf : cbufs) {
|
|
|
|
glNamedBufferData(cbuf, size, nullptr, GL_STREAM_DRAW);
|
|
|
|
}
|
|
|
|
}
|
2019-05-28 01:50:11 +02:00
|
|
|
|
2019-11-02 08:08:31 +01:00
|
|
|
OGLBufferCache::~OGLBufferCache() {
|
|
|
|
glDeleteBuffers(static_cast<GLsizei>(std::size(cbufs)), std::data(cbufs));
|
|
|
|
}
|
2019-05-28 01:50:11 +02:00
|
|
|
|
2020-04-05 23:23:49 +02:00
|
|
|
Buffer OGLBufferCache::CreateBlock(VAddr cpu_addr, std::size_t size) {
|
|
|
|
return std::make_shared<CachedBufferBlock>(cpu_addr, size);
|
2019-07-19 16:50:40 +02:00
|
|
|
}
|
|
|
|
|
2020-04-04 07:54:55 +02:00
|
|
|
GLuint OGLBufferCache::ToHandle(const Buffer& buffer) {
|
2019-07-19 16:50:40 +02:00
|
|
|
return buffer->GetHandle();
|
2018-08-29 00:27:03 +02:00
|
|
|
}
|
2018-10-02 19:47:26 +02:00
|
|
|
|
2020-04-04 07:54:55 +02:00
|
|
|
GLuint OGLBufferCache::GetEmptyBuffer(std::size_t) {
|
|
|
|
return 0;
|
2019-05-28 01:50:11 +02:00
|
|
|
}
|
|
|
|
|
2019-07-19 16:50:40 +02:00
|
|
|
void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
|
|
const u8* data) {
|
2020-04-04 07:54:55 +02:00
|
|
|
glNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
|
2019-06-20 08:22:25 +02:00
|
|
|
static_cast<GLsizeiptr>(size), data);
|
2019-05-28 01:50:11 +02:00
|
|
|
}
|
|
|
|
|
2019-07-19 16:50:40 +02:00
|
|
|
void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
|
|
|
|
u8* data) {
|
2019-07-20 18:54:31 +02:00
|
|
|
MICROPROFILE_SCOPE(OpenGL_Buffer_Download);
|
2020-02-20 18:14:03 +01:00
|
|
|
glMemoryBarrier(GL_BUFFER_UPDATE_BARRIER_BIT);
|
2020-04-04 07:54:55 +02:00
|
|
|
glGetNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
|
2019-06-20 08:22:25 +02:00
|
|
|
static_cast<GLsizeiptr>(size), data);
|
2018-08-29 00:27:03 +02:00
|
|
|
}
|
|
|
|
|
2019-07-19 16:50:40 +02:00
|
|
|
void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
|
|
|
|
std::size_t dst_offset, std::size_t size) {
|
2020-04-04 07:54:55 +02:00
|
|
|
glCopyNamedBufferSubData(src->GetHandle(), dst->GetHandle(), static_cast<GLintptr>(src_offset),
|
|
|
|
static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
|
2018-08-29 00:27:03 +02:00
|
|
|
}
|
|
|
|
|
2019-11-02 08:08:31 +01:00
|
|
|
OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer,
|
|
|
|
std::size_t size) {
|
|
|
|
DEBUG_ASSERT(cbuf_cursor < std::size(cbufs));
|
|
|
|
const GLuint& cbuf = cbufs[cbuf_cursor++];
|
|
|
|
glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer);
|
2020-04-04 07:54:55 +02:00
|
|
|
return {cbuf, 0};
|
2019-11-02 08:08:31 +01:00
|
|
|
}
|
|
|
|
|
2018-08-29 00:27:03 +02:00
|
|
|
} // namespace OpenGL
|