gsp_gpu.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #pragma once
  5. #include <cstddef>
  6. #include <string>
  7. #include "common/bit_field.h"
  8. #include "common/common_types.h"
  9. #include "core/hle/service/service.h"
  10. ////////////////////////////////////////////////////////////////////////////////////////////////////
  11. // Namespace GSP_GPU
  12. namespace GSP_GPU {
  13. /// GSP interrupt ID
  14. enum class InterruptId : u8 {
  15. PSC0 = 0x00,
  16. PSC1 = 0x01,
  17. PDC0 = 0x02, // Seems called every vertical screen line
  18. PDC1 = 0x03, // Seems called every frame
  19. PPF = 0x04,
  20. P3D = 0x05,
  21. DMA = 0x06,
  22. };
  23. /// GSP command ID
  24. enum class CommandId : u32 {
  25. REQUEST_DMA = 0x00,
  26. /// Submits a commandlist for execution by the GPU.
  27. SUBMIT_GPU_CMDLIST = 0x01,
  28. // Fills a given memory range with a particular value
  29. SET_MEMORY_FILL = 0x02,
  30. // Copies an image and optionally performs color-conversion or scaling.
  31. // This is highly similar to the GameCube's EFB copy feature
  32. SET_DISPLAY_TRANSFER = 0x03,
  33. // Conceptionally similar to SET_DISPLAY_TRANSFER and presumable uses the same hardware path
  34. SET_TEXTURE_COPY = 0x04,
  35. /// Flushes up to 3 cache regions in a single command.
  36. CACHE_FLUSH = 0x05,
  37. };
  38. /// GSP thread interrupt relay queue
  39. struct InterruptRelayQueue {
  40. // Index of last interrupt in the queue
  41. u8 index;
  42. // Number of interrupts remaining to be processed by the userland code
  43. u8 number_interrupts;
  44. // Error code - zero on success, otherwise an error has occurred
  45. u8 error_code;
  46. u8 padding1;
  47. u32 missed_PDC0;
  48. u32 missed_PDC1;
  49. InterruptId slot[0x34]; ///< Interrupt ID slots
  50. };
  51. static_assert(sizeof(InterruptRelayQueue) == 0x40,
  52. "InterruptRelayQueue struct has incorrect size");
  53. struct FrameBufferInfo {
  54. BitField<0, 1, u32> active_fb; // 0 = first, 1 = second
  55. u32 address_left;
  56. u32 address_right;
  57. u32 stride; // maps to 0x1EF00X90 ?
  58. u32 format; // maps to 0x1EF00X70 ?
  59. u32 shown_fb; // maps to 0x1EF00X78 ?
  60. u32 unknown;
  61. };
  62. static_assert(sizeof(FrameBufferInfo) == 0x1c, "Struct has incorrect size");
  63. struct FrameBufferUpdate {
  64. BitField<0, 1, u8> index; // Index used for GSP::SetBufferSwap
  65. BitField<0, 1, u8> is_dirty; // true if GSP should update GPU framebuffer registers
  66. u16 pad1;
  67. FrameBufferInfo framebuffer_info[2];
  68. u32 pad2;
  69. };
  70. static_assert(sizeof(FrameBufferUpdate) == 0x40, "Struct has incorrect size");
  71. // TODO: Not sure if this padding is correct.
  72. // Chances are the second block is stored at offset 0x24 rather than 0x20.
  73. #ifndef _MSC_VER
  74. static_assert(offsetof(FrameBufferUpdate, framebuffer_info[1]) == 0x20, "FrameBufferInfo element has incorrect alignment");
  75. #endif
  76. /// GSP command
  77. struct Command {
  78. BitField<0, 8, CommandId> id;
  79. union {
  80. struct {
  81. u32 source_address;
  82. u32 dest_address;
  83. u32 size;
  84. } dma_request;
  85. struct {
  86. u32 address;
  87. u32 size;
  88. u32 flags;
  89. u32 unused[3];
  90. u32 do_flush;
  91. } submit_gpu_cmdlist;
  92. struct {
  93. u32 start1;
  94. u32 value1;
  95. u32 end1;
  96. u32 start2;
  97. u32 value2;
  98. u32 end2;
  99. u16 control1;
  100. u16 control2;
  101. } memory_fill;
  102. struct {
  103. u32 in_buffer_address;
  104. u32 out_buffer_address;
  105. u32 in_buffer_size;
  106. u32 out_buffer_size;
  107. u32 flags;
  108. } display_transfer;
  109. struct {
  110. u32 in_buffer_address;
  111. u32 out_buffer_address;
  112. u32 size;
  113. u32 in_width_gap;
  114. u32 out_width_gap;
  115. u32 flags;
  116. } texture_copy;
  117. struct {
  118. struct {
  119. u32 address;
  120. u32 size;
  121. } regions[3];
  122. } cache_flush;
  123. u8 raw_data[0x1C];
  124. };
  125. };
  126. static_assert(sizeof(Command) == 0x20, "Command struct has incorrect size");
  127. /// GSP shared memory GX command buffer header
  128. struct CommandBuffer {
  129. union {
  130. u32 hex;
  131. // Current command index. This index is updated by GSP module after loading the command
  132. // data, right before the command is processed. When this index is updated by GSP module,
  133. // the total commands field is decreased by one as well.
  134. BitField<0,8,u32> index;
  135. // Total commands to process, must not be value 0 when GSP module handles commands. This
  136. // must be <=15 when writing a command to shared memory. This is incremented by the
  137. // application when writing a command to shared memory, after increasing this value
  138. // TriggerCmdReqQueue is only used if this field is value 1.
  139. BitField<8,8,u32> number_commands;
  140. };
  141. u32 unk[7];
  142. Command commands[0xF];
  143. };
  144. static_assert(sizeof(CommandBuffer) == 0x200, "CommandBuffer struct has incorrect size");
  145. /// Interface to "srv:" service
  146. class Interface : public Service::Interface {
  147. public:
  148. Interface();
  149. ~Interface() override;
  150. std::string GetPortName() const override {
  151. return "gsp::Gpu";
  152. }
  153. };
  154. /**
  155. * Signals that the specified interrupt type has occurred to userland code
  156. * @param interrupt_id ID of interrupt that is being signalled
  157. */
  158. void SignalInterrupt(InterruptId interrupt_id);
  159. void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info);
  160. /**
  161. * Retrieves the framebuffer info stored in the GSP shared memory for the
  162. * specified screen index and thread id.
  163. * @param thread_id GSP thread id of the process that accesses the structure that we are requesting.
  164. * @param screen_index Index of the screen we are requesting (Top = 0, Bottom = 1).
  165. * @returns FramebufferUpdate Information about the specified framebuffer.
  166. */
  167. FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index);
  168. } // namespace