gpu_thread.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // Copyright 2019 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <atomic>
  6. #include <condition_variable>
  7. #include <mutex>
  8. #include <optional>
  9. #include <thread>
  10. #include <variant>
  11. #include "common/threadsafe_queue.h"
  12. #include "video_core/gpu.h"
  13. namespace Tegra {
  14. struct FramebufferConfig;
  15. class DmaPusher;
  16. } // namespace Tegra
  17. namespace Core {
  18. class System;
  19. namespace Timing {
  20. struct EventType;
  21. } // namespace Timing
  22. } // namespace Core
  23. namespace VideoCommon::GPUThread {
  24. /// Command to signal to the GPU thread that processing has ended
  25. struct EndProcessingCommand final {};
  26. /// Command to signal to the GPU thread that a command list is ready for processing
  27. struct SubmitListCommand final {
  28. explicit SubmitListCommand(Tegra::CommandList&& entries) : entries{std::move(entries)} {}
  29. Tegra::CommandList entries;
  30. };
  31. /// Command to signal to the GPU thread that a swap buffers is pending
  32. struct SwapBuffersCommand final {
  33. explicit SwapBuffersCommand(std::optional<const Tegra::FramebufferConfig> framebuffer)
  34. : framebuffer{std::move(framebuffer)} {}
  35. std::optional<Tegra::FramebufferConfig> framebuffer;
  36. };
  37. /// Command to signal to the GPU thread to flush a region
  38. struct FlushRegionCommand final {
  39. explicit constexpr FlushRegionCommand(CacheAddr addr, u64 size) : addr{addr}, size{size} {}
  40. CacheAddr addr;
  41. u64 size;
  42. };
  43. /// Command to signal to the GPU thread to invalidate a region
  44. struct InvalidateRegionCommand final {
  45. explicit constexpr InvalidateRegionCommand(CacheAddr addr, u64 size) : addr{addr}, size{size} {}
  46. CacheAddr addr;
  47. u64 size;
  48. };
  49. /// Command to signal to the GPU thread to flush and invalidate a region
  50. struct FlushAndInvalidateRegionCommand final {
  51. explicit constexpr FlushAndInvalidateRegionCommand(CacheAddr addr, u64 size)
  52. : addr{addr}, size{size} {}
  53. CacheAddr addr;
  54. u64 size;
  55. };
  56. using CommandData =
  57. std::variant<EndProcessingCommand, SubmitListCommand, SwapBuffersCommand, FlushRegionCommand,
  58. InvalidateRegionCommand, FlushAndInvalidateRegionCommand>;
  59. struct CommandDataContainer {
  60. CommandDataContainer() = default;
  61. CommandDataContainer(CommandData&& data, u64 next_fence)
  62. : data{std::move(data)}, fence{next_fence} {}
  63. CommandData data;
  64. u64 fence{};
  65. };
  66. /// Struct used to synchronize the GPU thread
  67. struct SynchState final {
  68. std::atomic_bool is_running{true};
  69. void WaitForSynchronization(u64 fence);
  70. using CommandQueue = Common::SPSCQueue<CommandDataContainer>;
  71. CommandQueue queue;
  72. u64 last_fence{};
  73. std::atomic<u64> signaled_fence{};
  74. };
  75. /// Class used to manage the GPU thread
  76. class ThreadManager final {
  77. public:
  78. explicit ThreadManager(Core::System& system);
  79. ~ThreadManager();
  80. /// Creates and starts the GPU thread.
  81. void StartThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_pusher);
  82. /// Push GPU command entries to be processed
  83. void SubmitList(Tegra::CommandList&& entries);
  84. /// Swap buffers (render frame)
  85. void SwapBuffers(
  86. std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer);
  87. /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
  88. void FlushRegion(CacheAddr addr, u64 size);
  89. /// Notify rasterizer that any caches of the specified region should be invalidated
  90. void InvalidateRegion(CacheAddr addr, u64 size);
  91. /// Notify rasterizer that any caches of the specified region should be flushed and invalidated
  92. void FlushAndInvalidateRegion(CacheAddr addr, u64 size);
  93. private:
  94. /// Pushes a command to be executed by the GPU thread
  95. u64 PushCommand(CommandData&& command_data);
  96. private:
  97. SynchState state;
  98. Core::System& system;
  99. Core::Timing::EventType* synchronization_event{};
  100. std::thread thread;
  101. std::thread::id thread_id;
  102. };
  103. } // namespace VideoCommon::GPUThread