1 /*---------------------------------------------------------------------------*
2 
3   Copyright (C) 2010-2011 Nintendo.  All rights reserved.
4 
5   These coded instructions, statements, and computer programs contain
6   proprietary information of Nintendo of America Inc. and/or Nintendo
7   Company Ltd., and are protected by Federal copyright law.  They may
8   not be disclosed to third parties or copied or duplicated in any form,
9   in whole or in part, without the prior written consent of Nintendo.
10 
11  *---------------------------------------------------------------------------*/
12 
13 // gx2Manage.h
14 //
15 // Declares management function prototypes for gx2 library.
16 
17 #ifndef _CAFE_GX2_MANAGE_H_
18 #define _CAFE_GX2_MANAGE_H_
19 
20 #ifdef __cplusplus
21 extern "C"
22 {
23 #endif // __cplusplus
24 
25 
26 /// @addtogroup GX2ManagementGroup
27 /// @{
28 
29 /// @addtogroup GX2ManagementInitGroup
30 /// @{
31 
32 /// \brief Initialize GX2.
33 ///
34 /// GX2Init should be called only once until GX2Shutdown is called (no ref-counting is done).
35 ///
36 /// Calling GX2Init determines which CPU core becomes the "main" core.  Only the thread running on
37 /// the main core can submit GX2 commands to the GPU.  One thread each on other core can still
38 /// create GX2 display lists.  Threads that call GX2 commands must have their affinity set to only a
39 /// single core!  One reason for these restrictions is that GX2 makes use of the write-gather
40 /// facility of the CPU, which has only 1 instance for each core.
41 ///
42 /// The command-buffer pool base address should be set with the \ref GX2_INIT_ATTRIB_CB_BASE attribute.
43 /// The size of the command buffer pool should be specified with the \ref GX2_INIT_ATTRIB_CB_SIZE attribute.
44 /// If \ref GX2_INIT_ATTRIB_CB_BASE is not set, GX2 will allocate the buffer from the default heap.
45 ///
46 /// GX2Init will get argc/argv from the OS, although you may override those values by specifying the
47 /// GX2_INIT_ATTRIB_ARGC and GX2_INIT_ATTRIB_ARGV attributes.
48 ///
49 /// Command-line arguments for GX2 are gathered from the OS.  The arguments that GX2 recognizes are:
50 /// - -tvesync        : Waits for TV handshake to finish before continuing
51 /// - -profile_mode=N : Sets the \ref GX2ProfileMode to the value N (in decimal, or 0xN for hex)
52 /// - -toss_stage=N   : Sets the \ref GX2TossStage to the value N
53 ///
54 /// The profiling mode can also be set with \ref GX2_INIT_ATTRIB_PROFILE_MODE attrib.
55 /// The toss stage can also be set with \ref GX2_INIT_ATTRIB_TOSS_STAGE attrib.
56 /// Command-line values for these will override attribute values.
57 ///
58 /// \param initAttribs  A list of \ref GX2InitAttrib, each followed by their value,
59 ///                     terminated with 0 (\ref GX2_INIT_ATTRIB_NULL), or NULL if no attribs needed.
60 ///
61 /// \donotcall
62 /// \gx2_dl
63 /// \nomulticore
64 /// \userheap{\ref GX2_INIT_ATTRIB_CB_BASE is not set. This will be from the default heap.}
65 /// \enddonotcall
66 
67 ///
68 /// \writesgpu
69 /// \alwayswritesgpu
70 ///
71 void GX2API GX2Init(u32 *initAttribs);
72 
73 /// \brief Shutdown GX2.
74 ///
75 /// \note If you didn't call \ref GX2Init from the default core, then you must be sure
76 /// to synchronize the cores after calling GX2Shutdown to prevent a race condition where
77 /// the OS shuts down lower-level drivers before GX2 is properly shut down.
78 ///
79 /// \note GX2 frees command buffer pool from system dedicated heap, if it is allocated.
80 ///
81 /// \donotcall
82 /// \gx2_dl
83 /// \nomulticore
84 /// \userheap{\ref GX2_INIT_ATTRIB_CB_BASE is not set when \ref GX2Init is called. This will be to the default heap.}
85 /// \enddonotcall
86 ///
87 /// \writesgpu
88 /// \alwayswritesgpu
89 ///
90 void GX2API GX2Shutdown(void);
91 
92 /// \brief Returns core id which GX2 was initialized on; returns -1 if GX2 is not initialized.
93 ///
94 /// \donotcall \threadsafe \devonly \enddonotcall
95 ///
96 s32 GX2API GX2GetMainCoreId(void);
97 
98 /// @}
99 /// @addtogroup GX2ManagementSyncGroup
100 /// @{
101 
102 /// \brief Send any buffered graphics commands to the GPU.
103 ///
104 /// \donotcall \nomulticore \gx2_dl \enddonotcall
105 ///
106 /// \writesgpu
107 /// \writesgpu{if commands are in the command buffer}
108 ///
109 void GX2API GX2Flush(void);
110 
111 /// \brief Have CPU wait until GPU finishes all submitted commands.
112 ///
113 /// \note This puts the thread to sleep until the work is done.
114 /// \note This calls GX2Flush internally so that you don't have to.
115 /// \note This must be called immediately prior to calling
116 ///       <a href="../../procswitch/procui/processmessages.html">ProcUIProcessMessage</a>.
117 ///
118 /// \donotcall \nomulticore \gx2_dl \enddonotcall
119 ///
120 /// \writesgpu
121 /// \alwayswritesgpu
122 ///
123 GX2Boolean GX2API GX2DrawDone(void);
124 
125 /// \brief Get timestamp of last submitted (flushed) command buffer.
126 ///
127 /// \donotcall \threadsafe \devonly \enddonotcall
128 ///
129 u64 GX2API GX2GetLastSubmittedTimeStamp(void);
130 
131 /// \brief Get timestamp of last command buffer that GPU has finished processing.
132 ///
133 /// \donotcall \notthreadsafe \devonly \enddonotcall
134 ///
135 u64 GX2API GX2GetRetiredTimeStamp(void);
136 
137 /// \brief Wait until the timestamp is returned from the GPU.  GX2_FALSE will be returned if the
138 /// timeout was reached before the timestamp value was returned from the GPU.
139 ///
140 /// \donotcall \gx2_typical \enddonotcall
141 ///
142 /// \writesgpu
143 /// \directwritesgpu
144 ///
145 GX2Boolean GX2API GX2WaitTimeStamp(u64 ts);
146 
147 // ----
148 
149 /// \brief GX2 display list overrun callback structure.
150 ///
151 /// When GX2 detects a display overrun condition, it will invoke the optional
152 /// \ref GX2_CB_EVENT_DL_OVERRUN callback function. The user-provided data
153 /// pointer \p userDataPtr must point to a structure that begins with a
154 /// \ref GX2DisplayListOverrun structure when invoking \ref GX2SetEventCallback.
155 /// The \ref GX2DisplayListOverrun structure provides for communication between
156 /// GX2 and the user in handling the overrun condition.
157 ///
158 /// When the user callback function is invoked, GX2 will initialize the
159 /// contents of \p oldDisplayList and \p oldByteSize with the display list
160 /// information for the buffer that caused the overrun in the current core.
161 /// \p newByteSize will be set to the minimum required space needed. The
162 /// callback function must allocate a new display list buffer and set
163 /// \p newDisplayList and \p newByteSize appropriately before returning
164 /// control to GX2.
165 ///
166 /// \warning Display lists generated using the overrun callback must be
167 ///          called sequentially.
168 ///
169 /// \sa GX2SetEventCallback
170 ///
171 typedef struct _GX2DisplayListOverrun {
172     void *oldDisplayList;   ///< Pointer to the original display list buffer
173     u32   oldByteSize;      ///< Final size of the original display list buffer
174     void *newDisplayList;   ///< Pointer to a new display list buffer
175     u32   newByteSize;      ///< Size of the new display list buffer that was
176                             ///  allocated. When the callback is called, GX2
177                             ///  sets this to the minimum size that should be
178                             ///  allocated for the new display list.
179     u32   padding0;         ///< Reserved for future use, must be 0
180     u32   padding1;         ///< Reserved for future use, must be 0
181 } GX2DisplayListOverrun;
182 
183 /// \brief Prototype for GX2 (interrupt) callback functions.
184 ///
185 /// \param event       The event which resulted in this callback.
186 /// \param userDataPtr The user data pointer which was provided when the callback was set up.
187 ///
188 typedef void (*GX2CallbackFunction)(GX2CallbackEvent event, void *userDataPtr);
189 
190 /// \brief Set up a callback for a GX2 event.
191 ///
192 /// \param event       The event that this callback will handle.
193 /// \param functionPtr A pointer to the callback function.
194 /// \param userDataPtr A pointer which will be passed to the callback when the event occurs.
195 ///
196 /// \note The \ref GX2_CB_EVENT_USER_TS_BOTTOM event shares an interrupt that
197 ///       is also used by the command-buffer-management code.  The callback will
198 ///       also get called for each command buffer or direct display list that
199 ///       is sent to the GPU. The callback will need to look at the returned
200 ///       timestamp and compare with the previous one to determine if the event
201 ///       was triggered by a user time stamp or a system one.
202 ///
203 /// \note If you set the \ref GX2_CB_EVENT_USER_TS_BOTTOM callback, you will
204 ///       also disable an optimization to ignore (mask) bottom-of-pipe
205 ///       interrupts until the command-buffer-management code actually cares
206 ///       about them. Set the callback to NULL when it is not being used to
207 ///       reenable this optimization.
208 ///
209 /// \note If you set the \ref GX2_CB_EVENT_DL_OVERRUN callback, you must specify
210 ///       a valid \p userDataPtr that begins with the structure
211 ///       \ref GX2DisplayListOverrun.  When the callback is invoked, the
212 ///       application must update this structure to point to a new display list
213 ///       to be used for future GX2 API calls. During this callback it is
214 ///       \b forbidden to call any GX2 APIs as this may result in a recursive
215 ///       call to the callback. For more information see
216 ///       \ref GX2DisplayListOverrun.
217 ///
218 /// \warning Failing to set the \ref GX2_CB_EVENT_DL_OVERRUN callback or failure
219 ///          to provide a valid display list before exiting the callback
220 ///          function will result in an OSPanic error being invoked if a
221 ///          display list buffer overrun occurs.
222 ///
223 /// \warning Display lists generated using the overrun callback must be
224 ///          called sequentially.
225 ///
226 /// \donotcall \gx2_typical \enddonotcall
227 ///
228 void GX2API GX2SetEventCallback(GX2CallbackEvent event, GX2CallbackFunction functionPtr, void *userDataPtr);
229 
230 /// \brief Get info about callback for a GX2 event.
231 ///
232 /// \param event       The event that the callback handles.
233 /// \param functionPtr A return pointer for the callback function pointer.
234 /// \param userDataPtr A return pointer for the user-provided data pointer.
235 ///
236 /// \donotcall \threadsafe \devonly \enddonotcall
237 ///
238 void GX2API GX2GetEventCallback(GX2CallbackEvent event, GX2CallbackFunction *functionPtr, void **userDataPtr);
239 
240 /// \brief Request the GPU to write out a user time stamp.
241 ///
242 /// When the GPU reaches the indicated event, it will write out
243 /// the timeStampValue to the given tsBuffer location.  If
244 /// requested, it can also trigger an interrupt callback request.
245 ///
246 /// \note Please see \ref GX2SetEventCallback for notes regarding the
247 /// GX2_CB_EVENT_USER_TS_BOTTOM event.
248 ///
249 /// \note The time stamp value is written with the lower 32 bits first
250 /// (due to hardware limitations).  The value must not be written to a
251 /// cacheline that is shared with any CPU-written data.
252 ///
253 /// \param tsBuffer       A pointer for where the time stamp value will be written.
254 /// \param timeStampValue The time stamp value to write when the event occurs.
255 /// \param when           The point in time at which to write the time stamp.
256 /// \param triggerIntCB   A boolean indicating if the event should trigger an interrupt callback.
257 ///
258 /// \donotcall \gx2_typical \enddonotcall
259 ///
260 /// \writesgpu
261 /// \alwayswritesgpu
262 ///
263 void GX2API GX2SubmitUserTimeStamp(u64 *tsBuffer, u64 timeStampValue, GX2PipeEvent when, GX2Boolean triggerIntCB);
264 
265 /// \brief Helper function to properly read a user timestamp value.
266 ///
267 /// \param  tsBuffer The pointer to the time stamp buffer.
268 /// \return          The value in the time stamp buffer.
269 ///
270 /// \donotcall \notthreadsafe \devonly \enddonotcall
271 ///
GX2ReadUserTimeStamp(u64 * tsBuffer)272 GX2_INLINE u64 GX2ReadUserTimeStamp(u64 *tsBuffer) {
273     // This will destroy any CPU-written data in the same cacheline:
274     DCInvalidateRange((void *) tsBuffer, 32);
275     return ((*tsBuffer)>>32) | ((*tsBuffer)<<32);
276 }
277 
278 /// \brief Make GPU CP wait for ((*fencePtr & fenceMask) op fenceValue) before proceeding.
279 ///
280 /// The wait is done at the top of the pipeline.  An operation of GX2_COMPARE_NEVER is not allowed
281 /// (it would hang the GPU).
282 ///
283 /// \param fencePtr   Pointer to the u32 value the GPU should read.
284 /// \param fenceMask  The read value is anded with this mask first.
285 /// \param op         The type of compare operation to perform.
286 /// \param fenceValue The value to be compared with.
287 ///
288 /// \donotcall \gx2_typical \enddonotcall
289 ///
290 /// \writesgpu
291 /// \alwayswritesgpu
292 ///
293 void GX2API GX2SetGPUFence(u32 *fencePtr, u32 fenceMask, GX2CompareFunction op, u32 fenceValue);
294 
295 // ----
296 
297 /// \brief Initialize GX2 semaphore.
298 ///
299 /// This is a helper function to initialise the semaphore for syncronize GPU7 with DMA Engine.
300 /// The semaphore value is kept in memory at the given location.
301 /// It is initialized to a given count and flushed from the cache.
302 /// This API has exactly the same functional capability as \ref DMAEInitSemaphore.
303 ///
304 /// \param  semaphoreAddr   Location of semaphore data in memory
305 /// \param  semaphoreCount  Initial semaphore count
306 ///
307 /// \donotcall \notthreadsafe \devonly \enddonotcall
308 ///
GX2InitSemaphore(u64 * semaphoreAddr,u64 semaphoreCount)309 GX2_INLINE void GX2InitSemaphore(u64 *semaphoreAddr, u64 semaphoreCount) {
310     // Store u64 byte-reversed (hardware requirement)
311     * (__bytereversed u64 *) semaphoreAddr = semaphoreCount;
312     DCFlushRange(semaphoreAddr, sizeof(u64));
313 }
314 
315 /// \brief Have GPU7 wait on or signal a memory semaphore.
316 ///
317 /// This function is used to syncronize the GPU with the DMA Engine.
318 /// The semaphore value is kept in memory at the given location.
319 /// It should be initialized and flushed from the cache before use.
320 ///
321 /// \param  semaphoreAddr   Location of semaphore data in memory
322 /// \param  semaphoreAction Indicates whether to wait on or signal the semaphore
323 ///
324 /// \donotcall \gx2_typical \enddonotcall
325 ///
326 /// \writesgpu
327 /// \alwayswritesgpu
328 ///
329 void GX2API GX2SetSemaphore(u64 *semaphoreAddr, GX2SemaphoreAction semaphoreAction);
330 
331 /// @}
332 /// @addtogroup GX2ManagementResetGroup
333 /// @{
334 
335 /// \brief Set a new value for various GX2 miscellaneous system parameters.
336 ///
337 /// This function is a general entry point for setting various GX2 parameters.
338 /// These parameters relate to GPU reset at the moment, but might be extended to
339 /// other types of functionality in the future.
340 ///
341 /// The available parameters are:
342 ///  - GX2_MISC_HANG_STATE: indicates if GPU is hung; returns:
343 ///    - GX2_HANG_STATE_OK: GPU is okay.
344 ///    - GX2_HANG_STATE_TS: time-out waiting for timestamp or GX2DrawDone.
345 ///    - GX2_HANG_STATE_CB: time-out waiting for command buffer space.
346 ///    - GX2_HANG_STATE_RB: time-out waiting for ring buffer space.
347 ///    - GX2_HANG_STATE_WF: time-out waiting for scan buffer flip (GX2WaitForFlip).
348 ///    - GX2_HANG_STATE_ETC: a named value that the user may set to indicate a hang.
349 ///  - GX2_MISC_HANG_RESPONSE: indicates response to GPU time-out (hang).
350 ///    Default is set based on production/development mode setting:
351 ///    - GX2_HANG_RESPONSE_NONE: set hang state & otherwise do nothing (reset will be done by user code).
352 ///    - GX2_HANG_RESPONSE_DEBUG: dump debug output and wait (Development default).
353 ///    - GX2_HANG_RESPONSE_RESET: set hang state & enable automatic reset at swap buffer time (Production default).
354 ///    (other values reserved for future behaviors).
355 ///    Automatic reset, if enabled, may occur during GX2SwapScanBuffers;
356 ///    it is triggered by the time-outs above or by a combination of these two:
357 ///  - GX2_MISC_HANG_RESET_SWAP_TIMEOUT: number of milliseconds since last swap before a hang is indicated;
358 ///      (both time & count conditions must be met before a hang is indicated)
359 ///  - GX2_MISC_HANG_RESET_SWAP_COUNT: number of frames waiting in the pipeline before a hang is indicated
360 ///      (both time & count conditions must be met before a hang is indicated)
361 ///
362 /// \returns true if parameter/value pair is valid; false otherwise.
363 ///
364 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall
365 ///
366 GX2Boolean GX2API GX2SetMiscParam(GX2MiscType param, u32 value);
367 
368 /// \brief Get the value for various GX2 miscellaneous system parameters.
369 ///
370 /// See \ref GX2SetMiscParam for a list of possible parameters and values.
371 ///
372 /// \return The value of the requested parameter, or 0xffffffff for bad parameter value.
373 ///
374 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall
375 ///
376 u32 GX2API GX2GetMiscParam(GX2MiscType param);
377 
378 /// \brief Reset the GPU.
379 ///
380 /// \param reserved Reserved for future use; set to 0 for now.
381 ///
382 /// \donotcall \nomulticore \gx2_dl \enddonotcall
383 ///
384 /// \clobberstate
385 ///
386 /// \writesgpu
387 /// \directwritesgpu
388 ///
389 void GX2API GX2ResetGPU(u32 reserved);
390 
391 /// @}
392 /// @addtogroup GX2ManagementDLGroup
393 /// @{
394 
395 /// \brief Create a display list that can be executed later.
396 /// \note The memory in pDisplayList will be written to by the write-gatherer and needs to be
397 /// flushed from CPU cache with GX2Invalidate() before using.
398 /// \note The maximum display list size is 0xfffff u32's, or 4M-4 bytes.
399 ///
400 /// \param pDisplayList    pointer to a buffer to hold the display list data.
401 /// \param byteSize        the size of the display list buffer in bytes.
402 /// \param enableProfiling Initial profiling state for the display list
403 ///
404 /// \note The memory used for pDisplayList must be allocated from MEM2 using
405 /// an API such as MEMAllocFromDefaultHeapEx.
406 ///
407 /// \note The memory used for pDisplayList must be allocated from MEM2 only.
408 /// You cannot create display lists in MEM1.
409 ///
410 /// \note The memory used for pDisplayList must be aligned to \ref GX2_DISPLAY_LIST_ALIGNMENT.
411 ///
412 /// \note The profiling state is stored with the state context so if GX2SetContextState is called
413 ///       within the display list the profiling state (enabled or disabled) may change.
414 ///       If GX2SetContextState() is not called in the display list the correct context state
415 ///       (with respect to profiling) must be set before calling GX2CallDisplayList() or
416 ///       GX2DirectCallDisplayList() to execute the display list.
417 ///
418 /// \donotcall \gx2_dl \enddonotcall
419 ///
420 void GX2API GX2BeginDisplayListEx(void* pDisplayList, u32 byteSize, GX2Boolean enableProfiling);
421 
422 /// \brief Create a display list that can be executed later.
423 /// \note The memory in pDisplayList will be written to by the write-gatherer and needs to be
424 /// flushed from CPU cache with GX2Invalidate() before using.
425 /// \note The maximum display list size is 0xfffff u32's, or 4M-4 bytes.
426 ///
427 /// \param pDisplayList  pointer to a buffer to hold the display list data.
428 /// \param byteSize      the size of the display list buffer in bytes.
429 ///
430 /// \note The memory used for pDisplayList must be allocated from MEM2 using
431 /// an API such as MEMAllocFromDefaultHeapEx.
432 ///
433 /// \note The memory used for pDisplayList must be allocated from MEM2 only.
434 /// You cannot create display lists in MEM1.
435 ///
436 /// \note The memory used for pDisplayList must be aligned to \ref GX2_DISPLAY_LIST_ALIGNMENT.
437 ///
438 /// \note HW Profiling will be enabled for the Display list
439 ///
440 /// \donotcall \gx2_dl \enddonotcall
441 ///
GX2BeginDisplayList(void * pDisplayList,u32 byteSize)442 GX2_INLINE void GX2BeginDisplayList(void* pDisplayList, u32 byteSize)
443 {
444     GX2BeginDisplayListEx(pDisplayList, byteSize, GX2_ENABLE);
445 }
446 
447 /// \brief End the display list generation.
448 ///
449 /// \param pDisplayList  pointer to the display list buffer.
450 /// \return              the actual size of the display list in bytes.
451 ///
452 /// \donotcall \gx2_typical \enddonotcall
453 ///
454 u32 GX2API GX2EndDisplayList(void* pDisplayList);
455 
456 /// \brief Execute the displaylist by adding it directly to the graphics ring buffer.
457 /// \note This function can only be called from the main thread.
458 ///
459 /// \param pDisplayList  pointer to the display list buffer.
460 /// \param byteSize      the size of the display list in bytes.
461 ///
462 /// \note pDisplayList must aligned by GX2_DISPLAY_LIST_ALIGNMENT.
463 ///
464 /// \donotcall \nomulticore \gx2_dl \enddonotcall
465 ///
466 /// \writesgpu
467 /// \alwayswritesgpu
468 ///
469 void GX2API GX2DirectCallDisplayList(void* pDisplayList, u32 byteSize);
470 
471 /// \brief Execute the displaylist by adding it to the current display list or command buffer.
472 /// \note A display list referenced in this call cannot call another display list (no nesting).
473 ///
474 /// \param pDisplayList  pointer to the display list buffer.
475 /// \param byteSize      the size of the display list in bytes.
476 ///
477 /// \note pDisplayList must be aligned by GX2_DISPLAY_LIST_ALIGNMENT.
478 ///
479 /// \donotcall \gx2_typical \enddonotcall
480 ///
481 /// \writesgpu
482 /// \alwayswritesgpu
483 ///
484 void GX2API GX2CallDisplayList(void* pDisplayList, u32 byteSize);
485 
486 /// \brief Get status of whether we're currently writing to a display list or not.
487 ///
488 /// \return GX2_TRUE if we are currently in between GX2BeginDisplayList/GX2EndDisplayList, else GX2_FALSE.
489 ///
490 /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall
491 ///
492 GX2Boolean GX2API GX2GetDisplayListWriteStatus(void);
493 
494 /// \brief Get information about the current display list being made.
495 ///
496 /// \note If you are not currently making a display list, the parameters are ignored
497 ///       and GX2_FALSE is returned.
498 ///
499 /// \note If an input pointer is NULL, it is ignored.
500 ///
501 /// \param ppDisplayList  pointer to hold result for the current display list pointer.
502 /// \param pByteSizeMax   pointer to hold result for the max size of the display list in bytes.
503 ///
504 /// \return GX2_TRUE if we are currently in between GX2BeginDisplayList/GX2EndDisplayList, else GX2_FALSE.
505 ///
506 /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall
507 ///
508 GX2Boolean GX2API GX2GetCurrentDisplayList(void **ppDisplayList, u32 *pByteSizeMax);
509 
510 /// \brief Copy a display list buffer into the current display list.
511 ///
512 /// This API will copy each command from pDisplayList into the current
513 /// display list or command buffer.
514 ///
515 /// \note After calling this API, pDisplayList will be in the CPU cache.
516 ///       Before pDisplayList is used by \ref GX2CallDisplayList or
517 ///       \ref GX2DirectCallDisplayList it is best to flush it from the CPU
518 ///       cache.
519 ///
520 /// \param pDisplayList Ptr to a display list; should be aligned by GX2_DISPLAY_LIST_ALIGNMENT.
521 /// \param byteSize Size of the display list in bytes; should be a multiple of 4.
522 ///
523 /// \donotcall \gx2_typical \enddonotcall
524 ///
525 /// \writesgpu
526 /// \alwayswritesgpu
527 ///
528 void GX2API GX2CopyDisplayList(void * pDisplayList, u32 byteSize);
529 
530 /// @}
531 
532 /// @}
533 
534 
535 #ifdef __cplusplus
536 }
537 #endif // __cplusplus
538 
539 #endif // _CAFE_GX2_MANAGE_H_
540