1 /*---------------------------------------------------------------------------*
2
3 Copyright 2010-2014 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 #ifndef _GX2UTCOPY_H_
14 #define _GX2UTCOPY_H_
15
16 // Note: Currently this header depends on gx2.h being included first to define
17 // types like s32 and structures like GX2Surface.
18 #include <cafe/gx2.h>
19
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23
24 /// @addtogroup GX2UTCopyAndConvertGroup
25 /// @{
26
27 /// \brief Rectangular region
28 typedef struct _GX2UTRect {
29 s32 left;
30 s32 top;
31 s32 right;
32 s32 bottom;
33 } GX2UTRect;
34
35 /// \brief Setup all of the constant render state needed for \ref GX2UTCopySurface.
36 ///
37 /// \param enable Enable or disable the state
38 ///
39 /// This enables and disables the state used by \ref GX2UTCopySurface and
40 /// \ref GX2UTCopySurfaceRectOp. After finishing all copy operations, it is
41 /// necessary to call this function to disable the copy state and sets any
42 /// changed state to the GX2 default state. A smaller yet equivalent
43 /// routine can be written using knowledge of the application's desired state.
44 /// To customize the state that is restored, refer to the library source
45 /// (src/lib/gx2ut/gx2utCopy.cpp).
46 ///
47 /// \donotcall \gx2_typical \enddonotcall
48 ///
49 /// \clobberstate
50 ///
51 /// \writesgpu
52 /// \alwayswritesgpu
53 ///
54 void GX2UTSetCopyState(GX2Boolean enable);
55
56 /// \brief Copy the specified source surface rectangle to the dest surface rectangle.
57 ///
58 /// \param srcSurface Pointer to source surface structure
59 /// \param srcMip Mip level of surface to read (0 typically)
60 /// \param srcSlice Slice to read for array & 3D (0 typically)
61 /// \param srcRect Pointer to the source region to copy.
62 /// \param dstSurface Pointer to destination surface structure
63 /// \param dstMip Mip level of dest surface to write (0 typically)
64 /// \param dstSlice Slice to write for array & 3D (0 typically)
65 /// \param dstRect Pointer to the destination region to copy.
66 /// \param dstAuxPtr Destination MSAA auxPtr for AA buffer or NULL for non-AA buffers.
67 /// \param dstAuxSize Destination MSAA auxSize for AA buffers or NULL for non-AA buffers.
68 ///
69 /// This function assumes \ref GX2UTSetCopyState
70 /// (or comparable state setup function) has been called to setup required
71 /// render state.
72 ///
73 /// Copies a region from one surface to a region of another surface.
74 /// Setting the rectangular regions to a top-left of (0,0) and a bottom-right
75 /// of (width, height) will blt the entire surface without any flipping (the
76 /// right and bottom are exclusive).
77 ///
78 /// The srcRect/dstRect dimensions should be relative to the mipmap level
79 /// dimensions, not the base level dimensions.
80 ///
81 /// \note Compressed textures must be copied on a 4x4 pixel alignment.
82 /// Coordinates are in terms of pixels, not blocks.
83 /// For compressed textures the source and destination formats must
84 /// match.
85 ///
86 /// \note It is not necessary to call \ref GX2Invalidate on the
87 /// source/destination buffers. This is done internally.
88 ///
89 /// \note If the source is an AA buffer, you must call
90 /// \ref GX2ExpandAAColorBuffer or \ref GX2UTExpandAAColorBuffer first.
91 ///
92 /// \note This copy, as it is, will be impacted by the toss stage
93 /// (\ref GX2TossStageSect) setup at GX2Init time. To avoid this, call
94 /// this function from a separate state context with profiling disabled.
95 /// See \ref GX2SetupContextStateEx for more information.
96 ///
97 /// \warning Stretching is not supported for depth/stencil/compressed formats.
98 ///
99 /// \clobberstate
100 ///
101 /// \donotcall \gx2_typical \enddonotcall
102 ///
103 /// \writesgpu
104 /// \alwayswritesgpu
105 ///
106 void GX2UTCopySurfaceRectOp(const GX2Surface *srcSurface,
107 u32 srcMip, u32 srcSlice, GX2UTRect *srcRect,
108 GX2Surface *dstSurface,
109 u32 dstMip, u32 dstSlice, GX2UTRect *dstRect,
110 void* dstAuxPtr, u32 dstAuxSize);
111
112 /// \brief Copy the specified source surface to the dest surface.
113 ///
114 /// \param srcSurface Pointer to source surface structure
115 /// \param srcMip Mip level of surface to read (0 typically)
116 /// \param srcSlice Slice to read for array & 3D (0 typically)
117 /// \param dstSurface Pointer to destination surface structure
118 /// \param dstMip Mip level of dest surface to write (0 typically)
119 /// \param dstSlice Slice to write for array & 3D (0 typically)
120 /// \param dstAuxPtr Destination MSAA auxPtr for AA buffer or NULL for non-AA buffers.
121 /// \param dstAuxSize Destination MSAA auxSize for AA buffers or NULL for non-AA buffers.
122 ///
123 /// This function assumes \ref GX2UTSetCopyState
124 /// (or comparable state setup function) has been called to setup required
125 /// render state.
126 ///
127 /// Copies a region from one surface to a region of another surface.
128 /// Setting the rectangular regions to a top-left of (0,0) and a bottom-right
129 /// of (width, height) will blt the entire surface without any flipping (the
130 /// right and bottom are exclusive).
131 ///
132 /// \note Compressed textures must be copied on a 4x4 pixel alignment.
133 /// Coordinates are in terms of pixels, not blocks.
134 /// For compressed textures the source and destination formats must
135 /// match.
136 ///
137 /// \note It is not necessary to call \ref GX2Invalidate on the
138 /// source/destination buffers. This is done internally.
139 ///
140 /// \note If the source is an AA buffer, you must call
141 /// \ref GX2ExpandAAColorBuffer or \ref GX2UTExpandAAColorBuffer first.
142 ///
143 /// \note This copy, as it is, will be impacted by the toss stage
144 /// (\ref GX2TossStageSect) setup at GX2Init time. To avoid this, call
145 /// this function from a separate state context with profiling disabled.
146 /// See \ref GX2SetupContextStateEx for more information.
147 ///
148 /// \warning Stretching is not supported for depth/stencil/compressed formats.
149 ///
150 /// \clobberstate
151 ///
152 /// \donotcall \gx2_typical \enddonotcall
153 ///
154 /// \writesgpu
155 /// \alwayswritesgpu
156 ///
GX2UTCopySurfaceOp(const GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice,void * dstAuxPtr,u32 dstAuxSize)157 GX2_INLINE void GX2UTCopySurfaceOp(const GX2Surface *srcSurface,
158 u32 srcMip, u32 srcSlice,
159 GX2Surface *dstSurface,
160 u32 dstMip, u32 dstSlice,
161 void* dstAuxPtr, u32 dstAuxSize)
162 {
163 GX2UTRect srcRect = {0};
164 GX2UTRect dstRect = {0};
165
166 GX2UTDebugTagIndent(__func__);
167
168 // This may be stretch copy so rectangles need to match
169 // source and destination surfaces.
170 srcRect.right = GX2Max(1, srcSurface->width >> srcMip);
171 srcRect.bottom = GX2Max(1, srcSurface->height >> srcMip);
172 dstRect.right = GX2Max(1, dstSurface->width >> dstMip);
173 dstRect.bottom = GX2Max(1, dstSurface->height >> dstMip);
174
175 GX2UTCopySurfaceRectOp(srcSurface, srcMip, srcSlice, &srcRect,
176 dstSurface, dstMip, dstSlice, &dstRect,
177 dstAuxPtr, dstAuxSize);
178 GX2UTDebugTagUndent();
179 }
180
181 /// \brief Copy the specified source surface to the dest surface.
182 ///
183 /// \param srcSurface Pointer to source surface structure
184 /// \param srcMip Mip level of surface to read (0 typically)
185 /// \param srcSlice Slice to read for array & 3D (0 typically)
186 /// \param srcRect Pointer to the source region to copy.
187 /// \param dstSurface Pointer to destination surface structure
188 /// \param dstMip Mip level of dest surface to write (0 typically)
189 /// \param dstSlice Slice to write for array & 3D (0 typically)
190 /// \param dstRect Pointer to the destination region to copy.
191 /// \param dstAuxPtr Destination MSAA auxPtr for AA buffer or NULL for non-AA buffers.
192 /// \param dstAuxSize Destination MSAA auxSize for AA buffers or NULL for non-AA buffers.
193 ///
194 /// This function assumes \ref GX2UTSetCopyState
195 /// (or comparable state setup function) has been called to setup required
196 /// render state.
197 ///
198 /// Copies a region from one surface to a region of another surface.
199 /// Setting the rectangular regions to a top-left of (0,0) and a bottom-right
200 /// of (width, height) will blt the entire surface without any flipping (the
201 /// right and bottom are exclusive).
202 ///
203 /// The srcRect/dstRect dimensions should be relative to the mipmap level
204 /// dimensions, not the base level dimensions.
205 ///
206 /// \note Compressed textures must be copied on a 4x4 pixel alignment.
207 /// Coordinates are in terms of pixels, not blocks.
208 /// For compressed textures the source and destination formats must
209 /// match.
210 ///
211 /// \note It is not necessary to call \ref GX2Invalidate on the
212 /// source/destination buffers. This is done internally.
213 ///
214 /// \note If the source is an AA buffer, you must call
215 /// \ref GX2ExpandAAColorBuffer or \ref GX2UTExpandAAColorBuffer first.
216 ///
217 /// \note This copy, as it is, will be impacted by the toss stage
218 /// (\ref GX2TossStageSect) setup at GX2Init time. To avoid this, call
219 /// this function from a separate state context with profiling disabled.
220 /// See \ref GX2SetupContextStateEx for more information.
221 ///
222 /// \warning The behavior of this routine has changed from SDK 2.12.00!
223 /// It now disables state shadowing and requires
224 /// \ref GX2SetContextState afterward. To avoid this, please use
225 /// \ref GX2UTCopySurfaceRectOp instead.
226 ///
227 /// \warning Stretching is not supported for depth/stencil/compressed formats.
228 ///
229 /// \warning Better performing alternatives exist. Please see
230 /// \ref GX2UTAdvancedGX2ReplacementAPISect.
231 ///
232 /// \clobberstate
233 /// \disablesstateshadow
234 ///
235 /// \donotcall \gx2_typical \enddonotcall
236 ///
237 /// \writesgpu
238 /// \alwayswritesgpu
239 ///
GX2UTCopySurfaceRect(const GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2UTRect * srcRect,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice,GX2UTRect * dstRect,void * dstAuxPtr,u32 dstAuxSize)240 GX2_INLINE void GX2UTCopySurfaceRect(const GX2Surface *srcSurface,
241 u32 srcMip, u32 srcSlice,
242 GX2UTRect *srcRect,
243 GX2Surface *dstSurface,
244 u32 dstMip, u32 dstSlice,
245 GX2UTRect *dstRect,
246 void* dstAuxPtr, u32 dstAuxSize)
247 {
248 GX2UTDebugTagIndent(__func__);
249
250 // Disable state shadowing. If your app is using state shadowing,
251 // you will need to restore the context after calling this function.
252 GX2SetContextState(NULL);
253
254 // Setup all of the constant render state needed for the copy.
255 GX2UTSetCopyState(GX2_ENABLE);
256
257 // Setup parameter specific render state and copy.
258 GX2UTCopySurfaceRectOp(srcSurface, srcMip, srcSlice, srcRect,
259 dstSurface, dstMip, dstSlice, dstRect,
260 dstAuxPtr, dstAuxSize);
261
262 // Disable special hardware state and set state back to GX2 default
263 GX2UTSetCopyState(GX2_DISABLE);
264
265
266 GX2UTDebugTagUndent();
267 }
268
269 /// \brief Copy the specified source surface to the dest surface.
270 ///
271 /// \deprecated This API has been deprecated and may not be available in future
272 /// releases. Please use \ref GX2UTCopySurfaceRect instead.
273 ///
274 /// \param srcSurface Pointer to source surface structure
275 /// \param srcMip Mip level of surface to read (0 typically)
276 /// \param srcSlice Slice to read for array & 3D (0 typically)
277 /// \param srcRect Pointer to the source region to copy.
278 /// \param dstSurface Pointer to destination surface structure
279 /// \param dstMip Mip level of dest surface to write (0 typically)
280 /// \param dstSlice Slice to write for array & 3D (0 typically)
281 /// \param dstRect Pointer to the destination region to copy.
282 /// \param dstAuxPtr Destination MSAA auxPtr for AA buffer or NULL for non-AA buffers.
283 /// \param dstAuxSize Destination MSAA auxSize for AA buffers or NULL for non-AA buffers.
284 ///
285 /// This routine copys one surface to another in the same way as
286 /// \ref GX2CopySurfaceEx.
287 ///
288 /// The source and destination rectangles are relative to the current miplevel.
289 ///
290 /// \note Compressed textures must be copied on a 4x4 pixel alignment.
291 /// Coordinates are in terms of pixels, not blocks.
292 /// For compressed textures the source and destination formats must
293 /// match.
294 ///
295 /// \note It is not necessary to call \ref GX2Invalidate on the
296 /// source/destination buffers. This is done internally.
297 ///
298 /// \warning Better performing alternatives exist. Please see
299 /// \ref GX2UTAdvancedGX2ReplacementAPISect.
300 ///
301 /// \clobberstate
302 /// \disablesstateshadow
303 ///
304 /// \donotcall \gx2_typical \enddonotcall
305 ///
306 /// \writesgpu
307 /// \alwayswritesgpu
308 ///
GX2UTSetAndCopySurfaceRect(const GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2UTRect * srcRect,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice,GX2UTRect * dstRect,void * dstAuxPtr,u32 dstAuxSize)309 GX2_INLINE void GX2UTSetAndCopySurfaceRect(const GX2Surface *srcSurface,
310 u32 srcMip, u32 srcSlice,
311 GX2UTRect *srcRect,
312 GX2Surface *dstSurface,
313 u32 dstMip, u32 dstSlice,
314 GX2UTRect *dstRect,
315 void* dstAuxPtr, u32 dstAuxSize)
316 {
317 GX2UTDebugTagIndent(__func__);
318
319 // Setup parameter specific render state and copy.
320 GX2UTCopySurfaceRect(srcSurface, srcMip, srcSlice, srcRect,
321 dstSurface, dstMip, dstSlice, dstRect,
322 dstAuxPtr, dstAuxSize);
323
324 GX2UTDebugTagUndent();
325 }
326
327 /// \brief Copy the specified source surface to the dest surface.
328 ///
329 /// \param srcSurface Pointer to source surface structure
330 /// \param srcMip Mip level of surface to read (0 typically)
331 /// \param srcSlice Slice to read for array & 3D (0 typically)
332 /// \param dstSurface Pointer to destination surface structure
333 /// \param dstMip Mip level of dest surface to write (0 typically)
334 /// \param dstSlice Slice to write for array & 3D (0 typically)
335 /// \param numRects Number of rectangles to copy
336 /// \param pSrcRects Array of source rectangles to copy
337 /// \param pDstPoints Array of destination points to copy the rectangles to.
338 ///
339 /// This function mimics the behavior of GX2 and is intended to be an optimized
340 /// replacement for \ref GX2CopySurfaceEx.
341 ///
342 /// The rectangles in pSrcRects should be relative to the mip-level dimensions.
343 ///
344 /// \note Compressed textures must be copied on a 4x4 pixel alignment.
345 /// Coordinates are in terms of pixels, not blocks.
346 /// For compressed textures the source and destination formats must
347 /// match.
348 ///
349 /// \note It is not necessary to call \ref GX2Invalidate on the
350 /// source/destination buffers. This is done internally.
351 ///
352 /// \warning Better performing alternatives exist. Please see
353 /// \ref GX2UTAdvancedGX2ReplacementAPISect.
354 ///
355 /// \clobberstate
356 /// \disablesstateshadow
357 ///
358 /// \donotcall \gx2_typical \enddonotcall
359 ///
360 /// \writesgpu
361 /// \alwayswritesgpu
362 ///
GX2UTCopySurfaceEx(const GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice,u32 numRects,GX2RectInt * pSrcRects,GX2PointInt * pDstPoints)363 GX2_INLINE void GX2UTCopySurfaceEx(const GX2Surface *srcSurface,
364 u32 srcMip, u32 srcSlice,
365 GX2Surface *dstSurface,
366 u32 dstMip, u32 dstSlice,
367 u32 numRects,
368 GX2RectInt* pSrcRects,
369 GX2PointInt* pDstPoints)
370 {
371 GX2UTRect srcRect;
372 GX2UTRect dstRect;
373
374 GX2UTDebugTagIndent(__func__);
375
376 // Disable state shadowing. If your app is using state shadowing,
377 // you will need to restore the context after calling this function.
378 GX2SetContextState(NULL);
379
380 // Setup all of the constant render state needed for the copy.
381 GX2UTSetCopyState(GX2_ENABLE);
382
383 for (int i = 0; i < numRects; i++)
384 {
385 // Setup the source rectangle
386 srcRect.left = pSrcRects[i].left;
387 srcRect.right = pSrcRects[i].right;
388 srcRect.top = pSrcRects[i].top;
389 srcRect.bottom = pSrcRects[i].bottom;
390
391 // Setup the destination rectangle
392 dstRect.left = pDstPoints[i].x;
393 dstRect.right = pDstPoints[i].x + pSrcRects[i].right - pSrcRects[i].left;
394 dstRect.top = pDstPoints[i].y + pSrcRects[i].top;
395 dstRect.bottom = pDstPoints[i].y + pSrcRects[i].bottom - pSrcRects[i].top;
396 //Setup parameter specific render state and copy.
397 GX2UTCopySurfaceRectOp(srcSurface, srcMip, srcSlice, &srcRect,
398 dstSurface, dstMip, dstSlice, &dstRect,
399 NULL, 0);
400 }
401
402 // Disable special hardware state and set state back to GX2 default
403 GX2UTSetCopyState(GX2_DISABLE);
404
405 GX2UTDebugTagUndent();
406 }
407
408 /// \brief Copy the specified source surface to the dest surface.
409 ///
410 /// \param srcSurface Pointer to source surface structure
411 /// \param srcMip Mip level of surface to read (0 typically)
412 /// \param srcSlice Slice to read for array & 3D (0 typically)
413 /// \param dstSurface Pointer to destination surface structure
414 /// \param dstMip Mip level of dest surface to write (0 typically)
415 /// \param dstSlice Slice to write for array & 3D (0 typically)
416 ///
417 /// This function mimics the behavior of GX2 and is intended to be an optimized
418 /// replacement for \ref GX2CopySurface.
419 ///
420 /// This function assumes \ref GX2UTSetCopyState()
421 /// (or comparable state setup function) has been called to setup required
422 /// render state.
423 ///
424 /// To specify the source and destination regions or to copy AA color
425 /// buffers, use \ref GX2UTCopySurfaceRectOp instead.
426 ///
427 /// \note It is not necessary to call \ref GX2Invalidate on the
428 /// source/destination buffers. This is done internally.
429 ///
430 /// \note This copy, as it is, will be impacted by the toss stage
431 /// (\ref GX2TossStageSect) setup at GX2Init time. To avoid this, call
432 /// this function from a separate state context with profiling disabled.
433 /// See \ref GX2SetupContextStateEx for more information.
434 ///
435 ///
436 /// \warning The behavior of this routine has changed from SDK 2.12.00!
437 /// It now disables state shadowing and requires
438 /// \ref GX2SetContextState afterward. To avoid this, please use
439 /// \ref GX2UTCopySurfaceRectOp instead.
440 ///
441 /// \warning Stretching is not supported for depth/stencil/compressed formats.
442 ///
443 /// \warning Better performing alternatives exist. Please see
444 /// \ref GX2UTAdvancedGX2ReplacementAPISect.
445 ///
446 /// \clobberstate
447 /// \disablesstateshadow
448 ///
449 /// \donotcall \gx2_typical \enddonotcall
450 ///
451 /// \writesgpu
452 /// \alwayswritesgpu
453 ///
GX2UTCopySurface(const GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice)454 GX2_INLINE void GX2UTCopySurface(const GX2Surface *srcSurface,
455 u32 srcMip, u32 srcSlice,
456 GX2Surface *dstSurface,
457 u32 dstMip, u32 dstSlice)
458 {
459 GX2UTRect srcRect;
460 GX2UTRect dstRect;
461
462 //We need to adjust rectangles based on the mip level
463 srcRect.left = 0;
464 srcRect.top = 0;
465 srcRect.right = GX2Max(1, srcSurface->width >> srcMip);
466 srcRect.bottom = GX2Max(1, srcSurface->height >> srcMip);
467
468 dstRect.left = 0;
469 dstRect.top = 0;
470 dstRect.right = GX2Max(1, dstSurface->width >> dstMip);
471 dstRect.bottom = GX2Max(1, dstSurface->height >> dstMip);
472
473 GX2UTDebugTagIndent(__func__);
474
475 // Disable state shadowing. If your app is using state shadowing,
476 // you will need to restore the context after calling this function.
477 GX2SetContextState(NULL);
478
479 // Setup all of the constant render state needed for the copy.
480 GX2UTSetCopyState(GX2_ENABLE);
481
482 GX2UTCopySurfaceRectOp(srcSurface, srcMip, srcSlice, &srcRect,
483 dstSurface, dstMip, dstSlice, &dstRect,
484 NULL, 0);
485
486 // Disable special hardware state and set state back to GX2 default
487 GX2UTSetCopyState(GX2_DISABLE);
488
489 GX2UTDebugTagUndent();
490 }
491
492 /// \brief Copy the specified source surface to the dest surface.
493 ///
494 /// \deprecated This API has been deprecated and may not be available in future
495 /// releases. Please use \ref GX2UTCopySurface instead.
496 ///
497 /// \param srcSurface Pointer to source surface structure
498 /// \param srcMip Mip level of surface to read (0 typically)
499 /// \param srcSlice Slice to read for array & 3D (0 typically)
500 /// \param dstSurface Pointer to destination surface structure
501 /// \param dstMip Mip level of dest surface to write (0 typically)
502 /// \param dstSlice Slice to write for array & 3D (0 typically)
503 ///
504 /// This function mimics the behavior of GX2 and is intended to be an optimized
505 /// replacement for \ref GX2CopySurface.
506 ///
507 /// \note It is not necessary to call \ref GX2Invalidate on the
508 /// source/destination buffers. This is done internally.
509 ///
510 /// \warning Better performing alternatives exist. Please see
511 /// \ref GX2UTAdvancedGX2ReplacementAPISect.
512 ///
513 /// \clobberstate
514 /// \disablesstateshadow
515 ///
516 /// \donotcall \gx2_typical \enddonotcall
517 ///
518 /// \writesgpu
519 /// \alwayswritesgpu
520 ///
GX2UTSetAndCopySurface(const GX2Surface * srcSurface,u32 srcMip,u32 srcSlice,GX2Surface * dstSurface,u32 dstMip,u32 dstSlice)521 GX2_INLINE void GX2UTSetAndCopySurface(
522 const GX2Surface *srcSurface, u32 srcMip, u32 srcSlice,
523 GX2Surface *dstSurface, u32 dstMip, u32 dstSlice)
524 {
525 GX2UTDebugTagIndent(__func__);
526
527 //Setup parameter specific render state and copy.
528 GX2UTCopySurface(srcSurface, srcMip, srcSlice,
529 dstSurface, dstMip, dstSlice);
530
531 GX2UTDebugTagUndent();
532 }
533
534 /// @}
535
536 #ifdef __cplusplus
537 }
538 #endif // __cplusplus
539
540 #endif // _GX2UTCOPY_H_
541