summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2020-02-06 21:39:59 -0500
committerGravatar GitHub2020-02-06 21:39:59 -0500
commit09d766d3574b94dbc349ab24359e87e8d08177d9 (patch)
tree12bbdd55bfa407e717eafbcb44a945aa76af2fd3 /src
parentMerge pull request #3366 from bunnei/swkbd-fixes (diff)
parentgl_rasterizer: Fix instanced draw arrays (diff)
downloadyuzu-09d766d3574b94dbc349ab24359e87e8d08177d9.tar.gz
yuzu-09d766d3574b94dbc349ab24359e87e8d08177d9.tar.xz
yuzu-09d766d3574b94dbc349ab24359e87e8d08177d9.zip
Merge pull request #3362 from ReinUsesLisp/fix-instanced
gl_rasterizer: Fix instanced draw arrays
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp127
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h7
2 files changed, 28 insertions, 106 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 362942e09..46a7433ea 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -248,9 +248,6 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
248} 248}
249 249
250GLintptr RasterizerOpenGL::SetupIndexBuffer() { 250GLintptr RasterizerOpenGL::SetupIndexBuffer() {
251 if (accelerate_draw != AccelDraw::Indexed) {
252 return 0;
253 }
254 MICROPROFILE_SCOPE(OpenGL_Index); 251 MICROPROFILE_SCOPE(OpenGL_Index);
255 const auto& regs = system.GPU().Maxwell3D().regs; 252 const auto& regs = system.GPU().Maxwell3D().regs;
256 const std::size_t size = CalculateIndexBufferSize(); 253 const std::size_t size = CalculateIndexBufferSize();
@@ -546,7 +543,8 @@ void RasterizerOpenGL::Clear() {
546 } 543 }
547} 544}
548 545
549void RasterizerOpenGL::DrawPrelude() { 546void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
547 MICROPROFILE_SCOPE(OpenGL_Drawing);
550 auto& gpu = system.GPU().Maxwell3D(); 548 auto& gpu = system.GPU().Maxwell3D();
551 549
552 SyncRasterizeEnable(state); 550 SyncRasterizeEnable(state);
@@ -567,9 +565,6 @@ void RasterizerOpenGL::DrawPrelude() {
567 565
568 buffer_cache.Acquire(); 566 buffer_cache.Acquire();
569 567
570 // Draw the vertex batch
571 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
572
573 std::size_t buffer_size = CalculateVertexArraysSize(); 568 std::size_t buffer_size = CalculateVertexArraysSize();
574 569
575 // Add space for index buffer 570 // Add space for index buffer
@@ -596,7 +591,11 @@ void RasterizerOpenGL::DrawPrelude() {
596 // Upload vertex and index data. 591 // Upload vertex and index data.
597 SetupVertexBuffer(vao); 592 SetupVertexBuffer(vao);
598 SetupVertexInstances(vao); 593 SetupVertexInstances(vao);
599 index_buffer_offset = SetupIndexBuffer(); 594
595 GLintptr index_buffer_offset;
596 if (is_indexed) {
597 index_buffer_offset = SetupIndexBuffer();
598 }
600 599
601 // Prepare packed bindings. 600 // Prepare packed bindings.
602 bind_ubo_pushbuffer.Setup(); 601 bind_ubo_pushbuffer.Setup();
@@ -630,6 +629,7 @@ void RasterizerOpenGL::DrawPrelude() {
630 // As all cached buffers are invalidated, we need to recheck their state. 629 // As all cached buffers are invalidated, we need to recheck their state.
631 gpu.dirty.ResetVertexArrays(); 630 gpu.dirty.ResetVertexArrays();
632 } 631 }
632 gpu.dirty.memory_general = false;
633 633
634 shader_program_manager->ApplyTo(state); 634 shader_program_manager->ApplyTo(state);
635 state.Apply(); 635 state.Apply();
@@ -637,106 +637,33 @@ void RasterizerOpenGL::DrawPrelude() {
637 if (texture_cache.TextureBarrier()) { 637 if (texture_cache.TextureBarrier()) {
638 glTextureBarrier(); 638 glTextureBarrier();
639 } 639 }
640}
641
642struct DrawParams {
643 bool is_indexed{};
644 bool is_instanced{};
645 GLenum primitive_mode{};
646 GLint count{};
647 GLint base_vertex{};
648
649 // Indexed settings
650 GLenum index_format{};
651 GLintptr index_buffer_offset{};
652
653 // Instanced setting
654 GLint num_instances{};
655 GLint base_instance{};
656
657 void DispatchDraw() {
658 if (is_indexed) {
659 const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset);
660 if (is_instanced) {
661 glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format,
662 index_buffer_ptr, num_instances,
663 base_vertex, base_instance);
664 } else {
665 glDrawElementsBaseVertex(primitive_mode, count, index_format, index_buffer_ptr,
666 base_vertex);
667 }
668 } else {
669 if (is_instanced) {
670 glDrawArraysInstancedBaseInstance(primitive_mode, base_vertex, count, num_instances,
671 base_instance);
672 } else {
673 glDrawArrays(primitive_mode, base_vertex, count);
674 }
675 }
676 }
677};
678
679bool RasterizerOpenGL::DrawBatch(bool is_indexed) {
680 accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays;
681 640
682 MICROPROFILE_SCOPE(OpenGL_Drawing); 641 const GLuint base_instance = static_cast<GLuint>(gpu.regs.vb_base_instance);
683 642 const GLsizei num_instances =
684 DrawPrelude(); 643 static_cast<GLsizei>(is_instanced ? gpu.mme_draw.instance_count : 1);
685 644 if (is_indexed) {
686 auto& maxwell3d = system.GPU().Maxwell3D(); 645 const GLenum index_format = MaxwellToGL::IndexFormat(gpu.regs.index_array.format);
687 const auto& regs = maxwell3d.regs; 646 const GLint base_vertex = static_cast<GLint>(gpu.regs.vb_element_base);
688 const auto current_instance = maxwell3d.state.current_instance; 647 const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.index_array.count);
689 DrawParams draw_call{}; 648 glDrawElementsInstancedBaseVertexBaseInstance(
690 draw_call.is_indexed = is_indexed; 649 primitive_mode, num_vertices, index_format,
691 draw_call.num_instances = static_cast<GLint>(1); 650 reinterpret_cast<const void*>(index_buffer_offset), num_instances, base_vertex,
692 draw_call.base_instance = static_cast<GLint>(current_instance); 651 base_instance);
693 draw_call.is_instanced = current_instance > 0;
694 draw_call.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
695 if (draw_call.is_indexed) {
696 draw_call.count = static_cast<GLint>(regs.index_array.count);
697 draw_call.base_vertex = static_cast<GLint>(regs.vb_element_base);
698 draw_call.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
699 draw_call.index_buffer_offset = index_buffer_offset;
700 } else { 652 } else {
701 draw_call.count = static_cast<GLint>(regs.vertex_buffer.count); 653 const GLint base_vertex = static_cast<GLint>(gpu.regs.vertex_buffer.first);
702 draw_call.base_vertex = static_cast<GLint>(regs.vertex_buffer.first); 654 const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.vertex_buffer.count);
655 glDrawArraysInstancedBaseInstance(primitive_mode, base_vertex, num_vertices, num_instances,
656 base_instance);
703 } 657 }
704 draw_call.DispatchDraw(); 658}
705 659
706 maxwell3d.dirty.memory_general = false; 660bool RasterizerOpenGL::DrawBatch(bool is_indexed) {
707 accelerate_draw = AccelDraw::Disabled; 661 Draw(is_indexed, false);
708 return true; 662 return true;
709} 663}
710 664
711bool RasterizerOpenGL::DrawMultiBatch(bool is_indexed) { 665bool RasterizerOpenGL::DrawMultiBatch(bool is_indexed) {
712 accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays; 666 Draw(is_indexed, true);
713
714 MICROPROFILE_SCOPE(OpenGL_Drawing);
715
716 DrawPrelude();
717
718 auto& maxwell3d = system.GPU().Maxwell3D();
719 const auto& regs = maxwell3d.regs;
720 const auto& draw_setup = maxwell3d.mme_draw;
721 DrawParams draw_call{};
722 draw_call.is_indexed = is_indexed;
723 draw_call.num_instances = static_cast<GLint>(draw_setup.instance_count);
724 draw_call.base_instance = static_cast<GLint>(regs.vb_base_instance);
725 draw_call.is_instanced = draw_setup.instance_count > 1;
726 draw_call.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
727 if (draw_call.is_indexed) {
728 draw_call.count = static_cast<GLint>(regs.index_array.count);
729 draw_call.base_vertex = static_cast<GLint>(regs.vb_element_base);
730 draw_call.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
731 draw_call.index_buffer_offset = index_buffer_offset;
732 } else {
733 draw_call.count = static_cast<GLint>(regs.vertex_buffer.count);
734 draw_call.base_vertex = static_cast<GLint>(regs.vertex_buffer.first);
735 }
736 draw_call.DispatchDraw();
737
738 maxwell3d.dirty.memory_general = false;
739 accelerate_draw = AccelDraw::Disabled;
740 return true; 667 return true;
741} 668}
742 669
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 6a27cf497..0501f3828 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -103,7 +103,7 @@ private:
103 std::size_t size); 103 std::size_t size);
104 104
105 /// Syncs all the state, shaders, render targets and textures setting before a draw call. 105 /// Syncs all the state, shaders, render targets and textures setting before a draw call.
106 void DrawPrelude(); 106 void Draw(bool is_indexed, bool is_instanced);
107 107
108 /// Configures the current textures to use for the draw command. 108 /// Configures the current textures to use for the draw command.
109 void SetupDrawTextures(std::size_t stage_index, const Shader& shader); 109 void SetupDrawTextures(std::size_t stage_index, const Shader& shader);
@@ -220,12 +220,7 @@ private:
220 220
221 GLintptr SetupIndexBuffer(); 221 GLintptr SetupIndexBuffer();
222 222
223 GLintptr index_buffer_offset;
224
225 void SetupShaders(GLenum primitive_mode); 223 void SetupShaders(GLenum primitive_mode);
226
227 enum class AccelDraw { Disabled, Arrays, Indexed };
228 AccelDraw accelerate_draw = AccelDraw::Disabled;
229}; 224};
230 225
231} // namespace OpenGL 226} // namespace OpenGL