diff options
| author | 2019-12-29 01:28:53 -0300 | |
|---|---|---|
| committer | 2020-02-28 17:56:42 -0300 | |
| commit | 758ad3f75d49be811237c297265038f80c16ee8c (patch) | |
| tree | 71f3fd600b58f241f8caa9e09caf6ed9a630c693 /src | |
| parent | maxwell_3d: Change write dirty flags to a bitset (diff) | |
| download | yuzu-758ad3f75d49be811237c297265038f80c16ee8c.tar.gz yuzu-758ad3f75d49be811237c297265038f80c16ee8c.tar.xz yuzu-758ad3f75d49be811237c297265038f80c16ee8c.zip | |
gl_state_tracker: Add dirty flags for buffers and divisors
Diffstat (limited to 'src')
4 files changed, 56 insertions, 22 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 211b11489..bb89985cc 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -164,12 +164,22 @@ void RasterizerOpenGL::SetupVertexFormat() { | |||
| 164 | 164 | ||
| 165 | void RasterizerOpenGL::SetupVertexBuffer() { | 165 | void RasterizerOpenGL::SetupVertexBuffer() { |
| 166 | auto& gpu = system.GPU().Maxwell3D(); | 166 | auto& gpu = system.GPU().Maxwell3D(); |
| 167 | const auto& regs = gpu.regs; | 167 | auto& flags = gpu.dirty.flags; |
| 168 | if (!flags[Dirty::VertexBuffers]) { | ||
| 169 | return; | ||
| 170 | } | ||
| 171 | flags[Dirty::VertexBuffers] = false; | ||
| 168 | 172 | ||
| 169 | MICROPROFILE_SCOPE(OpenGL_VB); | 173 | MICROPROFILE_SCOPE(OpenGL_VB); |
| 170 | 174 | ||
| 171 | // Upload all guest vertex arrays sequentially to our buffer | 175 | // Upload all guest vertex arrays sequentially to our buffer |
| 172 | for (u32 index = 0; index < Maxwell::NumVertexArrays; ++index) { | 176 | const auto& regs = gpu.regs; |
| 177 | for (std::size_t index = 0; index < Maxwell::NumVertexArrays; ++index) { | ||
| 178 | if (!flags[Dirty::VertexBuffer0 + index]) { | ||
| 179 | continue; | ||
| 180 | } | ||
| 181 | flags[Dirty::VertexBuffer0 + index] = false; | ||
| 182 | |||
| 173 | const auto& vertex_array = regs.vertex_array[index]; | 183 | const auto& vertex_array = regs.vertex_array[index]; |
| 174 | if (!vertex_array.IsEnabled()) { | 184 | if (!vertex_array.IsEnabled()) { |
| 175 | continue; | 185 | continue; |
| @@ -183,33 +193,30 @@ void RasterizerOpenGL::SetupVertexBuffer() { | |||
| 183 | const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); | 193 | const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); |
| 184 | 194 | ||
| 185 | // Bind the vertex array to the buffer at the current offset. | 195 | // Bind the vertex array to the buffer at the current offset. |
| 186 | vertex_array_pushbuffer.SetVertexBuffer(index, vertex_buffer, vertex_buffer_offset, | 196 | vertex_array_pushbuffer.SetVertexBuffer(static_cast<GLuint>(index), vertex_buffer, |
| 187 | vertex_array.stride); | 197 | vertex_buffer_offset, vertex_array.stride); |
| 188 | |||
| 189 | if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { | ||
| 190 | // Enable vertex buffer instancing with the specified divisor. | ||
| 191 | glVertexBindingDivisor(index, vertex_array.divisor); | ||
| 192 | } else { | ||
| 193 | // Disable the vertex buffer instancing. | ||
| 194 | glVertexBindingDivisor(index, 0); | ||
| 195 | } | ||
| 196 | } | 198 | } |
| 197 | } | 199 | } |
| 198 | 200 | ||
| 199 | void RasterizerOpenGL::SetupVertexInstances() { | 201 | void RasterizerOpenGL::SetupVertexInstances() { |
| 200 | auto& gpu = system.GPU().Maxwell3D(); | 202 | auto& gpu = system.GPU().Maxwell3D(); |
| 201 | const auto& regs = gpu.regs; | 203 | auto& flags = gpu.dirty.flags; |
| 204 | if (!flags[Dirty::VertexInstances]) { | ||
| 205 | return; | ||
| 206 | } | ||
| 207 | flags[Dirty::VertexInstances] = false; | ||
| 202 | 208 | ||
| 203 | // Upload all guest vertex arrays sequentially to our buffer | 209 | const auto& regs = gpu.regs; |
| 204 | for (u32 index = 0; index < 16; ++index) { | 210 | for (std::size_t index = 0; index < 16; ++index) { |
| 205 | if (regs.instanced_arrays.IsInstancingEnabled(index) && | 211 | if (!flags[Dirty::VertexInstance0 + index]) { |
| 206 | regs.vertex_array[index].divisor != 0) { | 212 | continue; |
| 207 | // Enable vertex buffer instancing with the specified divisor. | ||
| 208 | glVertexBindingDivisor(index, regs.vertex_array[index].divisor); | ||
| 209 | } else { | ||
| 210 | // Disable the vertex buffer instancing. | ||
| 211 | glVertexBindingDivisor(index, 0); | ||
| 212 | } | 213 | } |
| 214 | flags[Dirty::VertexInstance0 + index] = false; | ||
| 215 | |||
| 216 | const auto gl_index = static_cast<GLuint>(index); | ||
| 217 | const bool instancing_enabled = regs.instanced_arrays.IsInstancingEnabled(gl_index); | ||
| 218 | const GLuint divisor = instancing_enabled ? regs.vertex_array[index].divisor : 0; | ||
| 219 | glVertexBindingDivisor(gl_index, divisor); | ||
| 213 | } | 220 | } |
| 214 | } | 221 | } |
| 215 | 222 | ||
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.cpp b/src/video_core/renderer_opengl/gl_state_tracker.cpp index 319fd825b..7150b9247 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.cpp +++ b/src/video_core/renderer_opengl/gl_state_tracker.cpp | |||
| @@ -71,6 +71,26 @@ void SetupDirtyColorMasks(Tables& tables) { | |||
| 71 | FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks); | 71 | FillBlock(tables[1], OFF(color_mask), NUM(color_mask), ColorMasks); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | void SetupDirtyVertexArrays(Tables& tables) { | ||
| 75 | static constexpr std::size_t num_array = 3; | ||
| 76 | static constexpr std::size_t instance_base_offset = 3; | ||
| 77 | for (std::size_t i = 0; i < Regs::NumVertexArrays; ++i) { | ||
| 78 | const std::size_t array_offset = OFF(vertex_array) + i * NUM(vertex_array[0]); | ||
| 79 | const std::size_t limit_offset = OFF(vertex_array_limit) + i * NUM(vertex_array_limit[0]); | ||
| 80 | |||
| 81 | FillBlock(tables, array_offset, num_array, VertexBuffer0 + i, VertexBuffers); | ||
| 82 | FillBlock(tables, limit_offset, NUM(vertex_array_limit), VertexBuffer0 + i, VertexBuffers); | ||
| 83 | |||
| 84 | const std::size_t instance_array_offset = array_offset + instance_base_offset; | ||
| 85 | tables[0][instance_array_offset] = static_cast<u8>(VertexInstance0 + i); | ||
| 86 | tables[1][instance_array_offset] = VertexInstances; | ||
| 87 | |||
| 88 | const std::size_t instance_offset = OFF(instanced_arrays) + i; | ||
| 89 | tables[0][instance_offset] = static_cast<u8>(VertexInstance0 + i); | ||
| 90 | tables[1][instance_offset] = VertexInstances; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | |||
| 74 | void SetupDirtyVertexFormat(Tables& tables) { | 94 | void SetupDirtyVertexFormat(Tables& tables) { |
| 75 | for (std::size_t i = 0; i < Regs::NumVertexAttributes; ++i) { | 95 | for (std::size_t i = 0; i < Regs::NumVertexAttributes; ++i) { |
| 76 | const std::size_t offset = OFF(vertex_attrib_format) + i * NUM(vertex_attrib_format[0]); | 96 | const std::size_t offset = OFF(vertex_attrib_format) + i * NUM(vertex_attrib_format[0]); |
| @@ -115,6 +135,7 @@ void StateTracker::Initialize() { | |||
| 115 | SetupDirtyColorMasks(tables); | 135 | SetupDirtyColorMasks(tables); |
| 116 | SetupDirtyViewports(tables); | 136 | SetupDirtyViewports(tables); |
| 117 | SetupDirtyScissors(tables); | 137 | SetupDirtyScissors(tables); |
| 138 | SetupDirtyVertexArrays(tables); | ||
| 118 | SetupDirtyVertexFormat(tables); | 139 | SetupDirtyVertexFormat(tables); |
| 119 | 140 | ||
| 120 | auto& store = dirty.on_write_stores; | 141 | auto& store = dirty.on_write_stores; |
diff --git a/src/video_core/renderer_opengl/gl_state_tracker.h b/src/video_core/renderer_opengl/gl_state_tracker.h index a368aefd7..85667cee1 100644 --- a/src/video_core/renderer_opengl/gl_state_tracker.h +++ b/src/video_core/renderer_opengl/gl_state_tracker.h | |||
| @@ -78,6 +78,10 @@ public: | |||
| 78 | 78 | ||
| 79 | flags[OpenGL::Dirty::VertexBuffers] = true; | 79 | flags[OpenGL::Dirty::VertexBuffers] = true; |
| 80 | flags[OpenGL::Dirty::VertexBuffer0] = true; | 80 | flags[OpenGL::Dirty::VertexBuffer0] = true; |
| 81 | |||
| 82 | flags[OpenGL::Dirty::VertexInstances] = true; | ||
| 83 | flags[OpenGL::Dirty::VertexInstance0 + 0] = true; | ||
| 84 | flags[OpenGL::Dirty::VertexInstance0 + 1] = true; | ||
| 81 | } | 85 | } |
| 82 | 86 | ||
| 83 | void NotifyViewport0() { | 87 | void NotifyViewport0() { |
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index caa193c50..cbe916488 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -611,6 +611,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | |||
| 611 | 611 | ||
| 612 | glEnableVertexAttribArray(PositionLocation); | 612 | glEnableVertexAttribArray(PositionLocation); |
| 613 | glEnableVertexAttribArray(TexCoordLocation); | 613 | glEnableVertexAttribArray(TexCoordLocation); |
| 614 | glVertexAttribDivisor(PositionLocation, 0); | ||
| 615 | glVertexAttribDivisor(TexCoordLocation, 0); | ||
| 614 | glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE, | 616 | glVertexAttribFormat(PositionLocation, 2, GL_FLOAT, GL_FALSE, |
| 615 | offsetof(ScreenRectVertex, position)); | 617 | offsetof(ScreenRectVertex, position)); |
| 616 | glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE, | 618 | glVertexAttribFormat(TexCoordLocation, 2, GL_FLOAT, GL_FALSE, |