yuzu-emu
/
yuzu-android
Archived
1
0
Fork 0

Merge pull request #7488 from vonchenplus/support_multiple_videos_playing

Support multiple videos playing
This commit is contained in:
bunnei 2021-12-07 18:38:14 -08:00 committed by GitHub
commit 815189eaf3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 45 additions and 40 deletions

View File

@ -20,8 +20,12 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>&
switch (command.group) { switch (command.group) {
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
case 0x1: case 0x1: {
return Submit(input, output); if (!fd_to_id.contains(fd)) {
fd_to_id[fd] = next_id++;
}
return Submit(fd, input, output);
}
case 0x2: case 0x2:
return GetSyncpoint(input, output); return GetSyncpoint(input, output);
case 0x3: case 0x3:
@ -66,7 +70,10 @@ void nvhost_nvdec::OnOpen(DeviceFD fd) {}
void nvhost_nvdec::OnClose(DeviceFD fd) { void nvhost_nvdec::OnClose(DeviceFD fd) {
LOG_INFO(Service_NVDRV, "NVDEC video stream ended"); LOG_INFO(Service_NVDRV, "NVDEC video stream ended");
system.GPU().ClearCdmaInstance(); const auto iter = fd_to_id.find(fd);
if (iter != fd_to_id.end()) {
system.GPU().ClearCdmaInstance(iter->second);
}
} }
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View File

@ -24,6 +24,9 @@ public:
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
private:
u32 next_id{};
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View File

@ -59,7 +59,8 @@ NvResult nvhost_nvdec_common::SetNVMAPfd(const std::vector<u8>& input) {
return NvResult::Success; return NvResult::Success;
} }
NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u8>& output) { NvResult nvhost_nvdec_common::Submit(DeviceFD fd, const std::vector<u8>& input,
std::vector<u8>& output) {
IoctlSubmit params{}; IoctlSubmit params{};
std::memcpy(&params, input.data(), sizeof(IoctlSubmit)); std::memcpy(&params, input.data(), sizeof(IoctlSubmit));
LOG_DEBUG(Service_NVDRV, "called NVDEC Submit, cmd_buffer_count={}", params.cmd_buffer_count); 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
Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count); Tegra::ChCommandHeaderList cmdlist(cmd_buffer.word_count);
system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(), system.Memory().ReadBlock(object->addr + cmd_buffer.offset, cmdlist.data(),
cmdlist.size() * sizeof(u32)); cmdlist.size() * sizeof(u32));
gpu.PushCommandBuffer(cmdlist); gpu.PushCommandBuffer(fd_to_id[fd], cmdlist);
} }
std::memcpy(output.data(), &params, sizeof(IoctlSubmit)); std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
// Some games expect command_buffers to be written back // Some games expect command_buffers to be written back

View File

@ -104,13 +104,14 @@ protected:
/// Ioctl command implementations /// Ioctl command implementations
NvResult SetNVMAPfd(const std::vector<u8>& input); NvResult SetNVMAPfd(const std::vector<u8>& input);
NvResult Submit(const std::vector<u8>& input, std::vector<u8>& output); NvResult Submit(DeviceFD fd, const std::vector<u8>& input, std::vector<u8>& output);
NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetSyncpoint(const std::vector<u8>& input, std::vector<u8>& output);
NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output); NvResult GetWaitbase(const std::vector<u8>& input, std::vector<u8>& output);
NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output); NvResult MapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output); NvResult UnmapBuffer(const std::vector<u8>& input, std::vector<u8>& output);
NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output); NvResult SetSubmitTimeout(const std::vector<u8>& input, std::vector<u8>& output);
std::unordered_map<DeviceFD, u32> fd_to_id{};
s32_le nvmap_fd{}; s32_le nvmap_fd{};
u32_le submit_timeout{}; u32_le submit_timeout{};
std::shared_ptr<nvmap> nvmap_dev; std::shared_ptr<nvmap> nvmap_dev;

View File

@ -21,7 +21,10 @@ NvResult nvhost_vic::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& i
case 0x0: case 0x0:
switch (command.cmd) { switch (command.cmd) {
case 0x1: case 0x1:
return Submit(input, output); if (!fd_to_id.contains(fd)) {
fd_to_id[fd] = next_id++;
}
return Submit(fd, input, output);
case 0x2: case 0x2:
return GetSyncpoint(input, output); return GetSyncpoint(input, output);
case 0x3: case 0x3:
@ -65,7 +68,10 @@ NvResult nvhost_vic::Ioctl3(DeviceFD fd, Ioctl command, const std::vector<u8>& i
void nvhost_vic::OnOpen(DeviceFD fd) {} void nvhost_vic::OnOpen(DeviceFD fd) {}
void nvhost_vic::OnClose(DeviceFD fd) { void nvhost_vic::OnClose(DeviceFD fd) {
system.GPU().ClearCdmaInstance(); const auto iter = fd_to_id.find(fd);
if (iter != fd_to_id.end()) {
system.GPU().ClearCdmaInstance(iter->second);
}
} }
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View File

@ -23,5 +23,8 @@ public:
void OnOpen(DeviceFD fd) override; void OnOpen(DeviceFD fd) override;
void OnClose(DeviceFD fd) override; void OnClose(DeviceFD fd) override;
private:
u32 next_id{};
}; };
} // namespace Service::Nvidia::Devices } // namespace Service::Nvidia::Devices

