maxwell_dma.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. // Copyright 2018 yuzu Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <array>
  6. #include "common/assert.h"
  7. #include "common/bit_field.h"
  8. #include "common/common_funcs.h"
  9. #include "common/common_types.h"
  10. #include "video_core/gpu.h"
  11. #include "video_core/memory_manager.h"
  12. namespace Tegra::Engines {
  13. class MaxwellDMA final {
  14. public:
  15. explicit MaxwellDMA(MemoryManager& memory_manager);
  16. ~MaxwellDMA() = default;
  17. /// Write the value to the register identified by method.
  18. void WriteReg(u32 method, u32 value);
  19. struct Regs {
  20. static constexpr size_t NUM_REGS = 0x1D6;
  21. struct Parameters {
  22. union {
  23. BitField<0, 4, u32> block_depth;
  24. BitField<4, 4, u32> block_height;
  25. BitField<8, 4, u32> block_width;
  26. };
  27. u32 size_x;
  28. u32 size_y;
  29. u32 size_z;
  30. u32 pos_z;
  31. union {
  32. BitField<0, 16, u32> pos_x;
  33. BitField<16, 16, u32> pos_y;
  34. };
  35. u32 BlockHeight() const {
  36. return 1 << block_height;
  37. }
  38. };
  39. static_assert(sizeof(Parameters) == 24, "Parameters has wrong size");
  40. enum class CopyMode : u32 {
  41. None = 0,
  42. Unk1 = 1,
  43. Unk2 = 2,
  44. };
  45. enum class QueryMode : u32 {
  46. None = 0,
  47. Short = 1,
  48. Long = 2,
  49. };
  50. enum class QueryIntr : u32 {
  51. None = 0,
  52. Block = 1,
  53. NonBlock = 2,
  54. };
  55. union {
  56. struct {
  57. INSERT_PADDING_WORDS(0xC0);
  58. struct {
  59. union {
  60. BitField<0, 2, CopyMode> copy_mode;
  61. BitField<2, 1, u32> flush;
  62. BitField<3, 2, QueryMode> query_mode;
  63. BitField<5, 2, QueryIntr> query_intr;
  64. BitField<7, 1, u32> is_src_linear;
  65. BitField<8, 1, u32> is_dst_linear;
  66. BitField<9, 1, u32> enable_2d;
  67. BitField<10, 1, u32> enable_swizzle;
  68. };
  69. } exec;
  70. INSERT_PADDING_WORDS(0x3F);
  71. struct {
  72. u32 address_high;
  73. u32 address_low;
  74. GPUVAddr Address() const {
  75. return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
  76. address_low);
  77. }
  78. } src_address;
  79. struct {
  80. u32 address_high;
  81. u32 address_low;
  82. GPUVAddr Address() const {
  83. return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
  84. address_low);
  85. }
  86. } dst_address;
  87. u32 src_pitch;
  88. u32 dst_pitch;
  89. u32 x_count;
  90. u32 y_count;
  91. INSERT_PADDING_WORDS(0xBB);
  92. Parameters dst_params;
  93. INSERT_PADDING_WORDS(1);
  94. Parameters src_params;
  95. INSERT_PADDING_WORDS(0x13);
  96. };
  97. std::array<u32, NUM_REGS> reg_array;
  98. };
  99. } regs{};
  100. MemoryManager& memory_manager;
  101. private:
  102. /// Performs the copy from the source buffer to the destination buffer as configured in the
  103. /// registers.
  104. void HandleCopy();
  105. };
  106. #define ASSERT_REG_POSITION(field_name, position) \
  107. static_assert(offsetof(MaxwellDMA::Regs, field_name) == position * 4, \
  108. "Field " #field_name " has invalid position")
  109. ASSERT_REG_POSITION(exec, 0xC0);
  110. ASSERT_REG_POSITION(src_address, 0x100);
  111. ASSERT_REG_POSITION(dst_address, 0x102);
  112. ASSERT_REG_POSITION(src_pitch, 0x104);
  113. ASSERT_REG_POSITION(dst_pitch, 0x105);
  114. ASSERT_REG_POSITION(x_count, 0x106);
  115. ASSERT_REG_POSITION(y_count, 0x107);
  116. ASSERT_REG_POSITION(dst_params, 0x1C3);
  117. ASSERT_REG_POSITION(src_params, 0x1CA);
  118. #undef ASSERT_REG_POSITION
  119. } // namespace Tegra::Engines