diff options
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | 25 | ||||
| -rw-r--r-- | src/video_core/command_classes/host1x.cpp | 21 | ||||
| -rw-r--r-- | src/video_core/command_classes/host1x.h | 49 |
3 files changed, 23 insertions, 72 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index 64370ad4c..4898dc27a 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp | |||
| @@ -73,14 +73,15 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 73 | offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset); | 73 | offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset); |
| 74 | offset = SpliceVectors(input, fences, params.fence_count, offset); | 74 | offset = SpliceVectors(input, fences, params.fence_count, offset); |
| 75 | 75 | ||
| 76 | for (std::size_t i = 0; i < syncpt_increments.size(); i++) { | ||
| 77 | SyncptIncr syncpt_incr = syncpt_increments[i]; | ||
| 78 | |||
| 79 | fences[i].id = syncpt_incr.id; | ||
| 80 | fences[i].value = | ||
| 81 | syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments); | ||
| 82 | } | ||
| 83 | auto& gpu = system.GPU(); | 76 | auto& gpu = system.GPU(); |
| 77 | if (gpu.UseNvdec()) { | ||
| 78 | for (std::size_t i = 0; i < syncpt_increments.size(); i++) { | ||
| 79 | const SyncptIncr& syncpt_incr = syncpt_increments[i]; | ||
| 80 | fences[i].id = syncpt_incr.id; | ||
| 81 | fences[i].value = | ||
| 82 | syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments); | ||
| 83 | } | ||
| 84 | } | ||
| 84 | for (const auto& cmd_buffer : command_buffers) { | 85 | for (const auto& cmd_buffer : command_buffers) { |
| 85 | auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); | 86 | auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); |
| 86 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); | 87 | ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); |
| @@ -95,11 +96,13 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u | |||
| 95 | cmdlist.size() * sizeof(u32)); | 96 | cmdlist.size() * sizeof(u32)); |
| 96 | gpu.PushCommandBuffer(cmdlist); | 97 | gpu.PushCommandBuffer(cmdlist); |
| 97 | } | 98 | } |
| 98 | fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1); | 99 | if (gpu.UseNvdec()) { |
| 99 | 100 | ||
| 100 | Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}}; | 101 | fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1); |
| 101 | gpu.PushCommandBuffer(cmdlist); | ||
| 102 | 102 | ||
| 103 | Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}}; | ||
| 104 | gpu.PushCommandBuffer(cmdlist); | ||
| 105 | } | ||
| 103 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); | 106 | std::memcpy(output.data(), ¶ms, sizeof(IoctlSubmit)); |
| 104 | // Some games expect command_buffers to be written back | 107 | // Some games expect command_buffers to be written back |
| 105 | offset = sizeof(IoctlSubmit); | 108 | offset = sizeof(IoctlSubmit); |
| @@ -118,7 +121,7 @@ NvResult nvhost_nvdec_common::GetSyncpoint(const std::vector<u8>& input, std::ve | |||
| 118 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); | 121 | std::memcpy(¶ms, input.data(), sizeof(IoctlGetSyncpoint)); |
| 119 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); | 122 | LOG_DEBUG(Service_NVDRV, "called GetSyncpoint, id={}", params.param); |
| 120 | 123 | ||
| 121 | if (device_syncpoints[params.param] == 0) { | 124 | if (device_syncpoints[params.param] == 0 && system.GPU().UseNvdec()) { |
| 122 | device_syncpoints[params.param] = syncpoint_manager.AllocateSyncpoint(); | 125 | device_syncpoints[params.param] = syncpoint_manager.AllocateSyncpoint(); |
| 123 | } | 126 | } |
| 124 | params.value = device_syncpoints[params.param]; | 127 | params.value = device_syncpoints[params.param]; |
diff --git a/src/video_core/command_classes/host1x.cpp b/src/video_core/command_classes/host1x.cpp index 9d0a1b4d9..b12494528 100644 --- a/src/video_core/command_classes/host1x.cpp +++ b/src/video_core/command_classes/host1x.cpp | |||
| @@ -10,22 +10,14 @@ Tegra::Host1x::Host1x(GPU& gpu_) : gpu(gpu_) {} | |||
| 10 | 10 | ||
| 11 | Tegra::Host1x::~Host1x() = default; | 11 | Tegra::Host1x::~Host1x() = default; |
| 12 | 12 | ||
| 13 | void Tegra::Host1x::StateWrite(u32 offset, u32 arguments) { | 13 | void Tegra::Host1x::ProcessMethod(Method method, u32 argument) { |
| 14 | u8* const state_offset = reinterpret_cast<u8*>(&state) + offset * sizeof(u32); | ||
| 15 | std::memcpy(state_offset, &arguments, sizeof(u32)); | ||
| 16 | } | ||
| 17 | |||
| 18 | void Tegra::Host1x::ProcessMethod(Method method, const std::vector<u32>& arguments) { | ||
| 19 | StateWrite(static_cast<u32>(method), arguments[0]); | ||
| 20 | switch (method) { | 14 | switch (method) { |
| 21 | case Method::WaitSyncpt: | ||
| 22 | Execute(arguments[0]); | ||
| 23 | break; | ||
| 24 | case Method::LoadSyncptPayload32: | 15 | case Method::LoadSyncptPayload32: |
| 25 | syncpoint_value = arguments[0]; | 16 | syncpoint_value = argument; |
| 26 | break; | 17 | break; |
| 18 | case Method::WaitSyncpt: | ||
| 27 | case Method::WaitSyncpt32: | 19 | case Method::WaitSyncpt32: |
| 28 | Execute(arguments[0]); | 20 | Execute(argument); |
| 29 | break; | 21 | break; |
| 30 | default: | 22 | default: |
| 31 | UNIMPLEMENTED_MSG("Host1x method 0x{:X}", static_cast<u32>(method)); | 23 | 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 | |||
| 34 | } | 26 | } |
| 35 | 27 | ||
| 36 | void Tegra::Host1x::Execute(u32 data) { | 28 | void Tegra::Host1x::Execute(u32 data) { |
| 37 | u32 syncpointId = (data & 0xFF); | 29 | gpu.WaitFence(data, syncpoint_value); |
| 38 | u32 threshold = state.load_syncpoint_payload32; | ||
| 39 | |||
| 40 | gpu.WaitFence(syncpointId, threshold); | ||
| 41 | } | 30 | } |
diff --git a/src/video_core/command_classes/host1x.h b/src/video_core/command_classes/host1x.h index 013eaa0c1..7e94799dd 100644 --- a/src/video_core/command_classes/host1x.h +++ b/src/video_core/command_classes/host1x.h | |||
| @@ -14,64 +14,23 @@ class Nvdec; | |||
| 14 | 14 | ||
| 15 | class Host1x { | 15 | class Host1x { |
| 16 | public: | 16 | public: |
| 17 | struct Host1xClassRegisters { | ||
| 18 | u32 incr_syncpt{}; | ||
| 19 | u32 incr_syncpt_ctrl{}; | ||
| 20 | u32 incr_syncpt_error{}; | ||
| 21 | INSERT_PADDING_WORDS(5); | ||
| 22 | u32 wait_syncpt{}; | ||
| 23 | u32 wait_syncpt_base{}; | ||
| 24 | u32 wait_syncpt_incr{}; | ||
| 25 | u32 load_syncpt_base{}; | ||
| 26 | u32 incr_syncpt_base{}; | ||
| 27 | u32 clear{}; | ||
| 28 | u32 wait{}; | ||
| 29 | u32 wait_with_interrupt{}; | ||
| 30 | u32 delay_use{}; | ||
| 31 | u32 tick_count_high{}; | ||
| 32 | u32 tick_count_low{}; | ||
| 33 | u32 tick_ctrl{}; | ||
| 34 | INSERT_PADDING_WORDS(23); | ||
| 35 | u32 ind_ctrl{}; | ||
| 36 | u32 ind_off2{}; | ||
| 37 | u32 ind_off{}; | ||
| 38 | std::array<u32, 31> ind_data{}; | ||
| 39 | INSERT_PADDING_WORDS(1); | ||
| 40 | u32 load_syncpoint_payload32{}; | ||
| 41 | u32 stall_ctrl{}; | ||
| 42 | u32 wait_syncpt32{}; | ||
| 43 | u32 wait_syncpt_base32{}; | ||
| 44 | u32 load_syncpt_base32{}; | ||
| 45 | u32 incr_syncpt_base32{}; | ||
| 46 | u32 stall_count_high{}; | ||
| 47 | u32 stall_count_low{}; | ||
| 48 | u32 xref_ctrl{}; | ||
| 49 | u32 channel_xref_high{}; | ||
| 50 | u32 channel_xref_low{}; | ||
| 51 | }; | ||
| 52 | static_assert(sizeof(Host1xClassRegisters) == 0x164, "Host1xClassRegisters is an invalid size"); | ||
| 53 | |||
| 54 | enum class Method : u32 { | 17 | enum class Method : u32 { |
| 55 | WaitSyncpt = offsetof(Host1xClassRegisters, wait_syncpt) / 4, | 18 | WaitSyncpt = 0x8, |
| 56 | LoadSyncptPayload32 = offsetof(Host1xClassRegisters, load_syncpoint_payload32) / 4, | 19 | LoadSyncptPayload32 = 0x4e, |
| 57 | WaitSyncpt32 = offsetof(Host1xClassRegisters, wait_syncpt32) / 4, | 20 | WaitSyncpt32 = 0x50, |
| 58 | }; | 21 | }; |
| 59 | 22 | ||
| 60 | explicit Host1x(GPU& gpu); | 23 | explicit Host1x(GPU& gpu); |
| 61 | ~Host1x(); | 24 | ~Host1x(); |
| 62 | 25 | ||
| 63 | /// Writes the method into the state, Invoke Execute() if encountered | 26 | /// Writes the method into the state, Invoke Execute() if encountered |
| 64 | void ProcessMethod(Method method, const std::vector<u32>& arguments); | 27 | void ProcessMethod(Method method, u32 argument); |
| 65 | 28 | ||
| 66 | private: | 29 | private: |
| 67 | /// For Host1x, execute is waiting on a syncpoint previously written into the state | 30 | /// For Host1x, execute is waiting on a syncpoint previously written into the state |
| 68 | void Execute(u32 data); | 31 | void Execute(u32 data); |
| 69 | 32 | ||
| 70 | /// Write argument into the provided offset | ||
| 71 | void StateWrite(u32 offset, u32 arguments); | ||
| 72 | |||
| 73 | u32 syncpoint_value{}; | 33 | u32 syncpoint_value{}; |
| 74 | Host1xClassRegisters state{}; | ||
| 75 | GPU& gpu; | 34 | GPU& gpu; |
| 76 | }; | 35 | }; |
| 77 | 36 | ||