From bf1c1788cab4740d8c46c30ad8a97021b2e858f9 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Tue, 30 Mar 2021 20:37:40 +1100
Subject: [PATCH 1/2] nvdrv: Cleanup CDMA Processor on device closure

Brings us a step closer to unifying all channels to share a common interface.
---
 src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp | 10 ++++------
 src/video_core/gpu.cpp                              | 13 ++++++++-----
 src/video_core/gpu.h                                |  3 +++
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
index c8031970b9..4e58b9b80f 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp
@@ -32,11 +32,6 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
         case 0x9:
             return MapBuffer(input, output);
         case 0xa: {
-            if (command.length == 0x1c) {
-                LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
-                Tegra::ChCommandHeaderList cmdlist{{0xDEADB33F}};
-                system.GPU().PushCommandBuffer(cmdlist);
-            }
             return UnmapBuffer(input, output);
         }
         default:
@@ -70,6 +65,9 @@ NvResult nvhost_nvdec::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>&
 }
 
 void nvhost_nvdec::OnOpen(DeviceFD fd) {}
-void nvhost_nvdec::OnClose(DeviceFD fd) {}
+
+void nvhost_nvdec::OnClose(DeviceFD fd) {
+    system.GPU().ClearCommandBuffer();
+}
 
 } // namespace Service::Nvidia::Devices
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index c61f446196..811e248a32 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -480,11 +480,7 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
     if (!use_nvdec) {
         return;
     }
-    // This condition fires when a video stream ends, clear all intermediary data
-    if (entries[0].raw == 0xDEADB33F) {
-        cdma_pusher.reset();
-        return;
-    }
+
     if (!cdma_pusher) {
         cdma_pusher = std::make_unique<Tegra::CDmaPusher>(*this);
     }
@@ -496,6 +492,13 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
     cdma_pusher->ProcessEntries(std::move(entries));
 }
 
+void GPU::ClearCommandBuffer() {
+    // This condition fires when a video stream ends, clear all intermediary data
+    if (cdma_pusher) {
+        cdma_pusher.reset();
+    }
+}
+
 void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
     gpu_thread.SwapBuffers(framebuffer);
 }
diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h
index b2ee454964..d40982a546 100644
--- a/src/video_core/gpu.h
+++ b/src/video_core/gpu.h
@@ -324,6 +324,9 @@ public:
     /// Push GPU command buffer entries to be processed
     void PushCommandBuffer(Tegra::ChCommandHeaderList& entries);
 
+    /// Frees the CDMAPusher to free up resources
+    void ClearCommandBuffer();
+
     /// Swap buffers (render frame)
     void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);
 

From edb1d5d242f5b86543b17a091ed31ebb02dabec0 Mon Sep 17 00:00:00 2001
From: Chloe Marcec <dmarcecguzman@gmail.com>
Date: Fri, 16 Apr 2021 13:52:32 +1000
Subject: [PATCH 2/2] Address issues

---
 src/video_core/gpu.cpp | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp
index 811e248a32..36c31fec29 100644
--- a/src/video_core/gpu.cpp
+++ b/src/video_core/gpu.cpp
@@ -494,9 +494,8 @@ void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) {
 
 void GPU::ClearCommandBuffer() {
     // This condition fires when a video stream ends, clear all intermediary data
-    if (cdma_pusher) {
-        cdma_pusher.reset();
-    }
+    cdma_pusher.reset();
+    LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
 }
 
 void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {