gpu_thread.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #pragma once
  4. #include <atomic>
  5. #include <condition_variable>
  6. #include <mutex>
  7. #include <optional>
  8. #include <thread>
  9. #include <variant>
  10. #include "common/bounded_threadsafe_queue.h"
  11. #include "common/polyfill_thread.h"
  12. #include "video_core/framebuffer_config.h"
  13. namespace Tegra {
  14. struct FramebufferConfig;
  15. namespace Control {
  16. class Scheduler;
  17. }
  18. } // namespace Tegra
  19. namespace Core {
  20. namespace Frontend {
  21. class GraphicsContext;
  22. }
  23. class System;
  24. } // namespace Core
  25. namespace VideoCore {
  26. class RasterizerInterface;
  27. class RendererBase;
  28. } // namespace VideoCore
  29. namespace VideoCommon::GPUThread {
  30. /// Command to signal to the GPU thread that a command list is ready for processing
  31. struct SubmitListCommand final {
  32. explicit SubmitListCommand(s32 channel_, Tegra::CommandList&& entries_)
  33. : channel{channel_}, entries{std::move(entries_)} {}
  34. s32 channel;
  35. Tegra::CommandList entries;
  36. };
  37. /// Command to signal to the GPU thread to flush a region
  38. struct FlushRegionCommand final {
  39. explicit constexpr FlushRegionCommand(DAddr addr_, u64 size_) : addr{addr_}, size{size_} {}
  40. DAddr 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(DAddr addr_, u64 size_) : addr{addr_}, size{size_} {}
  46. DAddr 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(DAddr addr_, u64 size_)
  52. : addr{addr_}, size{size_} {}
  53. DAddr addr;
  54. u64 size;
  55. };
  56. /// Command to make the gpu look into pending requests
  57. struct GPUTickCommand final {};
  58. using CommandData =
  59. std::variant<std::monostate, SubmitListCommand, FlushRegionCommand, InvalidateRegionCommand,
  60. FlushAndInvalidateRegionCommand, GPUTickCommand>;
  61. struct CommandDataContainer {
  62. CommandDataContainer() = default;
  63. explicit CommandDataContainer(CommandData&& data_, u64 next_fence_, bool block_)
  64. : data{std::move(data_)}, fence{next_fence_}, block(block_) {}
  65. CommandData data;
  66. u64 fence{};
  67. bool block{};
  68. };
  69. /// Struct used to synchronize the GPU thread
  70. struct SynchState final {
  71. using CommandQueue = Common::MPSCQueue<CommandDataContainer>;
  72. std::mutex write_lock;
  73. CommandQueue queue;
  74. u64 last_fence{};
  75. std::atomic<u64> signaled_fence{};
  76. std::condition_variable_any cv;
  77. };
  78. /// Class used to manage the GPU thread
  79. class ThreadManager final {
  80. public:
  81. explicit ThreadManager(Core::System& system_, bool is_async_);
  82. ~ThreadManager();
  83. /// Creates and starts the GPU thread.
  84. void StartThread(VideoCore::RendererBase& renderer, Core::Frontend::GraphicsContext& context,
  85. Tegra::Control::Scheduler& scheduler);
  86. /// Push GPU command entries to be processed
  87. void SubmitList(s32 channel, Tegra::CommandList&& entries);
  88. /// Notify rasterizer that any caches of the specified region should be flushed to Switch memory
  89. void FlushRegion(DAddr addr, u64 size);
  90. /// Notify rasterizer that any caches of the specified region should be invalidated
  91. void InvalidateRegion(DAddr addr, u64 size);
  92. /// Notify rasterizer that any caches of the specified region should be flushed and invalidated
  93. void FlushAndInvalidateRegion(DAddr addr, u64 size);
  94. void TickGPU();
  95. private:
  96. /// Pushes a command to be executed by the GPU thread
  97. u64 PushCommand(CommandData&& command_data, bool block = false);
  98. Core::System& system;
  99. const bool is_async;
  100. VideoCore::RasterizerInterface* rasterizer = nullptr;
  101. SynchState state;
  102. std::jthread thread;
  103. };
  104. } // namespace VideoCommon::GPUThread