diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/engines/maxwell_3d.cpp | 116 | ||||
| -rw-r--r-- | src/video_core/engines/maxwell_3d.h | 8 |
2 files changed, 63 insertions, 61 deletions
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp index 6d43e23ea..212427b8b 100644 --- a/src/video_core/engines/maxwell_3d.cpp +++ b/src/video_core/engines/maxwell_3d.cpp | |||
| @@ -126,6 +126,7 @@ void Maxwell3D::InitializeRegisterDefaults() { | |||
| 126 | draw_command[MAXWELL3D_REG_INDEX(draw_inline_index)] = true; | 126 | draw_command[MAXWELL3D_REG_INDEX(draw_inline_index)] = true; |
| 127 | draw_command[MAXWELL3D_REG_INDEX(inline_index_2x16.even)] = true; | 127 | draw_command[MAXWELL3D_REG_INDEX(inline_index_2x16.even)] = true; |
| 128 | draw_command[MAXWELL3D_REG_INDEX(inline_index_4x8.index0)] = true; | 128 | draw_command[MAXWELL3D_REG_INDEX(inline_index_4x8.index0)] = true; |
| 129 | draw_command[MAXWELL3D_REG_INDEX(draw.instance_id)] = true; | ||
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { | 132 | void Maxwell3D::ProcessMacro(u32 method, const u32* base_start, u32 amount, bool is_last_call) { |
| @@ -285,31 +286,58 @@ void Maxwell3D::CallMethod(u32 method, u32 method_argument, bool is_last_call) { | |||
| 285 | ASSERT_MSG(method < Regs::NUM_REGS, | 286 | ASSERT_MSG(method < Regs::NUM_REGS, |
| 286 | "Invalid Maxwell3D register, increase the size of the Regs structure"); | 287 | "Invalid Maxwell3D register, increase the size of the Regs structure"); |
| 287 | 288 | ||
| 289 | const u32 argument = ProcessShadowRam(method, method_argument); | ||
| 290 | ProcessDirtyRegisters(method, argument); | ||
| 291 | |||
| 288 | if (draw_command[method]) { | 292 | if (draw_command[method]) { |
| 289 | regs.reg_array[method] = method_argument; | 293 | regs.reg_array[method] = method_argument; |
| 290 | deferred_draw_method.push_back(method); | 294 | deferred_draw_method.push_back(method); |
| 291 | auto u32_to_u8 = [&](const u32 argument) { | 295 | auto update_inline_index = [&](const u32 index) { |
| 292 | inline_index_draw_indexes.push_back(static_cast<u8>(argument & 0x000000ff)); | 296 | inline_index_draw_indexes.push_back(static_cast<u8>(index & 0x000000ff)); |
| 293 | inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0x0000ff00) >> 8)); | 297 | inline_index_draw_indexes.push_back(static_cast<u8>((index & 0x0000ff00) >> 8)); |
| 294 | inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0x00ff0000) >> 16)); | 298 | inline_index_draw_indexes.push_back(static_cast<u8>((index & 0x00ff0000) >> 16)); |
| 295 | inline_index_draw_indexes.push_back(static_cast<u8>((argument & 0xff000000) >> 24)); | 299 | inline_index_draw_indexes.push_back(static_cast<u8>((index & 0xff000000) >> 24)); |
| 300 | draw_mode = DrawMode::InlineIndex; | ||
| 296 | }; | 301 | }; |
| 297 | if (MAXWELL3D_REG_INDEX(draw_inline_index) == method) { | 302 | switch (method) { |
| 298 | u32_to_u8(method_argument); | 303 | case MAXWELL3D_REG_INDEX(draw.end): |
| 299 | } else if (MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method) { | 304 | switch (draw_mode) { |
| 300 | u32_to_u8(regs.inline_index_2x16.even); | 305 | case DrawMode::General: |
| 301 | u32_to_u8(regs.inline_index_2x16.odd); | 306 | ProcessDraw(1); |
| 302 | } else if (MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) { | 307 | break; |
| 303 | u32_to_u8(regs.inline_index_4x8.index0); | 308 | case DrawMode::InlineIndex: |
| 304 | u32_to_u8(regs.inline_index_4x8.index1); | 309 | regs.index_buffer.count = static_cast<u32>(inline_index_draw_indexes.size() / 4); |
| 305 | u32_to_u8(regs.inline_index_4x8.index2); | 310 | regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; |
| 306 | u32_to_u8(regs.inline_index_4x8.index3); | 311 | ProcessDraw(1); |
| 312 | inline_index_draw_indexes.clear(); | ||
| 313 | break; | ||
| 314 | case DrawMode::Instance: | ||
| 315 | break; | ||
| 316 | } | ||
| 317 | break; | ||
| 318 | case MAXWELL3D_REG_INDEX(draw_inline_index): | ||
| 319 | update_inline_index(method_argument); | ||
| 320 | break; | ||
| 321 | case MAXWELL3D_REG_INDEX(inline_index_2x16.even): | ||
| 322 | update_inline_index(regs.inline_index_2x16.even); | ||
| 323 | update_inline_index(regs.inline_index_2x16.odd); | ||
| 324 | break; | ||
| 325 | case MAXWELL3D_REG_INDEX(inline_index_4x8.index0): | ||
| 326 | update_inline_index(regs.inline_index_4x8.index0); | ||
| 327 | update_inline_index(regs.inline_index_4x8.index1); | ||
| 328 | update_inline_index(regs.inline_index_4x8.index2); | ||
| 329 | update_inline_index(regs.inline_index_4x8.index3); | ||
| 330 | break; | ||
| 331 | case MAXWELL3D_REG_INDEX(draw.instance_id): | ||
| 332 | draw_mode = | ||
| 333 | (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || | ||
| 334 | (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) | ||
| 335 | ? DrawMode::Instance | ||
| 336 | : DrawMode::General; | ||
| 337 | break; | ||
| 307 | } | 338 | } |
| 308 | } else { | 339 | } else { |
| 309 | ProcessDeferredDraw(); | 340 | ProcessDeferredDraw(); |
| 310 | |||
| 311 | const u32 argument = ProcessShadowRam(method, method_argument); | ||
| 312 | ProcessDirtyRegisters(method, argument); | ||
| 313 | ProcessMethodCall(method, argument, method_argument, is_last_call); | 341 | ProcessMethodCall(method, argument, method_argument, is_last_call); |
| 314 | } | 342 | } |
| 315 | } | 343 | } |
| @@ -620,57 +648,27 @@ void Maxwell3D::ProcessDraw(u32 instance_count) { | |||
| 620 | } | 648 | } |
| 621 | 649 | ||
| 622 | void Maxwell3D::ProcessDeferredDraw() { | 650 | void Maxwell3D::ProcessDeferredDraw() { |
| 623 | if (deferred_draw_method.empty()) { | 651 | if (draw_mode != DrawMode::Instance || deferred_draw_method.empty()) { |
| 624 | return; | 652 | return; |
| 625 | } | 653 | } |
| 626 | 654 | ||
| 627 | enum class DrawMode { | ||
| 628 | Undefined, | ||
| 629 | General, | ||
| 630 | Instance, | ||
| 631 | }; | ||
| 632 | DrawMode draw_mode{DrawMode::Undefined}; | ||
| 633 | u32 method_count = static_cast<u32>(deferred_draw_method.size()); | 655 | u32 method_count = static_cast<u32>(deferred_draw_method.size()); |
| 634 | u32 method = deferred_draw_method[method_count - 1]; | 656 | u32 instance_count = 1; |
| 635 | if (MAXWELL3D_REG_INDEX(draw.end) != method) { | 657 | u32 vertex_buffer_count = 0; |
| 636 | return; | 658 | u32 index_buffer_count = 0; |
| 637 | } | 659 | for (u32 index = 0; index < method_count; ++index) { |
| 638 | draw_mode = (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Subsequent) || | 660 | u32 method = deferred_draw_method[index]; |
| 639 | (regs.draw.instance_id == Maxwell3D::Regs::Draw::InstanceId::Unchanged) | 661 | if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) { |
| 640 | ? DrawMode::Instance | 662 | instance_count = ++vertex_buffer_count; |
| 641 | : DrawMode::General; | 663 | } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) { |
| 642 | u32 instance_count = 0; | 664 | instance_count = ++index_buffer_count; |
| 643 | if (draw_mode == DrawMode::Instance) { | ||
| 644 | u32 vertex_buffer_count = 0; | ||
| 645 | u32 index_buffer_count = 0; | ||
| 646 | for (u32 index = 0; index < method_count; ++index) { | ||
| 647 | method = deferred_draw_method[index]; | ||
| 648 | if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) { | ||
| 649 | instance_count = ++vertex_buffer_count; | ||
| 650 | } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) { | ||
| 651 | instance_count = ++index_buffer_count; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | ASSERT_MSG(!(vertex_buffer_count && index_buffer_count), | ||
| 655 | "Instance both indexed and direct?"); | ||
| 656 | } else { | ||
| 657 | instance_count = 1; | ||
| 658 | for (u32 index = 0; index < method_count; ++index) { | ||
| 659 | method = deferred_draw_method[index]; | ||
| 660 | if (MAXWELL3D_REG_INDEX(draw_inline_index) == method || | ||
| 661 | MAXWELL3D_REG_INDEX(inline_index_2x16.even) == method || | ||
| 662 | MAXWELL3D_REG_INDEX(inline_index_4x8.index0) == method) { | ||
| 663 | regs.index_buffer.count = static_cast<u32>(inline_index_draw_indexes.size() / 4); | ||
| 664 | regs.index_buffer.format = Regs::IndexFormat::UnsignedInt; | ||
| 665 | break; | ||
| 666 | } | ||
| 667 | } | 665 | } |
| 668 | } | 666 | } |
| 667 | ASSERT_MSG(!(vertex_buffer_count && index_buffer_count), "Instance both indexed and direct?"); | ||
| 669 | 668 | ||
| 670 | ProcessDraw(instance_count); | 669 | ProcessDraw(instance_count); |
| 671 | 670 | ||
| 672 | deferred_draw_method.clear(); | 671 | deferred_draw_method.clear(); |
| 673 | inline_index_draw_indexes.clear(); | ||
| 674 | } | 672 | } |
| 675 | 673 | ||
| 676 | } // namespace Tegra::Engines | 674 | } // namespace Tegra::Engines |
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h index c3099f9a6..84c497ebd 100644 --- a/src/video_core/engines/maxwell_3d.h +++ b/src/video_core/engines/maxwell_3d.h | |||
| @@ -3148,10 +3148,12 @@ private: | |||
| 3148 | /// Handles use of topology overrides (e.g., to avoid using a topology assigned from a macro) | 3148 | /// Handles use of topology overrides (e.g., to avoid using a topology assigned from a macro) |
| 3149 | void ProcessTopologyOverride(); | 3149 | void ProcessTopologyOverride(); |
| 3150 | 3150 | ||
| 3151 | void ProcessDraw(u32 instance_count = 1); | 3151 | /// Handles deferred draw(e.g., instance draw). |
| 3152 | |||
| 3153 | void ProcessDeferredDraw(); | 3152 | void ProcessDeferredDraw(); |
| 3154 | 3153 | ||
| 3154 | /// Handles a draw. | ||
| 3155 | void ProcessDraw(u32 instance_count = 1); | ||
| 3156 | |||
| 3155 | /// Returns a query's value or an empty object if the value will be deferred through a cache. | 3157 | /// Returns a query's value or an empty object if the value will be deferred through a cache. |
| 3156 | std::optional<u64> GetQueryResult(); | 3158 | std::optional<u64> GetQueryResult(); |
| 3157 | 3159 | ||
| @@ -3178,6 +3180,8 @@ private: | |||
| 3178 | 3180 | ||
| 3179 | std::array<bool, Regs::NUM_REGS> draw_command{}; | 3181 | std::array<bool, Regs::NUM_REGS> draw_command{}; |
| 3180 | std::vector<u32> deferred_draw_method; | 3182 | std::vector<u32> deferred_draw_method; |
| 3183 | enum class DrawMode : u32 { General = 0, Instance, InlineIndex }; | ||
| 3184 | DrawMode draw_mode{DrawMode::General}; | ||
| 3181 | }; | 3185 | }; |
| 3182 | 3186 | ||
| 3183 | #define ASSERT_REG_POSITION(field_name, position) \ | 3187 | #define ASSERT_REG_POSITION(field_name, position) \ |