summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-01-06 01:53:27 -0300
committerGravatar ReinUsesLisp2019-01-06 16:49:24 -0300
commit35c095898bf51098d9b2a71447850f3e1b0fc350 (patch)
tree38775f691f339e341330211185bd9dc0cf766442 /src
parentgl_state: Drop uniform buffer state tracking (diff)
downloadyuzu-35c095898bf51098d9b2a71447850f3e1b0fc350.tar.gz
yuzu-35c095898bf51098d9b2a71447850f3e1b0fc350.tar.xz
yuzu-35c095898bf51098d9b2a71447850f3e1b0fc350.zip
gl_rasterizer: Use DSA for vertex array objects
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp62
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h6
-rw-r--r--src/video_core/renderer_opengl/gl_resource_manager.cpp5
-rw-r--r--src/video_core/renderer_opengl/gl_state.cpp26
-rw-r--r--src/video_core/renderer_opengl/gl_state.h4
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp29
6 files changed, 53 insertions, 79 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 089daf96f..7ce8c2bcc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -135,27 +135,25 @@ void RasterizerOpenGL::CheckExtensions() {
135 } 135 }
136} 136}
137 137
138void RasterizerOpenGL::SetupVertexFormat() { 138GLuint RasterizerOpenGL::SetupVertexFormat() {
139 auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); 139 auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
140 const auto& regs = gpu.regs; 140 const auto& regs = gpu.regs;
141 141
142 if (!gpu.dirty_flags.vertex_attrib_format) 142 if (!gpu.dirty_flags.vertex_attrib_format) {
143 return; 143 return state.draw.vertex_array;
144 }
144 gpu.dirty_flags.vertex_attrib_format = false; 145 gpu.dirty_flags.vertex_attrib_format = false;
145 146
146 MICROPROFILE_SCOPE(OpenGL_VAO); 147 MICROPROFILE_SCOPE(OpenGL_VAO);
147 148
148 auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format); 149 auto [iter, is_cache_miss] = vertex_array_cache.try_emplace(regs.vertex_attrib_format);
149 auto& VAO = iter->second; 150 auto& vao_entry = iter->second;
150 151
151 if (is_cache_miss) { 152 if (is_cache_miss) {
152 VAO.Create(); 153 vao_entry.Create();
153 state.draw.vertex_array = VAO.handle; 154 const GLuint vao = vao_entry.handle;
154 state.ApplyVertexBufferState();
155 155
156 // The index buffer binding is stored within the VAO. Stupid OpenGL, but easy to work 156 glVertexArrayElementBuffer(vao, buffer_cache.GetHandle());
157 // around.
158 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_cache.GetHandle());
159 157
160 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL. 158 // Use the vertex array as-is, assumes that the data is formatted correctly for OpenGL.
161 // Enables the first 16 vertex attributes always, as we don't know which ones are actually 159 // Enables the first 16 vertex attributes always, as we don't know which ones are actually
@@ -163,7 +161,7 @@ void RasterizerOpenGL::SetupVertexFormat() {
163 // for now to avoid OpenGL errors. 161 // for now to avoid OpenGL errors.
164 // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't 162 // TODO(Subv): Analyze the shader to identify which attributes are actually used and don't
165 // assume every shader uses them all. 163 // assume every shader uses them all.
166 for (unsigned index = 0; index < 16; ++index) { 164 for (u32 index = 0; index < 16; ++index) {
167 const auto& attrib = regs.vertex_attrib_format[index]; 165 const auto& attrib = regs.vertex_attrib_format[index];
168 166
169 // Ignore invalid attributes. 167 // Ignore invalid attributes.
@@ -178,28 +176,29 @@ void RasterizerOpenGL::SetupVertexFormat() {
178 176
179 ASSERT(buffer.IsEnabled()); 177 ASSERT(buffer.IsEnabled());
180 178
181 glEnableVertexAttribArray(index); 179 glEnableVertexArrayAttrib(vao, index);
182 if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt || 180 if (attrib.type == Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::SignedInt ||
183 attrib.type == 181 attrib.type ==
184 Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) { 182 Tegra::Engines::Maxwell3D::Regs::VertexAttribute::Type::UnsignedInt) {
185 glVertexAttribIFormat(index, attrib.ComponentCount(), 183 glVertexArrayAttribIFormat(vao, index, attrib.ComponentCount(),
186 MaxwellToGL::VertexType(attrib), attrib.offset); 184 MaxwellToGL::VertexType(attrib), attrib.offset);
187 } else { 185 } else {
188 glVertexAttribFormat(index, attrib.ComponentCount(), 186 glVertexArrayAttribFormat(
189 MaxwellToGL::VertexType(attrib), 187 vao, index, attrib.ComponentCount(), MaxwellToGL::VertexType(attrib),
190 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset); 188 attrib.IsNormalized() ? GL_TRUE : GL_FALSE, attrib.offset);
191 } 189 }
192 glVertexAttribBinding(index, attrib.buffer); 190 glVertexArrayAttribBinding(vao, index, attrib.buffer);
193 } 191 }
194 } 192 }
195 state.draw.vertex_array = VAO.handle;
196 state.ApplyVertexBufferState();
197 193
198 // Rebinding the VAO invalidates the vertex buffer bindings. 194 // Rebinding the VAO invalidates the vertex buffer bindings.
199 gpu.dirty_flags.vertex_array = 0xFFFFFFFF; 195 gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
196
197 state.draw.vertex_array = vao_entry.handle;
198 return vao_entry.handle;
200} 199}
201 200
202void RasterizerOpenGL::SetupVertexBuffer() { 201void RasterizerOpenGL::SetupVertexBuffer(GLuint vao) {
203 auto& gpu = Core::System::GetInstance().GPU().Maxwell3D(); 202 auto& gpu = Core::System::GetInstance().GPU().Maxwell3D();
204 const auto& regs = gpu.regs; 203 const auto& regs = gpu.regs;
205 204
@@ -217,7 +216,7 @@ void RasterizerOpenGL::SetupVertexBuffer() {
217 if (!vertex_array.IsEnabled()) 216 if (!vertex_array.IsEnabled())
218 continue; 217 continue;
219 218
220 Tegra::GPUVAddr start = vertex_array.StartAddress(); 219 const Tegra::GPUVAddr start = vertex_array.StartAddress();
221 const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); 220 const Tegra::GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
222 221
223 ASSERT(end > start); 222 ASSERT(end > start);
@@ -225,21 +224,18 @@ void RasterizerOpenGL::SetupVertexBuffer() {
225 const GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size); 224 const GLintptr vertex_buffer_offset = buffer_cache.UploadMemory(start, size);
226 225
227 // Bind the vertex array to the buffer at the current offset. 226 // Bind the vertex array to the buffer at the current offset.
228 glBindVertexBuffer(index, buffer_cache.GetHandle(), vertex_buffer_offset, 227 glVertexArrayVertexBuffer(vao, index, buffer_cache.GetHandle(), vertex_buffer_offset,
229 vertex_array.stride); 228 vertex_array.stride);
230 229
231 if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) { 230 if (regs.instanced_arrays.IsInstancingEnabled(index) && vertex_array.divisor != 0) {
232 // Enable vertex buffer instancing with the specified divisor. 231 // Enable vertex buffer instancing with the specified divisor.
233 glVertexBindingDivisor(index, vertex_array.divisor); 232 glVertexArrayBindingDivisor(vao, index, vertex_array.divisor);
234 } else { 233 } else {
235 // Disable the vertex buffer instancing. 234 // Disable the vertex buffer instancing.
236 glVertexBindingDivisor(index, 0); 235 glVertexArrayBindingDivisor(vao, index, 0);
237 } 236 }
238 } 237 }
239 238
240 // Implicit set by glBindVertexBuffer. Stupid glstate handling...
241 state.draw.vertex_buffer = buffer_cache.GetHandle();
242
243 gpu.dirty_flags.vertex_array = 0; 239 gpu.dirty_flags.vertex_array = 0;
244} 240}
245 241
@@ -689,9 +685,6 @@ void RasterizerOpenGL::DrawArrays() {
689 // Draw the vertex batch 685 // Draw the vertex batch
690 const bool is_indexed = accelerate_draw == AccelDraw::Indexed; 686 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
691 687
692 state.draw.vertex_buffer = buffer_cache.GetHandle();
693 state.ApplyVertexBufferState();
694
695 std::size_t buffer_size = CalculateVertexArraysSize(); 688 std::size_t buffer_size = CalculateVertexArraysSize();
696 689
697 // Add space for index buffer (keeping in mind non-core primitives) 690 // Add space for index buffer (keeping in mind non-core primitives)
@@ -721,8 +714,9 @@ void RasterizerOpenGL::DrawArrays() {
721 gpu.dirty_flags.vertex_array = 0xFFFFFFFF; 714 gpu.dirty_flags.vertex_array = 0xFFFFFFFF;
722 } 715 }
723 716
724 SetupVertexFormat(); 717 const GLuint vao = SetupVertexFormat();
725 SetupVertexBuffer(); 718 SetupVertexBuffer(vao);
719
726 DrawParameters params = SetupDraw(); 720 DrawParameters params = SetupDraw();
727 SetupShaders(params.primitive_mode); 721 SetupShaders(params.primitive_mode);
728 722
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 8a891ffc7..bac5de91e 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -209,8 +209,10 @@ private:
209 209
210 std::size_t CalculateIndexBufferSize() const; 210 std::size_t CalculateIndexBufferSize() const;
211 211
212 void SetupVertexFormat(); 212 /// Updates and returns a vertex array object representing current vertex format
213 void SetupVertexBuffer(); 213 GLuint SetupVertexFormat();
214
215 void SetupVertexBuffer(GLuint vao);
214 216
215 DrawParameters SetupDraw(); 217 DrawParameters SetupDraw();
216 218
diff --git a/src/video_core/renderer_opengl/gl_resource_manager.cpp b/src/video_core/renderer_opengl/gl_resource_manager.cpp
index c17d5ac00..1da744158 100644
--- a/src/video_core/renderer_opengl/gl_resource_manager.cpp
+++ b/src/video_core/renderer_opengl/gl_resource_manager.cpp
@@ -117,7 +117,7 @@ void OGLBuffer::Create() {
117 return; 117 return;
118 118
119 MICROPROFILE_SCOPE(OpenGL_ResourceCreation); 119 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
120 glGenBuffers(1, &handle); 120 glCreateBuffers(1, &handle);
121} 121}
122 122
123void OGLBuffer::Release() { 123void OGLBuffer::Release() {
@@ -126,7 +126,6 @@ void OGLBuffer::Release() {
126 126
127 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion); 127 MICROPROFILE_SCOPE(OpenGL_ResourceDeletion);
128 glDeleteBuffers(1, &handle); 128 glDeleteBuffers(1, &handle);
129 OpenGLState::GetCurState().ResetBuffer(handle).Apply();
130 handle = 0; 129 handle = 0;
131} 130}
132 131
@@ -152,7 +151,7 @@ void OGLVertexArray::Create() {
152 return; 151 return;
153 152
154 MICROPROFILE_SCOPE(OpenGL_ResourceCreation); 153 MICROPROFILE_SCOPE(OpenGL_ResourceCreation);
155 glGenVertexArrays(1, &handle); 154 glCreateVertexArrays(1, &handle);
156} 155}
157 156
158void OGLVertexArray::Release() { 157void OGLVertexArray::Release() {
diff --git a/src/video_core/renderer_opengl/gl_state.cpp b/src/video_core/renderer_opengl/gl_state.cpp
index e54aff995..79bb52ddf 100644
--- a/src/video_core/renderer_opengl/gl_state.cpp
+++ b/src/video_core/renderer_opengl/gl_state.cpp
@@ -83,7 +83,6 @@ OpenGLState::OpenGLState() {
83 draw.read_framebuffer = 0; 83 draw.read_framebuffer = 0;
84 draw.draw_framebuffer = 0; 84 draw.draw_framebuffer = 0;
85 draw.vertex_array = 0; 85 draw.vertex_array = 0;
86 draw.vertex_buffer = 0;
87 draw.shader_program = 0; 86 draw.shader_program = 0;
88 draw.program_pipeline = 0; 87 draw.program_pipeline = 0;
89 88
@@ -513,18 +512,6 @@ void OpenGLState::ApplyFramebufferState() const {
513 } 512 }
514} 513}
515 514
516void OpenGLState::ApplyVertexBufferState() const {
517 // Vertex array
518 if (draw.vertex_array != cur_state.draw.vertex_array) {
519 glBindVertexArray(draw.vertex_array);
520 }
521
522 // Vertex buffer
523 if (draw.vertex_buffer != cur_state.draw.vertex_buffer) {
524 glBindBuffer(GL_ARRAY_BUFFER, draw.vertex_buffer);
525 }
526}
527
528void OpenGLState::ApplyDepthClamp() const { 515void OpenGLState::ApplyDepthClamp() const {
529 if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane && 516 if (depth_clamp.far_plane == cur_state.depth_clamp.far_plane &&
530 depth_clamp.near_plane == cur_state.depth_clamp.near_plane) { 517 depth_clamp.near_plane == cur_state.depth_clamp.near_plane) {
@@ -542,7 +529,11 @@ void OpenGLState::ApplyDepthClamp() const {
542 529
543void OpenGLState::Apply() const { 530void OpenGLState::Apply() const {
544 ApplyFramebufferState(); 531 ApplyFramebufferState();
545 ApplyVertexBufferState(); 532
533 // Vertex array
534 if (draw.vertex_array != cur_state.draw.vertex_array) {
535 glBindVertexArray(draw.vertex_array);
536 }
546 537
547 // Shader program 538 // Shader program
548 if (draw.shader_program != cur_state.draw.shader_program) { 539 if (draw.shader_program != cur_state.draw.shader_program) {
@@ -633,13 +624,6 @@ OpenGLState& OpenGLState::ResetPipeline(GLuint handle) {
633 return *this; 624 return *this;
634} 625}
635 626
636OpenGLState& OpenGLState::ResetBuffer(GLuint handle) {
637 if (draw.vertex_buffer == handle) {
638 draw.vertex_buffer = 0;
639 }
640 return *this;
641}
642
643OpenGLState& OpenGLState::ResetVertexArray(GLuint handle) { 627OpenGLState& OpenGLState::ResetVertexArray(GLuint handle) {
644 if (draw.vertex_array == handle) { 628 if (draw.vertex_array == handle) {
645 draw.vertex_array = 0; 629 draw.vertex_array = 0;
diff --git a/src/video_core/renderer_opengl/gl_state.h b/src/video_core/renderer_opengl/gl_state.h
index 170dd4047..9dc3f0cc8 100644
--- a/src/video_core/renderer_opengl/gl_state.h
+++ b/src/video_core/renderer_opengl/gl_state.h
@@ -154,7 +154,6 @@ public:
154 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING 154 GLuint read_framebuffer; // GL_READ_FRAMEBUFFER_BINDING
155 GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING 155 GLuint draw_framebuffer; // GL_DRAW_FRAMEBUFFER_BINDING
156 GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING 156 GLuint vertex_array; // GL_VERTEX_ARRAY_BINDING
157 GLuint vertex_buffer; // GL_ARRAY_BUFFER_BINDING
158 GLuint shader_program; // GL_CURRENT_PROGRAM 157 GLuint shader_program; // GL_CURRENT_PROGRAM
159 GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING 158 GLuint program_pipeline; // GL_PROGRAM_PIPELINE_BINDING
160 } draw; 159 } draw;
@@ -207,8 +206,6 @@ public:
207 void Apply() const; 206 void Apply() const;
208 /// Apply only the state afecting the framebuffer 207 /// Apply only the state afecting the framebuffer
209 void ApplyFramebufferState() const; 208 void ApplyFramebufferState() const;
210 /// Apply only the state afecting the vertex buffer
211 void ApplyVertexBufferState() const;
212 /// Set the initial OpenGL state 209 /// Set the initial OpenGL state
213 static void ApplyDefaultState(); 210 static void ApplyDefaultState();
214 /// Resets any references to the given resource 211 /// Resets any references to the given resource
@@ -216,7 +213,6 @@ public:
216 OpenGLState& ResetSampler(GLuint handle); 213 OpenGLState& ResetSampler(GLuint handle);
217 OpenGLState& ResetProgram(GLuint handle); 214 OpenGLState& ResetProgram(GLuint handle);
218 OpenGLState& ResetPipeline(GLuint handle); 215 OpenGLState& ResetPipeline(GLuint handle);
219 OpenGLState& ResetBuffer(GLuint handle);
220 OpenGLState& ResetVertexArray(GLuint handle); 216 OpenGLState& ResetVertexArray(GLuint handle);
221 OpenGLState& ResetFramebuffer(GLuint handle); 217 OpenGLState& ResetFramebuffer(GLuint handle);
222 void EmulateViewportWithScissor(); 218 void EmulateViewportWithScissor();
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 4947f06fd..c268c9686 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -245,19 +245,20 @@ void RendererOpenGL::InitOpenGLObjects() {
245 245
246 // Generate VAO 246 // Generate VAO
247 vertex_array.Create(); 247 vertex_array.Create();
248
249 state.draw.vertex_array = vertex_array.handle; 248 state.draw.vertex_array = vertex_array.handle;
250 state.draw.vertex_buffer = vertex_buffer.handle;
251 state.Apply();
252 249
253 // Attach vertex data to VAO 250 // Attach vertex data to VAO
254 glBufferData(GL_ARRAY_BUFFER, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW); 251 glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
255 glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), 252 glVertexArrayAttribFormat(vertex_array.handle, attrib_position, 2, GL_FLOAT, GL_FALSE,
256 (GLvoid*)offsetof(ScreenRectVertex, position)); 253 offsetof(ScreenRectVertex, position));
257 glVertexAttribPointer(attrib_tex_coord, 2, GL_FLOAT, GL_FALSE, sizeof(ScreenRectVertex), 254 glVertexArrayAttribFormat(vertex_array.handle, attrib_tex_coord, 2, GL_FLOAT, GL_FALSE,
258 (GLvoid*)offsetof(ScreenRectVertex, tex_coord)); 255 offsetof(ScreenRectVertex, tex_coord));
259 glEnableVertexAttribArray(attrib_position); 256 glVertexArrayAttribBinding(vertex_array.handle, attrib_position, 0);
260 glEnableVertexAttribArray(attrib_tex_coord); 257 glVertexArrayAttribBinding(vertex_array.handle, attrib_tex_coord, 0);
258 glEnableVertexArrayAttrib(vertex_array.handle, attrib_position);
259 glEnableVertexArrayAttrib(vertex_array.handle, attrib_tex_coord);
260 glVertexArrayVertexBuffer(vertex_array.handle, 0, vertex_buffer.handle, 0,
261 sizeof(ScreenRectVertex));
261 262
262 // Allocate textures for the screen 263 // Allocate textures for the screen
263 screen_info.texture.resource.Create(); 264 screen_info.texture.resource.Create();
@@ -369,14 +370,12 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
369 state.texture_units[0].texture = screen_info.display_texture; 370 state.texture_units[0].texture = screen_info.display_texture;
370 state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA}; 371 state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
371 // Workaround brigthness problems in SMO by enabling sRGB in the final output 372 // Workaround brigthness problems in SMO by enabling sRGB in the final output
372 // if it has been used in the frame 373 // if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987
373 // Needed because of this bug in QT
374 // QTBUG-50987
375 state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed(); 374 state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed();
376 state.Apply(); 375 state.Apply();
377 glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices.data()); 376 glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), vertices.data());
378 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 377 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
379 // restore default state 378 // Restore default state
380 state.framebuffer_srgb.enabled = false; 379 state.framebuffer_srgb.enabled = false;
381 state.texture_units[0].texture = 0; 380 state.texture_units[0].texture = 0;
382 state.Apply(); 381 state.Apply();