diff options
| author | 2019-06-07 12:56:30 -0400 | |
|---|---|---|
| committer | 2019-07-05 15:49:11 -0400 | |
| commit | 82b829625b89a706dd0d867c529f533fe928710c (patch) | |
| tree | 1d5e4bfcde8843e377ae51e3f0741b9abaa1a26a /src/core | |
| parent | nv_services: Correct buffer queue fencing and GPFifo fencing (diff) | |
| download | yuzu-82b829625b89a706dd0d867c529f533fe928710c.tar.gz yuzu-82b829625b89a706dd0d867c529f533fe928710c.tar.xz yuzu-82b829625b89a706dd0d867c529f533fe928710c.zip | |
video_core: Implement GPU side Syncpoints
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | 30 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/devices/nvhost_gpu.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/nvdata.h | 2 |
3 files changed, 33 insertions, 7 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index 8a53eddb1..9d1107594 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp | |||
| @@ -143,7 +143,7 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp | |||
| 143 | IoctlSubmitGpfifo params{}; | 143 | IoctlSubmitGpfifo params{}; |
| 144 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); | 144 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); |
| 145 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", | 145 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", |
| 146 | params.address, params.num_entries, params.flags); | 146 | params.address, params.num_entries, params.flags.raw); |
| 147 | 147 | ||
| 148 | ASSERT_MSG(input.size() == sizeof(IoctlSubmitGpfifo) + | 148 | ASSERT_MSG(input.size() == sizeof(IoctlSubmitGpfifo) + |
| 149 | params.num_entries * sizeof(Tegra::CommandListHeader), | 149 | params.num_entries * sizeof(Tegra::CommandListHeader), |
| @@ -153,7 +153,17 @@ u32 nvhost_gpu::SubmitGPFIFO(const std::vector<u8>& input, std::vector<u8>& outp | |||
| 153 | std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], | 153 | std::memcpy(entries.data(), &input[sizeof(IoctlSubmitGpfifo)], |
| 154 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 154 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 155 | 155 | ||
| 156 | Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); | 156 | UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0); |
| 157 | UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); | ||
| 158 | |||
| 159 | auto& gpu = Core::System::GetInstance().GPU(); | ||
| 160 | u32 current_syncpoint_value = gpu.GetSyncpointValue(params.fence_out.id); | ||
| 161 | if (params.flags.increment.Value()) { | ||
| 162 | params.fence_out.value += current_syncpoint_value; | ||
| 163 | } else { | ||
| 164 | params.fence_out.value = current_syncpoint_value; | ||
| 165 | } | ||
| 166 | gpu.PushGPUEntries(std::move(entries)); | ||
| 157 | 167 | ||
| 158 | // TODO(Blinkhawk): Figure how thoios fence is set | 168 | // TODO(Blinkhawk): Figure how thoios fence is set |
| 159 | // params.fence_out.value = 0; | 169 | // params.fence_out.value = 0; |
| @@ -168,16 +178,24 @@ u32 nvhost_gpu::KickoffPB(const std::vector<u8>& input, std::vector<u8>& output) | |||
| 168 | IoctlSubmitGpfifo params{}; | 178 | IoctlSubmitGpfifo params{}; |
| 169 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); | 179 | std::memcpy(¶ms, input.data(), sizeof(IoctlSubmitGpfifo)); |
| 170 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", | 180 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, gpfifo={:X}, num_entries={:X}, flags={:X}", |
| 171 | params.address, params.num_entries, params.flags); | 181 | params.address, params.num_entries, params.flags.raw); |
| 172 | 182 | ||
| 173 | Tegra::CommandList entries(params.num_entries); | 183 | Tegra::CommandList entries(params.num_entries); |
| 174 | Memory::ReadBlock(params.address, entries.data(), | 184 | Memory::ReadBlock(params.address, entries.data(), |
| 175 | params.num_entries * sizeof(Tegra::CommandListHeader)); | 185 | params.num_entries * sizeof(Tegra::CommandListHeader)); |
| 176 | 186 | ||
| 177 | Core::System::GetInstance().GPU().PushGPUEntries(std::move(entries)); | 187 | UNIMPLEMENTED_IF(params.flags.add_wait.Value() != 0); |
| 188 | UNIMPLEMENTED_IF(params.flags.add_increment.Value() != 0); | ||
| 189 | |||
| 190 | auto& gpu = Core::System::GetInstance().GPU(); | ||
| 191 | u32 current_syncpoint_value = gpu.GetSyncpointValue(params.fence_out.id); | ||
| 192 | if (params.flags.increment.Value()) { | ||
| 193 | params.fence_out.value += current_syncpoint_value; | ||
| 194 | } else { | ||
| 195 | params.fence_out.value = current_syncpoint_value; | ||
| 196 | } | ||
| 197 | gpu.PushGPUEntries(std::move(entries)); | ||
| 178 | 198 | ||
| 179 | // TODO(Blinkhawk): Figure how thoios fence is set | ||
| 180 | // params.fence_out.value = 0; | ||
| 181 | std::memcpy(output.data(), ¶ms, output.size()); | 199 | std::memcpy(output.data(), ¶ms, output.size()); |
| 182 | return 0; | 200 | return 0; |
| 183 | } | 201 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index d95cedb09..0729eeb8d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h | |||
| @@ -153,7 +153,13 @@ private: | |||
| 153 | struct IoctlSubmitGpfifo { | 153 | struct IoctlSubmitGpfifo { |
| 154 | u64_le address; // pointer to gpfifo entry structs | 154 | u64_le address; // pointer to gpfifo entry structs |
| 155 | u32_le num_entries; // number of fence objects being submitted | 155 | u32_le num_entries; // number of fence objects being submitted |
| 156 | u32_le flags; | 156 | union { |
| 157 | u32_le raw; | ||
| 158 | BitField<0, 1, u32_le> add_wait; // append a wait sync_point to the list | ||
| 159 | BitField<1, 1, u32_le> add_increment; // append an increment to the list | ||
| 160 | BitField<2, 1, u32_le> new_hw_format; // Mostly ignored | ||
| 161 | BitField<8, 1, u32_le> increment; // increment the returned fence | ||
| 162 | } flags; | ||
| 157 | Fence fence_out; // returned new fence object for others to wait on | 163 | Fence fence_out; // returned new fence object for others to wait on |
| 158 | }; | 164 | }; |
| 159 | static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(Fence), | 165 | static_assert(sizeof(IoctlSubmitGpfifo) == 16 + sizeof(Fence), |
diff --git a/src/core/hle/service/nvdrv/nvdata.h b/src/core/hle/service/nvdrv/nvdata.h index 7e1dce232..fd5f79f36 100644 --- a/src/core/hle/service/nvdrv/nvdata.h +++ b/src/core/hle/service/nvdrv/nvdata.h | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | 5 | ||
| 6 | namespace Service::Nvidia { | 6 | namespace Service::Nvidia { |
| 7 | 7 | ||
| 8 | constexpr u32 MaxSyncPoints = 192; | ||
| 9 | |||
| 8 | struct Fence { | 10 | struct Fence { |
| 9 | s32 id; | 11 | s32 id; |
| 10 | u32 value; | 12 | u32 value; |