kepler_memory.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. #define KEPLERMEMORY_REG_INDEX(field_name) \
  23. (offsetof(Tegra::Engines::KeplerMemory::Regs, field_name) / sizeof(u32))
  24. class KeplerMemory final {
  25. public:
  26. KeplerMemory(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
  27. MemoryManager& memory_manager);
  28. ~KeplerMemory();
  29. /// Write the value to the register identified by method.
  30. void CallMethod(const GPU::MethodCall& method_call);
  31. struct Regs {
  32. static constexpr size_t NUM_REGS = 0x7F;
  33. union {
  34. struct {
  35. INSERT_PADDING_WORDS(0x60);
  36. u32 line_length_in;
  37. u32 line_count;
  38. struct {
  39. u32 address_high;
  40. u32 address_low;
  41. u32 pitch;
  42. union {
  43. BitField<0, 4, u32> block_width;
  44. BitField<4, 4, u32> block_height;
  45. BitField<8, 4, u32> block_depth;
  46. };
  47. u32 width;
  48. u32 height;
  49. u32 depth;
  50. u32 z;
  51. u32 x;
  52. u32 y;
  53. GPUVAddr Address() const {
  54. return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) |
  55. address_low);
  56. }
  57. u32 BlockWidth() const {
  58. return 1U << block_width.Value();
  59. }
  60. u32 BlockHeight() const {
  61. return 1U << block_height.Value();
  62. }
  63. u32 BlockDepth() const {
  64. return 1U << block_depth.Value();
  65. }
  66. } dest;
  67. struct {
  68. union {
  69. BitField<0, 1, u32> linear;
  70. };
  71. } exec;
  72. u32 data;
  73. INSERT_PADDING_WORDS(0x11);
  74. };
  75. std::array<u32, NUM_REGS> reg_array;
  76. };
  77. } regs{};
  78. struct {
  79. u32 write_offset = 0;
  80. u32 copy_size = 0;
  81. std::vector<u8> inner_buffer;
  82. } state{};
  83. private:
  84. Core::System& system;
  85. VideoCore::RasterizerInterface& rasterizer;
  86. MemoryManager& memory_manager;
  87. void ProcessExec();
  88. void ProcessData(u32 data, bool is_last_call);
  89. };
  90. #define ASSERT_REG_POSITION(field_name, position) \
  91. static_assert(offsetof(KeplerMemory::Regs, field_name) == position * 4, \
  92. "Field " #field_name " has invalid position")
  93. ASSERT_REG_POSITION(line_length_in, 0x60);
  94. ASSERT_REG_POSITION(line_count, 0x61);
  95. ASSERT_REG_POSITION(dest, 0x62);
  96. ASSERT_REG_POSITION(exec, 0x6C);
  97. ASSERT_REG_POSITION(data, 0x6D);
  98. #undef ASSERT_REG_POSITION
  99. } // namespace Tegra::Engines