diff options
author | Fernando Sahmkow <fsahmkow27@gmail.com> | 2022-02-09 15:00:05 +0100 |
---|---|---|
committer | Fernando Sahmkow <fsahmkow27@gmail.com> | 2023-01-01 22:43:57 +0100 |
commit | a5a94f52ffcbf3119d272a9369021a213ea6dad2 (patch) | |
tree | ba6d42b142894d0f3f0ac34fb6ce491442bae8fd /src/video_core/macro | |
parent | Merge pull request #9538 from merryhime/char-concat (diff) | |
download | yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar.gz yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar.bz2 yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar.lz yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar.xz yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.tar.zst yuzu-a5a94f52ffcbf3119d272a9369021a213ea6dad2.zip |
Diffstat (limited to 'src/video_core/macro')
-rw-r--r-- | src/video_core/macro/macro_hle.cpp | 53 |
1 files changed, 27 insertions, 26 deletions
diff --git a/src/video_core/macro/macro_hle.cpp b/src/video_core/macro/macro_hle.cpp index 8549db2e4..1cc202cc7 100644 --- a/src/video_core/macro/macro_hle.cpp +++ b/src/video_core/macro/macro_hle.cpp @@ -53,42 +53,43 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& // Multidraw Indirect void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) { - SCOPE_EXIT({ - // Clean everything. - maxwell3d.regs.vertex_id_base = 0x0; - maxwell3d.CallMethod(0x8e3, 0x640, true); - maxwell3d.CallMethod(0x8e4, 0x0, true); - maxwell3d.CallMethod(0x8e5, 0x0, true); - maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - }); const u32 start_indirect = parameters[0]; const u32 end_indirect = parameters[1]; if (start_indirect >= end_indirect) { // Nothing to do. return; } - const u32 padding = parameters[3]; - const std::size_t max_draws = parameters[4]; + const auto topology = + static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]); + const u32 padding = parameters[3]; // padding is in words + // size of each indirect segment const u32 indirect_words = 5 + padding; - const std::size_t first_draw = start_indirect; - const std::size_t effective_draws = end_indirect - start_indirect; - const std::size_t last_draw = start_indirect + std::min(effective_draws, max_draws); - - for (std::size_t index = first_draw; index < last_draw; index++) { + const u32 stride = indirect_words * sizeof(u32); + const GPUVAddr start_address = maxwell3d.current_dma_segment + 4 * sizeof(u32); + const std::size_t draw_count = end_indirect - start_indirect; + u32 lowest_first = std::numeric_limits<u32>::max(); + u32 highest_limit = std::numeric_limits<u32>::min(); + for (std::size_t index = 0; index < draw_count; index++) { const std::size_t base = index * indirect_words + 5; - const u32 base_vertex = parameters[base + 3]; - const u32 base_instance = parameters[base + 4]; - maxwell3d.regs.vertex_id_base = base_vertex; - maxwell3d.CallMethod(0x8e3, 0x640, true); - maxwell3d.CallMethod(0x8e4, base_vertex, true); - maxwell3d.CallMethod(0x8e5, base_instance, true); - maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; - maxwell3d.draw_manager->DrawIndex( - static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]), - parameters[base + 2], parameters[base], base_vertex, base_instance, - parameters[base + 1]); + const u32 count = parameters[base]; + const u32 first_index = parameters[base + 2]; + lowest_first = std::min(lowest_first, first_index); + highest_limit = std::max(highest_limit, first_index + count); } + + const u32 base_vertex = parameters[8]; + const u32 base_instance = parameters[9]; + maxwell3d.CallMethod(0x8e3, 0x640, true); + maxwell3d.CallMethod(0x8e4, base_vertex, true); + maxwell3d.CallMethod(0x8e5, base_instance, true); + auto& params = maxwell3d.draw_manager->GetIndirectParams(); + params.start_address = start_address; + params.buffer_size = sizeof(u32) + stride * draw_count; + params.max_draw_counts = draw_count; + params.stride = stride; + maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true; + maxwell3d.draw_manager->DrawIndexedIndirect(topology, 0, highest_limit); } // Multi-layer Clear |