summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
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 c428f06e4..52e5d2005 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -244,9 +244,6 @@ void RasterizerOpenGL::SetupVertexInstances(GLuint vao) {
244} 244}
245 245
246GLintptr RasterizerOpenGL::SetupIndexBuffer() { 246GLintptr RasterizerOpenGL::SetupIndexBuffer() {
247 if (accelerate_draw != AccelDraw::Indexed) {
248 return 0;
249 }
250 MICROPROFILE_SCOPE(OpenGL_Index); 247 MICROPROFILE_SCOPE(OpenGL_Index);
251 const auto& regs = system.GPU().Maxwell3D().regs; 248 const auto& regs = system.GPU().Maxwell3D().regs;
252 const std::size_t size = CalculateIndexBufferSize(); 249 const std::size_t size = CalculateIndexBufferSize();
@@ -542,7 +539,8 @@ void RasterizerOpenGL::Clear() {
542 } 539 }
543} 540}
544 541
545void RasterizerOpenGL::DrawPrelude() { 542void RasterizerOpenGL::Draw(bool is_indexed, bool is_instanced) {
543 MICROPROFILE_SCOPE(OpenGL_Drawing);
546 auto& gpu = system.GPU().Maxwell3D(); 544 auto& gpu = system.GPU().Maxwell3D();
547 545
548 SyncRasterizeEnable(state); 546 SyncRasterizeEnable(state);
@@ -563,9 +561,6 @@ void RasterizerOpenGL::DrawPrelude() {
563 561
564 buffer_cache.Acquire(); 562 buffer_cache.Acquire();
565 563
566 // Draw the vertex batch
567 const bool is_indexed = accelerate_draw == AccelDraw::Indexed;
568
569 std::size_t buffer_size = CalculateVertexArraysSize(); 564 std::size_t buffer_size = CalculateVertexArraysSize();
570 565
571 // Add space for index buffer 566 // Add space for index buffer
@@ -592,7 +587,11 @@ void RasterizerOpenGL::DrawPrelude() {
592 // Upload vertex and index data. 587 // Upload vertex and index data.
593 SetupVertexBuffer(vao); 588 SetupVertexBuffer(vao);
594 SetupVertexInstances(vao); 589 SetupVertexInstances(vao);
595 index_buffer_offset = SetupIndexBuffer(); 590
591 GLintptr index_buffer_offset;
592 if (is_indexed) {
593 index_buffer_offset = SetupIndexBuffer();
594 }
596 595
597 // Prepare packed bindings. 596 // Prepare packed bindings.
598 bind_ubo_pushbuffer.Setup(); 597 bind_ubo_pushbuffer.Setup();
@@ -626,6 +625,7 @@ void RasterizerOpenGL::DrawPrelude() {
626 // As all cached buffers are invalidated, we need to recheck their state. 625 // As all cached buffers are invalidated, we need to recheck their state.
627 gpu.dirty.ResetVertexArrays(); 626 gpu.dirty.ResetVertexArrays();
628 } 627 }
628 gpu.dirty.memory_general = false;
629 629
630 shader_program_manager->ApplyTo(state); 630 shader_program_manager->ApplyTo(state);
631 state.Apply(); 631 state.Apply();
@@ -633,106 +633,33 @@ void RasterizerOpenGL::DrawPrelude() {
633 if (texture_cache.TextureBarrier()) { 633 if (texture_cache.TextureBarrier()) {
634 glTextureBarrier(); 634 glTextureBarrier();
635 } 635 }
636}
637
638struct DrawParams {
639 bool is_indexed{};
640 bool is_instanced{};
641 GLenum primitive_mode{};
642 GLint count{};
643 GLint base_vertex{};
644
645 // Indexed settings
646 GLenum index_format{};
647 GLintptr index_buffer_offset{};
648
649 // Instanced setting
650 GLint num_instances{};
651 GLint base_instance{};
652
653 void DispatchDraw() {
654 if (is_indexed) {
655 const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset);
656 if (is_instanced) {
657 glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format,
658 index_buffer_ptr, num_instances,
659 base_vertex, base_instance);
660 } else {
661 glDrawElementsBaseVertex(primitive_mode, count, index_format, index_buffer_ptr,
662 base_vertex);
663 }
664 } else {
665 if (is_instanced) {
666 glDrawArraysInstancedBaseInstance(primitive_mode, base_vertex, count, num_instances,
667 base_instance);
668 } else {
669 glDrawArrays(primitive_mode, base_vertex, count);
670 }
671 }
672 }
673};
674
675bool RasterizerOpenGL::DrawBatch(bool is_indexed) {
676 accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays;
677 636
678 MICROPROFILE_SCOPE(OpenGL_Drawing); 637 const GLuint base_instance = static_cast<GLuint>(gpu.regs.vb_base_instance);
679 638 const GLsizei num_instances =
680 DrawPrelude(); 639 static_cast<GLsizei>(is_instanced ? gpu.mme_draw.instance_count : 1);
681 640 if (is_indexed) {
682 auto& maxwell3d = system.GPU().Maxwell3D(); 641 const GLenum index_format = MaxwellToGL::IndexFormat(gpu.regs.index_array.format);
683 const auto& regs = maxwell3d.regs; 642 const GLint base_vertex = static_cast<GLint>(gpu.regs.vb_element_base);
684 const auto current_instance = maxwell3d.state.current_instance; 643 const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.index_array.count);
685 DrawParams draw_call{}; 644 glDrawElementsInstancedBaseVertexBaseInstance(
686 draw_call.is_indexed = is_indexed; 645 primitive_mode, num_vertices, index_format,
687 draw_call.num_instances = static_cast<GLint>(1); 646 reinterpret_cast<const void*>(index_buffer_offset), num_instances, base_vertex,
688 draw_call.base_instance = static_cast<GLint>(current_instance); 647 base_instance);
689 draw_call.is_instanced = current_instance > 0;
690 draw_call.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
691 if (draw_call.is_indexed) {
692 draw_call.count = static_cast<GLint>(regs.index_array.count);
693 draw_call.base_vertex = static_cast<GLint>(regs.vb_element_base);
694 draw_call.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
695 draw_call.index_buffer_offset = index_buffer_offset;
696 } else { 648 } else {
697 draw_call.count = static_cast<GLint>(regs.vertex_buffer.count); 649 const GLint base_vertex = static_cast<GLint>(gpu.regs.vertex_buffer.first);
698 draw_call.base_vertex = static_cast<GLint>(regs.vertex_buffer.first); 650 const GLsizei num_vertices = static_cast<GLsizei>(gpu.regs.vertex_buffer.count);
651 glDrawArraysInstancedBaseInstance(primitive_mode, base_vertex, num_vertices, num_instances,
652 base_instance);
699 } 653 }
700 draw_call.DispatchDraw(); 654}
701 655
702 maxwell3d.dirty.memory_general = false; 656bool RasterizerOpenGL::DrawBatch(bool is_indexed) {
703 accelerate_draw = AccelDraw::Disabled; 657 Draw(is_indexed, false);
704 return true; 658 return true;
705} 659}
706 660
707bool RasterizerOpenGL::DrawMultiBatch(bool is_indexed) { 661bool RasterizerOpenGL::DrawMultiBatch(bool is_indexed) {
708 accelerate_draw = is_indexed ? AccelDraw::Indexed : AccelDraw::Arrays; 662 Draw(is_indexed, true);
709
710 MICROPROFILE_SCOPE(OpenGL_Drawing);
711
712 DrawPrelude();
713
714 auto& maxwell3d = system.GPU().Maxwell3D();
715 const auto& regs = maxwell3d.regs;
716 const auto& draw_setup = maxwell3d.mme_draw;
717 DrawParams draw_call{};
718 draw_call.is_indexed = is_indexed;
719 draw_call.num_instances = static_cast<GLint>(draw_setup.instance_count);
720 draw_call.base_instance = static_cast<GLint>(regs.vb_base_instance);
721 draw_call.is_instanced = draw_setup.instance_count > 1;
722 draw_call.primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology);
723 if (draw_call.is_indexed) {
724 draw_call.count = static_cast<GLint>(regs.index_array.count);
725 draw_call.base_vertex = static_cast<GLint>(regs.vb_element_base);
726 draw_call.index_format = MaxwellToGL::IndexFormat(regs.index_array.format);
727 draw_call.index_buffer_offset = index_buffer_offset;
728 } else {
729 draw_call.count = static_cast<GLint>(regs.vertex_buffer.count);
730 draw_call.base_vertex = static_cast<GLint>(regs.vertex_buffer.first);
731 }
732 draw_call.DispatchDraw();
733
734 maxwell3d.dirty.memory_general = false;
735 accelerate_draw = AccelDraw::Disabled;
736 return true; 663 return true;
737} 664}
738 665
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