mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-11-03 20:24:43 +01:00 
			
		
		
		
	MacroHLE: Add MultidrawIndirect HLE Macro.
This commit is contained in:
		
							parent
							
								
									d9e375acc3
								
							
						
					
					
						commit
						a60b669ef4
					
				@ -3,6 +3,8 @@
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include "common/scope_exit.h"
 | 
			
		||||
#include "video_core/dirty_flags.h"
 | 
			
		||||
#include "video_core/engines/maxwell_3d.h"
 | 
			
		||||
#include "video_core/macro/macro.h"
 | 
			
		||||
#include "video_core/macro/macro_hle.h"
 | 
			
		||||
@ -58,6 +60,7 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
 | 
			
		||||
    maxwell3d.regs.index_array.first = parameters[3];
 | 
			
		||||
    maxwell3d.regs.reg_array[0x446] = element_base; // vertex id base?
 | 
			
		||||
    maxwell3d.regs.index_array.count = parameters[1];
 | 
			
		||||
    maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
 | 
			
		||||
    maxwell3d.regs.vb_element_base = element_base;
 | 
			
		||||
    maxwell3d.regs.vb_base_instance = base_instance;
 | 
			
		||||
    maxwell3d.mme_draw.instance_count = instance_count;
 | 
			
		||||
@ -80,10 +83,67 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
 | 
			
		||||
    maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr std::array<std::pair<u64, HLEFunction>, 3> hle_funcs{{
 | 
			
		||||
// Multidraw Indirect
 | 
			
		||||
void HLE_3F5E74B9C9A50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
 | 
			
		||||
    SCOPE_EXIT({
 | 
			
		||||
        // Clean everything.
 | 
			
		||||
        maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base?
 | 
			
		||||
        maxwell3d.regs.index_array.count = 0;
 | 
			
		||||
        maxwell3d.regs.vb_element_base = 0x0;
 | 
			
		||||
        maxwell3d.regs.vb_base_instance = 0x0;
 | 
			
		||||
        maxwell3d.mme_draw.instance_count = 0;
 | 
			
		||||
        maxwell3d.CallMethodFromMME(0x8e3, 0x640);
 | 
			
		||||
        maxwell3d.CallMethodFromMME(0x8e4, 0x0);
 | 
			
		||||
        maxwell3d.CallMethodFromMME(0x8e5, 0x0);
 | 
			
		||||
        maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
 | 
			
		||||
        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 auto topology =
 | 
			
		||||
        static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
 | 
			
		||||
    maxwell3d.regs.draw.topology.Assign(topology);
 | 
			
		||||
    const u32 padding = parameters[3];
 | 
			
		||||
    const std::size_t max_draws = parameters[4];
 | 
			
		||||
 | 
			
		||||
    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 std::size_t base = index * indirect_words + 5;
 | 
			
		||||
        const u32 num_vertices = parameters[base];
 | 
			
		||||
        const u32 instance_count = parameters[base + 1];
 | 
			
		||||
        const u32 first_index = parameters[base + 2];
 | 
			
		||||
        const u32 base_vertex = parameters[base + 3];
 | 
			
		||||
        const u32 base_instance = parameters[base + 4];
 | 
			
		||||
        maxwell3d.regs.index_array.first = first_index;
 | 
			
		||||
        maxwell3d.regs.reg_array[0x446] = base_vertex;
 | 
			
		||||
        maxwell3d.regs.index_array.count = num_vertices;
 | 
			
		||||
        maxwell3d.regs.vb_element_base = base_vertex;
 | 
			
		||||
        maxwell3d.regs.vb_base_instance = base_instance;
 | 
			
		||||
        maxwell3d.mme_draw.instance_count = instance_count;
 | 
			
		||||
        maxwell3d.CallMethodFromMME(0x8e3, 0x640);
 | 
			
		||||
        maxwell3d.CallMethodFromMME(0x8e4, base_vertex);
 | 
			
		||||
        maxwell3d.CallMethodFromMME(0x8e5, base_instance);
 | 
			
		||||
        maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
 | 
			
		||||
        if (maxwell3d.ShouldExecute()) {
 | 
			
		||||
            maxwell3d.Rasterizer().Draw(true, true);
 | 
			
		||||
        }
 | 
			
		||||
        maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
constexpr std::array<std::pair<u64, HLEFunction>, 4> hle_funcs{{
 | 
			
		||||
    {0x771BB18C62444DA0, &HLE_771BB18C62444DA0},
 | 
			
		||||
    {0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD},
 | 
			
		||||
    {0x0217920100488FF7, &HLE_0217920100488FF7},
 | 
			
		||||
    {0x3F5E74B9C9A50164, &HLE_3F5E74B9C9A50164},
 | 
			
		||||
}};
 | 
			
		||||
 | 
			
		||||
class HLEMacroImpl final : public CachedMacro {
 | 
			
		||||
@ -99,6 +159,7 @@ private:
 | 
			
		||||
    Engines::Maxwell3D& maxwell3d;
 | 
			
		||||
    HLEFunction func;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // Anonymous namespace
 | 
			
		||||
 | 
			
		||||
HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user