summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp75
1 files changed, 38 insertions, 37 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 98e6296f1..f045008eb 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -19,26 +19,29 @@
19namespace Service::Nvidia::Devices { 19namespace Service::Nvidia::Devices {
20 20
21namespace { 21namespace {
22// Splice vectors will copy count amount of type T from the input vector into the dst vector. 22// Copies count amount of type T from the input vector into the dst vector.
23// Returns the number of bytes written into dst.
23template <typename T> 24template <typename T>
24std::size_t SpliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count, 25std::size_t SliceVectors(const std::vector<u8>& input, std::vector<T>& dst, std::size_t count,
25 std::size_t offset) { 26 std::size_t offset) {
26 if (!dst.empty()) { 27 if (dst.empty()) {
27 std::memcpy(dst.data(), input.data() + offset, count * sizeof(T)); 28 return 0;
28 } 29 }
29 return 0; 30 const size_t bytes_copied = count * sizeof(T);
31 std::memcpy(dst.data(), input.data() + offset, bytes_copied);
32 return bytes_copied;
30} 33}
31 34
32// Write vectors will write data to the output buffer 35// Writes the data in src to an offset into the dst vector. The offset is specified in bytes
36// Returns the number of bytes written into dst.
33template <typename T> 37template <typename T>
34std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) { 38std::size_t WriteVectors(std::vector<u8>& dst, const std::vector<T>& src, std::size_t offset) {
35 if (src.empty()) { 39 if (src.empty()) {
36 return 0; 40 return 0;
37 } else {
38 std::memcpy(dst.data() + offset, src.data(), src.size() * sizeof(T));
39 offset += src.size() * sizeof(T);
40 return offset;
41 } 41 }
42 const size_t bytes_copied = src.size() * sizeof(T);
43 std::memcpy(dst.data() + offset, src.data(), bytes_copied);
44 return bytes_copied;
42} 45}
43} // Anonymous namespace 46} // Anonymous namespace
44 47
@@ -62,7 +65,6 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
62 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); 65 LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count);
63 66
64 // Instantiate param buffers 67 // Instantiate param buffers
65 std::size_t offset = sizeof(IoctlSubmit);
66 std::vector<CommandBuffer> command_buffers(params.cmd_buffer_count); 68 std::vector<CommandBuffer> command_buffers(params.cmd_buffer_count);
67 std::vector<Reloc> relocs(params.relocation_count); 69 std::vector<Reloc> relocs(params.relocation_count);
68 std::vector<u32> reloc_shifts(params.relocation_count); 70 std::vector<u32> reloc_shifts(params.relocation_count);
@@ -70,13 +72,14 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
70 std::vector<SyncptIncr> wait_checks(params.syncpoint_count); 72 std::vector<SyncptIncr> wait_checks(params.syncpoint_count);
71 std::vector<Fence> fences(params.fence_count); 73 std::vector<Fence> fences(params.fence_count);
72 74
73 // Splice input into their respective buffers 75 // Slice input into their respective buffers
74 offset = SpliceVectors(input, command_buffers, params.cmd_buffer_count, offset); 76 std::size_t offset = sizeof(IoctlSubmit);
75 offset = SpliceVectors(input, relocs, params.relocation_count, offset); 77 offset += SliceVectors(input, command_buffers, params.cmd_buffer_count, offset);
76 offset = SpliceVectors(input, reloc_shifts, params.relocation_count, offset); 78 offset += SliceVectors(input, relocs, params.relocation_count, offset);
77 offset = SpliceVectors(input, syncpt_increments, params.syncpoint_count, offset); 79 offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset);
78 offset = SpliceVectors(input, wait_checks, params.syncpoint_count, offset); 80 offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset);
79 offset = SpliceVectors(input, fences, params.fence_count, offset); 81 offset += SliceVectors(input, wait_checks, params.syncpoint_count, offset);
82 offset += SliceVectors(input, fences, params.fence_count, offset);
80 83
81 auto& gpu = system.GPU(); 84 auto& gpu = system.GPU();
82 if (gpu.UseNvdec()) { 85 if (gpu.UseNvdec()) {
@@ -88,7 +91,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
88 } 91 }
89 } 92 }
90 for (const auto& cmd_buffer : command_buffers) { 93 for (const auto& cmd_buffer : command_buffers) {
91 auto object = nvmap_dev->GetObject(cmd_buffer.memory_id); 94 const auto object = nvmap_dev->GetObject(cmd_buffer.memory_id);
92 ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;); 95 ASSERT_OR_EXECUTE(object, return NvResult::InvalidState;);
93 const auto map = FindBufferMap(object->dma_map_addr); 96 const auto map = FindBufferMap(object->dma_map_addr);
94 if (!map) { 97 if (!map) {
@@ -102,21 +105,19 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
102 gpu.PushCommandBuffer(cmdlist); 105 gpu.PushCommandBuffer(cmdlist);
103 } 106 }
104 if (gpu.UseNvdec()) { 107 if (gpu.UseNvdec()) {
105
106 fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1); 108 fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1);
107
108 Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}}; 109 Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}};
109 gpu.PushCommandBuffer(cmdlist); 110 gpu.PushCommandBuffer(cmdlist);
110 } 111 }
111 std::memcpy(output.data(), &params, sizeof(IoctlSubmit)); 112 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
112 // Some games expect command_buffers to be written back 113 // Some games expect command_buffers to be written back
113 offset = sizeof(IoctlSubmit); 114 offset = sizeof(IoctlSubmit);
114 offset = WriteVectors(output, command_buffers, offset); 115 offset += WriteVectors(output, command_buffers, offset);
115 offset = WriteVectors(output, relocs, offset); 116 offset += WriteVectors(output, relocs, offset);
116 offset = WriteVectors(output, reloc_shifts, offset); 117 offset += WriteVectors(output, reloc_shifts, offset);
117 offset = WriteVectors(output, syncpt_increments, offset); 118 offset += WriteVectors(output, syncpt_increments, offset);
118 offset = WriteVectors(output, wait_checks, offset); 119 offset += WriteVectors(output, wait_checks, offset);
119 offset = WriteVectors(output, fences, offset); 120 offset += WriteVectors(output, fences, offset);
120 121
121 return NvResult::Success; 122 return NvResult::Success;
122} 123}
@@ -148,14 +149,14 @@ NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vecto
148 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); 149 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
149 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); 150 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
150 151
151 SpliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); 152 SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
152 153
153 auto& gpu = system.GPU(); 154 auto& gpu = system.GPU();
154 155
155 for (auto& cmf_buff : cmd_buffer_handles) { 156 for (auto& cmd_buffer : cmd_buffer_handles) {
156 auto object{nvmap_dev->GetObject(cmf_buff.map_handle)}; 157 auto object{nvmap_dev->GetObject(cmd_buffer.map_handle)};
157 if (!object) { 158 if (!object) {
158 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmf_buff.map_handle); 159 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmd_buffer.map_handle);
159 std::memcpy(output.data(), &params, output.size()); 160 std::memcpy(output.data(), &params, output.size());
160 return NvResult::InvalidState; 161 return NvResult::InvalidState;
161 } 162 }
@@ -170,7 +171,7 @@ NvResult nvhost_nvdec_common::MapBuffer(const std::vector<u8>& input, std::vecto
170 if (!object->dma_map_addr) { 171 if (!object->dma_map_addr) {
171 LOG_ERROR(Service_NVDRV, "failed to map size={}", object->size); 172 LOG_ERROR(Service_NVDRV, "failed to map size={}", object->size);
172 } else { 173 } else {
173 cmf_buff.map_address = object->dma_map_addr; 174 cmd_buffer.map_address = object->dma_map_addr;
174 AddBufferMap(object->dma_map_addr, object->size, object->addr, 175 AddBufferMap(object->dma_map_addr, object->size, object->addr,
175 object->status == nvmap::Object::Status::Allocated); 176 object->status == nvmap::Object::Status::Allocated);
176 } 177 }
@@ -186,14 +187,14 @@ NvResult nvhost_nvdec_common::UnmapBuffer(const std::vector<u8>& input, std::vec
186 IoctlMapBuffer params{}; 187 IoctlMapBuffer params{};
187 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer)); 188 std::memcpy(&params, input.data(), sizeof(IoctlMapBuffer));
188 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries); 189 std::vector<MapBufferEntry> cmd_buffer_handles(params.num_entries);
189 SpliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer)); 190 SliceVectors(input, cmd_buffer_handles, params.num_entries, sizeof(IoctlMapBuffer));
190 191
191 auto& gpu = system.GPU(); 192 auto& gpu = system.GPU();
192 193
193 for (auto& cmf_buff : cmd_buffer_handles) { 194 for (auto& cmd_buffer : cmd_buffer_handles) {
194 const auto object{nvmap_dev->GetObject(cmf_buff.map_handle)}; 195 const auto object{nvmap_dev->GetObject(cmd_buffer.map_handle)};
195 if (!object) { 196 if (!object) {
196 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmf_buff.map_handle); 197 LOG_ERROR(Service_NVDRV, "invalid cmd_buffer nvmap_handle={:X}", cmd_buffer.map_handle);
197 std::memcpy(output.data(), &params, output.size()); 198 std::memcpy(output.data(), &params, output.size());
198 return NvResult::InvalidState; 199 return NvResult::InvalidState;
199 } 200 }