summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp13
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp5
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.cpp10
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_vic.h3
-rw-r--r--src/video_core/gpu.cpp44
-rw-r--r--src/video_core/gpu.h4
8 files changed, 45 insertions, 40 deletions
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index 0d7d4ad03..8314d1ec2 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -20,8 +20,12 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
20 switch (command.group) { 20 switch (command.group) {
21 case 0x0: 21 case 0x0:
22 switch (command.cmd) { 22 switch (command.cmd) {
23 case 0x1: 23 case 0x1: {
24 return Submit(input, output); 24 if (!fd_to_id.contains(fd)) {
25 fd_to_id[fd] = next_id++;
26 }
27 return Submit(fd, input, output);
28 }
25 case 0x2: 29 case 0x2:
26 return GetSyncpoint(input, output); 30 return GetSyncpoint(input, output);
27 case 0x3: 31 case 0x3:
@@ -66,7 +70,10 @@ void nvhost_nvdec::OnOpen(DeviceFD fd) {}
66 70
67void nvhost_nvdec::OnClose(DeviceFD fd) { 71void nvhost_nvdec::OnClose(DeviceFD fd) {
68 LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); 72 LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
69 system.GPU().ClearCdmaInstance(); 73 const auto iter = fd_to_id.find(fd);
74 if (iter != fd_to_id.end()) {
75 system.GPU().ClearCdmaInstance(iter->second);
76 }
70} 77}
71 78
72} // namespace Service::Nvidia::Devices 79} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
index 523d96e3a..a507c4d0a 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.h
@@ -24,6 +24,9 @@ public:
24 24
25 void OnOpen(DeviceFD fd) override; 25 void OnOpen(DeviceFD fd) override;
26 void OnClose(DeviceFD fd) override; 26 void OnClose(DeviceFD fd) override;
27
28private:
29 u32 next_id{};
27}; 30};
28 31
29} // namespace Service::Nvidia::Devices 32} // namespace Service::Nvidia::Devices
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 e61261f98..8a05f0668 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -59,7 +59,8 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) {
59 return NvResult::Success; 59 return NvResult::Success;
60} 60}
61 61
62NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u8>& output) { 62NvResult nvhost_nvdec_common::Submit(DeviceFD fd, const std::vector<u8>& input,
63 std::vector<u8>& output) {
63 IoctlSubmit params{}; 64 IoctlSubmit params{};
64 std::memcpy(&params, input.data(), sizeof(IoctlSubmit)); 65 std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
65 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); 66 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count);
@@ -93,7 +94,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
93 Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); 94 Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
94 system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(), 95 system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(),
95 cmdlist.size() * sizeof(u32)); 96 cmdlist.size() * sizeof(u32));
96 gpu.PushCommandBuffer(cmdlist); 97 gpu.PushCommandBuffer(fd_to_id[fd], cmdlist);
97 } 98 }
98 std::memcpy(output.data(), &params, sizeof(IoctlSubmit)); 99 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
99 // Some games expect command_buffers to be written back 100 // Some games expect command_buffers to be written back
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index 351625c17..e28c54df6 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -104,13 +104,14 @@ protected:
104 104
105 /// Ioctl command implementations 105 /// Ioctl command implementations
106 NvResult SetNVMAPfd(const std::vector<u8>& input); 106 NvResult SetNVMAPfd(const std::vector<u8>& input);
107 NvResult Submit(const std::vector<u8>& input, std::vector<u8>& output); 107 NvResult Submit(DeviceFD fd, const std::vector<u8>& input, std::vector<u8>& output);
108 NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); 108 NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
109 NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); 109 NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
110 NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); 110 NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
111 NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output); 111 NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
112 NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output); 112 NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output);
113 113
114 std::unordered_map<DeviceFD, u32> fd_to_id{};
114 s32_le nvmap_fd{}; 115 s32_le nvmap_fd{};
115 u32_le submit_timeout{}; 116 u32_le submit_timeout{};
116 std::shared_ptr<nvmap> nvmap_dev; 117 std::shared_ptr<nvmap> nvmap_dev;
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
index eac4dd530..76b39806f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.cpp
@@ -21,7 +21,10 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i
21 case 0x0: 21 case 0x0:
22 switch (command.cmd) { 22 switch (command.cmd) {
23 case 0x1: 23 case 0x1:
24 return Submit(input, output); 24 if (!fd_to_id.contains(fd)) {
25 fd_to_id[fd] = next_id++;
26 }
27 return Submit(fd, input, output);
25 case 0x2: 28 case 0x2:
26 return GetSyncpoint(input, output); 29 return GetSyncpoint(input, output);
27 case 0x3: 30 case 0x3:
@@ -65,7 +68,10 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i
65void nvhost_vic::OnOpen(DeviceFD fd) {} 68void nvhost_vic::OnOpen(DeviceFD fd) {}
66 69
67void nvhost_vic::OnClose(DeviceFD fd) { 70void nvhost_vic::OnClose(DeviceFD fd) {
68 system.GPU().ClearCdmaInstance(); 71 const auto iter = fd_to_id.find(fd);
72 if (iter != fd_to_id.end()) {
73 system.GPU().ClearCdmaInstance(iter->second);
74 }
69} 75}
70 76
71} // namespace Service::Nvidia::Devices 77} // namespace Service::Nvidia::Devices
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_vic.h b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
index 6d7fda9d1..c9732c037 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_vic.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_vic.h
@@ -23,5 +23,8 @@ public:
23 23
24 void OnOpen(DeviceFD fd) override; 24 void OnOpen(DeviceFD fd) override;
25 void OnClose(DeviceFD fd) override; 25 void OnClose(DeviceFD fd) override;
26
27private:
28 u32 next_id{};
26}; 29};
27} // namespace Service::Nvidia::Devices 30} // namespace Service::Nvidia::Devices
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index ab7c21a49..8788f5148 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -185,16 +185,6 @@ struct GPU::Impl {
185 return *dma_pusher; 185 return *dma_pusher;
186 } 186 }
187 187
188 /// Returns a reference to the GPU CDMA pusher.
189 [[nodiscard]] Tegra::CDmaPusher& CDmaPusher() {
190 return *cdma_pusher;
191 }
192
193 /// Returns a const reference to the GPU CDMA pusher.
194 [[nodiscard]] const Tegra::CDmaPusher& CDmaPusher() const {
195 return *cdma_pusher;
196 }
197
198 /// Returns a reference to the underlying renderer. 188 /// Returns a reference to the underlying renderer.
199 [[nodiscard]] VideoCore::RendererBase& Renderer() { 189 [[nodiscard]] VideoCore::RendererBase& Renderer() {
200 return *renderer; 190 return *renderer;
@@ -338,25 +328,27 @@ struct GPU::Impl {
338 } 328 }
339 329
340 /// Push GPU command buffer entries to be processed 330 /// Push GPU command buffer entries to be processed
341 void PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { 331 void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) {
342 if (!use_nvdec) { 332 if (!use_nvdec) {
343 return; 333 return;
344 } 334 }
345 335
346 if (!cdma_pusher) { 336 if (!cdma_pushers.contains(id)) {
347 cdma_pusher = std::make_unique<Tegra::CDmaPusher>(gpu); 337 cdma_pushers.insert_or_assign(id, std::make_unique<Tegra::CDmaPusher>(gpu));
348 } 338 }
349 339
350 // SubmitCommandBuffer would make the nvdec operations async, this is not currently working 340 // SubmitCommandBuffer would make the nvdec operations async, this is not currently working
351 // TODO(ameerj): RE proper async nvdec operation 341 // TODO(ameerj): RE proper async nvdec operation
352 // gpu_thread.SubmitCommandBuffer(std::move(entries)); 342 // gpu_thread.SubmitCommandBuffer(std::move(entries));
353 343 cdma_pushers[id]->ProcessEntries(std::move(entries));
354 cdma_pusher->ProcessEntries(std::move(entries));
355 } 344 }
356 345
357 /// Frees the CDMAPusher instance to free up resources 346 /// Frees the CDMAPusher instance to free up resources
358 void ClearCdmaInstance() { 347 void ClearCdmaInstance(u32 id) {
359 cdma_pusher.reset(); 348 const auto iter = cdma_pushers.find(id);
349 if (iter != cdma_pushers.end()) {
350 cdma_pushers.erase(iter);
351 }
360 } 352 }
361 353
362 /// Swap buffers (render frame) 354 /// Swap buffers (render frame)
@@ -659,7 +651,7 @@ struct GPU::Impl {
659 Core::System& system; 651 Core::System& system;
660 std::unique_ptr<Tegra::MemoryManager> memory_manager; 652 std::unique_ptr<Tegra::MemoryManager> memory_manager;
661 std::unique_ptr<Tegra::DmaPusher> dma_pusher; 653 std::unique_ptr<Tegra::DmaPusher> dma_pusher;
662 std::unique_ptr<Tegra::CDmaPusher> cdma_pusher; 654 std::map<u32, std::unique_ptr<Tegra::CDmaPusher>> cdma_pushers;
663 std::unique_ptr<VideoCore::RendererBase> renderer; 655 std::unique_ptr<VideoCore::RendererBase> renderer;
664 VideoCore::RasterizerInterface* rasterizer = nullptr; 656 VideoCore::RasterizerInterface* rasterizer = nullptr;
665 const bool use_nvdec; 657 const bool use_nvdec;
@@ -811,14 +803,6 @@ const Tegra::DmaPusher& GPU::DmaPusher() const {
811 return impl->DmaPusher(); 803 return impl->DmaPusher();
812} 804}
813 805
814Tegra::CDmaPusher& GPU::CDmaPusher() {
815 return impl->CDmaPusher();
816}
817
818const Tegra::CDmaPusher& GPU::CDmaPusher() const {
819 return impl->CDmaPusher();
820}
821
822VideoCore::RendererBase& GPU::Renderer() { 806VideoCore::RendererBase& GPU::Renderer() {
823 return impl->Renderer(); 807 return impl->Renderer();
824} 808}
@@ -887,12 +871,12 @@ void GPU::PushGPUEntries(Tegra::CommandList&& entries) {
887 impl->PushGPUEntries(std::move(entries)); 871 impl->PushGPUEntries(std::move(entries));
888} 872}
889 873
890void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { 874void GPU::PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) {
891 impl->PushCommandBuffer(entries); 875 impl->PushCommandBuffer(id, entries);
892} 876}
893 877
894void GPU::ClearCdmaInstance() { 878void GPU::ClearCdmaInstance(u32 id) {
895 impl->ClearCdmaInstance(); 879 impl->ClearCdmaInstance(id);
896} 880}
897 881
898void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { 882void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index c89a5d693..500411176 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -242,10 +242,10 @@ public:
242 void PushGPUEntries(Tegra::CommandList&& entries); 242 void PushGPUEntries(Tegra::CommandList&& entries);
243 243
244 /// Push GPU command buffer entries to be processed 244 /// Push GPU command buffer entries to be processed
245 void PushCommandBuffer(Tegra::ChCommandHeaderList& entries); 245 void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries);
246 246
247 /// Frees the CDMAPusher instance to free up resources 247 /// Frees the CDMAPusher instance to free up resources
248 void ClearCdmaInstance(); 248 void ClearCdmaInstance(u32 id);
249 249
250 /// Swap buffers (render frame) 250 /// Swap buffers (render frame)
251 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer); 251 void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);