aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/video_core/host1x/host1x.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/host1x/host1x.h')
-rw-r--r--src/video_core/host1x/host1x.h148
1 files changed, 143 insertions, 5 deletions
diff --git a/src/video_core/host1x/host1x.h b/src/video_core/host1x/host1x.h
index d72d97b7b..8debac93d 100644
--- a/src/video_core/host1x/host1x.h
+++ b/src/video_core/host1x/host1x.h
@@ -3,9 +3,14 @@
#pragma once
+#include <unordered_map>
+#include <unordered_set>
+#include <queue>
+
#include "common/common_types.h"
#include "common/address_space.h"
+#include "video_core/cdma_pusher.h"
#include "video_core/host1x/gpu_device_memory_manager.h"
#include "video_core/host1x/syncpoint_manager.h"
#include "video_core/memory_manager.h"
@@ -14,15 +19,137 @@ namespace Core {
class System;
} // namespace Core
-namespace Tegra {
+namespace FFmpeg {
+class Frame;
+} // namespace FFmpeg
+
+namespace Tegra::Host1x {
+class Nvdec;
+
+class FrameQueue {
+public:
+ void Open(s32 fd) {
+ std::scoped_lock l{m_mutex};
+ m_presentation_order.insert({fd, {}});
+ m_decode_order.insert({fd, {}});
+ }
+
+ void Close(s32 fd) {
+ std::scoped_lock l{m_mutex};
+ m_presentation_order.erase(fd);
+ m_decode_order.erase(fd);
+ }
+
+ s32 VicFindNvdecFdFromOffset(u64 search_offset) {
+ std::scoped_lock l{m_mutex};
+ // Vic does not know which nvdec is producing frames for it, so search all the fds here for
+ // the given offset.
+ for (auto& map : m_presentation_order) {
+ for (auto& [offset, frame] : map.second) {
+ if (offset == search_offset) {
+ return map.first;
+ }
+ }
+ }
+
+ for (auto& map : m_decode_order) {
+ for (auto& [offset, frame] : map.second) {
+ if (offset == search_offset) {
+ return map.first;
+ }
+ }
+ }
+
+ return -1;
+ }
-namespace Host1x {
+ void PushPresentOrder(s32 fd, u64 offset, std::shared_ptr<FFmpeg::Frame>&& frame) {
+ std::scoped_lock l{m_mutex};
+ auto map = m_presentation_order.find(fd);
+ if (map == m_presentation_order.end()) {
+ return;
+ }
+ map->second.emplace_back(offset, std::move(frame));
+ }
+
+ void PushDecodeOrder(s32 fd, u64 offset, std::shared_ptr<FFmpeg::Frame>&& frame) {
+ std::scoped_lock l{m_mutex};
+ auto map = m_decode_order.find(fd);
+ if (map == m_decode_order.end()) {
+ return;
+ }
+ map->second.insert_or_assign(offset, std::move(frame));
+ }
+
+ std::shared_ptr<FFmpeg::Frame> GetFrame(s32 fd, u64 offset) {
+ if (fd == -1) {
+ return {};
+ }
+
+ std::scoped_lock l{m_mutex};
+ auto present_map = m_presentation_order.find(fd);
+ if (present_map != m_presentation_order.end() && present_map->second.size() > 0) {
+ return GetPresentOrderLocked(fd);
+ }
+
+ auto decode_map = m_decode_order.find(fd);
+ if (decode_map != m_decode_order.end() && decode_map->second.size() > 0) {
+ return GetDecodeOrderLocked(fd, offset);
+ }
+
+ return {};
+ }
+
+private:
+ std::shared_ptr<FFmpeg::Frame> GetPresentOrderLocked(s32 fd) {
+ auto map = m_presentation_order.find(fd);
+ if (map == m_presentation_order.end() || map->second.size() == 0) {
+ return {};
+ }
+ auto frame = std::move(map->second.front().second);
+ map->second.pop_front();
+ return frame;
+ }
+
+ std::shared_ptr<FFmpeg::Frame> GetDecodeOrderLocked(s32 fd, u64 offset) {
+ auto map = m_decode_order.find(fd);
+ if (map == m_decode_order.end() || map->second.size() == 0) {
+ return {};
+ }
+ auto it = map->second.find(offset);
+ if (it == map->second.end()) {
+ return {};
+ }
+ return std::move(map->second.extract(it).mapped());
+ }
+
+ using FramePtr = std::shared_ptr<FFmpeg::Frame>;
+
+ std::mutex m_mutex{};
+ std::unordered_map<s32, std::deque<std::pair<u64, FramePtr>>> m_presentation_order;
+ std::unordered_map<s32, std::unordered_map<u64, FramePtr>> m_decode_order;
+};
+
+enum class ChannelType : u32 {
+ MsEnc = 0,
+ VIC = 1,
+ GPU = 2,
+ NvDec = 3,
+ Display = 4,
+ NvJpg = 5,
+ TSec = 6,
+ Max = 7,
+};
class Host1x {
public:
explicit Host1x(Core::System& system);
~Host1x();
+ Core::System& System() {
+ return system;
+ }
+
SyncpointManager& GetSyncpointManager() {
return syncpoint_manager;
}
@@ -55,14 +182,25 @@ public:
return *allocator;
}
+ void StartDevice(s32 fd, ChannelType type, u32 syncpt);
+ void StopDevice(s32 fd, ChannelType type);
+
+ void PushEntries(s32 fd, ChCommandHeaderList&& entries) {
+ auto it = devices.find(fd);
+ if (it == devices.end()) {
+ return;
+ }
+ it->second->PushEntries(std::move(entries));
+ }
+
private:
Core::System& system;
SyncpointManager syncpoint_manager;
Tegra::MaxwellDeviceMemoryManager memory_manager;
Tegra::MemoryManager gmmu_manager;
std::unique_ptr<Common::FlatAllocator<u32, 0, 32>> allocator;
+ FrameQueue frame_queue;
+ std::unordered_map<s32, std::unique_ptr<CDmaPusher>> devices;
};
-} // namespace Host1x
-
-} // namespace Tegra
+} // namespace Tegra::Host1x