maxwell_dma.h 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  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 <vector>
  8. #include "common/bit_field.h"
  9. #include "common/common_funcs.h"
  10. #include "common/common_types.h"
  11. #include "video_core/gpu.h"
  12. namespace Core {
  13. class System;
  14. }
  15. namespace Tegra {
  16. class MemoryManager;
  17. }
  18. namespace VideoCore {
  19. class RasterizerInterface;
  20. }
  21. namespace Tegra::Engines {
  22. /**
  23. * This Engine is known as GK104_Copy. Documentation can be found in:
  24. * https://github.com/envytools/envytools/blob/master/rnndb/fifo/gk104_copy.xml
  25. */
  26. class MaxwellDMA final {
  27. public:
  28. explicit MaxwellDMA(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
  29. MemoryManager& memory_manager);
  30. ~MaxwellDMA() = default;
  31. /// Write the value to the register identified by method.
  32. void CallMethod(const GPU::MethodCall& method_call);
  33. struct Regs {
  34. static constexpr std::size_t NUM_REGS = 0x1D6;
  35. struct Parameters {
  36. union {
  37. BitField<0, 4, u32> block_depth;
  38. BitField<4, 4, u32> block_height;
  39. BitField<8, 4, u32> block_width;
  40. };
  41. u32 size_x;
  42. u32 size_y;
  43. u32 size_z;
  44. u32 pos_z;
  45. union {
  46. BitField<0, 16, u32> pos_x;
  47. BitField<16, 16, u32> pos_y;
  48. };
  49. u32 BlockHeight() const {
  50. return block_height.Value();
  51. }
  52. u32 BlockDepth() const {
  53. return block_depth.Value();
  54. }
  55. };
  56. static_assert(sizeof(Parameters) == 24, "Parameters has wrong size");
  57. enum class ComponentMode : u32 {
  58. Src0 = 0,
  59. Src1 = 1,
  60. Src2 = 2,
  61. Src3 = 3,
  62. Const0 = 4,
  63. Const1 = 5,
  64. Zero = 6,
  65. };
  66. enum class CopyMode : u32 {
  67. None = 0,
  68. Unk1 = 1,
  69. Unk2 = 2,
  70. };
  71. enum class QueryMode : u32 {
  72. None = 0,
  73. Short = 1,
  74. Long = 2,
  75. };
  76. enum class QueryIntr : u32 {
  77. None = 0,
  78. Block = 1,
  79. NonBlock = 2,
  80. };
  81. union {
  82. struct {
  83. INSERT_PADDING_WORDS(0xC0);
  84. struct {
  85. union {
  86. BitField<0, 2, CopyMode> copy_mode;
  87. BitField<2, 1, u32> flush;
  88. BitField<3, 2, QueryMode> query_mode;
  89. BitField<5, 2, QueryIntr> query_intr;
  90. BitField<7, 1, u32> is_src_linear;
  91. BitField<8, 1, u32> is_dst_linear;
  92. BitField<9, 1, u32> enable_2d;
  93. BitField<10, 1, u32> enable_swizzle;
  94. };
  95. } exec;
  96. INSERT_PADDING_WORDS(0x3F);
  97. struct {
  98. u32 address_high;
  99. u32 address_low;
  100. GPUVAddr Address() const {
  101. return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
  102. address_low);
  103. }
  104. } src_address;
  105. struct {
  106. u32 address_high;
  107. u32 address_low;
  108. GPUVAddr Address() const {
  109. return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
  110. address_low);
  111. }
  112. } dst_address;
  113. u32 src_pitch;
  114. u32 dst_pitch;
  115. u32 x_count;
  116. u32 y_count;
  117. INSERT_PADDING_WORDS(0xB8);
  118. u32 const0;
  119. u32 const1;
  120. union {
  121. BitField<0, 4, ComponentMode> component0;
  122. BitField<4, 4, ComponentMode> component1;
  123. BitField<8, 4, ComponentMode> component2;
  124. BitField<12, 4, ComponentMode> component3;
  125. BitField<16, 2, u32> component_size;
  126. BitField<20, 3, u32> src_num_components;
  127. BitField<24, 3, u32> dst_num_components;
  128. u32 SrcBytePerPixel() const {
  129. return src_num_components.Value() * component_size.Value();
  130. }
  131. u32 DstBytePerPixel() const {
  132. return dst_num_components.Value() * component_size.Value();
  133. }
  134. } swizzle_config;
  135. Parameters dst_params;
  136. INSERT_PADDING_WORDS(1);
  137. Parameters src_params;
  138. INSERT_PADDING_WORDS(0x13);
  139. };
  140. std::array<u32, NUM_REGS> reg_array;
  141. };
  142. } regs{};
  143. private:
  144. Core::System& system;
  145. VideoCore::RasterizerInterface& rasterizer;
  146. MemoryManager& memory_manager;
  147. std::vector<u8> read_buffer;
  148. std::vector<u8> write_buffer;
  149. /// Performs the copy from the source buffer to the destination buffer as configured in the
  150. /// registers.
  151. void HandleCopy();
  152. };
  153. #define ASSERT_REG_POSITION(field_name, position) \
  154. static_assert(offsetof(MaxwellDMA::Regs, field_name) == position * 4, \
  155. "Field " #field_name " has invalid position")
  156. ASSERT_REG_POSITION(exec, 0xC0);
  157. ASSERT_REG_POSITION(src_address, 0x100);
  158. ASSERT_REG_POSITION(dst_address, 0x102);
  159. ASSERT_REG_POSITION(src_pitch, 0x104);
  160. ASSERT_REG_POSITION(dst_pitch, 0x105);
  161. ASSERT_REG_POSITION(x_count, 0x106);
  162. ASSERT_REG_POSITION(y_count, 0x107);
  163. ASSERT_REG_POSITION(const0, 0x1C0);
  164. ASSERT_REG_POSITION(const1, 0x1C1);
  165. ASSERT_REG_POSITION(swizzle_config, 0x1C2);
  166. ASSERT_REG_POSITION(dst_params, 0x1C3);
  167. ASSERT_REG_POSITION(src_params, 0x1CA);
  168. #undef ASSERT_REG_POSITION
  169. } // namespace Tegra::Engines