gsp_gpu.h 4.9 KB

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