mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-30 10:42:47 +01:00
fix for nvdec disabled, cleanup host1x
This commit is contained in:
parent
2c27127d04
commit
06cef3355e
3 changed files with 23 additions and 72 deletions
|
@ -73,14 +73,15 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
|
||||||
offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset);
|
offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset);
|
||||||
offset = SpliceVectors(input, fences, params.fence_count, offset);
|
offset = SpliceVectors(input, fences, params.fence_count, offset);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
|
|
||||||
SyncptIncr syncpt_incr = syncpt_increments[i];
|
|
||||||
|
|
||||||
fences[i].id = syncpt_incr.id;
|
|
||||||
fences[i].value =
|
|
||||||
syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments);
|
|
||||||
}
|
|
||||||
auto& gpu = system.GPU();
|
auto& gpu = system.GPU();
|
||||||
|
if (gpu.UseNvdec()) {
|
||||||
|
for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
|
||||||
|
const SyncptIncr& syncpt_incr = syncpt_increments[i];
|
||||||
|
fences[i].id = syncpt_incr.id;
|
||||||
|
fences[i].value =
|
||||||
|
syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (const auto& cmd_buffer : command_buffers) {
|
for (const auto& cmd_buffer : command_buffers) {
|
||||||
auto object = nvmap_dev->GetObject(cmd_buffer.memory_id);
|
auto object = nvmap_dev->GetObject(cmd_buffer.memory_id);
|
||||||
ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
|
ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
|
||||||
|
@ -95,11 +96,13 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
|
||||||
cmdlist.size() * sizeof(u32));
|
cmdlist.size() * sizeof(u32));
|
||||||
gpu.PushCommandBuffer(cmdlist);
|
gpu.PushCommandBuffer(cmdlist);
|
||||||
}
|
}
|
||||||
fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1);
|
if (gpu.UseNvdec()) {
|
||||||
|
|
||||||
Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}};
|
fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1);
|
||||||
gpu.PushCommandBuffer(cmdlist);
|
|
||||||
|
|
||||||
|
Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}};
|
||||||
|
gpu.PushCommandBuffer(cmdlist);
|
||||||
|
}
|
||||||
std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit));
|
std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit));
|
||||||
// Some games expect command_buffers to be written back
|
// Some games expect command_buffers to be written back
|
||||||
offset = sizeof(IoctlSubmit);
|
offset = sizeof(IoctlSubmit);
|
||||||
|
@ -118,7 +121,7 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::ve
|
||||||
std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint));
|
std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint));
|
||||||
LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param);
|
LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param);
|
||||||
|
|
||||||
if (device_syncpoints[params.param] == 0) {
|
if (device_syncpoints[params.param] == 0 && system.GPU().UseNvdec()) {
|
||||||
device_syncpoints[params.param] = syncpoint_manager.AllocateSyncpoint();
|
device_syncpoints[params.param] = syncpoint_manager.AllocateSyncpoint();
|
||||||
}
|
}
|
||||||
params.value = device_syncpoints[params.param];
|
params.value = device_syncpoints[params.param];
|
||||||
|
|
|
@ -10,22 +10,14 @@ Tegra::Host1x::Host1x(GPU& gpu_) : gpu(gpu_) {}
|
||||||
|
|
||||||
Tegra::Host1x::~Host1x() = default;
|
Tegra::Host1x::~Host1x() = default;
|
||||||
|
|
||||||
void Tegra::Host1x::StateWrite(u32 offset, u32 arguments) {
|
void Tegra::Host1x::ProcessMethod(Method method, u32 argument) {
|
||||||
u8* const state_offset = reinterpret_cast<u8*>(&state) + offset * sizeof(u32);
|
|
||||||
std::memcpy(state_offset, &arguments, sizeof(u32));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Tegra::Host1x::ProcessMethod(Method method, const std::vector<u32>& arguments) {
|
|
||||||
StateWrite(static_cast<u32>(method), arguments[0]);
|
|
||||||
switch (method) {
|
switch (method) {
|
||||||
case Method::WaitSyncpt:
|
|
||||||
Execute(arguments[0]);
|
|
||||||
break;
|
|
||||||
case Method::LoadSyncptPayload32:
|
case Method::LoadSyncptPayload32:
|
||||||
syncpoint_value = arguments[0];
|
syncpoint_value = argument;
|
||||||
break;
|
break;
|
||||||
|
case Method::WaitSyncpt:
|
||||||
case Method::WaitSyncpt32:
|
case Method::WaitSyncpt32:
|
||||||
Execute(arguments[0]);
|
Execute(argument);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED_MSG("Host1x method 0x{:X}", static_cast<u32>(method));
|
UNIMPLEMENTED_MSG("Host1x method 0x{:X}", static_cast<u32>(method));
|
||||||
|
@ -34,8 +26,5 @@ void Tegra::Host1x::ProcessMethod(Method method, const std::vector<u32>& argumen
|
||||||
}
|
}
|
||||||
|
|
||||||
void Tegra::Host1x::Execute(u32 data) {
|
void Tegra::Host1x::Execute(u32 data) {
|
||||||
u32 syncpointId = (data & 0xFF);
|
gpu.WaitFence(data, syncpoint_value);
|
||||||
u32 threshold = state.load_syncpoint_payload32;
|
|
||||||
|
|
||||||
gpu.WaitFence(syncpointId, threshold);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,64 +14,23 @@ class Nvdec;
|
||||||
|
|
||||||
class Host1x {
|
class Host1x {
|
||||||
public:
|
public:
|
||||||
struct Host1xClassRegisters {
|
|
||||||
u32 incr_syncpt{};
|
|
||||||
u32 incr_syncpt_ctrl{};
|
|
||||||
u32 incr_syncpt_error{};
|
|
||||||
INSERT_PADDING_WORDS(5);
|
|
||||||
u32 wait_syncpt{};
|
|
||||||
u32 wait_syncpt_base{};
|
|
||||||
u32 wait_syncpt_incr{};
|
|
||||||
u32 load_syncpt_base{};
|
|
||||||
u32 incr_syncpt_base{};
|
|
||||||
u32 clear{};
|
|
||||||
u32 wait{};
|
|
||||||
u32 wait_with_interrupt{};
|
|
||||||
u32 delay_use{};
|
|
||||||
u32 tick_count_high{};
|
|
||||||
u32 tick_count_low{};
|
|
||||||
u32 tick_ctrl{};
|
|
||||||
INSERT_PADDING_WORDS(23);
|
|
||||||
u32 ind_ctrl{};
|
|
||||||
u32 ind_off2{};
|
|
||||||
u32 ind_off{};
|
|
||||||
std::array<u32, 31> ind_data{};
|
|
||||||
INSERT_PADDING_WORDS(1);
|
|
||||||
u32 load_syncpoint_payload32{};
|
|
||||||
u32 stall_ctrl{};
|
|
||||||
u32 wait_syncpt32{};
|
|
||||||
u32 wait_syncpt_base32{};
|
|
||||||
u32 load_syncpt_base32{};
|
|
||||||
u32 incr_syncpt_base32{};
|
|
||||||
u32 stall_count_high{};
|
|
||||||
u32 stall_count_low{};
|
|
||||||
u32 xref_ctrl{};
|
|
||||||
u32 channel_xref_high{};
|
|
||||||
u32 channel_xref_low{};
|
|
||||||
};
|
|
||||||
static_assert(sizeof(Host1xClassRegisters) == 0x164, "Host1xClassRegisters is an invalid size");
|
|
||||||
|
|
||||||
enum class Method : u32 {
|
enum class Method : u32 {
|
||||||
WaitSyncpt = offsetof(Host1xClassRegisters, wait_syncpt) / 4,
|
WaitSyncpt = 0x8,
|
||||||
LoadSyncptPayload32 = offsetof(Host1xClassRegisters, load_syncpoint_payload32) / 4,
|
LoadSyncptPayload32 = 0x4e,
|
||||||
WaitSyncpt32 = offsetof(Host1xClassRegisters, wait_syncpt32) / 4,
|
WaitSyncpt32 = 0x50,
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit Host1x(GPU& gpu);
|
explicit Host1x(GPU& gpu);
|
||||||
~Host1x();
|
~Host1x();
|
||||||
|
|
||||||
/// Writes the method into the state, Invoke Execute() if encountered
|
/// Writes the method into the state, Invoke Execute() if encountered
|
||||||
void ProcessMethod(Method method, const std::vector<u32>& arguments);
|
void ProcessMethod(Method method, u32 argument);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// For Host1x, execute is waiting on a syncpoint previously written into the state
|
/// For Host1x, execute is waiting on a syncpoint previously written into the state
|
||||||
void Execute(u32 data);
|
void Execute(u32 data);
|
||||||
|
|
||||||
/// Write argument into the provided offset
|
|
||||||
void StateWrite(u32 offset, u32 arguments);
|
|
||||||
|
|
||||||
u32 syncpoint_value{};
|
u32 syncpoint_value{};
|
||||||
Host1xClassRegisters state{};
|
|
||||||
GPU& gpu;
|
GPU& gpu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue