diff options
| author | 2018-09-05 11:35:31 -0400 | |
|---|---|---|
| committer | 2018-09-05 11:35:31 -0400 | |
| commit | 527e362a839632ab2d9f7fae3147f53709469d32 (patch) | |
| tree | 9a70d16050f9ee4edb84e923ed92fc15ed9d4482 /src | |
| parent | Merge pull request #1240 from degasus/optimizations (diff) | |
| parent | renderer_opengl: Implement a buffer cache. (diff) | |
| download | yuzu-527e362a839632ab2d9f7fae3147f53709469d32.tar.gz yuzu-527e362a839632ab2d9f7fae3147f53709469d32.tar.xz yuzu-527e362a839632ab2d9f7fae3147f53709469d32.zip | |
Merge pull request #1217 from degasus/vbo_cache2
renderer_opengl: Implement a buffer cache.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.cpp | 90 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_buffer_cache.h | 57 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 101 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 19 |
5 files changed, 182 insertions, 86 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index aa5bc3bbe..1982b76c4 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt | |||
| @@ -22,6 +22,7 @@ add_library(video_core STATIC | |||
| 22 | rasterizer_interface.h | 22 | rasterizer_interface.h |
| 23 | renderer_base.cpp | 23 | renderer_base.cpp |
| 24 | renderer_base.h | 24 | renderer_base.h |
| 25 | renderer_opengl/gl_buffer_cache.cpp | ||
| 25 | renderer_opengl/gl_rasterizer.cpp | 26 | renderer_opengl/gl_rasterizer.cpp |
| 26 | renderer_opengl/gl_rasterizer.h | 27 | renderer_opengl/gl_rasterizer.h |
| 27 | renderer_opengl/gl_rasterizer_cache.cpp | 28 | renderer_opengl/gl_rasterizer_cache.cpp |
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.cpp b/src/video_core/renderer_opengl/gl_buffer_cache.cpp new file mode 100644 index 000000000..c85fbd306 --- /dev/null +++ b/src/video_core/renderer_opengl/gl_buffer_cache.cpp | |||
| @@ -0,0 +1,90 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/alignment.h" | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "core/core.h" | ||
| 8 | #include "core/memory.h" | ||
| 9 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | ||
| 10 | |||
| 11 | namespace OpenGL { | ||
| 12 | |||
| 13 | OGLBufferCache::OGLBufferCache(size_t size) : stream_buffer(GL_ARRAY_BUFFER, size) {} | ||
| 14 | |||
| 15 | GLintptr OGLBufferCache::UploadMemory(Tegra::GPUVAddr gpu_addr, size_t size, size_t alignment, | ||
| 16 | bool cache) { | ||
| 17 | auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); | ||
| 18 | const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; | ||
| 19 | |||
| 20 | // Cache management is a big overhead, so only cache entries with a given size. | ||
| 21 | // TODO: Figure out which size is the best for given games. | ||
| 22 | cache &= size >= 2048; | ||
| 23 | |||
| 24 | if (cache) { | ||
| 25 | auto entry = TryGet(*cpu_addr); | ||
| 26 | if (entry) { | ||
| 27 | if (entry->size >= size && entry->alignment == alignment) { | ||
| 28 | return entry->offset; | ||
| 29 | } | ||
| 30 | Unregister(entry); | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | AlignBuffer(alignment); | ||
| 35 | GLintptr uploaded_offset = buffer_offset; | ||
| 36 | |||
| 37 | Memory::ReadBlock(*cpu_addr, buffer_ptr, size); | ||
| 38 | |||
| 39 | buffer_ptr += size; | ||
| 40 | buffer_offset += size; | ||
| 41 | |||
| 42 | if (cache) { | ||
| 43 | auto entry = std::make_shared<CachedBufferEntry>(); | ||
| 44 | entry->offset = uploaded_offset; | ||
| 45 | entry->size = size; | ||
| 46 | entry->alignment = alignment; | ||
| 47 | entry->addr = *cpu_addr; | ||
| 48 | Register(entry); | ||
| 49 | } | ||
| 50 | |||
| 51 | return uploaded_offset; | ||
| 52 | } | ||
| 53 | |||
| 54 | GLintptr OGLBufferCache::UploadHostMemory(const void* raw_pointer, size_t size, size_t alignment) { | ||
| 55 | AlignBuffer(alignment); | ||
| 56 | std::memcpy(buffer_ptr, raw_pointer, size); | ||
| 57 | GLintptr uploaded_offset = buffer_offset; | ||
| 58 | |||
| 59 | buffer_ptr += size; | ||
| 60 | buffer_offset += size; | ||
| 61 | return uploaded_offset; | ||
| 62 | } | ||
| 63 | |||
| 64 | void OGLBufferCache::Map(size_t max_size) { | ||
| 65 | bool invalidate; | ||
| 66 | std::tie(buffer_ptr, buffer_offset_base, invalidate) = | ||
| 67 | stream_buffer.Map(static_cast<GLsizeiptr>(max_size), 4); | ||
| 68 | buffer_offset = buffer_offset_base; | ||
| 69 | |||
| 70 | if (invalidate) { | ||
| 71 | InvalidateAll(); | ||
| 72 | } | ||
| 73 | } | ||
| 74 | void OGLBufferCache::Unmap() { | ||
| 75 | stream_buffer.Unmap(buffer_offset - buffer_offset_base); | ||
| 76 | } | ||
| 77 | |||
| 78 | GLuint OGLBufferCache::GetHandle() { | ||
| 79 | return stream_buffer.GetHandle(); | ||
| 80 | } | ||
| 81 | |||
| 82 | void OGLBufferCache::AlignBuffer(size_t alignment) { | ||
| 83 | // Align the offset, not the mapped pointer | ||
| 84 | GLintptr offset_aligned = | ||
| 85 | static_cast<GLintptr>(Common::AlignUp(static_cast<size_t>(buffer_offset), alignment)); | ||
| 86 | buffer_ptr += offset_aligned - buffer_offset; | ||
| 87 | buffer_offset = offset_aligned; | ||
| 88 | } | ||
| 89 | |||
| 90 | } // namespace OpenGL | ||
diff --git a/src/video_core/renderer_opengl/gl_buffer_cache.h b/src/video_core/renderer_opengl/gl_buffer_cache.h new file mode 100644 index 000000000..9c7ad27e6 --- /dev/null +++ b/src/video_core/renderer_opengl/gl_buffer_cache.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // Copyright 2018 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <unordered_map> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "video_core/rasterizer_cache.h" | ||
| 12 | #include "video_core/renderer_opengl/gl_resource_manager.h" | ||
| 13 | #include "video_core/renderer_opengl/gl_stream_buffer.h" | ||
| 14 | |||
| 15 | namespace OpenGL { | ||
| 16 | |||
| 17 | struct CachedBufferEntry final { | ||
| 18 | VAddr GetAddr() const { | ||
| 19 | return addr; | ||
| 20 | } | ||
| 21 | |||
| 22 | size_t GetSizeInBytes() const { | ||
| 23 | return size; | ||
| 24 | } | ||
| 25 | |||
| 26 | VAddr addr; | ||
| 27 | size_t size; | ||
| 28 | GLintptr offset; | ||
| 29 | size_t alignment; | ||
| 30 | }; | ||
| 31 | |||
| 32 | class OGLBufferCache final : public RasterizerCache<std::shared_ptr<CachedBufferEntry>> { | ||
| 33 | public: | ||
| 34 | OGLBufferCache(size_t size); | ||
| 35 | |||
| 36 | GLintptr UploadMemory(Tegra::GPUVAddr gpu_addr, size_t size, size_t alignment = 4, | ||
| 37 | bool cache = true); | ||
| 38 | |||
| 39 | GLintptr UploadHostMemory(const void* raw_pointer, size_t size, size_t alignment = 4); | ||
| 40 | |||
| 41 | void Map(size_t max_size); | ||
| 42 | void Unmap(); | ||
| 43 | |||
| 44 | GLuint GetHandle(); | ||
| 45 | |||
| 46 | protected: | ||
| 47 | void AlignBuffer(size_t alignment); | ||
| 48 | |||
| 49 | private: | ||
| 50 | OGLStreamBuffer stream_buffer; | ||
| 51 | |||
| 52 | u8* buffer_ptr; | ||
| 53 | GLintptr buffer_offset; | ||
| 54 | GLintptr buffer_offset_base; | ||
| 55 | }; | ||
| 56 | |||
| 57 | } // namespace OpenGL | ||
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 7ee3f2ae7..c66a18155 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -43,7 +43,7 @@ MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(128, 128, 192)); | |||
| 43 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); | 43 | MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); |
| 44 | 44 | ||
| 45 | RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo& info) | 45 | RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo& info) |
| 46 | : emu_window{window}, screen_info{info}, stream_buffer(GL_ARRAY_BUFFER, STREAM_BUFFER_SIZE) { | 46 | : emu_window{window}, screen_info{info}, buffer_cache(STREAM_BUFFER_SIZE) { |
| 47 | // Create sampler objects | 47 | // Create sampler objects |
| 48 | for (size_t i = 0; i < texture_samplers.size(); ++i) { | 48 | for (size_t i = 0; i < texture_samplers.size(); ++i) { |
| 49 | texture_samplers[i].Create(); | 49 | texture_samplers[i].Create(); |
| @@ -83,14 +83,14 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo | |||
| 83 | 83 | ||
| 84 | hw_vao.Create(); | 84 | hw_vao.Create(); |
| 85 | 85 | ||
| 86 | state.draw.vertex_buffer = stream_buffer.GetHandle(); | 86 | state.draw.vertex_buffer = buffer_cache.GetHandle(); |
| 87 | 87 | ||
| 88 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); | 88 | shader_program_manager = std::make_unique<GLShader::ProgramManager>(); |
| 89 | state.draw.shader_program = 0; | 89 | state.draw.shader_program = 0; |
| 90 | state.draw.vertex_array = hw_vao.handle; | 90 | state.draw.vertex_array = hw_vao.handle; |
| 91 | state.Apply(); | 91 | state.Apply(); |
| 92 | 92 | ||
| 93 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, stream_buffer.GetHandle()); | 93 | glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_cache.GetHandle()); |
| 94 | 94 | ||
| 95 | glEnable(GL_BLEND); | 95 | glEnable(GL_BLEND); |
| 96 | 96 | ||
| @@ -101,14 +101,13 @@ RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& window, ScreenInfo | |||
| 101 | 101 | ||
| 102 | RasterizerOpenGL::~RasterizerOpenGL() {} | 102 | RasterizerOpenGL::~RasterizerOpenGL() {} |
| 103 | 103 | ||
| 104 | std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | 104 | void RasterizerOpenGL::SetupVertexArrays() { |
| 105 | GLintptr buffer_offset) { | ||
| 106 | MICROPROFILE_SCOPE(OpenGL_VAO); | 105 | MICROPROFILE_SCOPE(OpenGL_VAO); |
| 107 | const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); | 106 | const auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); |
| 108 | const auto& regs = gpu.regs; | 107 | const auto& regs = gpu.regs; |
| 109 | 108 | ||
| 110 | state.draw.vertex_array = hw_vao.handle; | 109 | state.draw.vertex_array = hw_vao.handle; |
| 111 | state.draw.vertex_buffer = stream_buffer.GetHandle(); | 110 | state.draw.vertex_buffer = buffer_cache.GetHandle(); |
| 112 | state.Apply(); | 111 | state.Apply(); |
| 113 | 112 | ||
| 114 | // Upload all guest vertex arrays sequentially to our buffer | 113 | // Upload all guest vertex arrays sequentially to our buffer |
| @@ -127,12 +126,10 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | |||
| 127 | ASSERT(end > start); | 126 | ASSERT(end > start); |
| 128 | u64 size = end - start + 1; | 127 | u64 size = end - start + 1; |
| 129 | 128 | ||
| 130 | GLintptr vertex_buffer_offset; | 129 | GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size); |
| 131 | std::tie(array_ptr, buffer_offset, vertex_buffer_offset) = | ||
| 132 | UploadMemory(array_ptr, buffer_offset, start, size); | ||
| 133 | 130 | ||
| 134 | // Bind the vertex array to the buffer at the current offset. | 131 | // Bind the vertex array to the buffer at the current offset. |
| 135 | glBindVertexBuffer(index, stream_buffer.GetHandle(), vertex_buffer_offset, | 132 | glBindVertexBuffer(index, buffer_cache.GetHandle(), vertex_buffer_offset, |
| 136 | vertex_array.stride); | 133 | vertex_array.stride); |
| 137 | 134 | ||
| 138 | if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { | 135 | if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { |
| @@ -177,11 +174,9 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupVertexArrays(u8* array_ptr, | |||
| 177 | } | 174 | } |
| 178 | glVertexAttribBinding(index, attrib.buffer); | 175 | glVertexAttribBinding(index, attrib.buffer); |
| 179 | } | 176 | } |
| 180 | |||
| 181 | return {array_ptr, buffer_offset}; | ||
| 182 | } | 177 | } |
| 183 | 178 | ||
| 184 | std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr buffer_offset) { | 179 | void RasterizerOpenGL::SetupShaders() { |
| 185 | MICROPROFILE_SCOPE(OpenGL_Shader); | 180 | MICROPROFILE_SCOPE(OpenGL_Shader); |
| 186 | auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); | 181 | auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); |
| 187 | 182 | ||
| @@ -199,21 +194,15 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr | |||
| 199 | continue; | 194 | continue; |
| 200 | } | 195 | } |
| 201 | 196 | ||
| 202 | std::tie(buffer_ptr, buffer_offset) = | ||
| 203 | AlignBuffer(buffer_ptr, buffer_offset, static_cast<size_t>(uniform_buffer_alignment)); | ||
| 204 | |||
| 205 | const size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 | 197 | const size_t stage{index == 0 ? 0 : index - 1}; // Stage indices are 0 - 5 |
| 206 | 198 | ||
| 207 | GLShader::MaxwellUniformData ubo{}; | 199 | GLShader::MaxwellUniformData ubo{}; |
| 208 | ubo.SetFromRegs(gpu.state.shader_stages[stage]); | 200 | ubo.SetFromRegs(gpu.state.shader_stages[stage]); |
| 209 | std::memcpy(buffer_ptr, &ubo, sizeof(ubo)); | 201 | GLintptr offset = buffer_cache.UploadHostMemory( |
| 202 | &ubo, sizeof(ubo), static_cast<size_t>(uniform_buffer_alignment)); | ||
| 210 | 203 | ||
| 211 | // Bind the buffer | 204 | // Bind the buffer |
| 212 | glBindBufferRange(GL_UNIFORM_BUFFER, stage, stream_buffer.GetHandle(), buffer_offset, | 205 | glBindBufferRange(GL_UNIFORM_BUFFER, stage, buffer_cache.GetHandle(), offset, sizeof(ubo)); |
| 213 | sizeof(ubo)); | ||
| 214 | |||
| 215 | buffer_ptr += sizeof(ubo); | ||
| 216 | buffer_offset += sizeof(ubo); | ||
| 217 | 206 | ||
| 218 | Shader shader{shader_cache.GetStageProgram(program)}; | 207 | Shader shader{shader_cache.GetStageProgram(program)}; |
| 219 | 208 | ||
| @@ -234,9 +223,8 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr | |||
| 234 | } | 223 | } |
| 235 | 224 | ||
| 236 | // Configure the const buffers for this shader stage. | 225 | // Configure the const buffers for this shader stage. |
| 237 | std::tie(buffer_ptr, buffer_offset, current_constbuffer_bindpoint) = | 226 | current_constbuffer_bindpoint = SetupConstBuffers(static_cast<Maxwell::ShaderStage>(stage), |
| 238 | SetupConstBuffers(buffer_ptr, buffer_offset, static_cast<Maxwell::ShaderStage>(stage), | 227 | shader, current_constbuffer_bindpoint); |
| 239 | shader, current_constbuffer_bindpoint); | ||
| 240 | 228 | ||
| 241 | // Configure the textures for this shader stage. | 229 | // Configure the textures for this shader stage. |
| 242 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, | 230 | current_texture_bindpoint = SetupTextures(static_cast<Maxwell::ShaderStage>(stage), shader, |
| @@ -250,8 +238,6 @@ std::pair<u8*, GLintptr> RasterizerOpenGL::SetupShaders(u8* buffer_ptr, GLintptr | |||
| 250 | } | 238 | } |
| 251 | 239 | ||
| 252 | shader_program_manager->UseTrivialGeometryShader(); | 240 | shader_program_manager->UseTrivialGeometryShader(); |
| 253 | |||
| 254 | return {buffer_ptr, buffer_offset}; | ||
| 255 | } | 241 | } |
| 256 | 242 | ||
| 257 | size_t RasterizerOpenGL::CalculateVertexArraysSize() const { | 243 | size_t RasterizerOpenGL::CalculateVertexArraysSize() const { |
| @@ -439,31 +425,6 @@ void RasterizerOpenGL::Clear() { | |||
| 439 | glClear(clear_mask); | 425 | glClear(clear_mask); |
| 440 | } | 426 | } |
| 441 | 427 | ||
| 442 | std::pair<u8*, GLintptr> RasterizerOpenGL::AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, | ||
| 443 | size_t alignment) { | ||
| 444 | // Align the offset, not the mapped pointer | ||
| 445 | GLintptr offset_aligned = | ||
| 446 | static_cast<GLintptr>(Common::AlignUp(static_cast<size_t>(buffer_offset), alignment)); | ||
| 447 | return {buffer_ptr + (offset_aligned - buffer_offset), offset_aligned}; | ||
| 448 | } | ||
| 449 | |||
| 450 | std::tuple<u8*, GLintptr, GLintptr> RasterizerOpenGL::UploadMemory(u8* buffer_ptr, | ||
| 451 | GLintptr buffer_offset, | ||
| 452 | Tegra::GPUVAddr gpu_addr, | ||
| 453 | size_t size, size_t alignment) { | ||
| 454 | std::tie(buffer_ptr, buffer_offset) = AlignBuffer(buffer_ptr, buffer_offset, alignment); | ||
| 455 | GLintptr uploaded_offset = buffer_offset; | ||
| 456 | |||
| 457 | auto& memory_manager = Core::System::GetInstance().GPU().MemoryManager(); | ||
| 458 | const boost::optional<VAddr> cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr)}; | ||
| 459 | Memory::ReadBlock(*cpu_addr, buffer_ptr, size); | ||
| 460 | |||
| 461 | buffer_ptr += size; | ||
| 462 | buffer_offset += size; | ||
| 463 | |||
| 464 | return {buffer_ptr, buffer_offset, uploaded_offset}; | ||
| 465 | } | ||
| 466 | |||
| 467 | void RasterizerOpenGL::DrawArrays() { | 428 | void RasterizerOpenGL::DrawArrays() { |
| 468 | if (accelerate_draw == AccelDraw::Disabled) | 429 | if (accelerate_draw == AccelDraw::Disabled) |
| 469 | return; | 430 | return; |
| @@ -489,7 +450,7 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 489 | const bool is_indexed = accelerate_draw == AccelDraw::Indexed; | 450 | const bool is_indexed = accelerate_draw == AccelDraw::Indexed; |
| 490 | const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; | 451 | const u64 index_buffer_size{regs.index_array.count * regs.index_array.FormatSizeInBytes()}; |
| 491 | 452 | ||
| 492 | state.draw.vertex_buffer = stream_buffer.GetHandle(); | 453 | state.draw.vertex_buffer = buffer_cache.GetHandle(); |
| 493 | state.Apply(); | 454 | state.Apply(); |
| 494 | 455 | ||
| 495 | size_t buffer_size = CalculateVertexArraysSize(); | 456 | size_t buffer_size = CalculateVertexArraysSize(); |
| @@ -506,25 +467,21 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 506 | // Add space for at least 18 constant buffers | 467 | // Add space for at least 18 constant buffers |
| 507 | buffer_size += Maxwell::MaxConstBuffers * (MaxConstbufferSize + uniform_buffer_alignment); | 468 | buffer_size += Maxwell::MaxConstBuffers * (MaxConstbufferSize + uniform_buffer_alignment); |
| 508 | 469 | ||
| 509 | u8* buffer_ptr; | 470 | buffer_cache.Map(buffer_size); |
| 510 | GLintptr buffer_offset; | ||
| 511 | std::tie(buffer_ptr, buffer_offset, std::ignore) = | ||
| 512 | stream_buffer.Map(static_cast<GLsizeiptr>(buffer_size), 4); | ||
| 513 | u8* buffer_ptr_base = buffer_ptr; | ||
| 514 | 471 | ||
| 515 | std::tie(buffer_ptr, buffer_offset) = SetupVertexArrays(buffer_ptr, buffer_offset); | 472 | SetupVertexArrays(); |
| 516 | 473 | ||
| 517 | // If indexed mode, copy the index buffer | 474 | // If indexed mode, copy the index buffer |
| 518 | GLintptr index_buffer_offset = 0; | 475 | GLintptr index_buffer_offset = 0; |
| 519 | if (is_indexed) { | 476 | if (is_indexed) { |
| 520 | MICROPROFILE_SCOPE(OpenGL_Index); | 477 | MICROPROFILE_SCOPE(OpenGL_Index); |
| 521 | std::tie(buffer_ptr, buffer_offset, index_buffer_offset) = UploadMemory( | 478 | index_buffer_offset = |
| 522 | buffer_ptr, buffer_offset, regs.index_array.StartAddress(), index_buffer_size); | 479 | buffer_cache.UploadMemory(regs.index_array.StartAddress(), index_buffer_size); |
| 523 | } | 480 | } |
| 524 | 481 | ||
| 525 | std::tie(buffer_ptr, buffer_offset) = SetupShaders(buffer_ptr, buffer_offset); | 482 | SetupShaders(); |
| 526 | 483 | ||
| 527 | stream_buffer.Unmap(buffer_ptr - buffer_ptr_base); | 484 | buffer_cache.Unmap(); |
| 528 | 485 | ||
| 529 | shader_program_manager->ApplyTo(state); | 486 | shader_program_manager->ApplyTo(state); |
| 530 | state.Apply(); | 487 | state.Apply(); |
| @@ -569,6 +526,7 @@ void RasterizerOpenGL::InvalidateRegion(VAddr addr, u64 size) { | |||
| 569 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); | 526 | MICROPROFILE_SCOPE(OpenGL_CacheManagement); |
| 570 | res_cache.InvalidateRegion(addr, size); | 527 | res_cache.InvalidateRegion(addr, size); |
| 571 | shader_cache.InvalidateRegion(addr, size); | 528 | shader_cache.InvalidateRegion(addr, size); |
| 529 | buffer_cache.InvalidateRegion(addr, size); | ||
| 572 | } | 530 | } |
| 573 | 531 | ||
| 574 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { | 532 | void RasterizerOpenGL::FlushAndInvalidateRegion(VAddr addr, u64 size) { |
| @@ -658,11 +616,8 @@ void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Tegra::Texture::TSCEntr | |||
| 658 | } | 616 | } |
| 659 | } | 617 | } |
| 660 | 618 | ||
| 661 | std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_ptr, | 619 | u32 RasterizerOpenGL::SetupConstBuffers(Maxwell::ShaderStage stage, Shader& shader, |
| 662 | GLintptr buffer_offset, | 620 | u32 current_bindpoint) { |
| 663 | Maxwell::ShaderStage stage, | ||
| 664 | Shader& shader, | ||
| 665 | u32 current_bindpoint) { | ||
| 666 | MICROPROFILE_SCOPE(OpenGL_UBO); | 621 | MICROPROFILE_SCOPE(OpenGL_UBO); |
| 667 | const auto& gpu = Core::System::GetInstance().GPU(); | 622 | const auto& gpu = Core::System::GetInstance().GPU(); |
| 668 | const auto& maxwell3d = gpu.Maxwell3D(); | 623 | const auto& maxwell3d = gpu.Maxwell3D(); |
| @@ -699,13 +654,11 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_pt | |||
| 699 | size = Common::AlignUp(size, sizeof(GLvec4)); | 654 | size = Common::AlignUp(size, sizeof(GLvec4)); |
| 700 | ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big"); | 655 | ASSERT_MSG(size <= MaxConstbufferSize, "Constbuffer too big"); |
| 701 | 656 | ||
| 702 | GLintptr const_buffer_offset; | 657 | GLintptr const_buffer_offset = buffer_cache.UploadMemory( |
| 703 | std::tie(buffer_ptr, buffer_offset, const_buffer_offset) = | 658 | buffer.address, size, static_cast<size_t>(uniform_buffer_alignment)); |
| 704 | UploadMemory(buffer_ptr, buffer_offset, buffer.address, size, | ||
| 705 | static_cast<size_t>(uniform_buffer_alignment)); | ||
| 706 | 659 | ||
| 707 | glBindBufferRange(GL_UNIFORM_BUFFER, current_bindpoint + bindpoint, | 660 | glBindBufferRange(GL_UNIFORM_BUFFER, current_bindpoint + bindpoint, |
| 708 | stream_buffer.GetHandle(), const_buffer_offset, size); | 661 | buffer_cache.GetHandle(), const_buffer_offset, size); |
| 709 | 662 | ||
| 710 | // Now configure the bindpoint of the buffer inside the shader | 663 | // Now configure the bindpoint of the buffer inside the shader |
| 711 | glUniformBlockBinding(shader->GetProgramHandle(), | 664 | glUniformBlockBinding(shader->GetProgramHandle(), |
| @@ -715,7 +668,7 @@ std::tuple<u8*, GLintptr, u32> RasterizerOpenGL::SetupConstBuffers(u8* buffer_pt | |||
| 715 | 668 | ||
| 716 | state.Apply(); | 669 | state.Apply(); |
| 717 | 670 | ||
| 718 | return {buffer_ptr, buffer_offset, current_bindpoint + static_cast<u32>(entries.size())}; | 671 | return current_bindpoint + static_cast<u32>(entries.size()); |
| 719 | } | 672 | } |
| 720 | 673 | ||
| 721 | u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, u32 current_unit) { | 674 | u32 RasterizerOpenGL::SetupTextures(Maxwell::ShaderStage stage, Shader& shader, u32 current_unit) { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 30045ebff..4c4b084b8 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h | |||
| @@ -18,7 +18,9 @@ | |||
| 18 | #include "common/common_types.h" | 18 | #include "common/common_types.h" |
| 19 | #include "video_core/engines/maxwell_3d.h" | 19 | #include "video_core/engines/maxwell_3d.h" |
| 20 | #include "video_core/memory_manager.h" | 20 | #include "video_core/memory_manager.h" |
| 21 | #include "video_core/rasterizer_cache.h" | ||
| 21 | #include "video_core/rasterizer_interface.h" | 22 | #include "video_core/rasterizer_interface.h" |
| 23 | #include "video_core/renderer_opengl/gl_buffer_cache.h" | ||
| 22 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" | 24 | #include "video_core/renderer_opengl/gl_rasterizer_cache.h" |
| 23 | #include "video_core/renderer_opengl/gl_resource_manager.h" | 25 | #include "video_core/renderer_opengl/gl_resource_manager.h" |
| 24 | #include "video_core/renderer_opengl/gl_shader_cache.h" | 26 | #include "video_core/renderer_opengl/gl_shader_cache.h" |
| @@ -109,9 +111,8 @@ private: | |||
| 109 | * @param current_bindpoint The offset at which to start counting new buffer bindpoints. | 111 | * @param current_bindpoint The offset at which to start counting new buffer bindpoints. |
| 110 | * @returns The next available bindpoint for use in the next shader stage. | 112 | * @returns The next available bindpoint for use in the next shader stage. |
| 111 | */ | 113 | */ |
| 112 | std::tuple<u8*, GLintptr, u32> SetupConstBuffers( | 114 | u32 SetupConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, Shader& shader, |
| 113 | u8* buffer_ptr, GLintptr buffer_offset, Tegra::Engines::Maxwell3D::Regs::ShaderStage stage, | 115 | u32 current_bindpoint); |
| 114 | Shader& shader, u32 current_bindpoint); | ||
| 115 | 116 | ||
| 116 | /* | 117 | /* |
| 117 | * Configures the current textures to use for the draw command. | 118 | * Configures the current textures to use for the draw command. |
| @@ -173,22 +174,16 @@ private: | |||
| 173 | std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers; | 174 | std::array<SamplerInfo, GLShader::NumTextureSamplers> texture_samplers; |
| 174 | 175 | ||
| 175 | static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; | 176 | static constexpr size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024; |
| 176 | OGLStreamBuffer stream_buffer; | 177 | OGLBufferCache buffer_cache; |
| 177 | OGLBuffer uniform_buffer; | 178 | OGLBuffer uniform_buffer; |
| 178 | OGLFramebuffer framebuffer; | 179 | OGLFramebuffer framebuffer; |
| 179 | GLint uniform_buffer_alignment; | 180 | GLint uniform_buffer_alignment; |
| 180 | 181 | ||
| 181 | size_t CalculateVertexArraysSize() const; | 182 | size_t CalculateVertexArraysSize() const; |
| 182 | 183 | ||
| 183 | std::pair<u8*, GLintptr> SetupVertexArrays(u8* array_ptr, GLintptr buffer_offset); | 184 | void SetupVertexArrays(); |
| 184 | 185 | ||
| 185 | std::pair<u8*, GLintptr> SetupShaders(u8* buffer_ptr, GLintptr buffer_offset); | 186 | void SetupShaders(); |
| 186 | |||
| 187 | std::pair<u8*, GLintptr> AlignBuffer(u8* buffer_ptr, GLintptr buffer_offset, size_t alignment); | ||
| 188 | |||
| 189 | std::tuple<u8*, GLintptr, GLintptr> UploadMemory(u8* buffer_ptr, GLintptr buffer_offset, | ||
| 190 | Tegra::GPUVAddr gpu_addr, size_t size, | ||
| 191 | size_t alignment = 4); | ||
| 192 | 187 | ||
| 193 | enum class AccelDraw { Disabled, Arrays, Indexed }; | 188 | enum class AccelDraw { Disabled, Arrays, Indexed }; |
| 194 | AccelDraw accelerate_draw = AccelDraw::Disabled; | 189 | AccelDraw accelerate_draw = AccelDraw::Disabled; |