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 // gx2Surface.h       (Shared between PC:gtxConvert and Gx2)
14 //
15 // Declares surface-related types & functions for gx2 library.
16 //
17 //   Note.  Data structures in this file exist in serialized
18 //   format in .gtx texture files.  Modifying any of the structures
19 //   hence runs huge risk of invalidating any or all texture files.
20 //
21 //  Also - do not add non 32-bit/element fields into these data structures,
22 //  they may not serialize correctly.
23 // -------------------------------------------------------
24 
25 #ifndef _CAFE_GX2_SURFACE_H_
26 #define _CAFE_GX2_SURFACE_H_
27 
28 #include <cafe/gx2/gx2rResource.h>
29 
30 #ifdef __cplusplus
31 extern "C" {
32 #endif
33 
34 /// @addtogroup GX2SurfaceGroup
35 /// @{
36 
37 /// @addtogroup GX2SurfaceAllGroup
38 /// @{
39 
40 //----------------------------------------------------------------------
41 // Defines
42 
43 /// \brief The number of registers used to describe textures
44 #define GX2_NUM_TEXTURE_REGISTERS      5
45 
46 /// \brief The number of registers used to describe color buffers
47 ///
48 #define GX2_NUM_COLOR_BUFFER_REGISTERS 5
49 
50 /// \brief The number of registers used to describe depth/stencil buffers
51 ///
52 #define GX2_NUM_DEPTH_BUFFER_REGISTERS 7
53 
54 /// \brief The number of registers used to describe HiStencil pretest state
55 ///
56 #define GX2_NUM_HISTENCIL_STATES 2
57 
58 /// \brief Minimum offset from pixel center of MSAA buffer. It ranges -8/16 to 7/16.
59 ///
60 #define GX2_MSAA_SAMPLE_LOCATION_MIN  -8
61 
62 /// \brief Maximum offset from pixel center at MSAA buffer. It ranges -8/16 to 7/16.
63 ///
64 #define GX2_MSAA_SAMPLE_LOCATION_MAX   7
65 
66 //----------------------------------------------------------------------
67 // Structures
68 
69 // !!!Note!!! - The GX2Surface structure is burned into .gtx file.
70 // Altering parameters or changing their order may invalidate all existing content.
71 
72 
73 /// \brief Describes a "surface", the common base element of textures, color & depth buffers.
74 ///
75 /// Since surfaces are very complex, all the user parameters are encapsulated in this structure.
76 /// In addition, there are fields for some computed values that are useful both for the user
77 /// as well as for certain APIs.  They are stored here to avoid calculating them multiple times.
78 /// Whenever a user value is changed, it's a good idea to call GX2CalcSurfaceSizeAndAlignment.
79 ///
80 #ifdef __ghs__
81 #pragma ghs nowarning 619 // "nonstandard unnamed field" for anonymous union when compiled as C
82 #endif
83 typedef struct _GX2Surface {
84     // Caution: This structure is serialized in the .gtx file format.
85     // Don't add non 32-bit per element sized fields; they may not transfer correctly.
86     /// (user) dimension: 1D, 2D, 3D, etc.
87     GX2SurfaceDim dim;
88     /// (user) size of s (x) dimension in pixels
89     u32 width;
90     /// (user) size of t (y) dimension in pixels
91     u32 height;
92     /// (user) size of r (p, z) dimension in pixels. 0 implies 1.
93     u32 depth;
94 
95     /// (user) number of mip levels, counting base level 0 as 1. 0 implies 1.
96     u32 numMips;
97 
98     /// (user) image format
99     GX2SurfaceFormat format;
100     /// (user) antialiasing mode
101     GX2AAMode aa;
102     union {
103     /// (user) intended use (texture, color buffer, etc) (if not using GX2R)
104     GX2SurfaceUse       use;
105     /// (user) type, semantics and options, if using GX2R
106     GX2RResourceFlags   resourceFlags;
107     };
108 
109     /// (calc) size of texture base image (level 0), in bytes
110     u32   imageSize;
111     union {
112     /// (user) pointer to texture base image (level 0)
113     void *imagePtr;
114     void *pMem;
115     };
116     /// (calc) size of mipmap pyramid (levels 1+), in bytes.  May be 0.
117     u32   mipSize;
118     /// (user) pointer to mipmap pyramid (levels 1+).  May be NULL.
119     void *mipPtr;
120 
121     /// (special) base tiling mode for the texture
122     GX2TileMode tileMode;
123     /// (special) pipe and bank swizzle modes for optimizing memory access
124     /// The lower 8 bits are 0 and unused. The next 8 bits are the swizzle value, of which only
125     /// values 0 through 7 are valid (set using GX2SetSurfaceSwizzle). The next 8 bits are
126     /// the mip-level at which the hardware stops swizzling and switches to using 1D tiling modes (calculated; not set by the user).
127     u32 swizzle;
128 
129     /// (calc) alignment to use when allocating image and mip levels, in bytes
130     u32 alignment;
131     /// (calc) used internally to set registers; padded image width in elements (pixels or BC 4x4 tiles)
132     u32 pitch;
133 
134     /// \brief (calc) Offsets to each mip level, in bytes.
135     ///
136     /// mipOffset[0] is special: it can be used to place levels 1+ after the base map.
137     /// (It indicates the size of the base map plus the padding needed for level 1.)
138     /// It should not be used for any other purpose.
139     ///
140     /// The location of a mip level image should be found only as follows:
141     /// - level 0 is given by imagePtr
142     /// - level 1 is given by mipPtr
143     /// - levels 2+ are given by (u32) mipPtr + mipOffset[level-1]
144     ///
145     /// \note This array is computed to reflect what the mipmapping hardware does intrinsically.
146     /// Altering it will not change the hardware's behavior.
147     /// It is provided to help software find the mip data when needed.
148     ///
149     u32 mipOffset[ 13 ]; // TODO: use GX2_LOG2_MAX_TEXTURE_SIZE instead
150 
151 } GX2Surface;
152 #ifdef __ghs__
153 #pragma ghs endnowarning
154 #endif
155 
156 /// @}
157 /// @addtogroup GX2SurfaceColorGroup
158 /// @{
159 
160 /// \brief Completely describes a color buffer (i.e., render target).
161 ///
162 /// In addition to GX2Surface, includes user fields to describe a color buffer.
163 /// Also includes hardware register settings for the same purpose.
164 /// It allows rendering to a given mip level or array slice.
165 ///
166 typedef struct _GX2ColorBuffer {
167 
168     /// main surface description
169     GX2Surface surface;
170 
171     /// (user) mip level to use (usually 0)
172     u32 viewMip;
173     /// (user) start slice in the array or 3D surface (usually 0)
174     u32 viewFirstSlice;
175     /// (user) number of slices (usually 1)
176     u32 viewNumSlices;
177 
178     /// Auxiliary buffer (for AA only) address
179     void *auxPtr;
180     /// Auxiliary buffer (for AA only) size
181     u32  auxSize;
182 
183     /// (calc) private, calculated by driver
184     u32 _regs[GX2_NUM_COLOR_BUFFER_REGISTERS];
185 
186 } GX2ColorBuffer;
187 
188 /// @}
189 /// @addtogroup GX2SurfaceDepthGroup
190 /// @{
191 
192 /// \brief Completely describes a depth/stencil buffer.
193 ///
194 /// In addition to GX2Surface, includes user fields to describe a depth/stencil buffer.
195 /// Also includes hardware register settings for the same purpose.
196 /// It allows rendering to a given mip level or array slice.
197 ///
198 typedef struct _GX2DepthBuffer {
199 
200     /// main surface description
201     GX2Surface surface;
202 
203     /// (user) mip level to use (usually 0)
204     u32 viewMip;
205     /// (user) start slice in the array or 3D surface (usually 0)
206     u32 viewFirstSlice;
207     /// (user) number of slices (usually 1)
208     u32 viewNumSlices;
209 
210     /// Hierarchical Z buffer address (optional)
211     void *hiZPtr;
212     /// Hierarchical Z buffer size (optional)
213     u32  hiZSize;
214 
215     /// (user) Value to use when clearing the depth buffer
216     f32 clearDepth;
217     /// (user) Value to use when clearing the stencil buffer. Only the least significant 8 bits are valid.
218     u32 clearStencil;
219 
220     /// (calc) private, calculated by driver
221     u32 _regs[GX2_NUM_DEPTH_BUFFER_REGISTERS];
222 
223 } GX2DepthBuffer;
224 
225 /// \brief Describes a single HiStencil pretest state.
226 ///
227 /// Supplied to \ref GX2HiStencilInfo to completely describe HiStencil pretest state
228 ///
229 typedef struct _GX2HiStencilState {
230 
231     /// (user) compare function
232     GX2CompareFunction function;
233     /// (user) reference value
234     u8 reference;
235     /// (user) mask
236     u8 mask;
237     /// (user) enable
238     GX2Boolean enable;
239 
240 } GX2HiStencilState;
241 
242 /// \brief Describes all HiStencil pretest states.
243 ///
244 /// Must be used in conjunction w/ GX2DepthBuffer to completely describe depth/stencil buffer
245 ///
246 typedef struct _GX2HiStencilInfo {
247 
248     /// (user) compare function
249     GX2HiStencilState state[GX2_NUM_HISTENCIL_STATES];
250 
251     /// (calc) private, calculated by driver
252     u32 _regs[GX2_NUM_HISTENCIL_STATES];
253 
254 } GX2HiStencilInfo;
255 
256 /// @}
257 /// @addtogroup GX2SurfaceAllGroup
258 /// @{
259 
260 // Rectangular region
261 // left, top are inclusive.
262 // right, bottom are exclusive
263 // 0,0 is the upper left of the surface
264 typedef struct _GX2RectInt {
265     s32 left;
266     s32 top;
267     s32 right;
268     s32 bottom;
269 } GX2RectInt;
270 
271 // A point
272 // 0,0 is the upper left of the surface
273 typedef struct _GX2PointInt {
274     s32 x;
275     s32 y;
276 } GX2PointInt;
277 
278 // An AA sampling point
279 // 0,0 is center of the AA sampling point
280 // It ranges -8 to 7 offset from pixel center.
281 typedef struct _GX2AASampleLoc {
282     s8 x[8];
283     s8 y[8];
284 } GX2AASampleLoc;
285 
286 /// @}
287 /// @addtogroup GX2SurfaceAllGroup
288 /// @{
289 
290 //----------------------------------------------------------------------
291 // Functions
292 
293 /// \brief Given a surface structure with user fields set, fill in size & other computed values.
294 ///
295 /// \note  There is presently a bug in this function concerning the selection of tile mode
296 ///        to use for BCx compressed textures below a certain size (128x64 pixels).  If given
297 ///        GX2_TILE_MODE_DEFAULT, the function will choose GX2_TILE_MODE_2D_TILED_THIN1.
298 ///        However, it should choose GX2_TILE_MODE_1D_TILED_THIN1 for BCx textures below the
299 ///        size of 128x64 pixels.  This affects the main image (mip 0) calculation.  The
300 ///        function will correctly recognize that the smaller mip levels are all 1D tiled.
301 ///        This function will be fixed in a future SDK; you should work around it in the mean
302 ///        time by avoiding the use of GX2_TILE_MODE_DEFAULT for BCx textures below 128x64
303 ///        pixels (use GX2_TILE_MODE_1D_TILED_THIN1 instead).
304 ///
305 /// \param surface Ptr to surface structure to update
306 ///
307 /// \donotcall \threadsafe \devonly \enddonotcall
308 ///
309 void GX2API GX2CalcSurfaceSizeAndAlignment(GX2Surface *surface);
310 
311 /// @}
312 /// @addtogroup GX2SurfaceColorGroup
313 /// @{
314 
315 /// \brief Given an initialized color buffer, calculate the size and alignment
316 /// for the aux (AA) buffer.  AA surfaces must have an aux buffer set up.
317 ///
318 /// \param colorBuffer Ptr to initialized colorBuffer structure to inquire about
319 /// \param pSize   Ptr to u32 to hold calculated size
320 /// \param pAlign  Ptr to u32 to hold calculated alignment
321 ///
322 /// \donotcall \threadsafe \devonly \enddonotcall
323 ///
324 void GX2API GX2CalcColorBufferAuxInfo(GX2ColorBuffer *colorBuffer, u32 *pSize,
325                                       u32 *pAlign);
326 
327 /// \brief Given a color buffer structure with user fields set, fill in register values.
328 ///
329 /// \param colorBuffer Ptr to color buffer structure to update.
330 ///
331 /// \donotcall \threadsafe \devonly \enddonotcall
332 ///
333 void GX2API GX2InitColorBufferRegs(GX2ColorBuffer *colorBuffer);
334 
335 /// @}
336 /// @addtogroup GX2SurfaceDepthGroup
337 /// @{
338 
339 /// \brief Given an initialized depth buffer, calculate the size and alignment
340 /// for the Hi-Z buffer.  The Hi-Z buffer is optional; it improves performance.
341 ///
342 /// \param depthBuffer Ptr to initialized depthBuffer structure to inquire about
343 /// \param pSize   Ptr to u32 to hold calculated size
344 /// \param pAlign  Ptr to u32 to hold calculated alignment
345 ///
346 /// \donotcall \threadsafe \devonly \enddonotcall
347 ///
348 void GX2API GX2CalcDepthBufferHiZInfo(GX2DepthBuffer *depthBuffer, u32 *pSize,
349                                       u32 *pAlign);
350 
351 /// \brief Given a depth buffer structure with user fields set, fill in register values.
352 ///
353 /// \param depthBuffer Ptr to depth buffer structure to update.
354 ///
355 /// \donotcall \threadsafe \devonly \enddonotcall
356 ///
357 void GX2API GX2InitDepthBufferRegs(GX2DepthBuffer *depthBuffer);
358 
359 /// \brief Allows setting the Hi-Z enable bit within a depth buffer structure
360 ///
361 /// \note The Hi-Z buffer ptr must be set (\ref GX2InitDepthBufferHiZPtr)
362 ///       before enabling Hi-Z
363 ///
364 /// \param depthBuffer Ptr to depth buffer structure to update.
365 /// \param hiZEnable boolean indicating whether hiZ should be enabled.
366 ///
367 /// \donotcall \threadsafe \devonly \enddonotcall
368 ///
369 void GX2API GX2InitDepthBufferHiZEnable(GX2DepthBuffer *depthBuffer,
370                                         GX2Boolean hiZEnable);
371 
372 /// \brief Allows setting the Z Range Base within a depth buffer structure.
373 ///
374 /// This function sets the Z Range Base setting for HiZ testing. The default
375 /// state is \ref GX2_ZRANGE_BASE_ZMIN (ideal for \ref GX2_COMPARE_GREATER and
376 /// \ref GX2_COMPARE_GEQUAL). Otherwise, \ref GX2_ZRANGE_BASE_ZMAX should be
377 /// used.
378 ///
379 /// \note This routine should be executed after \ref GX2InitDepthBufferRegs.
380 ///       Calling GX2InitDepthBufferRegs will reset this back to
381 ///       \ref GX2_ZRANGE_BASE_ZMIN.
382 ///
383 /// \warning The depth buffer must be clear or about to be cleared when the Z
384 ///          Range Base is changed or depth buffer corruption may result.
385 ///
386 /// \param depthBuffer Ptr to depth buffer structure to update.
387 /// \param rangeBase enum indicating which Z Range Base to use.
388 ///
389 /// \donotcall \threadsafe \devonly \enddonotcall
390 ///
391 void GX2API GX2InitDepthBufferRangeBase(GX2DepthBuffer *depthBuffer,
392                                         GX2ZRangeBase rangeBase);
393 
394 /// \brief Given a HiStencilInfo structure with user fields set, fill in register values.
395 ///
396 /// \param hiStencilInfo A set of 2 HiStencil pretest states.
397 ///
398 void GX2API GX2InitHiStencilInfoRegs(GX2HiStencilInfo *hiStencilInfo);
399 
400 /// \brief Helper function to set up HiStencilInfo structure in a convenient way.
401 ///
402 /// \param hiStencilInfo Ptr to HiStencil info structure to update.
403 /// \param state0 A HiStencil pretest state
404 /// \param state1 A HiStencil pretest state
405 ///
GX2InitHiStencilInfo(GX2HiStencilInfo * hiStencilInfo,GX2HiStencilState * state0,GX2HiStencilState * state1)406 GX2_INLINE void GX2InitHiStencilInfo(GX2HiStencilInfo *hiStencilInfo, GX2HiStencilState *state0, GX2HiStencilState *state1)
407 {
408     ASSERT(hiStencilInfo);
409 
410     if (state0)
411         hiStencilInfo->state[0] = *state0;
412 
413     if (state1)
414         hiStencilInfo->state[1] = *state1;
415 
416     GX2InitHiStencilInfoRegs(hiStencilInfo);
417 }
418 
419 /// @}
420 /// @addtogroup GX2SurfaceColorGroup
421 /// @{
422 
423 /// \brief Sets the given color buffer to be used as the given render target.
424 ///
425 /// The 'use' field must indicate color buffer usage.
426 ///
427 /// \note These set functions always update the address register based upon
428 ///       the user-provided pointer (thus there is no need to call the init
429 ///       function again when only changing the address pointer).
430 ///
431 /// \note The AA value within the given colorBuffer will only be set to the hardware
432 ///       when the target parameter is 0 (or GX2_RENDER_TARGET_0).  The AA values for the
433 ///       depth buffer and all color buffers which are in use must match.  GX2 currently
434 ///       does not verify this requirement. See Also \ref GX2SetAAMode().
435 ///
436 /// \note Warning: This function does not set the scissor box to the size of the color
437 ///       buffer. To prevent writing outside of the color buffer, \ref GX2SetScissor should be
438 ///       called in conjunction this function.
439 ///
440 /// \param colorBuffer Ptr to color buffer structure to use; all fields & registers should already be initialized.
441 /// \param target Which render target to configure
442 ///
443 /// \donotcall \gx2_typical \enddonotcall
444 ///
445 /// \writesgpu
446 /// \alwayswritesgpu
447 ///
448 void GX2API GX2SetColorBuffer(const GX2ColorBuffer *colorBuffer,
449                               GX2RenderTarget target);
450 
451 /// @}
452 /// @addtogroup GX2SurfaceDepthGroup
453 /// @{
454 
455 /// \brief Sets the given depth buffer to be used as the depth/stencil target.
456 ///
457 /// The 'use' field must indicate depth buffer usage.
458 ///
459 /// \note These set functions always update the address register based upon
460 ///       the user-provided pointer (thus there is no need to call the init
461 ///       function again when only changing the address pointer).
462 ///
463 /// \note Warning: This function doesn't set the AA registers. When setting just a depth
464 ///       buffer, verify that the AA mode of this depth buffer matches that of the last
465 ///       color buffer that was set, or call /ref GX2SetAAMode() if you need to explicitly
466 ///       set the AA mode for the depth buffer.
467 ///
468 /// \warning This function does not set the scissor box to the size of the color
469 ///       buffer. To prevent writing outside of the color buffer, \ref GX2SetScissor should be
470 ///       called in conjunction this function.
471 ///
472 /// \param depthBuffer Ptr to depth buffer structure to use; all fields & registers should already be initialized.
473 ///
474 /// \donotcall \gx2_typical \enddonotcall
475 ///
476 /// \writesgpu
477 /// \alwayswritesgpu
478 ///
479 void GX2API GX2SetDepthBuffer(const GX2DepthBuffer *depthBuffer);
480 
481 /// \brief Sets the given HiStencil info to be used as the HiStencil pretest state.
482 ///
483 /// Must be used in conjunction with \ref GX2SetDepthBuffer in order to fully
484 /// describe the depth/stencil buffer when HiStencil is used.
485 ///
486 /// \param hiStencilInfo Ptr to HiStencil info structure to use; all fields & registers should already be initialized.
487 ///
488 void GX2API GX2SetHiStencilInfo(const GX2HiStencilInfo *hiStencilInfo);
489 
490 /// @}
491 /// @addtogroup GX2SurfaceColorGroup
492 /// @{
493 
494 /// \brief Helper function for initializing color buffers
495 ///
496 /// \warning Do not use this function. Instead use
497 /// \ref GX2InitColorBufferFTV or \ref GX2InitColorBuffer.
498 ///
499 /// \donotcall \threadsafe \devonly \enddonotcall
500 ///
_GX2InitColorBuffer(GX2ColorBuffer * colorBuffer,u32 width,u32 height,GX2SurfaceFormat format,GX2AAMode aa)501 GX2_INLINE void _GX2InitColorBuffer(GX2ColorBuffer *colorBuffer,
502                                u32 width, u32 height,
503                                GX2SurfaceFormat format, GX2AAMode aa)
504 {
505     GX2_CHECK_ENUM_RANGE(format, GX2_SURFACE_FORMAT)
506     GX2_CHECK_ENUM_RANGE(aa, GX2_AA_MODE)
507 
508     colorBuffer->surface.dim = GX2_SURFACE_DIM_2D;
509     colorBuffer->surface.width = width;
510     colorBuffer->surface.height = height;
511     colorBuffer->surface.depth = 1;
512     colorBuffer->surface.numMips = 1; // 1 means base level only
513     colorBuffer->surface.mipPtr = NULL;
514     colorBuffer->surface.format = format;
515     colorBuffer->surface.aa = aa;
516     // colorBuffer->surface.use set by wrapping function
517 #ifdef GX2_ENABLE_FIX2197
518     colorBuffer->surface.tileMode = GX2_TILE_MODE_DEFAULT_FIX2197;
519 #else
520     colorBuffer->surface.tileMode = GX2_TILE_MODE_DEFAULT;
521 #endif
522     colorBuffer->surface.swizzle  = 0;
523     colorBuffer->viewMip = 0;
524     colorBuffer->viewFirstSlice = 0;
525     colorBuffer->viewNumSlices = 1;
526     GX2CalcSurfaceSizeAndAlignment(&colorBuffer->surface);
527 #ifndef GX2_SURFACE_STANDALONE
528     GX2InitColorBufferRegs(colorBuffer);
529 #endif
530 }
531 
532 /// \brief Helper function to set up color buffer structure in a convenient way.
533 ///
534 /// \note  Certain fields are set to typical default values.  If you wish to non-default
535 ///        values, then those fields must be set manually.  You may need to call
536 ///        \ref GX2CalcSurfaceSizeAndAlignment or \ref GX2InitColorBufferRegs after
537 ///        changing certain fields.
538 ///
539 /// \param colorBuffer Ptr to color buffer structure to initialize.
540 /// \param width  Desired width for color buffer.
541 /// \param height Desired height for color buffer.
542 /// \param format Desired surface format for color buffer.
543 /// \param aa     Desired AA mode for color buffer.
544 ///
545 /// \donotcall \threadsafe \devonly \enddonotcall
546 ///
GX2InitColorBuffer(GX2ColorBuffer * colorBuffer,u32 width,u32 height,GX2SurfaceFormat format,GX2AAMode aa)547 GX2_INLINE void GX2InitColorBuffer(GX2ColorBuffer *colorBuffer,
548                                u32 width, u32 height,
549                                GX2SurfaceFormat format, GX2AAMode aa)
550 {
551     colorBuffer->surface.use = GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE;
552     _GX2InitColorBuffer(colorBuffer, width, height, format, aa);
553 }
554 
555 /// \brief Helper function to set up color buffer image pointer.
556 ///
557 /// \note This function only changes the image pointer, not the mip pointer,
558 ///       which is normally not relevant to color buffers unless you're rendering to a mip level.
559 ///
560 /// \param colorBuffer Ptr to color buffer structure to update.
561 /// \param ptr New image pointer value.
562 ///
563 /// \donotcall \threadsafe \devonly \enddonotcall
564 ///
GX2InitColorBufferPtr(GX2ColorBuffer * colorBuffer,void * ptr)565 GX2_INLINE void GX2InitColorBufferPtr(GX2ColorBuffer *colorBuffer, void *ptr)
566 {
567     colorBuffer->surface.imagePtr = ptr;
568 }
569 
570 /// \brief Helper function to set up color buffer aux (AA) pointer.
571 ///
572 /// \note This function only needs to be called for AA surfaces.
573 ///       AA surfaces must have an aux buffer set up.
574 /// \note The auxPtr buffer must be initialized to \ref GX2_AUX_BUFFER_CLEAR_VALUE.
575 ///
576 /// \param colorBuffer Ptr to color buffer structure to update.
577 /// \param auxPtr New aux buffer pointer value.
578 ///
579 /// \donotcall \threadsafe \devonly \enddonotcall
580 ///
GX2InitColorBufferAuxPtr(GX2ColorBuffer * colorBuffer,void * auxPtr)581 GX2_INLINE void GX2InitColorBufferAuxPtr(GX2ColorBuffer *colorBuffer, void *auxPtr)
582 {
583     colorBuffer->auxPtr = auxPtr;
584 }
585 
586 /// \brief Helper function to set up color buffer that is a final TV render target.
587 ///
588 /// A "final" TV render target is one that will be copied to a TV scan buffer.
589 /// It needs to be designated to handle certain display corner cases.
590 /// (When a HD surface must be scaled down to display in NTSC/PAL.)
591 ///
592 /// In cases when the surface must be scaled down for proper display,
593 /// if the requested surface was AA, then AA will be disabled.
594 /// This is required to work around certain hardware limitations
595 /// (this avoids performance penalties from other possible work-arounds).
596 /// To see if AA was disabled, check the value of the surface->aa field
597 /// after making this call.
598 ///
599 /// An alternate solution to having the AA disabled is to instead choose a
600 /// final TV render target size that matches the reduced-size scan buffer.
601 /// See the \ref GX2DisplayPage page for details.
602 ///
603 /// \note  Certain fields are set to typical default values.  If you wish to non-default
604 ///        values, then those fields must be set manually.  You may need to call
605 ///        \ref GX2CalcSurfaceSizeAndAlignment or \ref GX2InitColorBufferRegs after
606 ///        changing certain fields.
607 ///
608 /// \param colorBuffer Ptr to color buffer structure to initialize.
609 /// \param width  Desired width for color buffer.
610 /// \param height Desired height for color buffer.
611 /// \param format Desired surface format for color buffer.
612 /// \param aa     Desired AA mode for color buffer.
613 ///
614 /// \donotcall \threadsafe \devonly \enddonotcall
615 ///
GX2InitColorBufferFTV(GX2ColorBuffer * colorBuffer,u32 width,u32 height,GX2SurfaceFormat format,GX2AAMode aa)616 GX2_INLINE void GX2InitColorBufferFTV(GX2ColorBuffer *colorBuffer,
617                                       u32 width, u32 height,
618                                       GX2SurfaceFormat format, GX2AAMode aa)
619 {
620     colorBuffer->surface.use = GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE_FTV;
621     _GX2InitColorBuffer(colorBuffer, width, height, format, aa);
622     // If aa was disabled, pad size/align to what aa would have required
623     if (colorBuffer->surface.aa != aa) {
624         GX2Surface paddedSurf = colorBuffer->surface;
625         paddedSurf.aa = aa;
626         paddedSurf.use = GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE;
627         GX2CalcSurfaceSizeAndAlignment(&paddedSurf);
628         ASSERT(colorBuffer->surface.imageSize <= paddedSurf.imageSize);
629         ASSERT(colorBuffer->surface.alignment <= paddedSurf.alignment);
630         colorBuffer->surface.imageSize = paddedSurf.imageSize;
631         colorBuffer->surface.alignment = paddedSurf.alignment;
632     }
633 }
634 
635 /// @}
636 /// @addtogroup GX2SurfaceDepthGroup
637 /// @{
638 
639 /// \brief Helper function to set up depth buffer structure in a convenient way.
640 ///
641 /// \note  Certain fields are set to typical default values.  If you wish to non-default
642 ///        values, then those fields must be set manually.  You may need to call
643 ///        \ref GX2CalcSurfaceSizeAndAlignment or \ref GX2InitDepthBufferRegs after
644 ///        changing certain fields.
645 ///
646 /// \param depthBuffer Ptr to depth buffer structure to initialize.
647 /// \param width  Desired width for depth buffer.
648 /// \param height Desired height for depth buffer.
649 /// \param format Desired surface format for depth buffer.
650 /// \param aa     Desired AA mode for depth buffer.
651 ///
652 /// \donotcall \threadsafe \devonly \enddonotcall
653 ///
GX2InitDepthBuffer(GX2DepthBuffer * depthBuffer,u32 width,u32 height,GX2SurfaceFormat format,GX2AAMode aa)654 GX2_INLINE void GX2InitDepthBuffer(GX2DepthBuffer *depthBuffer,
655                                u32 width, u32 height,
656                                GX2SurfaceFormat format, GX2AAMode aa)
657 {
658     GX2_CHECK_ENUM_RANGE(format, GX2_SURFACE_FORMAT)
659     GX2_CHECK_ENUM_RANGE(aa, GX2_AA_MODE)
660 
661     depthBuffer->surface.dim = GX2_SURFACE_DIM_2D;
662     depthBuffer->surface.width = width;
663     depthBuffer->surface.height = height;
664     depthBuffer->surface.depth = 1;
665     depthBuffer->surface.numMips = 1; // 1 means base level only
666     depthBuffer->surface.format = format;
667     depthBuffer->surface.aa = aa;
668     depthBuffer->surface.use = ((format==GX2_SURFACE_FORMAT_D_D24_S8_UNORM) || (format==GX2_SURFACE_FORMAT_D_D24_S8_FLOAT)) ? GX2_SURFACE_USE_DEPTH_BUFFER : GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE;
669     depthBuffer->surface.tileMode = GX2_TILE_MODE_DEFAULT;
670     depthBuffer->surface.swizzle  = 0;
671     depthBuffer->viewMip = 0;
672     depthBuffer->viewFirstSlice = 0;
673     depthBuffer->viewNumSlices = 1;
674     depthBuffer->hiZPtr=NULL;
675     depthBuffer->hiZSize=0;
676     depthBuffer->clearDepth = 1.0f;
677     depthBuffer->clearStencil = 0;
678     GX2CalcSurfaceSizeAndAlignment(&depthBuffer->surface);
679 #ifndef GX2_SURFACE_STANDALONE
680     GX2InitDepthBufferRegs(depthBuffer);
681 #endif
682 }
683 
684 /// \brief Helper function to set up depth buffer image pointer
685 ///
686 /// \note This function only changes the image pointer, not the mip pointer,
687 ///       which is normally not relevant to depth buffers unless you're rendering to a mip level.
688 ///
689 /// \param depthBuffer Ptr to depth buffer structure to update.
690 /// \param ptr New image pointer value.
691 ///
692 /// \donotcall \threadsafe \devonly \enddonotcall
693 ///
GX2InitDepthBufferPtr(GX2DepthBuffer * depthBuffer,void * ptr)694 GX2_INLINE void GX2InitDepthBufferPtr(GX2DepthBuffer *depthBuffer, void *ptr)
695 {
696     depthBuffer->surface.imagePtr = ptr;
697 }
698 
699 /// \brief Helper function to set up depth buffer Hi-Z pointer.
700 ///
701 /// Hierarchical Z-buffer is optional; it improves depth testing performance.
702 ///
703 /// \param depthBuffer Ptr to depth buffer structure to update.
704 /// \param hiZPtr New Hi-Z buffer pointer value.
705 ///
706 /// \donotcall \threadsafe \devonly \enddonotcall
707 ///
GX2InitDepthBufferHiZPtr(GX2DepthBuffer * depthBuffer,void * hiZPtr)708 GX2_INLINE void GX2InitDepthBufferHiZPtr(GX2DepthBuffer *depthBuffer, void *hiZPtr)
709 {
710     depthBuffer->hiZPtr = hiZPtr;
711     GX2InitDepthBufferHiZEnable(depthBuffer, (GX2Boolean)(hiZPtr != NULL));
712 }
713 
714 /// @}
715 /// @addtogroup GX2SurfaceCopyGroup
716 /// @{
717 
718 /// \brief Copies the specified source surface to dest surface.
719 ///
720 /// Only copies a single 2D mip slice at most.  The copy will be done by
721 /// the GPU, unless a surface uses LINEAR_SPECIAL tile format, in which case
722 /// a CPU copy is performed.  For CPU copies, you may need to synchronize with
723 /// the GPU (by calling \ref GX2DrawDone, for instance).
724 ///
725 /// \note This API may change rendering states and disable state shadowing.
726 ///       It may alter registers that cannot be restored by common GX2 functions.
727 ///       Therefore you should always call \ref GX2SetContextState() afterward
728 ///       (except when doing CPU copies).
729 ///
730 /// \note The source and destinations surfaces must be the same format and have
731 ///       the same dimensions.  Stretching is not supported.
732 ///
733 /// \note Copying of format GX2_SURFACE_FORMAT_T_NV12_UNORM is currently not
734 ///       supported.
735 ///
736 /// \note Compressed textures must be copied on a 4x4 pixel alignment.
737 ///       Coordinates are in terms of pixels, not blocks.
738 ///
739 /// \note CPU copies are very slow and should normally be avoided.
740 ///
741 /// \param srcSurface  Pointer to source surface structure
742 /// \param srcMip      Mip level of surface to read (0 typically)
743 /// \param srcSlice    Slice to read for array & 3D (0 typically)
744 /// \param dstSurface  Pointer to destination surface structure
745 /// \param dstMip      Mip level of dest surface to write (0 typically)
746 /// \param dstSlice    Slice to write for array & 3D (0 typically)
747 ///
748 /// \donotcall \gx2_typical \enddonotcall
749 ///
750 /// \clobberstate If source or destination mode are GX2_TILE_MODE_LINEAR_SPECIAL this does not clobber state.
751 /// \disablesstateshadow If source or destination mode are GX2_TILE_MODE_LINEAR_SPECIAL this does not disable state shadowing.
752 /// \notincompute
753 ///
754 /// \writesgpu
755 /// \writesgpu{if source and destination tiling modes are not \ref GX2_TILE_MODE_LINEAR_SPECIAL}
756 ///
757 void GX2API GX2CopySurface(const GX2Surface *srcSurface, u32 srcMip, u32 srcSlice,
758                            GX2Surface *dstSurface, u32 dstMip, u32 dstSlice);
759 
760 
761 /// \brief Copies the specified source surface sub-rectangles to the dest surface at specified points.
762 ///
763 /// Only copies from and to a single 2D mip slice at most.  This API does not support buffers that use
764 /// LINEAR_SPECIAL tiling.  All operations are performed using the GPU.
765 ///
766 /// \note This API may change rendering states and disable state shadowing.
767 ///       It may alter registers that cannot be restored by common GX2 functions.
768 ///       Therefore you should always call \ref GX2SetContextState() afterward
769 ///       (except when doing CPU copies).
770 ///
771 /// \note The source and destinations surfaces must be the same format and
772 ///       stretching is not supported.
773 ///
774 /// \note The source rectangles and destination points should be in dimensions
775 ///       relative to srcMip/dstMip and not the base level.
776 ///       For example, if the base level of the texture is 100x100 and you
777 ///       wanted to copy all of srcMip = 1, then the source
778 ///       rectangle would be from (0,0) to (50x50), since the size of the src
779 ///       mip is 50 (100/2) on each side.
780 ///
781 /// \note Copying of format GX2_SURFACE_FORMAT_T_NV12_UNORM is currently not
782 ///       supported.
783 ///
784 /// \note CPU copies are very slow and should normally be avoided.
785 ///
786 /// \param srcSurface  Pointer to source surface structure
787 /// \param srcMip      Mip level of surface to read (0 typically)
788 /// \param srcSlice    Slice to read for array & 3D (0 typically)
789 /// \param dstSurface  Pointer to destination surface structure
790 /// \param dstMip      Mip level of dest surface to write (0 typically)
791 /// \param dstSlice    Slice to write for array & 3D (0 typically)
792 /// \param numRects    The number of source rectangles and destination points that describe the sub-regions to copy (1 typically).
793 ///                    This number cannot be larger than GX2_MAX_COPY_SURFACE_EX_RECTS.
794 /// \param pSrcRects   A pointer to an array of source rectangles describing the region of srcSurface to copy from.
795 /// \param pDstPoints  A pointer to an array of destination points describing the locations in dstSurface to copy to.
796 ///
797 /// \donotcall \gx2_typical \enddonotcall
798 ///
799 /// \clobberstate
800 /// \disablesstateshadow
801 /// \notincompute
802 ///
803 /// \writesgpu
804 /// \writesgpu{if source and destination tiling modes are not \ref GX2_TILE_MODE_LINEAR_SPECIAL}
805 ///
806 void GX2API GX2CopySurfaceEx(const GX2Surface *srcSurface, u32 srcMip, u32 srcSlice,
807                              GX2Surface *dstSurface, u32 dstMip, u32 dstSlice,
808                              u32 numRects, GX2RectInt *pSrcRects, GX2PointInt *pDstPoints);
809 
810 
811 /// @}
812 /// @addtogroup GX2SurfaceTileGroup
813 /// @{
814 
815 /// \brief Allocates a tiling aperture which allows linear CPU access to a tiled surface.
816 ///
817 /// To access a pixel/texel in the linear view, use:
818 /// - pixel address = aperture address + (Y * surface.pitch + X) * bytes_per_pixel
819 ///
820 /// Note that reading/writing through the tiling aperture is slower than referring to
821 /// the tiled surface directly.  For just checking a few pixels, this is reasonable.
822 /// To read/write an entire surface, it is suggested to use a LINEAR_ALIGNED surface
823 /// instead, and have the GPU convert the linear surface to or from a tiled format.
824 ///
825 /// \note After writing to a tiling aperture, a "flush" operation is REQUIRED.  The
826 ///       flush is performed by simply reading back an address within the aperture.
827 ///       It ensures that the data has made it to memory, and it also is necessary
828 ///       to prevent a corruption issue that can occur with any GX2 commands that
829 ///       follow.  The flush must therefore be done after any tiling aperture writes
830 ///       and before calling any GX2 APIs that write out GPU commands.
831 ///
832 /// \note Only ~30 tiling apertures may be created simultaneously.  They should be freed
833 ///       (using \ref GX2FreeTilingAperture) after they are no longer needed.
834 ///       Calling \ref GX2FreeTilingAperture will perform the flush mentioned above.
835 ///
836 /// \note There is also a limit of ~256MB of aperture space that may be allocated
837 ///       at once.  (This limit may vary in the future.)
838 ///
839 /// \note There is a hardware bug for 1-byte pixel formats.  The required work-around
840 ///       is to invert two of the address bits when accessing such a surface via the
841 ///       the tiling aperture:
842 ///       - pixel address = aperture address + ((Y^2) * surface.pitch + (X^8))
843 ///
844 /// \note The tiling APIs are not reentrant (that is, they are not multicore safe).  You should either
845 ///       only call them from a single core, or else add a mutex around calls to them.
846 ///
847 /// \param pSurface    Pointer to surface structure to be accessed
848 /// \param mip         Which mip level to view (for textures only, otherwise use 0)
849 /// \param slice       Which 3D/array slice to view (as appropriate, otherwise use 0)
850 /// \param mode        Enable endian swap for this area's CPU read/write
851 /// \param pAppHandle  Returned handle to use when freeing tiling aperture
852 /// \param pAppAddress Returned base address to use when accessing surface linearly
853 ///
854 /// \donotcall \gx2_typical \enddonotcall
855 ///
856 /// \writesgpu
857 /// \directwritesgpu
858 ///
859 void GX2API GX2AllocateTilingApertureEx(const GX2Surface *pSurface, u32 mip,
860                                        u32 slice, GX2EndianSwapMode mode,
861                                        u32 *pAppHandle, void **pAppAddress);
862 
863 
864 /// \brief Allocates a tiling aperture which allows linear CPU access to a tiled surface.
865 ///
866 /// This is an inline function that calls \ref GX2AllocateTilingApertureEx with the endian
867 /// swap mode set to \ref GX2_ENDIANSWAP_NONE.
868 ///
869 /// \donotcall \gx2_typical \enddonotcall
870 ///
871 /// \writesgpu
872 /// \directwritesgpu
873 ///
GX2AllocateTilingAperture(const GX2Surface * pSurface,u32 mip,u32 slice,u32 * pAppHandle,void ** pAppAddress)874 GX2_INLINE void GX2AllocateTilingAperture(const GX2Surface *pSurface, u32 mip,
875                                u32 slice, u32 *pAppHandle, void **pAppAddress)
876 {
877     GX2AllocateTilingApertureEx(pSurface, mip, slice, GX2_ENDIANSWAP_NONE,
878                                 pAppHandle, pAppAddress);
879 }
880 
881 /// \brief Frees a tiling aperture which allows linear CPU access to a tiled surface.
882 ///
883 /// \param appHandle  Handle to tiling aperture to free
884 ///
885 /// \donotcall \gx2_typical \enddonotcall
886 ///
887 /// \writesgpu
888 /// \directwritesgpu
889 ///
890 void GX2API GX2FreeTilingAperture(u32 appHandle);
891 
892 /// @}
893 /// @addtogroup GX2SurfaceCopyGroup
894 /// @{
895 
896 /// \brief Resolves an MSAA color buffer to a single-sample color surface by
897 /// averaging the multiple sample colors together.  The source buffer is not modified.
898 ///
899 /// This resolve will use the GPU's fast fixed-function hardware to perform the resolve,
900 /// however only certain formats are supported.  See the function \ref GX2IsResolveSupported()
901 /// to see which formats support this fixed-function resolve path.  Calling this function with
902 /// an unsupported format will assert in a debug build, but result in undefined behavior in a
903 /// release build.  To perform an MSAA resolve on a format that is not supported by the
904 /// fixed-function resolve hardware, do not use this function, but instead use a custom shader
905 /// to blend the MSAA samples (see test\gx2\assets\shaders\simple\texture2DMS.ps) in a draw.
906 ///
907 /// If srcBuffer contains multiple slices, they will all be resolved to
908 /// the dstSurface beginning at dstSlice.  This function resolves only the single
909 /// miplevel specified by srcBuffer->viewMip and dstMip. This function resolves the number of
910 /// slices specified by srcBuffer->viewNumSlices starting with slice number
911 /// srcBuffer->viewFirstSlice.
912 ///
913 /// \note This API changes rendering states and disables state shadowing.
914 ///       It may alter registers that cannot be restored by common GX2 functions.
915 ///       Therefore you should always call \ref GX2SetContextState() afterward.
916 ///
917 /// \param srcBuffer  Pointer to a compressed MSAA color buffer
918 /// \param dstSurface Pointer to a single-sample surface
919 /// \param dstMip     Which mip level to write
920 /// \param dstSlice   Which 3D/array slice to start writing to
921 ///
922 /// \donotcall \gx2_typical \enddonotcall
923 ///
924 /// \clobberstate
925 /// \disablesstateshadow
926 /// \notincompute
927 ///
928 /// \writesgpu
929 /// \alwayswritesgpu
930 ///
931 void GX2API GX2ResolveAAColorBuffer(const GX2ColorBuffer *srcBuffer,
932                                     GX2Surface *dstSurface,
933                                     u32 dstMip, u32 dstSlice);
934 
935 /// \brief Expands an MSAA color buffer in-place to allow the surface to be
936 /// used as an MSAA texture.
937 ///
938 /// It is not necessary to call this function before calling \ref GX2ResolveAAColorBuffer.
939 /// This function modifies both the MSAA buffer and its auxiliary memory.
940 /// Subsequent draw calls to this buffer will undo the expand, so this must be
941 /// called between drawing to the buffer and texturing from it.  It is okay to
942 /// draw to this buffer after expanding it.
943 ///
944 /// All slices referred to by buffer->viewFirstSlice and
945 /// buffer->viewNumSlices will be expanded.  This function resolves only the single
946 /// miplevel specified by buffer->viewMip.
947 ///
948 /// \note This API changes rendering states and disables state shadowing.
949 ///       It may alter registers that cannot be restored by common GX2 functions.
950 ///       Therefore you should always call \ref GX2SetContextState() afterward.
951 ///
952 /// \param buffer Pointer to a compressed MSAA color buffer
953 ///
954 /// \donotcall \gx2_typical \enddonotcall
955 ///
956 /// \clobberstate
957 /// \disablesstateshadow
958 /// \notincompute
959 ///
960 /// \writesgpu
961 /// \alwayswritesgpu
962 ///
963 void GX2API GX2ExpandAAColorBuffer(GX2ColorBuffer *buffer);
964 
965 /// \brief Expands a HiZ depth buffer in-place.
966 ///
967 /// Prepares a HiZ depth buffer to be used as a texture. For the surface
968 /// to be usable as a texture it must have a \ref GX2SurfaceFormat that
969 /// is compatible with use as a texture. For example,
970 /// \ref GX2_SURFACE_FORMAT_D_D24_S8_UNORM cannot be used as a texture.
971 /// In addition, the depth-format texture must not be MSAA.  If you must
972 /// texture from D24_S8 format or MSAA depth data, then you must call
973 /// \ref GX2ConvertDepthBufferToTextureSurface instead.
974 ///
975 /// This function modifies both the depth buffer and its HiZ buffer.
976 /// Subsequent draw calls to this buffer will undo the expand, so this must be
977 /// called between drawing to the buffer and texturing from it.  It is fine to
978 /// draw to this buffer after expanding it.
979 ///
980 /// All slices referred to by buffer->viewFirstSlice and
981 /// buffer->viewNumSlices will be expanded.  This function resolves only the single
982 /// miplevel specified by buffer->viewMip.
983 ///
984 /// \note This API changes rendering states and disables state shadowing.
985 ///       It may alter registers that cannot be restored by common GX2 functions.
986 ///       Therefore you should always call \ref GX2SetContextState() afterward.
987 ///
988 /// \param buffer Pointer to a HiZ depth buffer structure
989 ///
990 /// \donotcall \gx2_typical \enddonotcall
991 ///
992 /// \clobberstate
993 /// \disablesstateshadow
994 /// \notincompute
995 ///
996 /// \writesgpu
997 /// \alwayswritesgpu
998 ///
999 void GX2API GX2ExpandDepthBuffer(GX2DepthBuffer *buffer);
1000 
1001 /// \brief Copies and converts a depth buffer to a format readable as a texture.
1002 ///
1003 /// Copies a depth buffer (with or without HiZ) to another surface while
1004 /// changing from depth-format tiling to texture/color-format tiling.
1005 /// This is only necessary for depth formats that cannot already be read
1006 /// by the texture unit (those with AA or D24_S8 format).  This is also
1007 /// necessary if you wish to convert a depth buffer directly into a color
1008 /// buffer.  The number of MSAA samples in the source and destination must
1009 /// match.
1010 ///
1011 /// The surface dstSurface must not have a use of GX2_SURFACE_USE_DEPTH_BUFFER
1012 /// as this API will convert the surface tiling to only be suitable for uses
1013 /// of GX2_SURFACE_USE_TEXTURE or GX2_SURFACE_USE_COLOR_BUFFER.
1014 ///
1015 /// Converting 'in-place' can be achieved if the source and destination surfaces
1016 /// have the same memory pointers.  The 'use' field in the source and
1017 /// destination surfaces must be set differently and correctly (USE_DEPTH_BUFFER
1018 /// for the source and !USE_DEPTH_BUFFER and [USE_TEXTURE or USE_COLOR_BUFFER]
1019 /// for the destination).  When copying 'in-place', the 'tileMode' must be
1020 /// the same for the source and destination.
1021 ///
1022 /// If the HiZ buffer is present, the depth data will be expanded during the
1023 /// conversion. When the conversion is not 'in-place', the source depth
1024 /// and HiZ buffers will not be modified and it is fine to draw to the source
1025 /// buffer after this operation.
1026 ///
1027 /// If srcBuffer contains multiple slices, they will all be expanded to
1028 /// the dstSurface beginning at dstSlice.  This function resolves only the single
1029 /// miplevel specified by srcBuffer->viewMip and dstMip. This function resolves
1030 /// the number of slices specified by srcBuffer->viewNumSlices starting with slice
1031 /// number srcBuffer->viewFirstSlice.
1032 ///
1033 /// The result of calling GX2ConvertDepthBufferToTextureSurface() on a
1034 /// D_D24_S8_UNORM depth buffer is a D24_S8 buffer, with both depth and stencil
1035 /// bits, that can be read by the texture unit.  (It is NOT necessary to call
1036 /// GX2ConvertDepthBufferToTextureSurface() twice on the D_D24_S8_UNORM to get both
1037 /// the depth and stencil data.) However, because the D24 depth data is 24-bits in
1038 /// UNORM format and then S8 stencil data is 8-bits in UINT format, a single
1039 /// texture sampler can only read one or the other (depth OR stencil data).  The
1040 /// GX2_SURFACE_FORMAT_T_R24_UNORM_X8 and GX2_SURFACE_FORMAT_T_X24_G8_UINT values
1041 /// are used to indicate the two formats used for reading the buffer, but the
1042 /// buffer always contains both the depth and stencil data.
1043 ///
1044 /// The render2depth demo shows how to read the depth and stencil data from the
1045 /// buffer, but does so in two different draw calls.  By using the same GX2Surface,
1046 /// pointing to the same memory buffer, setting the format field to either
1047 /// T_R24_UNORM_X8 or T_X24_G8_UINT simply selects in which format the bits will be
1048 /// read out of the buffer.  The GX2Texture structure's "compSel" field is used to
1049 /// read the depth data out of the X channel (GX2_COMP_SEL_XXXX) or the stencil
1050 /// data out of the Y channel (GX2_COMP_SEL_YYYY). It is also possible to read the
1051 /// depth and stencil data from the memory buffer in a single draw call as long as
1052 /// you setup two GX2Surface structures, two different samplers, "bind" the
1053 /// converted depth buffer to both, and perform two texture fetches.
1054 ///
1055 /// If converting a GX2_SURFACE_FORMAT_D_D24_S8_UNORM buffer using
1056 /// GX2ConvertDepthBufferToTextureSurface(), set the destination format to
1057 /// GX2_SURFACE_FORMAT_T_R24_UNORM_X8.  If converting a
1058 /// GX2_SURFACE_FORMAT_D_D32_FLOAT_S8_UINT_X24 buffer using
1059 /// GX2ConvertDepthBufferToTextureSurface(), set the destination format to
1060 /// GX2_SURFACE_FORMAT_T_R32_FLOAT_X8_X24.
1061 ///
1062 /// \note This API changes rendering states and disables state shadowing.
1063 ///       It may alter registers that cannot be restored by common GX2 functions.
1064 ///       Therefore you should always call \ref GX2SetContextState() afterward.
1065 ///
1066 /// \param srcBuffer  Pointer to a depth buffer structure
1067 /// \param dstSurface Pointer to a destination surface structure
1068 /// \param dstMip     Mip level of destination surface to write
1069 /// \param dstSlice   Slice to begin writing source slices to
1070 ///
1071 /// \donotcall \gx2_typical \enddonotcall
1072 ///
1073 /// \clobberstate
1074 /// \disablesstateshadow
1075 /// \notincompute
1076 ///
1077 /// \writesgpu
1078 /// \alwayswritesgpu
1079 ///
1080 void GX2API GX2ConvertDepthBufferToTextureSurface(const GX2DepthBuffer *srcBuffer,
1081                                                     GX2Surface *dstSurface,
1082                                                     u32 dstMip, u32 dstSlice);
1083 
1084 /// @}
1085 /// @addtogroup GX2SurfaceColorGroup
1086 /// @{
1087 
1088 /// \brief Given an NV12 format surface, create a surface structure that refers
1089 /// to the UV plane of the NV12 surface.
1090 ///
1091 /// \donotcall \threadsafe \devonly \enddonotcall
1092 ///
GX2InitNV12UVSurface(GX2Surface * dstUVSurface,GX2Surface * srcNV12Surface)1093 GX2_INLINE void GX2InitNV12UVSurface(GX2Surface *dstUVSurface, GX2Surface *srcNV12Surface)
1094 {
1095     ASSERT(srcNV12Surface && dstUVSurface);
1096     ASSERT(srcNV12Surface->format == GX2_SURFACE_FORMAT_T_NV12_UNORM);
1097     *dstUVSurface = *srcNV12Surface;
1098     dstUVSurface->height >>= 1;
1099     dstUVSurface->width >>= 1;
1100     dstUVSurface->pitch >>= 1;
1101     dstUVSurface->format = GX2_SURFACE_FORMAT_TC_R8_G8_UNORM;
1102     dstUVSurface->imagePtr = (void*)((u32)dstUVSurface->imagePtr + srcNV12Surface->mipOffset[0]);
1103     dstUVSurface->imageSize -= srcNV12Surface->mipOffset[0];
1104 }
1105 
1106 /// @}
1107 /// @addtogroup GX2SurfaceAllGroup
1108 /// @{
1109 
1110 /// \brief Returns the size in bits per pixel for a given surface format.
1111 ///        For block compressed formats, it returns the "effective" bits per pixel (bits per block/pixels per block).
1112 ///
1113 /// \donotcall \threadsafe \devonly \enddonotcall
1114 ///
1115 u32 GX2API GX2GetSurfaceFormatBits(GX2SurfaceFormat format);
1116 
1117 /// \brief Given a surface pointer and mip level, returns the swizzle offset.
1118 ///        If a surface is not compatible with swizzling, then 0 will be returned, even if
1119 ///        surface->swizzle is non-zero.
1120 ///
1121 /// \param  surface Ptr to surface structure.
1122 /// \param  mipLevel Mip level referenced.
1123 /// \return The Swizzle offset.
1124 ///
1125 /// \donotcall \threadsafe \devonly \enddonotcall
1126 ///
1127 u32 GX2API GX2GetSurfaceSwizzleOffset(GX2Surface *surface, u32 mipLevel);
1128 
1129 /// \brief Given a surface pointer, returns the swizzle that was set for that surface through
1130 ///        GX2SetSurfaceSwizzle().  If a non-zero swizzle was set through GX2SetSurfaceSwizzle(),
1131 ///        then GX2GetSurfaceSwizzle() will return the same non-zero swizzle even if the surface
1132 ///        is not compatible with swizzling.
1133 ///
1134 /// \param  surface Ptr to surface structure.
1135 /// \return The Swizzle value.
1136 ///
1137 /// \donotcall \threadsafe \devonly \enddonotcall
1138 ///
1139 u32 GX2API GX2GetSurfaceSwizzle(GX2Surface *surface);
1140 
1141 /// \brief Helper function to set the swizzle value on a given surface.
1142 ///
1143 /// \note Changing the swizzle value will cause all of the current contents of the buffer to appear corrupted if read.
1144 ///
1145 /// \param  surface Ptr to surface structure.
1146 /// \param  swizzle Desired swizzle value.
1147 ///
1148 /// \donotcall \threadsafe \devonly \enddonotcall
1149 ///
1150 void GX2API GX2SetSurfaceSwizzle(GX2Surface *surface, u32 swizzle);
1151 
1152 /// \brief Given a surface pointer and mip level, returns the mip pitch in pixels.
1153 ///
1154 /// \note For compressed formats, the pitch is in "elements" (4x4 pixel blocks).
1155 ///
1156 /// \param  surface Ptr to surface structure.
1157 /// \param  mipLevel Mip level referenced.
1158 /// \return The mip pitch in pixels or elements.
1159 ///
1160 /// \donotcall \threadsafe \devonly \enddonotcall
1161 ///
1162 u32 GX2API GX2GetSurfaceMipPitch(GX2Surface *surface, u32 mipLevel);
1163 
1164 /// \brief Given a surface pointer and mip level, returns the slice size in bytes.
1165 ///
1166 /// Returns (aligned_width * aligned_height * bytes_per_pixel * samples).
1167 /// The "aligned width" is equivalent to "pitch".
1168 ///
1169 /// \note A "slice" here is always a 2D slice.
1170 ///
1171 /// \param  surface Ptr to surface structure.
1172 /// \param  mipLevel Mip level referenced.
1173 /// \return The slice size in bytes.
1174 ///
1175 /// \donotcall \threadsafe \devonly \enddonotcall
1176 ///
1177 u32 GX2API GX2GetSurfaceMipSliceSize(GX2Surface *surface, u32 mipLevel);
1178 
1179 /// \brief Given a surface pointer and mip level, return the number of depth slices at that mip level.
1180 ///
1181 /// \param  surface Ptr to surface structure.
1182 /// \param  mipLevel Mip level referenced, where 0 is the first mip level.
1183 /// \return The number of max valid depth slices at that mip level.  1 is the smallest returned value.
1184 ///
1185 /// \donotcall \threadsafe \devonly \enddonotcall
1186 ///
GX2GetSurfaceMipDepth(const GX2Surface * surface,u32 mipLevel)1187 GX2_INLINE u32 GX2GetSurfaceMipDepth(const GX2Surface *surface, u32 mipLevel)
1188 {
1189     ASSERT(surface);
1190     ASSERT(mipLevel < surface->numMips);
1191     if(surface->dim != GX2_SURFACE_DIM_3D)
1192     {
1193         return surface->depth;
1194     }
1195     else
1196     {
1197         //For 3D surfaces, the number of depth slices decreases with miplevel.
1198         u32 depth = surface->depth >> mipLevel;
1199         //Returned depth should never be smaller than 1.
1200         return (depth >= 1) ? depth : 1;
1201     }
1202 }
1203 
1204 /// \brief Given a surface format, return GX2_TRUE if the format is a block compressed format (i.e. BC1).
1205 ///
1206 /// \param  format A surface format
1207 /// \return GX2_TRUE if the format is a block compressed format and GX2_FALSE otherwise.
1208 ///
1209 /// \donotcall \threadsafe \devonly \enddonotcall
1210 ///
1211 GX2Boolean GX2API GX2SurfaceIsCompressed(GX2SurfaceFormat format);
1212 
1213 
1214 /// \brief Given a surface format and use, return GX2_TRUE if the format is compatible with the use.
1215 ///
1216 /// \param  use A surface use
1217 /// \param  format A surface format
1218 /// \return GX2_TRUE if the format is compatible with the use and GX2_FALSE otherwise.
1219 /// \note "D" and "S" uses may not always be reported correctly.
1220 ///
1221 /// \donotcall \threadsafe \devonly \enddonotcall
1222 ///
1223 GX2Boolean GX2API GX2CheckSurfaceUseVsFormat(GX2SurfaceUse use, GX2SurfaceFormat format);
1224 
1225 /// \brief Sets the AA mode.
1226 ///
1227 /// This function sets the AA mode and can be used in conjunction
1228 /// with \ref GX2SetDepthBuffer() to setup depth only rendering.
1229 ///
1230 /// \note The AA mode is also set by \ref GX2SetColorBuffer() when the target
1231 ///       is GX2_RENDER_TARGET_0 or by \ref GX2UTSetRenderTargets().
1232 ///
1233 /// \param aa AA Mode to set \ref GX2AAMode.
1234 ///
1235 /// \donotcall \gx2_typical \enddonotcall
1236 ///
1237 /// \writesgpu
1238 /// \alwayswritesgpu
1239 ///
1240 void GX2API GX2SetAAMode(GX2AAMode aa);
1241 
1242 /// \brief Sets the AA mode with custom AA location.
1243 ///
1244 /// This function sets the AA mode and AA position and can be used in
1245 /// conjunction with \ref GX2SetDepthBuffer() to setup depth only rendering.
1246 ///
1247 /// \note All entries should be populated when MSAA is in use. This API
1248 ///       automatically fills all entries by repeating user specified sample
1249 ///       positions.(first two in GX2_AA_MODE_2X and four in GX2_AA_MODE_4X).
1250 /// \note The AA mode is also set by \ref GX2SetColorBuffer() when the target
1251 ///       is GX2_RENDER_TARGET_0 or by \ref GX2UTSetRenderTargets().
1252 ///       This API must be called afterward to customize the AA locations.
1253 ///
1254 /// \param sampleLoc AA location (up to x8 samples). Each sample ranges -8/16 to 7/16 offset from pixel center.
1255 /// \param aa AA Mode to set \ref GX2AAMode.
1256 ///
1257 /// \donotcall \gx2_typical \enddonotcall
1258 ///
1259 /// \writesgpu
1260 /// \alwayswritesgpu
1261 ///
1262 void GX2API GX2SetAAModeEx(GX2AASampleLoc* sampleLoc, GX2AAMode aa);
1263 
1264 /// @}
1265 
1266 /// @}
1267 
1268 #ifdef __cplusplus
1269 }
1270 #endif
1271 
1272 #endif // _CAFE_GX2_SURFACE_H_
1273