summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-12-29 01:28:53 -0300
committerGravatar ReinUsesLisp2020-02-28 17:56:42 -0300
commit758ad3f75d49be811237c297265038f80c16ee8c (patch)
tree71f3fd600b58f241f8caa9e09caf6ed9a630c693 /src
parentmaxwell_3d: Change write dirty flags to a bitset (diff)
downloadyuzu-758ad3f75d49be811237c297265038f80c16ee8c.tar.gz
yuzu-758ad3f75d49be811237c297265038f80c16ee8c.tar.xz
yuzu-758ad3f75d49be811237c297265038f80c16ee8c.zip
gl_state_tracker: Add dirty flags for buffers and divisors
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp51
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_state_tracker.h4
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp2
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
165void RasterizerOpenGL::SetupVertexBuffer() { 165void 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
199void RasterizerOpenGL::SetupVertexInstances() { 201void 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
74void 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
74void SetupDirtyVertexFormat(Tables& tables) { 94void 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,