cdma_pusher.h 2.9 KB

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