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