diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 35 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 7 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 38 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 10 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.cpp | 12 | ||||
| -rw-r--r-- | src/video_core/shader/shader_ir.h | 10 |
6 files changed, 81 insertions, 31 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 48fc1a9e1..d1f63a5eb 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -260,6 +260,9 @@ void Maxwell3D::CallMacroMethod(u32 method, std::size_t num_parameters, const u3 | |||
| 260 | 260 | ||
| 261 | // Execute the current macro. | 261 | // Execute the current macro. |
| 262 | macro_interpreter.Execute(macro_positions[entry], num_parameters, parameters); | 262 | macro_interpreter.Execute(macro_positions[entry], num_parameters, parameters); |
| 263 | if (mme_draw.current_mode != MMMEDrawMode::Undefined) { | ||
| 264 | FlushMMEInlineDraw(); | ||
| 265 | } | ||
| 263 | } | 266 | } |
| 264 | 267 | ||
| 265 | void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { | 268 | void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { |
| @@ -426,25 +429,37 @@ void Maxwell3D::CallMethodFromMME(const GPU::MethodCall& method_call) { | |||
| 426 | regs.reg_array[method] = method_call.argument; | 429 | regs.reg_array[method] = method_call.argument; |
| 427 | if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) || | 430 | if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count) || |
| 428 | method == MAXWELL3D_REG_INDEX(index_array.count)) { | 431 | method == MAXWELL3D_REG_INDEX(index_array.count)) { |
| 429 | MMMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count) | 432 | const MMMEDrawMode expected_mode = method == MAXWELL3D_REG_INDEX(vertex_buffer.count) |
| 430 | ? MMMEDrawMode::Array | 433 | ? MMMEDrawMode::Array |
| 431 | : MMMEDrawMode::Indexed; | 434 | : MMMEDrawMode::Indexed; |
| 432 | u32 count = method_call.argument; | 435 | const u32 count = method_call.argument; |
| 433 | while (true) { | 436 | while (true) { |
| 434 | if (mme_draw.current_mode == MMMEDrawMode::Undefined) { | 437 | if (mme_draw.current_mode == MMMEDrawMode::Undefined) { |
| 435 | mme_draw.current_mode = expected_mode; | 438 | if (mme_draw.gl_begin_consume) { |
| 436 | mme_draw.current_count = count; | 439 | mme_draw.current_mode = expected_mode; |
| 437 | mme_draw.instance_count = 1; | 440 | mme_draw.current_count = count; |
| 441 | mme_draw.instance_count = 1; | ||
| 442 | mme_draw.gl_begin_consume = false; | ||
| 443 | mme_draw.gl_end_count = 0; | ||
| 444 | } | ||
| 438 | break; | 445 | break; |
| 439 | } else { | 446 | } else { |
| 440 | if (mme_draw.current_mode == expected_mode && count == mme_draw.current_count) { | 447 | if (mme_draw.current_mode == expected_mode && count == mme_draw.current_count && |
| 448 | mme_draw.instance_mode && mme_draw.gl_begin_consume) { | ||
| 441 | mme_draw.instance_count++; | 449 | mme_draw.instance_count++; |
| 450 | mme_draw.gl_begin_consume = false; | ||
| 442 | break; | 451 | break; |
| 443 | } else { | 452 | } else { |
| 444 | FlushMMEInlineDraw(); | 453 | FlushMMEInlineDraw(); |
| 445 | } | 454 | } |
| 446 | } | 455 | } |
| 447 | } | 456 | } |
| 457 | } else if (method == MAXWELL3D_REG_INDEX(draw.vertex_begin_gl)) { | ||
| 458 | mme_draw.instance_mode = | ||
| 459 | (regs.draw.instance_next != 0) || (regs.draw.instance_cont != 0); | ||
| 460 | mme_draw.gl_begin_consume = true; | ||
| 461 | } else { | ||
| 462 | mme_draw.gl_end_count++; | ||
| 448 | } | 463 | } |
| 449 | } else { | 464 | } else { |
| 450 | if (mme_draw.current_mode != MMMEDrawMode::Undefined) { | 465 | if (mme_draw.current_mode != MMMEDrawMode::Undefined) { |
| @@ -458,6 +473,7 @@ void Maxwell3D::FlushMMEInlineDraw() { | |||
| 458 | LOG_DEBUG(HW_GPU, "called, topology={}, count={}", static_cast<u32>(regs.draw.topology.Value()), | 473 | LOG_DEBUG(HW_GPU, "called, topology={}, count={}", static_cast<u32>(regs.draw.topology.Value()), |
| 459 | regs.vertex_buffer.count); | 474 | regs.vertex_buffer.count); |
| 460 | ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); | 475 | ASSERT_MSG(!(regs.index_array.count && regs.vertex_buffer.count), "Both indexed and direct?"); |
| 476 | ASSERT(mme_draw.instance_count == mme_draw.gl_end_count); | ||
| 461 | 477 | ||
| 462 | auto debug_context = system.GetGPUDebugContext(); | 478 | auto debug_context = system.GetGPUDebugContext(); |
| 463 | 479 | ||
| @@ -488,6 +504,9 @@ void Maxwell3D::FlushMMEInlineDraw() { | |||
| 488 | mme_draw.current_mode = MMMEDrawMode::Undefined; | 504 | mme_draw.current_mode = MMMEDrawMode::Undefined; |
| 489 | mme_draw.current_count = 0; | 505 | mme_draw.current_count = 0; |
| 490 | mme_draw.instance_count = 0; | 506 | mme_draw.instance_count = 0; |
| 507 | mme_draw.instance_mode = false; | ||
| 508 | mme_draw.gl_begin_consume = false; | ||
| 509 | mme_draw.gl_end_count = 0; | ||
| 491 | } | 510 | } |
| 492 | 511 | ||
| 493 | void Maxwell3D::ProcessMacroUpload(u32 data) { | 512 | void Maxwell3D::ProcessMacroUpload(u32 data) { |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index 1547d930e..8fd3ec85c 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -1277,8 +1277,11 @@ public: | |||
| 1277 | 1277 | ||
| 1278 | struct MMEDrawState { | 1278 | struct MMEDrawState { |
| 1279 | MMMEDrawMode current_mode{MMMEDrawMode::Undefined}; | 1279 | MMMEDrawMode current_mode{MMMEDrawMode::Undefined}; |
| 1280 | u32 current_count; | 1280 | u32 current_count{}; |
| 1281 | u32 instance_count; | 1281 | u32 instance_count{}; |
| 1282 | bool instance_mode{}; | ||
| 1283 | bool gl_begin_consume{}; | ||
| 1284 | u32 gl_end_count{}; | ||
| 1282 | } mme_draw; | 1285 | } mme_draw; |
| 1283 | 1286 | ||
| 1284 | private: | 1287 | private: |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 5df7f3f56..f71a22738 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp | |||
| @@ -788,13 +788,13 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 788 | DrawPrelude(); | 788 | DrawPrelude(); |
| 789 | 789 | ||
| 790 | auto& maxwell3d = system.GPU().Maxwell3D(); | 790 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 791 | auto& regs = maxwell3d.regs; | 791 | const auto& regs = maxwell3d.regs; |
| 792 | auto current_instance = maxwell3d.state.current_instance; | 792 | const auto current_instance = maxwell3d.state.current_instance; |
| 793 | auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology); | 793 | const auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology); |
| 794 | if (accelerate_draw == AccelDraw::Indexed) { | 794 | if (accelerate_draw == AccelDraw::Indexed) { |
| 795 | auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format); | 795 | const auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format); |
| 796 | auto count = regs.index_array.count; | 796 | const auto count = regs.index_array.count; |
| 797 | auto base_vertex = static_cast<GLint>(regs.vb_element_base); | 797 | const auto base_vertex = static_cast<GLint>(regs.vb_element_base); |
| 798 | const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset); | 798 | const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset); |
| 799 | if (current_instance > 0) { | 799 | if (current_instance > 0) { |
| 800 | glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format, | 800 | glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format, |
| @@ -805,8 +805,8 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 805 | base_vertex); | 805 | base_vertex); |
| 806 | } | 806 | } |
| 807 | } else { | 807 | } else { |
| 808 | auto count = regs.vertex_buffer.count; | 808 | const auto count = regs.vertex_buffer.count; |
| 809 | auto vertex_first = regs.vertex_buffer.first; | 809 | const auto vertex_first = regs.vertex_buffer.first; |
| 810 | if (current_instance > 0) { | 810 | if (current_instance > 0) { |
| 811 | glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, 1, | 811 | glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, 1, |
| 812 | current_instance); | 812 | current_instance); |
| @@ -819,21 +819,19 @@ void RasterizerOpenGL::DrawArrays() { | |||
| 819 | maxwell3d.dirty.memory_general = false; | 819 | maxwell3d.dirty.memory_general = false; |
| 820 | } | 820 | } |
| 821 | 821 | ||
| 822 | #pragma optimize("", off) | ||
| 823 | |||
| 824 | void RasterizerOpenGL::DrawMultiArrays() { | 822 | void RasterizerOpenGL::DrawMultiArrays() { |
| 825 | DrawPrelude(); | 823 | DrawPrelude(); |
| 826 | 824 | ||
| 827 | auto& maxwell3d = system.GPU().Maxwell3D(); | 825 | auto& maxwell3d = system.GPU().Maxwell3D(); |
| 828 | auto& regs = maxwell3d.regs; | 826 | const auto& regs = maxwell3d.regs; |
| 829 | auto& draw_setup = maxwell3d.mme_draw; | 827 | const auto& draw_setup = maxwell3d.mme_draw; |
| 830 | auto num_instances = draw_setup.instance_count; | 828 | const auto num_instances = draw_setup.instance_count; |
| 831 | auto base_instance = static_cast<GLint>(regs.vb_base_instance); | 829 | const auto base_instance = static_cast<GLint>(regs.vb_base_instance); |
| 832 | auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology); | 830 | const auto primitive_mode = MaxwellToGL::PrimitiveTopology(regs.draw.topology); |
| 833 | if (draw_setup.current_mode == Tegra::Engines::Maxwell3D::MMMEDrawMode::Indexed) { | 831 | if (draw_setup.current_mode == Tegra::Engines::Maxwell3D::MMMEDrawMode::Indexed) { |
| 834 | auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format); | 832 | const auto index_format = MaxwellToGL::IndexFormat(regs.index_array.format); |
| 835 | auto count = regs.index_array.count; | 833 | const auto count = regs.index_array.count; |
| 836 | auto base_vertex = static_cast<GLint>(regs.vb_element_base); | 834 | const auto base_vertex = static_cast<GLint>(regs.vb_element_base); |
| 837 | const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset); | 835 | const auto index_buffer_ptr = reinterpret_cast<const void*>(index_buffer_offset); |
| 838 | if (num_instances > 1) { | 836 | if (num_instances > 1) { |
| 839 | glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format, | 837 | glDrawElementsInstancedBaseVertexBaseInstance(primitive_mode, count, index_format, |
| @@ -844,8 +842,8 @@ void RasterizerOpenGL::DrawMultiArrays() { | |||
| 844 | base_vertex); | 842 | base_vertex); |
| 845 | } | 843 | } |
| 846 | } else { | 844 | } else { |
| 847 | auto count = regs.vertex_buffer.count; | 845 | const auto count = regs.vertex_buffer.count; |
| 848 | auto vertex_first = regs.vertex_buffer.first; | 846 | const auto vertex_first = regs.vertex_buffer.first; |
| 849 | if (num_instances > 1) { | 847 | if (num_instances > 1) { |
| 850 | glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, num_instances, | 848 | glDrawArraysInstancedBaseInstance(primitive_mode, vertex_first, count, num_instances, |
| 851 | base_instance); | 849 | base_instance); |
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 62e32697e..f7e86ab26 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |||
| @@ -462,6 +462,14 @@ private: | |||
| 462 | code.AddLine("float gl_PointSize;"); | 462 | code.AddLine("float gl_PointSize;"); |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | if (ir.UsesInstanceId()) { | ||
| 466 | code.AddLine("int gl_InstanceID;"); | ||
| 467 | } | ||
| 468 | |||
| 469 | if (ir.UsesVertexId()) { | ||
| 470 | code.AddLine("int gl_VertexID;"); | ||
| 471 | } | ||
| 472 | |||
| 465 | --code.scope; | 473 | --code.scope; |
| 466 | code.AddLine("}};"); | 474 | code.AddLine("}};"); |
| 467 | code.AddNewLine(); | 475 | code.AddNewLine(); |
| @@ -964,7 +972,7 @@ private: | |||
| 964 | switch (element) { | 972 | switch (element) { |
| 965 | case 2: | 973 | case 2: |
| 966 | // Config pack's first value is instance_id. | 974 | // Config pack's first value is instance_id. |
| 967 | return {"gl_InstanceID", Type::Uint}; | 975 | return {"gl_InstanceID", Type::Int}; |
| 968 | case 3: | 976 | case 3: |
| 969 | return {"gl_VertexID", Type::Int}; | 977 | return {"gl_VertexID", Type::Int}; |
| 970 | } | 978 | } |
diff --git a/src/video_core/shader/shader_ir.cpp b/src/video_core/shader/shader_ir.cpp index bbbab0bca..2c357f310 100644 --- a/src/video_core/shader/shader_ir.cpp +++ b/src/video_core/shader/shader_ir.cpp | |||
| @@ -114,6 +114,18 @@ Node ShaderIR::GetOutputAttribute(Attribute::Index index, u64 element, Node buff | |||
| 114 | break; | 114 | break; |
| 115 | } | 115 | } |
| 116 | } | 116 | } |
| 117 | if (index == Attribute::Index::TessCoordInstanceIDVertexID) { | ||
| 118 | switch (element) { | ||
| 119 | case 2: | ||
| 120 | uses_instance_id = true; | ||
| 121 | break; | ||
| 122 | case 3: | ||
| 123 | uses_vertex_id = true; | ||
| 124 | break; | ||
| 125 | default: | ||
| 126 | break; | ||
| 127 | } | ||
| 128 | } | ||
| 117 | if (index == Attribute::Index::ClipDistances0123 || | 129 | if (index == Attribute::Index::ClipDistances0123 || |
| 118 | index == Attribute::Index::ClipDistances4567) { | 130 | index == Attribute::Index::ClipDistances4567) { |
| 119 | const auto clip_index = | 131 | const auto clip_index = |
diff --git a/src/video_core/shader/shader_ir.h b/src/video_core/shader/shader_ir.h index 6aed9bb84..2f03d83ba 100644 --- a/src/video_core/shader/shader_ir.h +++ b/src/video_core/shader/shader_ir.h | |||
| @@ -124,6 +124,14 @@ public: | |||
| 124 | return uses_point_size; | 124 | return uses_point_size; |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | bool UsesInstanceId() const { | ||
| 128 | return uses_instance_id; | ||
| 129 | } | ||
| 130 | |||
| 131 | bool UsesVertexId() const { | ||
| 132 | return uses_vertex_id; | ||
| 133 | } | ||
| 134 | |||
| 127 | bool HasPhysicalAttributes() const { | 135 | bool HasPhysicalAttributes() const { |
| 128 | return uses_physical_attributes; | 136 | return uses_physical_attributes; |
| 129 | } | 137 | } |
| @@ -373,6 +381,8 @@ private: | |||
| 373 | bool uses_viewport_index{}; | 381 | bool uses_viewport_index{}; |
| 374 | bool uses_point_size{}; | 382 | bool uses_point_size{}; |
| 375 | bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes | 383 | bool uses_physical_attributes{}; // Shader uses AL2P or physical attribute read/writes |
| 384 | bool uses_instance_id{}; | ||
| 385 | bool uses_vertex_id{}; | ||
| 376 | 386 | ||
| 377 | Tegra::Shader::Header header; | 387 | Tegra::Shader::Header header; |
| 378 | }; | 388 | }; |