cdma_pusher.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright 2020 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <memory>
  6. #include <unordered_map>
  7. #include <vector>
  8. #include <queue>
  9. #include "common/bit_field.h"
  10. #include "common/common_types.h"
  11. #include "video_core/command_classes/sync_manager.h"
  12. namespace Tegra {
  13. class GPU;
  14. class Nvdec;
  15. class Vic;
  16. class Host1x;
  17. enum class ChSubmissionMode : u32 {
  18. SetClass = 0,
  19. Incrementing = 1,
  20. NonIncrementing = 2,
  21. Mask = 3,
  22. Immediate = 4,
  23. Restart = 5,
  24. Gather = 6,
  25. };
  26. enum class ChClassId : u32 {
  27. NoClass = 0x0,
  28. Host1x = 0x1,
  29. VideoEncodeMpeg = 0x20,
  30. VideoEncodeNvEnc = 0x21,
  31. VideoStreamingVi = 0x30,
  32. VideoStreamingIsp = 0x32,
  33. VideoStreamingIspB = 0x34,
  34. VideoStreamingViI2c = 0x36,
  35. GraphicsVic = 0x5d,
  36. Graphics3D = 0x60,
  37. GraphicsGpu = 0x61,
  38. Tsec = 0xe0,
  39. TsecB = 0xe1,
  40. NvJpg = 0xc0,
  41. NvDec = 0xf0
  42. };
  43. enum class ChMethod : u32 {
  44. Empty = 0,
  45. SetMethod = 0x10,
  46. SetData = 0x11,
  47. };
  48. union ChCommandHeader {
  49. u32 raw;
  50. BitField<0, 16, u32> value;
  51. BitField<16, 12, ChMethod> method_offset;
  52. BitField<28, 4, ChSubmissionMode> submission_mode;
  53. };
  54. static_assert(sizeof(ChCommandHeader) == sizeof(u32), "ChCommand header is an invalid size");
  55. struct ChCommand {
  56. ChClassId class_id{};
  57. int method_offset{};
  58. std::vector<u32> arguments;
  59. };
  60. using ChCommandHeaderList = std::vector<ChCommandHeader>;
  61. using ChCommandList = std::vector<ChCommand>;
  62. struct ThiRegisters {
  63. u32_le increment_syncpt{};
  64. INSERT_PADDING_WORDS(1);
  65. u32_le increment_syncpt_error{};
  66. u32_le ctx_switch_incremement_syncpt{};
  67. INSERT_PADDING_WORDS(4);
  68. u32_le ctx_switch{};
  69. INSERT_PADDING_WORDS(1);
  70. u32_le ctx_syncpt_eof{};
  71. INSERT_PADDING_WORDS(5);
  72. u32_le method_0{};
  73. u32_le method_1{};
  74. INSERT_PADDING_WORDS(12);
  75. u32_le int_status{};
  76. u32_le int_mask{};
  77. };
  78. enum class ThiMethod : u32 {
  79. IncSyncpt = offsetof(ThiRegisters, increment_syncpt) / sizeof(u32),
  80. SetMethod0 = offsetof(ThiRegisters, method_0) / sizeof(u32),
  81. SetMethod1 = offsetof(ThiRegisters, method_1) / sizeof(u32),
  82. };
  83. class CDmaPusher {
  84. public:
  85. explicit CDmaPusher(GPU& gpu_);
  86. ~CDmaPusher();
  87. /// Push NVDEC command buffer entries into queue
  88. void Push(ChCommandHeaderList&& entries);
  89. /// Process queued command buffer entries
  90. void DispatchCalls();
  91. /// Process one queue element
  92. void Step();
  93. /// Invoke command class devices to execute the command based on the current state
  94. void ExecuteCommand(u32 state_offset, u32 data);
  95. private:
  96. /// Write arguments value to the ThiRegisters member at the specified offset
  97. void ThiStateWrite(ThiRegisters& state, u32 state_offset, const std::vector<u32>& arguments);
  98. GPU& gpu;
  99. std::shared_ptr<Tegra::Nvdec> nvdec_processor;
  100. std::unique_ptr<Tegra::Vic> vic_processor;
  101. std::unique_ptr<Tegra::Host1x> host1x_processor;
  102. std::unique_ptr<SyncptIncrManager> sync_manager;
  103. ChClassId current_class{};
  104. ThiRegisters vic_thi_state{};
  105. ThiRegisters nvdec_thi_state{};
  106. s32 count{};
  107. s32 offset{};
  108. u32 mask{};
  109. bool incrementing{};
  110. // Queue of command lists to be processed
  111. std::queue<ChCommandHeaderList> cdma_queue;
  112. };
  113. } // namespace Tegra