maxwell_dma.h 4.6 KB

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