cc935d997b
The purpose of make_pair is generally to deduce the types within the pair without explicitly specifying the types, so these usages were generally unnecessary, particularly when the type is enforced by the array declaration.
113 lines
4.5 KiB
C++
113 lines
4.5 KiB
C++
// Copyright 2020 yuzu Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#include <array>
|
|
#include <vector>
|
|
#include "video_core/engines/maxwell_3d.h"
|
|
#include "video_core/macro/macro_hle.h"
|
|
#include "video_core/rasterizer_interface.h"
|
|
|
|
namespace Tegra {
|
|
|
|
namespace {
|
|
// HLE'd functions
|
|
static void HLE_771BB18C62444DA0(Engines::Maxwell3D& maxwell3d,
|
|
const std::vector<u32>& parameters) {
|
|
const u32 instance_count = parameters[2] & maxwell3d.GetRegisterValue(0xD1B);
|
|
|
|
maxwell3d.regs.draw.topology.Assign(
|
|
static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0] &
|
|
~(0x3ffffff << 26)));
|
|
maxwell3d.regs.vb_base_instance = parameters[5];
|
|
maxwell3d.mme_draw.instance_count = instance_count;
|
|
maxwell3d.regs.vb_element_base = parameters[3];
|
|
maxwell3d.regs.index_array.count = parameters[1];
|
|
maxwell3d.regs.index_array.first = parameters[4];
|
|
|
|
if (maxwell3d.ShouldExecute()) {
|
|
maxwell3d.GetRasterizer().Draw(true, true);
|
|
}
|
|
maxwell3d.regs.index_array.count = 0;
|
|
maxwell3d.mme_draw.instance_count = 0;
|
|
maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
|
|
}
|
|
|
|
static void HLE_0D61FC9FAAC9FCAD(Engines::Maxwell3D& maxwell3d,
|
|
const std::vector<u32>& parameters) {
|
|
const u32 count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
|
|
|
|
maxwell3d.regs.vertex_buffer.first = parameters[3];
|
|
maxwell3d.regs.vertex_buffer.count = parameters[1];
|
|
maxwell3d.regs.vb_base_instance = parameters[4];
|
|
maxwell3d.regs.draw.topology.Assign(
|
|
static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]));
|
|
maxwell3d.mme_draw.instance_count = count;
|
|
|
|
if (maxwell3d.ShouldExecute()) {
|
|
maxwell3d.GetRasterizer().Draw(false, true);
|
|
}
|
|
maxwell3d.regs.vertex_buffer.count = 0;
|
|
maxwell3d.mme_draw.instance_count = 0;
|
|
maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
|
|
}
|
|
|
|
static void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d,
|
|
const std::vector<u32>& parameters) {
|
|
const u32 instance_count = (maxwell3d.GetRegisterValue(0xD1B) & parameters[2]);
|
|
const u32 element_base = parameters[4];
|
|
const u32 base_instance = parameters[5];
|
|
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.regs.vb_element_base = element_base;
|
|
maxwell3d.regs.vb_base_instance = base_instance;
|
|
maxwell3d.mme_draw.instance_count = instance_count;
|
|
maxwell3d.CallMethodFromMME(0x8e3, 0x640);
|
|
maxwell3d.CallMethodFromMME(0x8e4, element_base);
|
|
maxwell3d.CallMethodFromMME(0x8e5, base_instance);
|
|
maxwell3d.regs.draw.topology.Assign(
|
|
static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[0]));
|
|
if (maxwell3d.ShouldExecute()) {
|
|
maxwell3d.GetRasterizer().Draw(true, true);
|
|
}
|
|
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;
|
|
}
|
|
} // namespace
|
|
|
|
constexpr std::array<std::pair<u64, HLEFunction>, 3> hle_funcs{{
|
|
{0x771BB18C62444DA0, &HLE_771BB18C62444DA0},
|
|
{0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD},
|
|
{0x0217920100488FF7, &HLE_0217920100488FF7},
|
|
}};
|
|
|
|
HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d) : maxwell3d(maxwell3d) {}
|
|
HLEMacro::~HLEMacro() = default;
|
|
|
|
std::optional<std::unique_ptr<CachedMacro>> HLEMacro::GetHLEProgram(u64 hash) const {
|
|
const auto it = std::find_if(hle_funcs.cbegin(), hle_funcs.cend(),
|
|
[hash](const auto& pair) { return pair.first == hash; });
|
|
if (it == hle_funcs.end()) {
|
|
return std::nullopt;
|
|
}
|
|
return std::make_unique<HLEMacroImpl>(maxwell3d, it->second);
|
|
}
|
|
|
|
HLEMacroImpl::~HLEMacroImpl() = default;
|
|
|
|
HLEMacroImpl::HLEMacroImpl(Engines::Maxwell3D& maxwell3d, HLEFunction func)
|
|
: maxwell3d(maxwell3d), func(func) {}
|
|
|
|
void HLEMacroImpl::Execute(const std::vector<u32>& parameters, u32 method) {
|
|
func(maxwell3d, parameters);
|
|
}
|
|
|
|
} // namespace Tegra
|