1 /*---------------------------------------------------------------------------*
2
3 Copyright (C) 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 // gx2Misc.h
14 //
15 // Declares misc function prototypes for gx2 library.
16
17 #ifndef _CAFE_GX2_MISC_H_
18 #define _CAFE_GX2_MISC_H_
19
20 #if !(defined _WIN32 || defined _WIN64)
21 #include <cafe/mem.h>
22 #endif
23
24 #ifdef __cplusplus
25 extern "C"
26 {
27 #endif // __cplusplus
28
29 /// @addtogroup GX2UTComponentGroup
30 /// @{
31
32 // -----------------
33 // Types that are used in multiple areas
34
35 /// \brief Used to define a component (swap/routing) selection set
36 ///
37 /// Use the macros in \ref GX2UTComponentGroup to create or decode a selection.
38 /// There are also predefined variables to use for common selections.
39 ///
40 typedef u32 GX2CompSel;
41
42 /// \brief Macro to get X_R component from a component selection set
43 ///
44 #define GX2_GET_COMPONENT_X_R(v) (((v)>>24)&0xff)
45
46 /// \brief Macro to get Y_G component from a component selection set
47 ///
48 #define GX2_GET_COMPONENT_Y_G(v) (((v)>>16)&0xff)
49
50 /// \brief Macro to get Z_B component from a component selection set
51 ///
52 #define GX2_GET_COMPONENT_Z_B(v) (((v)>> 8)&0xff)
53
54 /// \brief Macro to get W_A component from a component selection set
55 ///
56 #define GX2_GET_COMPONENT_W_A(v) (((v)>> 0)&0xff)
57
58 /// \brief Macro to assemble a component selection set from individual components
59 ///
60 #define GX2_GET_COMP_SEL(x,y,z,w) ((((x)&0xff)<<24)|(((y)&0xff)<<16)|(((z)&0xff)<<8)|((w)&0xff))
61
62 /// \brief Predefined component select (0,0,0,1) or (0,0,0,1)
63 #define GX2_COMP_SEL_NONE GX2_GET_COMP_SEL(GX2_COMPONENT_C_0,GX2_COMPONENT_C_0,GX2_COMPONENT_C_0,GX2_COMPONENT_C_1)
64
65 /// \brief Predefined component select (X,0,0,1) or (R,0,0,1)
66 #define GX2_COMP_SEL_X001 GX2_GET_COMP_SEL(GX2_COMPONENT_X_R,GX2_COMPONENT_C_0,GX2_COMPONENT_C_0,GX2_COMPONENT_C_1)
67
68 /// \brief Predefined component select (X,Y,0,1) or (R,G,0,1)
69 #define GX2_COMP_SEL_XY01 GX2_GET_COMP_SEL(GX2_COMPONENT_X_R,GX2_COMPONENT_Y_G,GX2_COMPONENT_C_0,GX2_COMPONENT_C_1)
70
71 /// \brief Predefined component select (X,Y,Z,1) or (R,G,B,1)
72 #define GX2_COMP_SEL_XYZ1 GX2_GET_COMP_SEL(GX2_COMPONENT_X_R,GX2_COMPONENT_Y_G,GX2_COMPONENT_Z_B,GX2_COMPONENT_C_1)
73
74 /// \brief Predefined component select (X,Y,Z,W) or (R,G,B,A)
75 #define GX2_COMP_SEL_XYZW GX2_GET_COMP_SEL(GX2_COMPONENT_X_R,GX2_COMPONENT_Y_G,GX2_COMPONENT_Z_B,GX2_COMPONENT_W_A)
76
77 /// \brief Predefined component select (X,X,X,X) or (R,R,R,R)
78 #define GX2_COMP_SEL_XXXX GX2_GET_COMP_SEL(GX2_COMPONENT_X_R,GX2_COMPONENT_X_R,GX2_COMPONENT_X_R,GX2_COMPONENT_X_R)
79
80 /// \brief Predefined component select (Y,Y,Y,Y) or (G,G,G,G)
81 #define GX2_COMP_SEL_YYYY GX2_GET_COMP_SEL(GX2_COMPONENT_Y_G,GX2_COMPONENT_Y_G,GX2_COMPONENT_Y_G,GX2_COMPONENT_Y_G)
82
83 /// \brief Predefined component select (Z,Z,Z,Z) or (B,B,B,B)
84 #define GX2_COMP_SEL_ZZZZ GX2_GET_COMP_SEL(GX2_COMPONENT_Z_B,GX2_COMPONENT_Z_B,GX2_COMPONENT_Z_B,GX2_COMPONENT_Z_B)
85
86 /// \brief Predefined component select (W,W,W,W) or (A,A,A,A)
87 #define GX2_COMP_SEL_WWWW GX2_GET_COMP_SEL(GX2_COMPONENT_W_A,GX2_COMPONENT_W_A,GX2_COMPONENT_W_A,GX2_COMPONENT_W_A)
88
89 /// \brief Predefined component select (W,Z,Y,X) or (A,B,G,R)
90 #define GX2_COMP_SEL_WZYX GX2_GET_COMP_SEL(GX2_COMPONENT_W_A,GX2_COMPONENT_Z_B,GX2_COMPONENT_Y_G,GX2_COMPONENT_X_R)
91
92 /// \brief Predefined component select (W,X,Y,Z) or (A,R,G,B)
93 #define GX2_COMP_SEL_WXYZ GX2_GET_COMP_SEL(GX2_COMPONENT_W_A,GX2_COMPONENT_X_R,GX2_COMPONENT_Y_G,GX2_COMPONENT_Z_B);
94
95 /// @}
96 /// @addtogroup GX2UTHelperGroup
97 /// @{
98
99 // -----------------
100 // Utility #defines
101
102 /// \brief Swap byte order in a 32-bit int.
103 ///
104 #define GX2_SWAP_8_IN_32(x) \
105 ( (((x) >> 24) & 0xff) | (((x) >> 8) & 0xff00) | (((x) << 8) & 0xff0000) | (((x) << 24) & 0xff000000) )
106
107 /// \brief Swap byte order in a 16-bit int.
108 ///
109 /// Note: x must already be cast to a 16-bit int-type.
110 ///
111 #define GX2_SWAP_8_IN_16(x) \
112 ( ((x) >> 8) | ((x) << 8) )
113
114 /// \brief Swap 16-bit word order in a 32-bit int.
115 ///
116 /// Note: x must already be cast to a 32-bit int-type.
117 ///
118 #define GX2_SWAP_16_IN_32(x) \
119 ( ((x) >> 16) | ((x) << 16) )
120
121 /// \brief Swap byte order in a 64-bit int.
122 ///
123 /// \note 0xffull is a 64-bit constant = 0xff
124 #define GX2_SWAP_8_IN_64(x) \
125 ((((x)>>56)&(0xffull<< 0))|(((x)>>40)&(0xffull<< 8))|(((x)>>24)&(0xffull<<16))|(((x)>> 8)&(0xffull<<24))| \
126 (((x)<< 8)&(0xffull<<32))|(((x)<<24)&(0xffull<<40))|(((x)<<40)&(0xffull<<48))|(((x)<<56)&(0xffull<<56)))
127
128 /// \brief Utility function to copy and endian-swap a given range of bytes.
129 /// It performs a 8-in-32 swap while copying u32 units from source to dest.
130 /// For best results, you should also call DCZeroRange() on the dest first
131 /// (this can only be done when the range is 32-byte aligned in location and
132 /// size, though).
133 ///
134 /// \param dst Start of the given dest buffer range to copy and swap
135 /// \param src Start of the given src buffer range
136 /// \param byteLen Length of the given range specified in bytes. Must be a multiple of 4.
137 ///
138 /// \donotcall \threadsafe \enddonotcall
139 ///
GX2CopyEndianSwap(void * dst,const void * src,u32 byteLen)140 GX2_INLINE void GX2CopyEndianSwap(void *dst, const void *src, u32 byteLen)
141 {
142 ASSERT((byteLen % sizeof(u32))==0);
143 #if !(defined _WIN32 || defined _WIN64)
144 u32 i;
145 u32 *csrc = (u32 *) src;
146 __bytereversed u32 *cdst = (__bytereversed u32 *) dst;
147 for(i=0; i<(byteLen>>2); i++) cdst[i] = csrc[i];
148 #else
149 {
150 u32* csrc = (u32*)src;
151 u32* cdst = (u32*)dst;
152 u32 i;
153 for (i=0; i<byteLen>>2; i++)
154 {
155 cdst[i] = GX2_SWAP_8_IN_32(csrc[i]);
156 }
157 }
158 #endif
159 }
160
161 /// \brief Utility function to endian-swap a given range of bytes. 8-in-32 swap is done in-place.
162 ///
163 /// \note Length is given in bytes to mirror other APIs that operate on ranges.
164 /// \param ptr Start of the given range to swap
165 /// \param byteLen Length of the given range specified in bytes. Must be a multiple of 4.
166 ///
167 /// \donotcall \threadsafe \enddonotcall
168 ///
GX2EndianSwap(void * ptr,u32 byteLen)169 GX2_INLINE void GX2EndianSwap(void *ptr, u32 byteLen)
170 {
171 ASSERT((byteLen % sizeof(u32))==0);
172 #if !(defined _WIN32 || defined _WIN64)
173 u32 i;
174 u32 *src = (u32 *) ptr;
175 __bytereversed u32 *dst = (__bytereversed u32 *) ptr;
176 for(i=0; i<(byteLen>>2); i++) dst[i] = src[i];
177 #else
178 {
179 u32* src = (u32*)ptr;
180 u32 i;
181 for (i=0; i<byteLen>>2; i++)
182 {
183 src[i] = GX2_SWAP_8_IN_32(src[i]);
184 }
185 }
186 #endif
187 }
188
189 /// \brief Utility function to round a value up to a multiple of a power of 2 size
190 ///
191 /// \note This function only works if size is a power of 2
192 ///
193 /// \param value the input value to be rounded up
194 /// \param size a power of 2 multiple to round value up to
195 /// \return value rounded up to a multiple of size
196 ///
197 /// \donotcall \threadsafe \devonly \enddonotcall
198 ///
GX2RoundUp(u32 value,u32 size)199 GX2_INLINE u32 GX2RoundUp(u32 value, u32 size)
200 {
201 // assert if the size is not a power of 2
202 ASSERT((size & (size - 1)) == 0);
203 return ((value + (size - 1)) & ~(size - 1));
204 }
205
206 /// @}
207 /// @addtogroup GX2ManagementMemGroup
208 /// @{
209
210 /// \brief Type used for default GX2 memory allocator
211 typedef void* (*GX2DefaultAllocateFunc)(u32 userArg, u32 byteCount, u32 alignment);
212
213 /// \brief Type used for default GX2 memory free function
214 typedef void (*GX2DefaultFreeFunc)(u32 userArg, void* pMem);
215
216 /// \brief Set default functions to use for memory allocation/freeing.
217 ///
218 /// These will be used by GX2R regular & debug features as well as by the debug PM4 capture
219 /// unless other allocators are specifically set using other APIs. These functions can also
220 /// be easily used by the perf APIs by passing in \ref GX2MEMDefaultAllocator.
221 ///
222 /// If not set by the user, these will just call MEMAllocFromDefaultHeap/MEMFreeToDefaultHeap.
223 ///
224 /// \param pfnAlloc pointer to allocator function
225 /// \param pfnFree pointer to free function
226 ///
227 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall
228 ///
229 void GX2API GX2SetDefaultAllocator(GX2DefaultAllocateFunc pfnAlloc, GX2DefaultFreeFunc pfnFree);
230
231 /// \brief Get default functions to use for memory allocation/freeing.
232 /// \param ppfnAlloc pointer to get pointer to allocator function
233 /// \param ppfnFree pointer to get pointer to free function
234 ///
235 /// \donotcall \threadsafe \devonly \enddonotcall
236 ///
237 void GX2API GX2GetDefaultAllocator(GX2DefaultAllocateFunc *ppfnAlloc, GX2DefaultFreeFunc *ppfnFree);
238
239 #if !(defined _WIN32 || defined _WIN64)
240 /// \brief A pre-defined allocator that will call the default GX2 allocator/free functions
241 /// that are set up using \ref GX2SetDefaultAllocator.
242 extern MEMAllocator GX2MEMDefaultAllocator;
243 #endif
244
245 #ifdef _DEBUG
246 /// \brief Tell GX2 about graphics memory allocation.
247 ///
248 /// While not required, calling this function when allocating GPU-accessed
249 /// graphics data may help the GPU debugger PM4 frame capture feature
250 /// work properly or more efficiently.
251 ///
252 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall
253 ///
254 void GX2API GX2NotifyMemAlloc(void* addr, u32 size, u32 align);
255
256 /// \brief Tell GX2 about graphics memory free.
257 ///
258 /// While not required, calling this function when freeing GPU-accessed
259 /// graphics data may help the GPU debugger PM4 frame capture feature
260 /// work properly or more efficiently.
261 ///
262 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall
263 ///
264 void GX2API GX2NotifyMemFree(void* addr);
265 #else
GX2NotifyMemAlloc(const void * addr,u32 size,u32 align)266 GX2_INLINE void GX2NotifyMemAlloc(const void* addr, u32 size, u32 align){
267 addr=addr;
268 size=size;
269 align=align;
270 }
GX2NotifyMemFree(const void * addr)271 GX2_INLINE void GX2NotifyMemFree(const void* addr){
272 addr=addr;
273 }
274 #endif
275
276 /// \brief Invalidate GPU input caches or flush GPU output caches/pipelines.
277 ///
278 /// This function invalidates GPU input caches or flushes GPU output caches.
279 /// For CPU ranges, it calls DCFlushRange() (i.e., it flushes the data cache).
280 ///
281 /// Every memory range to be read by the GPU must be flushed or
282 /// invalidated from the CPU cache before use. For display lists,
283 /// you should call GX2Invalidate() on the memory *before* writing
284 /// to it with GX2 commands. For any vertex, texture, shader, or
285 /// uniform buffer data written by the CPU, you should call
286 /// GX2Invalidate() *after* writing it.
287 ///
288 /// For rendering to textures, this function must be called twice:
289 /// - Once to flush the color buffer (or depth buffer) write pipe
290 /// - Once to invalidate the texture read cache
291 ///
292 /// \note For GPU input cache flushes, you may specify a range of 0x0 - 0xffffffff.
293 /// This can make resource management easier for the CPU, though it may
294 /// cause some unnecessary invalidation.
295 /// \note For GPU output cache flushes, you may specify a range of 0x0 - 0xffffffff.
296 /// This can make resource management easier for the CPU, though it may cause some
297 /// unnecessary invalidation. In addition, the GPU has optimizations to avoid
298 /// unnecessary stalling when it is given ranges that match the ones it knows about.
299 ///
300 /// \param invType Flags indicating which invalidations/flushes to perform
301 /// \param ptr start of cached data area
302 /// \param size size of cached data area in bytes
303 ///
304 /// \donotcall \gx2_typical \enddonotcall
305 ///
306 /// \writesgpu
307 /// \writesgpu{if the invType contains any GPU invalidation bit}
308 ///
309 void GX2API GX2Invalidate( GX2InvalidateType invType, void *ptr, u32 size );
310
311 /// @}
312 /// @addtogroup GX2DebugGroup
313 /// @{
314
315 // -----------------
316 // Debugging Helpers
317
318 /// \brief Enable or disable debug drawing modes
319 ///
320 /// - "Flush per draw" makes sure that each draw command is submitted to the
321 /// hardware as soon as possible.
322 /// - "Done per flush" waits for each submit (of any type) to complete before
323 /// continuing.
324 ///
325 /// \note This function only operates in debug builds of GX2. In non-debug
326 /// builds, the function still exists, but does not do anything.
327 ///
328 /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall
329 ///
330 void GX2API GX2SetDebugMode(GX2DebugMode dm);
331
332 /// \brief Determines the maximum amount of time to wait for the GPU to
333 /// perform certain actions before regarding it as hung.
334 ///
335 /// This value affects functions such as \ref GX2WaitTimeStamp and
336 /// \ref GX2WaitForVsync. When GX2 thinks the GPU might be hung,
337 /// it can report the state of some GPU registers and determine which
338 /// GPU blocks are busy.
339 ///
340 /// This API can change the timeout value for debugging purposes. Note
341 /// that you should avoid setting the timeout to less than 17 msec, or
342 /// some functions will most likely timeout on you. The default timeout
343 /// is given by \ref GX2_DEFAULT_GPU_TIMEOUT_IN_MILLISEC.
344 ///
345 /// \param millisec amount of time before GX2 considers GPU to be hung
346 ///
347 /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall
348 ///
349 void GX2API GX2SetGPUTimeout(u32 millisec);
350
351 /// \brief Returns the value set by \ref GX2SetGPUTimeout
352 ///
353 /// \donotcall \fgonly \threadsafe \devonly \enddonotcall
354 ///
355 u32 GX2API GX2GetGPUTimeout(void);
356
357 /// \brief Determines the maximum number of interrupts allowed during
358 /// a single frame time (1/60 of a second) before a warning is issued.
359 ///
360 /// In debug builds only, a warning is printed out if this limit is
361 /// exceeded. This is to help alert the user of unexpected processing
362 /// that can interfere with normal operations. The default limit is
363 /// given by \ref GX2_DEFAULT_INTERRUPT_COUNT_LIMIT.
364 ///
365 /// \param limit The interrupt count limit during each 1/60 sec frame.
366 ///
367 /// \donotcall \fgonly \notthreadsafe \devonly \enddonotcall
368 ///
369 void GX2API GX2SetInterruptCountLimit(u32 limit);
370
371 /// \brief Helper function to see current GPU status.
372 ///
373 /// \warning This should not be used in production code.
374 ///
375 /// \donotcall \gx2_typical \enddonotcall
376 ///
377 void GX2API GX2PrintGPUStatus(void);
378
379 /// \brief Function used to set GX2Log-related settings.
380 ///
381 /// \donotcall \threadsafe \devonly \enddonotcall
382 ///
383 void GX2API GX2LogSetMisc(GX2LogAttrib attrib, u32 value);
384
385
386 /// @}
387 /// @addtogroup GX2DebugCaptureGroup
388 /// @{
389
390 /// \brief Function to write a user string to the PM4 capture
391 /// \param userTagType A semantic tag written with the string for tool use
392 /// \param formatString printf-style arguments, written to the captured command buffer
393 ///
394 /// \donotcall \gx2_typical \enddonotcall
395 ///
396 /// \writesgpu
397 /// \alwayswritesgpu
398 ///
399 void GX2API GX2DebugTagUserString(GX2DebugTagUserStringType userTagType, const char* formatString, ...);
400
401 /// \brief Use this version of \ref GX2DebugTagUserString if you want to forward a varargs wrapper
402 /// \param userTagType A semantic tag written with the string for tool use
403 /// \param formatString printf-style arguments, written to the captured command buffer
404 /// \param args Extract from varargs "..." using C standard library va_start()/va_end()
405 ///
406 /// \donotcall \gx2_typical \enddonotcall
407 ///
408 /// \writesgpu
409 /// \alwayswritesgpu
410 ///
411 void GX2API GX2DebugTagUserStringVA(GX2DebugTagUserStringType userTagType, const char* formatString, va_list args);
412
413 /// \brief Initialize the capture system.
414 ///
415 /// Initialize the capture system. The remote Capture button in the Spark GPU debugger
416 /// will be enabled after this call.
417 ///
418 /// \note You must link with gx2spark.a to use this function.
419 ///
420 /// \param initAttribs Reserved for future use.
421 ///
422 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \notcallback \devonly \enddonotcall
423 ///
424 void GX2DebugCaptureInit(u32 *initAttribs);
425
426 /// \brief Captures the PM4 command sequence and associated buffers to a capture file
427 /// for analysis with pm4parse tool or Spark GPU debugger.
428 ///
429 /// The capture will start at the next \ref GX2SwapScanBuffers and will end at
430 /// the subsequent occurrence of that function.
431 ///
432 /// \note This is the officially supported API for debug captures.
433 ///
434 /// \param filename Name of the .4mp output file in data/save/common
435 ///
436 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall
437 ///
438 void GX2API GX2DebugCaptureFrame(const char* filename);
439
440 /// \brief Similar to \ref GX2DebugCaptureFrame, but handles multiple frames.
441 ///
442 /// \note This function is deprecated. Please use \ref GX2DebugCaptureFrame instead.
443 ///
444 /// \param filename Name of the .4mp output file in data/save
445 /// \param numFrames Number of frames to capture
446 ///
447 /// \donotcall \fgonly \notthreadsafe \notinterrupt \notexception \devonly \enddonotcall
448 ///
449 void GX2API GX2DebugCaptureFrames(const char* filename, u32 numFrames);
450
451 /// \brief Start capturing the PM4 command sequence and associated buffers to a capture file.
452 ///
453 /// \note This API is for advanced usage. Capturing more or less than a full single frame
454 /// may present debugger support issues not present otherwise (we may not support such
455 /// usage). It should be fine for viewing with pm4parse, however.
456 ///
457 /// \param filename Name of the .4mp output file in data/save/common
458 /// \param optionFlags See \ref GX2DebugCaptureOptions
459 ///
460 /// \donotcall \nomulticore \gx2_dl \enddonotcall
461 ///
462 /// \writesgpu
463 /// \writesgpu{if \ref GX2_DEBUG_CAPTURE_NO_FLUSH is not set.}
464 ///
465 void GX2API GX2DebugCaptureStart(const char* filename, GX2DebugCaptureOptions optionFlags);
466
467 /// \brief Stops a PM4 capture.
468 ///
469 /// \note This API is for advanced usage. Capturing more or less than a full single frame
470 /// may present debugger support issues not present otherwise (we may not support such
471 /// usage). It should be fine for viewing with pm4parse, however.
472 ///
473 /// \param optionFlags See \ref GX2DebugCaptureOptions
474 ///
475 /// \donotcall \nomulticore \gx2_dl \enddonotcall
476 ///
477 /// \writesgpu
478 /// \writesgpu{if \ref GX2_DEBUG_CAPTURE_NO_FLUSH is not set.}
479 ///
480 void GX2API GX2DebugCaptureEnd(GX2DebugCaptureOptions optionFlags);
481
482 /// @}
483 /// @addtogroup GX2UTHelperGroup
484 /// @{
485
486 /// \brief Compile-time assert
487 #define GX2_STATIC_ASSERT(e, message) typedef int static_assert_failed_##message[!(e) ? -1 : 1]
488
489 /// \brief Set the bits in *pFlags
490 ///
491 /// \donotcall \threadsafe \enddonotcall
492 ///
GX2SetBitFlags(u32 * pFlags,u32 bits)493 GX2_INLINE void GX2SetBitFlags(u32* pFlags, u32 bits) { *pFlags |= bits; }
494
495 /// \brief Clear the bits in *pFlags
496 ///
497 /// \donotcall \threadsafe \enddonotcall
498 ///
GX2ClearBitFlags(u32 * pFlags,u32 bits)499 GX2_INLINE void GX2ClearBitFlags(u32* pFlags, u32 bits) { *pFlags &= ~bits; }
500
501 /// \brief Mask the bits in *pFlags
502 ///
503 /// \donotcall \threadsafe \enddonotcall
504 ///
GX2MaskBitFlags(u32 * pFlags,u32 mask)505 GX2_INLINE void GX2MaskBitFlags(u32* pFlags, u32 mask) { *pFlags &= mask; }
506
507 /// \brief Replace the bits in mask with bits
508 ///
509 /// \donotcall \threadsafe \enddonotcall
510 ///
GX2ReplaceBitFlags(u32 * pFlags,u32 mask,u32 bits)511 GX2_INLINE void GX2ReplaceBitFlags(u32* pFlags, u32 mask, u32 bits) { *pFlags &= ~mask; *pFlags |= (bits & mask); }
512
513 /// \brief Returns GX2_TRUE if any of the bits are set
514 ///
515 /// \donotcall \threadsafe \enddonotcall
516 ///
GX2TestBitFlagsAny(u32 flags,u32 bits)517 GX2_INLINE GX2Boolean GX2TestBitFlagsAny(u32 flags, u32 bits) { return (GX2Boolean)((flags & bits) != 0); }
518
519 /// \brief Returns GX2_TRUE if all of the bits are set
520 ///
521 /// \donotcall \threadsafe \enddonotcall
522 ///
GX2TestBitFlagsAll(u32 flags,u32 bits)523 GX2_INLINE GX2Boolean GX2TestBitFlagsAll(u32 flags, u32 bits) { return (GX2Boolean)((flags & bits) == bits); }
524
525 /// \brief Returns the min of a and b
526 ///
527 /// \donotcall \threadsafe \enddonotcall
528 ///
GX2Min(u32 a,u32 b)529 GX2_INLINE u32 GX2Min(u32 a, u32 b) { return (a < b) ? a : b; }
530
531 /// \brief Returns the max of a and b
532 ///
533 /// \donotcall \threadsafe \enddonotcall
534 ///
GX2Max(u32 a,u32 b)535 GX2_INLINE u32 GX2Max(u32 a, u32 b) { return (a > b) ? a : b; }
536
537 /// \brief Utility function, returns GX2_TRUE if the pointer meets the given alignment
538 ///
539 /// \donotcall \threadsafe \enddonotcall
540 ///
GX2IsAligned(const void * p,u32 alignment)541 GX2_INLINE GX2Boolean GX2IsAligned(const void *p, u32 alignment)
542 {
543 return (GX2Boolean)((u32)p == GX2RoundUp((u32)p, alignment));
544 }
545
546
547 /// \brief Returns true if the specified format supports the fast fixed-function box MSAA resolve.
548 ///
549 /// \donotcall \threadsafe \enddonotcall
550 ///
GX2IsResolveSupported(GX2SurfaceFormat format)551 GX2_INLINE GX2Boolean GX2IsResolveSupported(GX2SurfaceFormat format)
552 {
553 switch(format)
554 {
555 //Only the following formats support fixed function (box-filter) MSAA resolve
556 case GX2_SURFACE_FORMAT_TC_R32_G32_B32_A32_FLOAT:
557
558 case GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_FLOAT:
559 case GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_UNORM:
560 case GX2_SURFACE_FORMAT_TC_R16_G16_B16_A16_SNORM:
561 case GX2_SURFACE_FORMAT_TC_R32_G32_FLOAT:
562
563 case GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_UNORM:
564 case GX2_SURFACE_FORMAT_TCS_R8_G8_B8_A8_SRGB:
565 case GX2_SURFACE_FORMAT_TC_R8_G8_B8_A8_SNORM:
566 case GX2_SURFACE_FORMAT_TCS_R10_G10_B10_A2_UNORM:
567 case GX2_SURFACE_FORMAT_TCS_A2_B10_G10_R10_UNORM:
568 case GX2_SURFACE_FORMAT_TC_R11_G11_B10_FLOAT:
569 case GX2_SURFACE_FORMAT_TC_R16_G16_FLOAT:
570 case GX2_SURFACE_FORMAT_TC_R16_G16_UNORM:
571 case GX2_SURFACE_FORMAT_TC_R16_G16_SNORM:
572 case GX2_SURFACE_FORMAT_TCD_R32_FLOAT:
573
574 case GX2_SURFACE_FORMAT_TCS_R5_G6_B5_UNORM:
575 case GX2_SURFACE_FORMAT_TC_R5_G5_B5_A1_UNORM:
576 case GX2_SURFACE_FORMAT_TC_A1_B5_G5_R5_UNORM:
577 case GX2_SURFACE_FORMAT_TC_R4_G4_B4_A4_UNORM:
578 case GX2_SURFACE_FORMAT_TC_R8_G8_UNORM:
579 case GX2_SURFACE_FORMAT_TC_R8_G8_SNORM:
580 case GX2_SURFACE_FORMAT_TC_R16_FLOAT:
581 case GX2_SURFACE_FORMAT_TCD_R16_UNORM:
582 case GX2_SURFACE_FORMAT_TC_R16_SNORM:
583
584 case GX2_SURFACE_FORMAT_TC_R8_UNORM:
585 case GX2_SURFACE_FORMAT_TC_R8_SNORM:
586 case GX2_SURFACE_FORMAT_T_R4_G4_UNORM:
587 return GX2_TRUE;
588 }
589
590 return GX2_FALSE;
591 }
592
593 /// @}
594 /// @addtogroup GX2ManagementContextStateGroup
595 /// @{
596
597 /// \brief Context state data size in bytes.
598 ///
599 #define GX2_CONTEXT_STATE_DATA_SIZE 41216
600
601 /// \brief Context state
602 ///
603 /// Context state
604 typedef struct _GX2ContextState {
605 u32 data[GX2_CONTEXT_STATE_DATA_SIZE/sizeof(u32)];
606 } GX2ContextState;
607
608 /// \brief Call other GX2 commands to set up the default render state. See \ref GX2SetDefaultStateSect.
609 ///
610 /// \donotcall \gx2_typical \enddonotcall
611 ///
612 /// \clobberstate
613 ///
614 /// \writesgpu
615 /// \alwayswritesgpu
616 ///
617 void GX2API GX2SetDefaultState(void);
618
619 /// \brief Initialize the given context state memory with the default state and set it in use.
620 ///
621 /// \note When profiling is disabled GX2 will not override any state based on the profile mode or
622 /// toss stage that was setup during initialization.
623 ///
624 /// \note This function will normally create an internal display list as an optimization to speed
625 /// up calls to GX2SetupContextState. Since it must call GX2BeginDisplayList in order to
626 /// create the internal display list, this means you cannot call this function while
627 /// making a display list.
628 ///
629 /// \param pState pointer to a GX2ContextState buffer.
630 /// \param enableProfiling enable HW profiling for this context state.
631 ///
632 /// \donotcall \gx2_typical \enddonotcall
633 ///
634 /// \enablesstateshadow
635 /// \clobberstate
636 ///
637 /// \writesgpu
638 /// \alwayswritesgpu
639 ///
640 void GX2API GX2SetupContextStateEx(GX2ContextState* pState, GX2Boolean enableProfiling);
641
642 /// \brief Initialize the given context state memory with the default state and set it in use.
643 ///
644 /// \note HW Profiling will be enabled for the context state
645 ///
646 /// \param pState pointer to a GX2ContextState buffer.
647 ///
648 /// \donotcall \gx2_typical \enddonotcall
649 ///
650 /// \enablesstateshadow if pState is non-NULL.
651 /// \disablesstateshadow if pState is NULL.
652 /// \clobberstate
653 ///
654 /// \writesgpu
655 /// \alwayswritesgpu
656 ///
GX2SetupContextState(GX2ContextState * pState)657 GX2_INLINE void GX2SetupContextState(GX2ContextState* pState)
658 {
659 GX2SetupContextStateEx(pState, GX2_ENABLE);
660 }
661
662 /// \brief Loads the given context state and makes it current for future changes.
663 ///
664 /// \note If pState is NULL the previous context state is preserved
665 /// and future state changes will not be saved to memory.
666 /// (I.e., this disables state shadowing.)
667 ///
668 /// \note Normally this function will just call or copy an internal display list that
669 /// contains all the necessary load commands. A call is used unless we are in
670 /// the process of creating a display list, in which case a copy is done instead.
671 ///
672 /// \note This function invokes a full pipeline flush; it takes approx. 23 microseconds.
673 ///
674 /// \param pState pointer to an already-initialized GX2ContextState buffer, or NULL.
675 ///
676 /// \donotcall \gx2_typical \enddonotcall
677 ///
678 /// \clobberstate
679 /// \enablesstateshadow State shadowing is enabled if pState is non-NULL.
680 /// \disablesstateshadow State shadowing is disabled if pState is NULL.
681 /// \notincompute
682 ///
683 /// \writesgpu
684 /// \alwayswritesgpu
685 ///
686 void GX2API GX2SetContextState(const GX2ContextState* pState);
687
688 /// \brief Returns the pointer and size for the internal display list found in a GX2ContextState.
689 ///
690 /// \note To improve the performance of GX2SetContextState, when you call GX2SetupContextState,
691 /// we create an internal display list that performs all the necessary register loads.
692 /// Then, when you call GX2SetContextState, we either make a call to that display list (if
693 /// you are currently writing to a command buffer), or we copy that display list (if you
694 /// are currently writing to a display list). The latter is done to avoid having too many
695 /// nested display list calls. However, if you know you will not exceed the nesting level,
696 /// you can call the display list directly by getting its parameters with this API.
697 ///
698 /// \param pState pointer to an already-initialized GX2ContextState buffer.
699 /// \param ppDisplayList pointer to receive the display list pointer.
700 /// \param pByteSize pointer to receive the display list size.
701 ///
702 /// \donotcall \threadsafe \devonly \enddonotcall
703 ///
704 void GX2API GX2GetContextStateDisplayList(const GX2ContextState *pState, void **ppDisplayList, u32 *pByteSize);
705
706 /// \brief Patches a sequence of display list commands that were created using
707 /// offline display list compilation.
708 ///
709 /// \param pDisplayList Pointer to the start of the display list to patch
710 /// \param type Type GX2 entry that needs to be patched
711 /// \param offset Offset in u32s from the start of the display list
712 /// \param gx2ObjectPointer Pointer to the GX2 object that generated the patch
713 /// entry.
714 ///
715 /// See \ref gshCompileOfflineGX2Sect for more details.
716 ///
717 /// \warning After all display list entries have been patched, the user must
718 /// flush the CPU memory from the cache using \ref GX2Invalidate.
719 ///
720 /// \donotcall \threadsafe \devonly \enddonotcall
721 ///
722 void GX2API GX2PatchDisplayList(void *pDisplayList, GX2PatchType type, u32 offset, void *gx2ObjectPointer);
723 /// @}
724
725 #ifdef __cplusplus
726 }
727 #endif // __cplusplus
728
729 #endif // _CAFE_GX2_MISC_H_
730