libctru v2.5.0
Loading...
Searching...
No Matches
gspgpu.h
Go to the documentation of this file.
1/**
2 * @file gspgpu.h
3 * @brief GSPGPU service.
4 */
5#pragma once
6
7#define GSP_SCREEN_TOP 0 ///< ID of the top screen.
8#define GSP_SCREEN_BOTTOM 1 ///< ID of the bottom screen.
9#define GSP_SCREEN_WIDTH 240 ///< Width of the top/bottom screens.
10#define GSP_SCREEN_HEIGHT_TOP 400 ///< Height of the top screen.
11#define GSP_SCREEN_HEIGHT_TOP_2X 800 ///< Height of the top screen (2x).
12#define GSP_SCREEN_HEIGHT_BOTTOM 320 ///< Height of the bottom screen.
13
14/// Framebuffer information.
15typedef struct
16{
17 u32 active_framebuf; ///< Active framebuffer. (0 = first, 1 = second)
18 u32 *framebuf0_vaddr; ///< Framebuffer virtual address, for the main screen this is the 3D left framebuffer.
19 u32 *framebuf1_vaddr; ///< For the main screen: 3D right framebuffer address.
20 u32 framebuf_widthbytesize; ///< Value for 0x1EF00X90, controls framebuffer width.
21 u32 format; ///< Framebuffer format, this u16 is written to the low u16 for LCD register 0x1EF00X70.
22 u32 framebuf_dispselect; ///< Value for 0x1EF00X78, controls which framebuffer is displayed.
23 u32 unk; ///< Unknown.
25
26/// Framebuffer format.
27typedef enum
28{
29 GSP_RGBA8_OES=0, ///< RGBA8. (4 bytes)
30 GSP_BGR8_OES=1, ///< BGR8. (3 bytes)
31 GSP_RGB565_OES=2, ///< RGB565. (2 bytes)
32 GSP_RGB5_A1_OES=3, ///< RGB5A1. (2 bytes)
33 GSP_RGBA4_OES=4 ///< RGBA4. (2 bytes)
35
36/// Capture info entry.
37typedef struct
38{
39 u32 *framebuf0_vaddr; ///< Left framebuffer.
40 u32 *framebuf1_vaddr; ///< Right framebuffer.
41 u32 format; ///< Framebuffer format.
42 u32 framebuf_widthbytesize; ///< Framebuffer pitch.
44
45/// Capture info.
46typedef struct
47{
48 GSPGPU_CaptureInfoEntry screencapture[2]; ///< Capture info entries, one for each screen.
50
51/// GSPGPU events.
52typedef enum
53{
54 GSPGPU_EVENT_PSC0 = 0, ///< Memory fill completed.
58 GSPGPU_EVENT_PPF, ///< Display transfer finished.
59 GSPGPU_EVENT_P3D, ///< Command list processing finished.
61
62 GSPGPU_EVENT_MAX, ///< Used to know how many events there are.
64
65/**
66 * GSPGPU performance log entry.
67 *
68 * Use the lastDurationUs field when benchmarking single GPU operations, this is usally meant
69 * for 3D library writers.
70 *
71 * Use the difference between two totalDurationUs when using a GPU library (e.g. citro3d), as
72 * there can be multiple GPU operations (e.g. P3D, PPF) per render pass, or per frame, and so on.
73 * Don't use totalDurationUs as-is (rather, take the difference as just described), because it
74 * can overflow.
75 */
76typedef struct
77{
78 u32 lastDurationUs; ///< Duration of the last corresponding PICA200 operation (time between op is started and IRQ is received).
79 u32 totalDurationUs; ///< Sum of lastDurationUs for the corresponding PICA200 operation. Can overflow.
81
82/// GSPGPU performance log
83typedef struct
84{
85 GSPGPU_PerfLogEntry entries[GSPGPU_EVENT_MAX]; ///< Performance log entries (one per operation/"event").
87
88/**
89 * @brief Gets the number of bytes per pixel for the specified format.
90 * @param format See \ref GSPGPU_FramebufferFormat.
91 * @return Bytes per pixel.
92 */
93static inline unsigned gspGetBytesPerPixel(GSPGPU_FramebufferFormat format)
94{
95 switch (format)
96 {
97 case GSP_RGBA8_OES:
98 return 4;
99 default:
100 case GSP_BGR8_OES:
101 return 3;
102 case GSP_RGB565_OES:
103 case GSP_RGB5_A1_OES:
104 case GSP_RGBA4_OES:
105 return 2;
106 }
107}
108
109/// Initializes GSPGPU.
111
112/// Exits GSPGPU.
113void gspExit(void);
114
115/**
116 * @brief Gets a pointer to the current gsp::Gpu session handle.
117 * @return A pointer to the current gsp::Gpu session handle.
118 */
120
121/// Returns true if the application currently has GPU rights.
122bool gspHasGpuRight(void);
123
124/**
125 * @brief Presents a buffer to the specified screen.
126 * @param screen Screen ID (see \ref GSP_SCREEN_TOP and \ref GSP_SCREEN_BOTTOM)
127 * @param swap Specifies which set of framebuffer registers to configure and activate (0 or 1)
128 * @param fb_a Pointer to the framebuffer (in stereo mode: left eye)
129 * @param fb_b Pointer to the secondary framebuffer (only used in stereo mode for the right eye, otherwise pass the same as fb_a)
130 * @param stride Stride in bytes between scanlines
131 * @param mode Mode configuration to be written to LCD register
132 * @return true if a buffer had already been presented to the screen but not processed yet by GSP, false otherwise.
133 * @note The most recently presented buffer is processed and configured during the specified screen's next VBlank event.
134 */
135bool gspPresentBuffer(unsigned screen, unsigned swap, const void* fb_a, const void* fb_b, u32 stride, u32 mode);
136
137/**
138 * @brief Returns true if a prior \ref gspPresentBuffer command is still pending to be processed by GSP.
139 * @param screen Screen ID (see \ref GSP_SCREEN_TOP and \ref GSP_SCREEN_BOTTOM)
140 */
141bool gspIsPresentPending(unsigned screen);
142
143/**
144 * @brief Configures a callback to run when a GSPGPU event occurs.
145 * @param id ID of the event.
146 * @param cb Callback to run.
147 * @param data Data to be passed to the callback.
148 * @param oneShot When true, the callback is only executed once. When false, the callback is executed every time the event occurs.
149 */
150void gspSetEventCallback(GSPGPU_Event id, ThreadFunc cb, void* data, bool oneShot);
151
152/**
153 * @brief Waits for a GSPGPU event to occur.
154 * @param id ID of the event.
155 * @param nextEvent Whether to discard the current event and wait for the next event.
156 */
157void gspWaitForEvent(GSPGPU_Event id, bool nextEvent);
158
159/**
160 * @brief Waits for any GSPGPU event to occur.
161 * @return The ID of the event that occurred.
162 *
163 * The function returns immediately if there are unprocessed events at the time of call.
164 */
166
167/// Waits for PSC0
168#define gspWaitForPSC0() gspWaitForEvent(GSPGPU_EVENT_PSC0, false)
169
170/// Waits for PSC1
171#define gspWaitForPSC1() gspWaitForEvent(GSPGPU_EVENT_PSC1, false)
172
173/// Waits for VBlank.
174#define gspWaitForVBlank() gspWaitForVBlank0()
175
176/// Waits for VBlank0.
177#define gspWaitForVBlank0() gspWaitForEvent(GSPGPU_EVENT_VBlank0, true)
178
179/// Waits for VBlank1.
180#define gspWaitForVBlank1() gspWaitForEvent(GSPGPU_EVENT_VBlank1, true)
181
182/// Waits for PPF.
183#define gspWaitForPPF() gspWaitForEvent(GSPGPU_EVENT_PPF, false)
184
185/// Waits for P3D.
186#define gspWaitForP3D() gspWaitForEvent(GSPGPU_EVENT_P3D, false)
187
188/// Waits for DMA.
189#define gspWaitForDMA() gspWaitForEvent(GSPGPU_EVENT_DMA, false)
190
191/**
192 * @brief Submits a GX command.
193 * @param gxCommand GX command to execute.
194 */
195Result gspSubmitGxCommand(const u32 gxCommand[0x8]);
196
197/**
198 * @brief Acquires GPU rights.
199 * @param flags Flags to acquire with.
200 */
202
203/// Releases GPU rights.
205
206/**
207 * @brief Retrieves display capture info.
208 * @param captureinfo Pointer to output capture info to.
209 */
211
212/// Saves the VRAM sys area.
214
215/// Resets the GPU
217
218/// Restores the VRAM sys area.
220
221/**
222 * @brief Sets whether to force the LCD to black.
223 * @param flags Whether to force the LCD to black. (0 = no, non-zero = yes)
224 */
226
227/**
228 * @brief Updates a screen's framebuffer state.
229 * @param screenid ID of the screen to update.
230 * @param framebufinfo Framebuffer information to update with.
231 */
233
234/**
235 * @brief Flushes memory from the data cache.
236 * @param adr Address to flush.
237 * @param size Size of the memory to flush.
238 */
239Result GSPGPU_FlushDataCache(const void* adr, u32 size);
240
241/**
242 * @brief Invalidates memory in the data cache.
243 * @param adr Address to invalidate.
244 * @param size Size of the memory to invalidate.
245 */
246Result GSPGPU_InvalidateDataCache(const void* adr, u32 size);
247
248/**
249 * @brief Writes to GPU hardware registers.
250 * @param regAddr Register address to write to.
251 * @param data Data to write.
252 * @param size Size of the data to write.
253 */
254Result GSPGPU_WriteHWRegs(u32 regAddr, const u32* data, u8 size);
255
256/**
257 * @brief Writes to GPU hardware registers with a mask.
258 * @param regAddr Register address to write to.
259 * @param data Data to write.
260 * @param datasize Size of the data to write.
261 * @param maskdata Data of the mask.
262 * @param masksize Size of the mask.
263 */
264Result GSPGPU_WriteHWRegsWithMask(u32 regAddr, const u32* data, u8 datasize, const u32* maskdata, u8 masksize);
265
266/**
267 * @brief Reads from GPU hardware registers.
268 * @param regAddr Register address to read from.
269 * @param data Buffer to read data to.
270 * @param size Size of the buffer.
271 */
272Result GSPGPU_ReadHWRegs(u32 regAddr, u32* data, u8 size);
273
274/**
275 * @brief Registers the interrupt relay queue.
276 * @param eventHandle Handle of the GX command event.
277 * @param flags Flags to register with.
278 * @param outMemHandle Pointer to output the shared memory handle to.
279 * @param threadID Pointer to output the GSP thread ID to.
280 */
281Result GSPGPU_RegisterInterruptRelayQueue(Handle eventHandle, u32 flags, Handle* outMemHandle, u8* threadID);
282
283/// Unregisters the interrupt relay queue.
285
286/// Triggers a handling of commands written to shared memory.
288
289/**
290 * @brief Sets 3D_LEDSTATE to the input state value.
291 * @param disable False = 3D LED enable, true = 3D LED disable.
292 */
294
295/**
296 * @brief Enables or disables the performance log and clear
297 * its state to zero.
298 * @param enabled Whether to enable the performance log.
299 * @note It is assumed that no GPU operation is in progress when calling this function.
300 * @bug The official sysmodule forgets to clear the "start tick" states to 0, though
301 * this should not be much of an issue (as per the note above).
302 */
304
305/**
306 * @brief Retrieves the performance log.
307 * @param[out] outPerfLog Pointer to output the performance log to.
308 * @note Use the difference between two totalDurationUs when using a GPU library (e.g. citro3d), as
309 * there can be multiple GPU operations (e.g. P3D, PPF) per render pass, or per frame, and so on.
310 * Don't use totalDurationUs as-is (rather, take the difference as just described), because it
311 * can overflow.
312 * @note For a MemoryFill operation that uses both PSC0 and PSC1, take the maximum
313 * of the two "last duration" entries.
314 * @note For PDC0/PDC1 (VBlank0/1), the "last duration" entry corresponds to the time between
315 * the current PDC (VBlank) IRQ and the previous one. The official GSP sysmodule
316 * assumes both PDC0 and PDC1 IRQ happens at the same rate (this is almost always
317 * the case, but not always if user changes PDC timings), and sets both entries
318 * in the PDC0 handler.
319 * @bug The official sysmodule doesn't handle the PDC0/1 entries correctly after init. On the first
320 * frame \ref GSPGPU_SetPerfLogMode is enabled, "last duration" will have a nonsensical
321 * value; and "total duration" stays nonsensical. This isn't much of a problem, except for the
322 * first frame, because "total duration" is not supposed to be used as-is (you are supposed
323 * to take the difference of this field between two time points of your choosing, instead).
324 * @bug Since it is running at approx. 3.25 GiB/s per bank, some small PSC operations might
325 * complete before the official GSP has time to record the start time.
326 * @bug The official sysmodule doesn't properly handle data synchronization for the perflog,
327 * in practice this should be fine, however.
328 */
bool gspIsPresentPending(unsigned screen)
Returns true if a prior gspPresentBuffer command is still pending to be processed by GSP.
Result gspInit(void)
Initializes GSPGPU.
GSPGPU_Event
GSPGPU events.
Definition gspgpu.h:53
@ GSPGPU_EVENT_MAX
Used to know how many events there are.
Definition gspgpu.h:62
@ GSPGPU_EVENT_PPF
Display transfer finished.
Definition gspgpu.h:58
@ GSPGPU_EVENT_VBlank0
TODO.
Definition gspgpu.h:56
@ GSPGPU_EVENT_DMA
TODO.
Definition gspgpu.h:60
@ GSPGPU_EVENT_PSC0
Memory fill completed.
Definition gspgpu.h:54
@ GSPGPU_EVENT_PSC1
TODO.
Definition gspgpu.h:55
@ GSPGPU_EVENT_VBlank1
TODO.
Definition gspgpu.h:57
@ GSPGPU_EVENT_P3D
Command list processing finished.
Definition gspgpu.h:59
Result GSPGPU_SetLcdForceBlack(u8 flags)
Sets whether to force the LCD to black.
void gspExit(void)
Exits GSPGPU.
Result GSPGPU_FlushDataCache(const void *adr, u32 size)
Flushes memory from the data cache.
Result GSPGPU_AcquireRight(u8 flags)
Acquires GPU rights.
void gspSetEventCallback(GSPGPU_Event id, ThreadFunc cb, void *data, bool oneShot)
Configures a callback to run when a GSPGPU event occurs.
Result gspSubmitGxCommand(const u32 gxCommand[0x8])
Submits a GX command.
Result GSPGPU_SetLedForceOff(bool disable)
Sets 3D_LEDSTATE to the input state value.
Result GSPGPU_RegisterInterruptRelayQueue(Handle eventHandle, u32 flags, Handle *outMemHandle, u8 *threadID)
Registers the interrupt relay queue.
Result GSPGPU_SaveVramSysArea(void)
Saves the VRAM sys area.
Result GSPGPU_RestoreVramSysArea(void)
Restores the VRAM sys area.
Result GSPGPU_ImportDisplayCaptureInfo(GSPGPU_CaptureInfo *captureinfo)
Retrieves display capture info.
Result GSPGPU_WriteHWRegs(u32 regAddr, const u32 *data, u8 size)
Writes to GPU hardware registers.
Result GSPGPU_UnregisterInterruptRelayQueue(void)
Unregisters the interrupt relay queue.
GSPGPU_Event gspWaitForAnyEvent(void)
Waits for any GSPGPU event to occur.
static unsigned gspGetBytesPerPixel(GSPGPU_FramebufferFormat format)
Gets the number of bytes per pixel for the specified format.
Definition gspgpu.h:93
Handle * gspGetSessionHandle(void)
Gets a pointer to the current gsp::Gpu session handle.
void gspWaitForEvent(GSPGPU_Event id, bool nextEvent)
Waits for a GSPGPU event to occur.
Result GSPGPU_ReleaseRight(void)
Releases GPU rights.
Result GSPGPU_TriggerCmdReqQueue(void)
Triggers a handling of commands written to shared memory.
bool gspHasGpuRight(void)
Returns true if the application currently has GPU rights.
Result GSPGPU_GetPerfLog(GSPGPU_PerfLog *outPerfLog)
Retrieves the performance log.
Result GSPGPU_InvalidateDataCache(const void *adr, u32 size)
Invalidates memory in the data cache.
bool gspPresentBuffer(unsigned screen, unsigned swap, const void *fb_a, const void *fb_b, u32 stride, u32 mode)
Presents a buffer to the specified screen.
Result GSPGPU_SetPerfLogMode(bool enabled)
Enables or disables the performance log and clear its state to zero.
Result GSPGPU_WriteHWRegsWithMask(u32 regAddr, const u32 *data, u8 datasize, const u32 *maskdata, u8 masksize)
Writes to GPU hardware registers with a mask.
GSPGPU_FramebufferFormat
Framebuffer format.
Definition gspgpu.h:28
@ GSP_RGB5_A1_OES
RGB5A1. (2 bytes)
Definition gspgpu.h:32
@ GSP_RGBA4_OES
RGBA4. (2 bytes)
Definition gspgpu.h:33
@ GSP_BGR8_OES
BGR8. (3 bytes)
Definition gspgpu.h:30
@ GSP_RGBA8_OES
RGBA8. (4 bytes)
Definition gspgpu.h:29
@ GSP_RGB565_OES
RGB565. (2 bytes)
Definition gspgpu.h:31
Result GSPGPU_ResetGpuCore(void)
Resets the GPU.
Result GSPGPU_ReadHWRegs(u32 regAddr, u32 *data, u8 size)
Reads from GPU hardware registers.
Result GSPGPU_SetBufferSwap(u32 screenid, const GSPGPU_FramebufferInfo *framebufinfo)
Updates a screen's framebuffer state.
Capture info entry.
Definition gspgpu.h:38
u32 format
Framebuffer format.
Definition gspgpu.h:41
u32 * framebuf1_vaddr
Right framebuffer.
Definition gspgpu.h:40
u32 * framebuf0_vaddr
Left framebuffer.
Definition gspgpu.h:39
u32 framebuf_widthbytesize
Framebuffer pitch.
Definition gspgpu.h:42
Capture info.
Definition gspgpu.h:47
Framebuffer information.
Definition gspgpu.h:16
u32 unk
Unknown.
Definition gspgpu.h:23
u32 framebuf_widthbytesize
Value for 0x1EF00X90, controls framebuffer width.
Definition gspgpu.h:20
u32 format
Framebuffer format, this u16 is written to the low u16 for LCD register 0x1EF00X70.
Definition gspgpu.h:21
u32 * framebuf0_vaddr
Framebuffer virtual address, for the main screen this is the 3D left framebuffer.
Definition gspgpu.h:18
u32 active_framebuf
Active framebuffer. (0 = first, 1 = second)
Definition gspgpu.h:17
u32 * framebuf1_vaddr
For the main screen: 3D right framebuffer address.
Definition gspgpu.h:19
u32 framebuf_dispselect
Value for 0x1EF00X78, controls which framebuffer is displayed.
Definition gspgpu.h:22
GSPGPU performance log entry.
Definition gspgpu.h:77
u32 lastDurationUs
Duration of the last corresponding PICA200 operation (time between op is started and IRQ is received)...
Definition gspgpu.h:78
u32 totalDurationUs
Sum of lastDurationUs for the corresponding PICA200 operation. Can overflow.
Definition gspgpu.h:79
GSPGPU performance log.
Definition gspgpu.h:84
void(* ThreadFunc)(void *)
Thread entrypoint function.
Definition types.h:43
uint8_t u8
would be nice if newlib had this already
Definition types.h:21
u32 Handle
Resource handle.
Definition types.h:41
s32 Result
Function result.
Definition types.h:42
uint32_t u32
32-bit unsigned integer
Definition types.h:23