View File

@ -185,16 +185,6 @@ struct GPU::Impl {
return *dma_pusher; return *dma_pusher;
} }
/// Returns a reference to the GPU CDMA pusher.
[[nodiscard]] Tegra::CDmaPusher& CDmaPusher() {
return *cdma_pusher;
}
/// Returns a const reference to the GPU CDMA pusher.
[[nodiscard]] const Tegra::CDmaPusher& CDmaPusher() const {
return *cdma_pusher;
}
/// Returns a reference to the underlying renderer. /// Returns a reference to the underlying renderer.
[[nodiscard]] VideoCore::RendererBase& Renderer() { [[nodiscard]] VideoCore::RendererBase& Renderer() {
return *renderer; return *renderer;
@ -338,25 +328,27 @@ struct GPU::Impl {
} }
/// Push GPU command buffer entries to be processed /// Push GPU command buffer entries to be processed
void PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) {
if (!use_nvdec) { if (!use_nvdec) {
return; return;
} }
if (!cdma_pusher) { if (!cdma_pushers.contains(id)) {
cdma_pusher = std::make_unique<Tegra::CDmaPusher>(gpu); cdma_pushers.insert_or_assign(id, std::make_unique<Tegra::CDmaPusher>(gpu));
} }
// SubmitCommandBuffer would make the nvdec operations async, this is not currently working // SubmitCommandBuffer would make the nvdec operations async, this is not currently working
// TODO(ameerj): RE proper async nvdec operation // TODO(ameerj): RE proper async nvdec operation
// gpu_thread.SubmitCommandBuffer(std::move(entries)); // gpu_thread.SubmitCommandBuffer(std::move(entries));
cdma_pushers[id]->ProcessEntries(std::move(entries));
cdma_pusher->ProcessEntries(std::move(entries));
} }
/// Frees the CDMAPusher instance to free up resources /// Frees the CDMAPusher instance to free up resources
void ClearCdmaInstance() { void ClearCdmaInstance(u32 id) {
cdma_pusher.reset(); const auto iter = cdma_pushers.find(id);
if (iter != cdma_pushers.end()) {
cdma_pushers.erase(iter);
}
} }
/// Swap buffers (render frame) /// Swap buffers (render frame)
@ -659,7 +651,7 @@ struct GPU::Impl {
Core::System& system; Core::System& system;
std::unique_ptr<Tegra::MemoryManager> memory_manager; std::unique_ptr<Tegra::MemoryManager> memory_manager;
std::unique_ptr<Tegra::DmaPusher> dma_pusher; std::unique_ptr<Tegra::DmaPusher> dma_pusher;
std::unique_ptr<Tegra::CDmaPusher> cdma_pusher; std::map<u32, std::unique_ptr<Tegra::CDmaPusher>> cdma_pushers;
std::unique_ptr<VideoCore::RendererBase> renderer; std::unique_ptr<VideoCore::RendererBase> renderer;
VideoCore::RasterizerInterface* rasterizer = nullptr; VideoCore::RasterizerInterface* rasterizer = nullptr;
const bool use_nvdec; const bool use_nvdec;
@ -811,14 +803,6 @@ const Tegra::DmaPusher& GPU::DmaPusher() const {
return impl->DmaPusher(); return impl->DmaPusher();
} }
Tegra::CDmaPusher& GPU::CDmaPusher() {
return impl->CDmaPusher();
}
const Tegra::CDmaPusher& GPU::CDmaPusher() const {
return impl->CDmaPusher();
}
VideoCore::RendererBase& GPU::Renderer() { VideoCore::RendererBase& GPU::Renderer() {
return impl->Renderer(); return impl->Renderer();
} }
@ -887,12 +871,12 @@ void GPU::PushGPUEntries(Tegra::CommandList&& entries) {
impl->PushGPUEntries(std::move(entries)); impl->PushGPUEntries(std::move(entries));
} }
void GPU::PushCommandBuffer(Tegra::ChCommandHeaderList& entries) { void GPU::PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries) {
impl->PushCommandBuffer(entries); impl->PushCommandBuffer(id, entries);
} }
void GPU::ClearCdmaInstance() { void GPU::ClearCdmaInstance(u32 id) {
impl->ClearCdmaInstance(); impl->ClearCdmaInstance(id);
} }
void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) { void GPU::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {

View File

@ -242,10 +242,10 @@ public:
void PushGPUEntries(Tegra::CommandList&& entries); void PushGPUEntries(Tegra::CommandList&& entries);
/// Push GPU command buffer entries to be processed /// Push GPU command buffer entries to be processed
void PushCommandBuffer(Tegra::ChCommandHeaderList& entries); void PushCommandBuffer(u32 id, Tegra::ChCommandHeaderList& entries);
/// Frees the CDMAPusher instance to free up resources /// Frees the CDMAPusher instance to free up resources
void ClearCdmaInstance(); void ClearCdmaInstance(u32 id);
/// Swap buffers (render frame) /// Swap buffers (render frame)
void SwapBuffers(const Tegra::FramebufferConfig* framebuffer); void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);