gpu_thread.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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 Core
  20. namespace VideoCommon::GPUThread {
  21. /// Command to signal to the GPU thread that processing has ended
  22. struct EndProcessingCommand final {};
  23. /// Command to signal to the GPU thread that a command list is ready for processing
  24. struct SubmitListCommand final {
  25. explicit SubmitListCommand(Tegra::CommandList&& entries) : entries{std::move(entries)} {}
  26. Tegra::CommandList entries;
  27. };
  28. /// Command to signal to the GPU thread that a swap buffers is pending
  29. struct SwapBuffersCommand final {
  30. explicit SwapBuffersCommand(std::optional<const Tegra::FramebufferConfig> framebuffer)
  31. : framebuffer{std::move(framebuffer)} {}
  32. std::optional<Tegra::FramebufferConfig> framebuffer;
  33. };
  34. /// Command to signal to the GPU thread to flush a region
  35. struct FlushRegionCommand final {
  36. explicit constexpr FlushRegionCommand(CacheAddr addr, u64 size) : addr{addr}, size{size} {}
  37. CacheAddr addr;
  38. u64 size;
  39. };
  40. /// Command to signal to the GPU thread to invalidate a region
  41. struct InvalidateRegionCommand final {
  42. explicit constexpr InvalidateRegionCommand(CacheAddr addr, u64 size) : addr{addr}, size{size} {}
  43. CacheAddr addr;
  44. u64 size;
  45. };
  46. /// Command to signal to the GPU thread to flush and invalidate a region
  47. struct FlushAndInvalidateRegionCommand final {
  48. explicit constexpr FlushAndInvalidateRegionCommand(CacheAddr addr, u64 size)
  49. : addr{addr}, size{size} {}
  50. CacheAddr addr;
  51. u64 size;
  52. };
  53. using CommandData =
  54. std::variant<EndProcessingCommand, SubmitListCommand, SwapBuffersCommand, FlushRegionCommand,
  55. InvalidateRegionCommand, FlushAndInvalidateRegionCommand>;
  56. struct CommandDataContainer {
  57. CommandDataContainer() = default;
  58. CommandDataContainer(CommandData&& data, u64 next_fence)
  59. : data{std::move(data)}, fence{next_fence} {}
  60. CommandData data;
  61. u64 fence{};
  62. };
  63. /// Struct used to synchronize the GPU thread
  64. struct SynchState final {
  65. std::atomic_bool is_running{true};
  66. using CommandQueue = Common::SPSCQueue<CommandDataContainer>;
  67. CommandQueue queue;
  68. u64 last_fence{};
  69. std::atomic<u64> signaled_fence{};
  70. };
  71. /// Class used to manage the GPU thread
  72. class ThreadManager final {
  73. public:
  74. explicit ThreadManager(Core::System& system);
  75. ~ThreadManager();
  76. /// Creates and starts the GPU thread.
  77. void StartThread(VideoCore::RendererBase& renderer, Tegra::DmaPusher& dma_pusher);
  78. /// Push GPU command entries to be processed
  79. void SubmitList(Tegra::CommandList&& entries);
  80. /// Swap buffers (render frame)
  81. void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);
  82. /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
  83. void FlushRegion(CacheAddr addr, u64 size);
  84. /// Notify rasterizer that any caches of the specified region should be invalidated
  85. void InvalidateRegion(CacheAddr addr, u64 size);
  86. /// Notify rasterizer that any caches of the specified region should be flushed and invalidated
  87. void FlushAndInvalidateRegion(CacheAddr addr, u64 size);
  88. // Wait until the gpu thread is idle.
  89. void WaitIdle() const;
  90. private:
  91. /// Pushes a command to be executed by the GPU thread
  92. u64 PushCommand(CommandData&& command_data);
  93. private:
  94. SynchState state;
  95. Core::System& system;
  96. std::thread thread;
  97. std::thread::id thread_id;
  98. };
  99. } // namespace VideoCommon::GPUThread