summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/engines/maxwell_3d.cpp35
-rw-r--r--src/video_core/engines/maxwell_3d.h7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp38
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp10
-rw-r--r--src/video_core/shader/shader_ir.cpp12
-rw-r--r--src/video_core/shader/shader_ir.h10
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
265void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) { 268void 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
493void Maxwell3D::ProcessMacroUpload(u32 data) { 512void 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
1284private: 1287private:
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
824void RasterizerOpenGL::DrawMultiArrays() { 822void 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};