gpu_thread.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. namespace Frontend {
  19. class GraphicsContext;
  20. }
  21. class System;
  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(VAddr addr, u64 size) : addr{addr}, size{size} {}
  40. VAddr 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(VAddr addr, u64 size) : addr{addr}, size{size} {}
  46. VAddr 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(VAddr addr, u64 size)
  52. : addr{addr}, size{size} {}
  53. VAddr addr;
  54. u64 size;
  55. };
  56. /// Command called within the gpu, to schedule actions after a command list end
  57. struct OnCommandListEndCommand final {};
  58. /// Command to make the gpu look into pending requests
  59. struct GPUTickCommand final {};
  60. using CommandData =
  61. std::variant<EndProcessingCommand, SubmitListCommand, SwapBuffersCommand, FlushRegionCommand,
  62. InvalidateRegionCommand, FlushAndInvalidateRegionCommand, OnCommandListEndCommand,
  63. GPUTickCommand>;
  64. struct CommandDataContainer {
  65. CommandDataContainer() = default;
  66. CommandDataContainer(CommandData&& data, u64 next_fence)
  67. : data{std::move(data)}, fence{next_fence} {}
  68. CommandData data;
  69. u64 fence{};
  70. };
  71. /// Struct used to synchronize the GPU thread
  72. struct SynchState final {
  73. std::atomic_bool is_running{true};
  74. using CommandQueue = Common::MPSCQueue<CommandDataContainer>;
  75. CommandQueue queue;
  76. u64 last_fence{};
  77. std::atomic<u64> signaled_fence{};
  78. };
  79. /// Class used to manage the GPU thread
  80. class ThreadManager final {
  81. public:
  82. explicit ThreadManager(Core::System& system);
  83. ~ThreadManager();
  84. /// Creates and starts the GPU thread.
  85. void StartThread(VideoCore::RendererBase& renderer, Core::Frontend::GraphicsContext& context,
  86. Tegra::DmaPusher& dma_pusher);
  87. /// Push GPU command entries to be processed
  88. void SubmitList(Tegra::CommandList&& entries);
  89. /// Swap buffers (render frame)
  90. void SwapBuffers(const Tegra::FramebufferConfig* framebuffer);
  91. /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
  92. void FlushRegion(VAddr addr, u64 size);
  93. /// Notify rasterizer that any caches of the specified region should be invalidated
  94. void InvalidateRegion(VAddr addr, u64 size);
  95. /// Notify rasterizer that any caches of the specified region should be flushed and invalidated
  96. void FlushAndInvalidateRegion(VAddr addr, u64 size);
  97. // Wait until the gpu thread is idle.
  98. void WaitIdle() const;
  99. void OnCommandListEnd();
  100. private:
  101. /// Pushes a command to be executed by the GPU thread
  102. u64 PushCommand(CommandData&& command_data);
  103. private:
  104. SynchState state;
  105. Core::System& system;
  106. std::thread thread;
  107. std::thread::id thread_id;
  108. };
  109. } // namespace VideoCommon::GPUThread