summaryrefslogtreecommitdiff
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-04-04 02:54:55 -0300
committerGravatar ReinUsesLisp2020-04-16 02:33:34 -0300
commit090fd3fefab9ef251e6e5bf4011280a657340f2a (patch)
treeacfdc14d7e948ae296859d3d112f356f3279680c /src/video_core/renderer_opengl
parentMerge pull request #3636 from ReinUsesLisp/drop-vk-hpp (diff)
downloadyuzu-090fd3fefab9ef251e6e5bf4011280a657340f2a.tar.gz
yuzu-090fd3fefab9ef251e6e5bf4011280a657340f2a.tar.xz
yuzu-090fd3fefab9ef251e6e5bf4011280a657340f2a.zip
buffer_cache: Return handles instead of pointer to handles
The original idea of returning pointers is that handles can be moved. The problem is that the implementation didn't take that in mind and made everything harder to work with. This commit drops pointer to handles and returns the handles themselves. While it is still true that handles can be invalidated, this way we get an old handle instead of a dangling pointer. This problem can be solved in the future with sparse buffers.
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_buffer_cache.h12
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp39
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h4
-rw-r--r--src/video_core/renderer_opengl/utils.cpp62
-rw-r--r--src/video_core/renderer_opengl/utils.h43
6 files changed, 26 insertions, 152 deletions
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
index 4eb37a96c..cb5792407 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp
@@ -55,33 +55,31 @@ void OGLBufferCache::WriteBarrier() {
55 glMemoryBarrier(GL_ALL_BARRIER_BITS); 55 glMemoryBarrier(GL_ALL_BARRIER_BITS);
56} 56}
57 57
58const GLuint* OGLBufferCache::ToHandle(const Buffer& buffer) { 58GLuint OGLBufferCache::ToHandle(const Buffer& buffer) {
59 return buffer->GetHandle(); 59 return buffer->GetHandle();
60} 60}
61 61
62const GLuint* OGLBufferCache::GetEmptyBuffer(std::size_t) { 62GLuint OGLBufferCache::GetEmptyBuffer(std::size_t) {
63 static const GLuint null_buffer = 0; 63 return 0;
64 return &null_buffer;
65} 64}
66 65
67void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 66void OGLBufferCache::UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
68 const u8* data) { 67 const u8* data) {
69 glNamedBufferSubData(*buffer->GetHandle(), static_cast<GLintptr>(offset), 68 glNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
70 static_cast<GLsizeiptr>(size), data); 69 static_cast<GLsizeiptr>(size), data);
71} 70}
72 71
73void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 72void OGLBufferCache::DownloadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
74 u8* data) { 73 u8* data) {
75 MICROPROFILE_SCOPE(OpenGL_Buffer_Download); 74 MICROPROFILE_SCOPE(OpenGL_Buffer_Download);
76 glGetNamedBufferSubData(*buffer->GetHandle(), static_cast<GLintptr>(offset), 75 glGetNamedBufferSubData(buffer->GetHandle(), static_cast<GLintptr>(offset),
77 static_cast<GLsizeiptr>(size), data); 76 static_cast<GLsizeiptr>(size), data);
78} 77}
79 78
80void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset, 79void OGLBufferCache::CopyBlock(const Buffer& src, const Buffer& dst, std::size_t src_offset,
81 std::size_t dst_offset, std::size_t size) { 80 std::size_t dst_offset, std::size_t size) {
82 glCopyNamedBufferSubData(*src->GetHandle(), *dst->GetHandle(), 81 glCopyNamedBufferSubData(src->GetHandle(), dst->GetHandle(), static_cast<GLintptr>(src_offset),
83 static_cast<GLintptr>(src_offset), static_cast<GLintptr>(dst_offset), 82 static_cast<GLintptr>(dst_offset), static_cast<GLsizeiptr>(size));
84 static_cast<GLsizeiptr>(size));
85} 83}
86 84
87OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer, 85OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_pointer,
@@ -89,7 +87,7 @@ OGLBufferCache::BufferInfo OGLBufferCache::ConstBufferUpload(const void* raw_poi
89 DEBUG_ASSERT(cbuf_cursor < std::size(cbufs)); 87 DEBUG_ASSERT(cbuf_cursor < std::size(cbufs));
90 const GLuint& cbuf = cbufs[cbuf_cursor++]; 88 const GLuint& cbuf = cbufs[cbuf_cursor++];
91 glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer); 89 glNamedBufferSubData(cbuf, 0, static_cast<GLsizeiptr>(size), raw_pointer);
92 return {&cbuf, 0}; 90 return {cbuf, 0};
93} 91}
94 92
95} // namespace OpenGL 93} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h
index d94a11252..a74817857 100644
--- a/src/video_core/renderer_opengl/gl_buffer_cache.h
+++ b/src/video_core/renderer_opengl/gl_buffer_cache.h
@@ -34,12 +34,12 @@ public:
34 explicit CachedBufferBlock(VAddr cpu_addr, const std::size_t size); 34 explicit CachedBufferBlock(VAddr cpu_addr, const std::size_t size);
35 ~CachedBufferBlock(); 35 ~CachedBufferBlock();
36 36
37 const GLuint* GetHandle() const { 37 GLuint GetHandle() const {
38 return &gl_buffer.handle; 38 return gl_buffer.handle;
39 } 39 }
40 40
41private: 41private:
42 OGLBuffer gl_buffer{}; 42 OGLBuffer gl_buffer;
43}; 43};
44 44
45class OGLBufferCache final : public GenericBufferCache { 45class OGLBufferCache final : public GenericBufferCache {
@@ -48,7 +48,7 @@ public:
48 const Device& device, std::size_t stream_size); 48 const Device& device, std::size_t stream_size);
49 ~OGLBufferCache(); 49 ~OGLBufferCache();
50 50
51 const GLuint* GetEmptyBuffer(std::size_t) override; 51 GLuint GetEmptyBuffer(std::size_t) override;
52 52
53 void Acquire() noexcept { 53 void Acquire() noexcept {
54 cbuf_cursor = 0; 54 cbuf_cursor = 0;
@@ -57,9 +57,9 @@ public:
57protected: 57protected:
58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override; 58 Buffer CreateBlock(VAddr cpu_addr, std::size_t size) override;
59 59
60 void WriteBarrier() override; 60 GLuint ToHandle(const Buffer& buffer) override;
61 61
62 const GLuint* ToHandle(const Buffer& buffer) override; 62 void WriteBarrier() override;
63 63
64 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size, 64 void UploadBlockData(const Buffer& buffer, std::size_t offset, std::size_t size,
65 const u8* data) override; 65 const u8* data) override;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f31d960c7..91abeb9d7 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -188,10 +188,8 @@ void RasterizerOpenGL::SetupVertexBuffer() {
188 ASSERT(end > start); 188 ASSERT(end > start);
189 const u64 size = end - start + 1; 189 const u64 size = end - start + 1;
190 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); 190 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
191 191 glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset,
192 // Bind the vertex array to the buffer at the current offset. 192 vertex_array.stride);
193 vertex_array_pushbuffer.SetVertexBuffer(static_cast<GLuint>(index), vertex_buffer,
194 vertex_buffer_offset, vertex_array.stride);
195 } 193 }
196} 194}
197 195
@@ -222,7 +220,7 @@ GLintptr RasterizerOpenGL::SetupIndexBuffer() {
222 const auto& regs = system.GPU().Maxwell3D().regs; 220 const auto& regs = system.GPU().Maxwell3D().regs;
223 const std::size_t size = CalculateIndexBufferSize(); 221 const std::size_t size = CalculateIndexBufferSize();
224 const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size); 222 const auto [buffer, offset] = buffer_cache.UploadMemory(regs.index_array.IndexStart(), size);
225 vertex_array_pushbuffer.SetIndexBuffer(buffer); 223 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer);
226 return offset; 224 return offset;
227} 225}
228 226
@@ -524,7 +522,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
524 522
525 // Prepare vertex array format. 523 // Prepare vertex array format.
526 SetupVertexFormat(); 524 SetupVertexFormat();
527 vertex_array_pushbuffer.Setup();
528 525
529 // Upload vertex and index data. 526 // Upload vertex and index data.
530 SetupVertexBuffer(); 527 SetupVertexBuffer();
@@ -534,17 +531,13 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
534 index_buffer_offset = SetupIndexBuffer(); 531 index_buffer_offset = SetupIndexBuffer();
535 } 532 }
536 533
537 // Prepare packed bindings.
538 bind_ubo_pushbuffer.Setup();
539 bind_ssbo_pushbuffer.Setup();
540
541 // Setup emulation uniform buffer. 534 // Setup emulation uniform buffer.
542 GLShader::MaxwellUniformData ubo; 535 GLShader::MaxwellUniformData ubo;
543 ubo.SetFromRegs(gpu); 536 ubo.SetFromRegs(gpu);
544 const auto [buffer, offset] = 537 const auto [buffer, offset] =
545 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment()); 538 buffer_cache.UploadHostMemory(&ubo, sizeof(ubo), device.GetUniformBufferAlignment());
546 bind_ubo_pushbuffer.Push(EmulationUniformBlockBinding, buffer, offset, 539 glBindBufferRange(GL_UNIFORM_BUFFER, EmulationUniformBlockBinding, buffer, offset,
547 static_cast<GLsizeiptr>(sizeof(ubo))); 540 static_cast<GLsizeiptr>(sizeof(ubo)));
548 541
549 // Setup shaders and their used resources. 542 // Setup shaders and their used resources.
550 texture_cache.GuardSamplers(true); 543 texture_cache.GuardSamplers(true);
@@ -557,11 +550,6 @@ void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
557 // Signal the buffer cache that we are not going to upload more things. 550 // Signal the buffer cache that we are not going to upload more things.
558 buffer_cache.Unmap(); 551 buffer_cache.Unmap();
559 552
560 // Now that we are no longer uploading data, we can safely bind the buffers to OpenGL.
561 vertex_array_pushbuffer.Bind();
562 bind_ubo_pushbuffer.Bind();
563 bind_ssbo_pushbuffer.Bind();
564
565 program_manager.BindGraphicsPipeline(); 553 program_manager.BindGraphicsPipeline();
566 554
567 if (texture_cache.TextureBarrier()) { 555 if (texture_cache.TextureBarrier()) {
@@ -630,17 +618,11 @@ void RasterizerOpenGL::DispatchCompute(GPUVAddr code_addr) {
630 (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment()); 618 (Maxwell::MaxConstBufferSize + device.GetUniformBufferAlignment());
631 buffer_cache.Map(buffer_size); 619 buffer_cache.Map(buffer_size);
632 620
633 bind_ubo_pushbuffer.Setup();
634 bind_ssbo_pushbuffer.Setup();
635
636 SetupComputeConstBuffers(kernel); 621 SetupComputeConstBuffers(kernel);
637 SetupComputeGlobalMemory(kernel); 622 SetupComputeGlobalMemory(kernel);
638 623
639 buffer_cache.Unmap(); 624 buffer_cache.Unmap();
640 625
641 bind_ubo_pushbuffer.Bind();
642 bind_ssbo_pushbuffer.Bind();
643
644 const auto& launch_desc = system.GPU().KeplerCompute().launch_description; 626 const auto& launch_desc = system.GPU().KeplerCompute().launch_description;
645 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z); 627 glDispatchCompute(launch_desc.grid_dim_x, launch_desc.grid_dim_y, launch_desc.grid_dim_z);
646 ++num_queued_commands; 628 ++num_queued_commands;
@@ -771,8 +753,8 @@ void RasterizerOpenGL::SetupConstBuffer(u32 binding, const Tegra::Engines::Const
771 const ConstBufferEntry& entry) { 753 const ConstBufferEntry& entry) {
772 if (!buffer.enabled) { 754 if (!buffer.enabled) {
773 // Set values to zero to unbind buffers 755 // Set values to zero to unbind buffers
774 bind_ubo_pushbuffer.Push(binding, buffer_cache.GetEmptyBuffer(sizeof(float)), 0, 756 glBindBufferRange(GL_UNIFORM_BUFFER, binding, buffer_cache.GetEmptyBuffer(sizeof(float)), 0,
775 sizeof(float)); 757 sizeof(float));
776 return; 758 return;
777 } 759 }
778 760
@@ -783,7 +765,7 @@ void RasterizerOpenGL::SetupConstBuffer(u32 binding, const Tegra::Engines::Const
783 const auto alignment = device.GetUniformBufferAlignment(); 765 const auto alignment = device.GetUniformBufferAlignment();
784 const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false, 766 const auto [cbuf, offset] = buffer_cache.UploadMemory(buffer.address, size, alignment, false,
785 device.HasFastBufferSubData()); 767 device.HasFastBufferSubData());
786 bind_ubo_pushbuffer.Push(binding, cbuf, offset, size); 768 glBindBufferRange(GL_UNIFORM_BUFFER, binding, cbuf, offset, size);
787} 769}
788 770
789void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) { 771void RasterizerOpenGL::SetupDrawGlobalMemory(std::size_t stage_index, const Shader& shader) {
@@ -819,7 +801,8 @@ void RasterizerOpenGL::SetupGlobalMemory(u32 binding, const GlobalMemoryEntry& e
819 const auto alignment{device.GetShaderStorageBufferAlignment()}; 801 const auto alignment{device.GetShaderStorageBufferAlignment()};
820 const auto [ssbo, buffer_offset] = 802 const auto [ssbo, buffer_offset] =
821 buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten()); 803 buffer_cache.UploadMemory(gpu_addr, size, alignment, entry.IsWritten());
822 bind_ssbo_pushbuffer.Push(binding, ssbo, buffer_offset, static_cast<GLsizeiptr>(size)); 804 glBindBufferRange(GL_SHADER_STORAGE_BUFFER, binding, ssbo, buffer_offset,
805 static_cast<GLsizeiptr>(size));
823} 806}
824 807
825void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) { 808void RasterizerOpenGL::SetupDrawTextures(std::size_t stage_index, const Shader& shader) {
@@ -1432,7 +1415,7 @@ void RasterizerOpenGL::EndTransformFeedback() {
1432 const GPUVAddr gpu_addr = binding.Address(); 1415 const GPUVAddr gpu_addr = binding.Address();
1433 const std::size_t size = binding.buffer_size; 1416 const std::size_t size = binding.buffer_size;
1434 const auto [dest_buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true); 1417 const auto [dest_buffer, offset] = buffer_cache.UploadMemory(gpu_addr, size, 4, true);
1435 glCopyNamedBufferSubData(handle, *dest_buffer, 0, offset, static_cast<GLsizeiptr>(size)); 1418 glCopyNamedBufferSubData(handle, dest_buffer, 0, offset, static_cast<GLsizeiptr>(size));
1436 } 1419 }
1437} 1420}
1438 1421
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 435da4425..caea174d2 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -231,9 +231,7 @@ private:
231 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; 231 static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
232 OGLBufferCache buffer_cache; 232 OGLBufferCache buffer_cache;
233 233
234 VertexArrayPushBuffer vertex_array_pushbuffer{state_tracker}; 234 GLint vertex_binding = 0;
235 BindBuffersRangePushBuffer bind_ubo_pushbuffer{GL_UNIFORM_BUFFER};
236 BindBuffersRangePushBuffer bind_ssbo_pushbuffer{GL_SHADER_STORAGE_BUFFER};
237 235
238 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers> 236 std::array<OGLBuffer, Tegra::Engines::Maxwell3D::Regs::NumTransformFeedbackBuffers>
239 transform_feedback_buffers; 237 transform_feedback_buffers;
diff --git a/src/video_core/renderer_opengl/utils.cpp b/src/video_core/renderer_opengl/utils.cpp
index b751086fa..6d7bb16b2 100644
--- a/src/video_core/renderer_opengl/utils.cpp
+++ b/src/video_core/renderer_opengl/utils.cpp
@@ -14,68 +14,6 @@
14 14
15namespace OpenGL { 15namespace OpenGL {
16 16
17struct VertexArrayPushBuffer::Entry {
18 GLuint binding_index{};
19 const GLuint* buffer{};
20 GLintptr offset{};
21 GLsizei stride{};
22};
23
24VertexArrayPushBuffer::VertexArrayPushBuffer(StateTracker& state_tracker)
25 : state_tracker{state_tracker} {}
26
27VertexArrayPushBuffer::~VertexArrayPushBuffer() = default;
28
29void VertexArrayPushBuffer::Setup() {
30 index_buffer = nullptr;
31 vertex_buffers.clear();
32}
33
34void VertexArrayPushBuffer::SetIndexBuffer(const GLuint* buffer) {
35 index_buffer = buffer;
36}
37
38void VertexArrayPushBuffer::SetVertexBuffer(GLuint binding_index, const GLuint* buffer,
39 GLintptr offset, GLsizei stride) {
40 vertex_buffers.push_back(Entry{binding_index, buffer, offset, stride});
41}
42
43void VertexArrayPushBuffer::Bind() {
44 if (index_buffer) {
45 state_tracker.BindIndexBuffer(*index_buffer);
46 }
47
48 for (const auto& entry : vertex_buffers) {
49 glBindVertexBuffer(entry.binding_index, *entry.buffer, entry.offset, entry.stride);
50 }
51}
52
53struct BindBuffersRangePushBuffer::Entry {
54 GLuint binding;
55 const GLuint* buffer;
56 GLintptr offset;
57 GLsizeiptr size;
58};
59
60BindBuffersRangePushBuffer::BindBuffersRangePushBuffer(GLenum target) : target{target} {}
61
62BindBuffersRangePushBuffer::~BindBuffersRangePushBuffer() = default;
63
64void BindBuffersRangePushBuffer::Setup() {
65 entries.clear();
66}
67
68void BindBuffersRangePushBuffer::Push(GLuint binding, const GLuint* buffer, GLintptr offset,
69 GLsizeiptr size) {
70 entries.push_back(Entry{binding, buffer, offset, size});
71}
72
73void BindBuffersRangePushBuffer::Bind() {
74 for (const Entry& entry : entries) {
75 glBindBufferRange(target, entry.binding, *entry.buffer, entry.offset, entry.size);
76 }
77}
78
79void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info) { 17void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info) {
80 if (!GLAD_GL_KHR_debug) { 18 if (!GLAD_GL_KHR_debug) {
81 // We don't need to throw an error as this is just for debugging 19 // We don't need to throw an error as this is just for debugging
diff --git a/src/video_core/renderer_opengl/utils.h b/src/video_core/renderer_opengl/utils.h
index 47ee3177b..9c09ee12c 100644
--- a/src/video_core/renderer_opengl/utils.h
+++ b/src/video_core/renderer_opengl/utils.h
@@ -11,49 +11,6 @@
11 11
12namespace OpenGL { 12namespace OpenGL {
13 13
14class StateTracker;
15
16class VertexArrayPushBuffer final {
17public:
18 explicit VertexArrayPushBuffer(StateTracker& state_tracker);
19 ~VertexArrayPushBuffer();
20
21 void Setup();
22
23 void SetIndexBuffer(const GLuint* buffer);
24
25 void SetVertexBuffer(GLuint binding_index, const GLuint* buffer, GLintptr offset,
26 GLsizei stride);
27
28 void Bind();
29
30private:
31 struct Entry;
32
33 StateTracker& state_tracker;
34
35 const GLuint* index_buffer{};
36 std::vector<Entry> vertex_buffers;
37};
38
39class BindBuffersRangePushBuffer final {
40public:
41 explicit BindBuffersRangePushBuffer(GLenum target);
42 ~BindBuffersRangePushBuffer();
43
44 void Setup();
45
46 void Push(GLuint binding, const GLuint* buffer, GLintptr offset, GLsizeiptr size);
47
48 void Bind();
49
50private:
51 struct Entry;
52
53 GLenum target;
54 std::vector<Entry> entries;
55};
56
57void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info = {}); 14void LabelGLObject(GLenum identifier, GLuint handle, VAddr addr, std::string_view extra_info = {});
58 15
59} // namespace OpenGL 16} // namespace OpenGL