amdgpu/addrlib: Rewrite tile mode optmization code
[mesa.git] / src / amd / addrlib / r800 / egbaddrlib.cpp
1 /*
2 * Copyright © 2014 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 */
26
27 /**
28 ***************************************************************************************************
29 * @file egbaddrlib.cpp
30 * @brief Contains the EgBasedAddrLib class implementation
31 ***************************************************************************************************
32 */
33
34 #include "egbaddrlib.h"
35
36 /**
37 ***************************************************************************************************
38 * EgBasedAddrLib::EgBasedAddrLib
39 *
40 * @brief
41 * Constructor
42 *
43 * @note
44 *
45 ***************************************************************************************************
46 */
47 EgBasedAddrLib::EgBasedAddrLib(const AddrClient* pClient) :
48 AddrLib(pClient),
49 m_ranks(0),
50 m_logicalBanks(0),
51 m_bankInterleave(1)
52 {
53 }
54
55 /**
56 ***************************************************************************************************
57 * EgBasedAddrLib::~EgBasedAddrLib
58 *
59 * @brief
60 * Destructor
61 ***************************************************************************************************
62 */
63 EgBasedAddrLib::~EgBasedAddrLib()
64 {
65 }
66
67 /**
68 ***************************************************************************************************
69 * EgBasedAddrLib::DispatchComputeSurfaceInfo
70 *
71 * @brief
72 * Compute surface sizes include padded pitch,height,slices,total size in bytes,
73 * meanwhile output suitable tile mode and base alignment might be changed in this
74 * call as well. Results are returned through output parameters.
75 *
76 * @return
77 * TRUE if no error occurs
78 ***************************************************************************************************
79 */
80 BOOL_32 EgBasedAddrLib::DispatchComputeSurfaceInfo(
81 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
82 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
83 ) const
84 {
85 AddrTileMode tileMode = pIn->tileMode;
86 UINT_32 bpp = pIn->bpp;
87 UINT_32 numSamples = pIn->numSamples;
88 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
89 UINT_32 pitch = pIn->width;
90 UINT_32 height = pIn->height;
91 UINT_32 numSlices = pIn->numSlices;
92 UINT_32 mipLevel = pIn->mipLevel;
93 ADDR_SURFACE_FLAGS flags = pIn->flags;
94
95 ADDR_TILEINFO tileInfoDef = {0};
96 ADDR_TILEINFO* pTileInfo = &tileInfoDef;
97
98 UINT_32 padDims = 0;
99 BOOL_32 valid;
100
101 tileMode = DegradeLargeThickTile(tileMode, bpp);
102
103 // Only override numSamples for NI above
104 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
105 {
106 if (numFrags != numSamples) // This means EQAA
107 {
108 // The real surface size needed is determined by number of fragments
109 numSamples = numFrags;
110 }
111
112 // Save altered numSamples in pOut
113 pOut->numSamples = numSamples;
114 }
115
116 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
117 ADDR_ASSERT(pOut->pTileInfo);
118
119 if (pOut->pTileInfo != NULL)
120 {
121 pTileInfo = pOut->pTileInfo;
122 }
123
124 // Set default values
125 if (pIn->pTileInfo != NULL)
126 {
127 if (pTileInfo != pIn->pTileInfo)
128 {
129 *pTileInfo = *pIn->pTileInfo;
130 }
131 }
132 else
133 {
134 memset(pTileInfo, 0, sizeof(ADDR_TILEINFO));
135 }
136
137 // For macro tile mode, we should calculate default tiling parameters
138 HwlSetupTileInfo(tileMode,
139 flags,
140 bpp,
141 pitch,
142 height,
143 numSamples,
144 pIn->pTileInfo,
145 pTileInfo,
146 pIn->tileType,
147 pOut);
148
149 if (flags.cube)
150 {
151 if (mipLevel == 0)
152 {
153 padDims = 2;
154 }
155
156 if (numSlices == 1)
157 {
158 // This is calculating one face, remove cube flag
159 flags.cube = 0;
160 }
161 }
162
163 switch (tileMode)
164 {
165 case ADDR_TM_LINEAR_GENERAL://fall through
166 case ADDR_TM_LINEAR_ALIGNED:
167 valid = ComputeSurfaceInfoLinear(pIn, pOut, padDims);
168 break;
169
170 case ADDR_TM_1D_TILED_THIN1://fall through
171 case ADDR_TM_1D_TILED_THICK:
172 valid = ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, tileMode);
173 break;
174
175 case ADDR_TM_2D_TILED_THIN1: //fall through
176 case ADDR_TM_2D_TILED_THICK: //fall through
177 case ADDR_TM_3D_TILED_THIN1: //fall through
178 case ADDR_TM_3D_TILED_THICK: //fall through
179 case ADDR_TM_2D_TILED_XTHICK: //fall through
180 case ADDR_TM_3D_TILED_XTHICK: //fall through
181 case ADDR_TM_PRT_TILED_THIN1: //fall through
182 case ADDR_TM_PRT_2D_TILED_THIN1://fall through
183 case ADDR_TM_PRT_3D_TILED_THIN1://fall through
184 case ADDR_TM_PRT_TILED_THICK: //fall through
185 case ADDR_TM_PRT_2D_TILED_THICK://fall through
186 case ADDR_TM_PRT_3D_TILED_THICK:
187 valid = ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, tileMode);
188 break;
189
190 default:
191 valid = FALSE;
192 ADDR_ASSERT_ALWAYS();
193 break;
194 }
195
196 return valid;
197 }
198
199 /**
200 ***************************************************************************************************
201 * EgBasedAddrLib::ComputeSurfaceInfoLinear
202 *
203 * @brief
204 * Compute linear surface sizes include padded pitch, height, slices, total size in
205 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
206 * will not be changed here. Results are returned through output parameters.
207 *
208 * @return
209 * TRUE if no error occurs
210 ***************************************************************************************************
211 */
212 BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoLinear(
213 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
214 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
215 UINT_32 padDims ///< [in] Dimensions to padd
216 ) const
217 {
218 UINT_32 expPitch = pIn->width;
219 UINT_32 expHeight = pIn->height;
220 UINT_32 expNumSlices = pIn->numSlices;
221
222 // No linear MSAA on real H/W, keep this for TGL
223 UINT_32 numSamples = pOut->numSamples;
224
225 const UINT_32 microTileThickness = 1;
226
227 //
228 // Compute the surface alignments.
229 //
230 ComputeSurfaceAlignmentsLinear(pIn->tileMode,
231 pIn->bpp,
232 pIn->flags,
233 &pOut->baseAlign,
234 &pOut->pitchAlign,
235 &pOut->heightAlign);
236
237 if ((pIn->tileMode == ADDR_TM_LINEAR_GENERAL) && pIn->flags.color && (pIn->height > 1))
238 {
239 #if !ALT_TEST
240 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
241 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
242 // It is OK if it is accessed per line.
243 ADDR_ASSERT((pIn->width % 8) == 0);
244 #endif
245 }
246
247 pOut->depthAlign = microTileThickness;
248
249 expPitch = HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
250
251 //
252 // Pad pitch and height to the required granularities.
253 //
254 PadDimensions(pIn->tileMode,
255 pIn->bpp,
256 pIn->flags,
257 numSamples,
258 pOut->pTileInfo,
259 padDims,
260 pIn->mipLevel,
261 &expPitch, pOut->pitchAlign,
262 &expHeight, pOut->heightAlign,
263 &expNumSlices, microTileThickness);
264
265 expPitch = HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
266
267 //
268 // Adjust per HWL
269 //
270
271 UINT_64 logicalSliceSize;
272
273 logicalSliceSize = HwlGetSizeAdjustmentLinear(pIn->tileMode,
274 pIn->bpp,
275 numSamples,
276 pOut->baseAlign,
277 pOut->pitchAlign,
278 &expPitch,
279 &expHeight,
280 &pOut->heightAlign);
281
282
283 pOut->pitch = expPitch;
284 pOut->height = expHeight;
285 pOut->depth = expNumSlices;
286
287 pOut->surfSize = logicalSliceSize * expNumSlices;
288
289 pOut->tileMode = pIn->tileMode;
290
291 return TRUE;
292 }
293
294 /**
295 ***************************************************************************************************
296 * EgBasedAddrLib::ComputeSurfaceInfoMicroTiled
297 *
298 * @brief
299 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
300 * size in bytes, meanwhile alignments as well. Results are returned through output
301 * parameters.
302 *
303 * @return
304 * TRUE if no error occurs
305 ***************************************************************************************************
306 */
307 BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMicroTiled(
308 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
309 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
310 UINT_32 padDims, ///< [in] Dimensions to padd
311 AddrTileMode expTileMode ///< [in] Expected tile mode
312 ) const
313 {
314 BOOL_32 valid = TRUE;
315
316 UINT_32 microTileThickness;
317 UINT_32 expPitch = pIn->width;
318 UINT_32 expHeight = pIn->height;
319 UINT_32 expNumSlices = pIn->numSlices;
320
321 // No 1D MSAA on real H/W, keep this for TGL
322 UINT_32 numSamples = pOut->numSamples;
323
324 //
325 // Compute the micro tile thickness.
326 //
327 microTileThickness = ComputeSurfaceThickness(expTileMode);
328
329 //
330 // Extra override for mip levels
331 //
332 if (pIn->mipLevel > 0)
333 {
334 //
335 // Reduce tiling mode from thick to thin if the number of slices is less than the
336 // micro tile thickness.
337 //
338 if ((expTileMode == ADDR_TM_1D_TILED_THICK) &&
339 (expNumSlices < ThickTileThickness))
340 {
341 expTileMode = HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK, expNumSlices, NULL);
342 if (expTileMode != ADDR_TM_1D_TILED_THICK)
343 {
344 microTileThickness = 1;
345 }
346 }
347 }
348
349 //
350 // Compute the surface restrictions.
351 //
352 ComputeSurfaceAlignmentsMicroTiled(expTileMode,
353 pIn->bpp,
354 pIn->flags,
355 pIn->mipLevel,
356 numSamples,
357 &pOut->baseAlign,
358 &pOut->pitchAlign,
359 &pOut->heightAlign);
360
361 pOut->depthAlign = microTileThickness;
362
363 //
364 // Pad pitch and height to the required granularities.
365 // Compute surface size.
366 // Return parameters.
367 //
368 PadDimensions(expTileMode,
369 pIn->bpp,
370 pIn->flags,
371 numSamples,
372 pOut->pTileInfo,
373 padDims,
374 pIn->mipLevel,
375 &expPitch, pOut->pitchAlign,
376 &expHeight, pOut->heightAlign,
377 &expNumSlices, microTileThickness);
378
379 //
380 // Get HWL specific pitch adjustment
381 //
382 UINT_64 logicalSliceSize = HwlGetSizeAdjustmentMicroTiled(microTileThickness,
383 pIn->bpp,
384 pIn->flags,
385 numSamples,
386 pOut->baseAlign,
387 pOut->pitchAlign,
388 &expPitch,
389 &expHeight);
390
391
392 pOut->pitch = expPitch;
393 pOut->height = expHeight;
394 pOut->depth = expNumSlices;
395
396 pOut->surfSize = logicalSliceSize * expNumSlices;
397
398 pOut->tileMode = expTileMode;
399
400 return valid;
401 }
402
403
404 /**
405 ***************************************************************************************************
406 * EgBasedAddrLib::ComputeSurfaceInfoMacroTiled
407 *
408 * @brief
409 * Compute 2D/macro tiled surface sizes include padded pitch, height, slices, total
410 * size in bytes, meanwhile output suitable tile mode and alignments might be changed
411 * in this call as well. Results are returned through output parameters.
412 *
413 * @return
414 * TRUE if no error occurs
415 ***************************************************************************************************
416 */
417 BOOL_32 EgBasedAddrLib::ComputeSurfaceInfoMacroTiled(
418 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
419 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
420 UINT_32 padDims, ///< [in] Dimensions to padd
421 AddrTileMode expTileMode ///< [in] Expected tile mode
422 ) const
423 {
424 BOOL_32 valid = TRUE;
425
426 AddrTileMode origTileMode = expTileMode;
427 UINT_32 microTileThickness;
428
429 UINT_32 paddedPitch;
430 UINT_32 paddedHeight;
431 UINT_64 bytesPerSlice;
432
433 UINT_32 expPitch = pIn->width;
434 UINT_32 expHeight = pIn->height;
435 UINT_32 expNumSlices = pIn->numSlices;
436
437 UINT_32 numSamples = pOut->numSamples;
438
439 //
440 // Compute the surface restrictions as base
441 // SanityCheckMacroTiled is called in ComputeSurfaceAlignmentsMacroTiled
442 //
443 valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
444 pIn->bpp,
445 pIn->flags,
446 pIn->mipLevel,
447 numSamples,
448 pOut->pTileInfo,
449 &pOut->baseAlign,
450 &pOut->pitchAlign,
451 &pOut->heightAlign);
452
453 if (valid)
454 {
455 //
456 // Compute the micro tile thickness.
457 //
458 microTileThickness = ComputeSurfaceThickness(expTileMode);
459
460 //
461 // Find the correct tiling mode for mip levels
462 //
463 if (pIn->mipLevel > 0)
464 {
465 //
466 // Try valid tile mode
467 //
468 expTileMode = ComputeSurfaceMipLevelTileMode(expTileMode,
469 pIn->bpp,
470 expPitch,
471 expHeight,
472 expNumSlices,
473 numSamples,
474 pOut->pitchAlign,
475 pOut->heightAlign,
476 pOut->pTileInfo);
477
478 if (!IsMacroTiled(expTileMode)) // Downgraded to micro-tiled
479 {
480 return ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, expTileMode);
481 }
482 else
483 {
484 if (microTileThickness != ComputeSurfaceThickness(expTileMode))
485 {
486 //
487 // Re-compute if thickness changed since bank-height may be changed!
488 //
489 return ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, expTileMode);
490 }
491 }
492 }
493
494 paddedPitch = expPitch;
495 paddedHeight = expHeight;
496
497 //
498 // Re-cal alignment
499 //
500 if (expTileMode != origTileMode) // Tile mode is changed but still macro-tiled
501 {
502 valid = ComputeSurfaceAlignmentsMacroTiled(expTileMode,
503 pIn->bpp,
504 pIn->flags,
505 pIn->mipLevel,
506 numSamples,
507 pOut->pTileInfo,
508 &pOut->baseAlign,
509 &pOut->pitchAlign,
510 &pOut->heightAlign);
511 }
512
513 //
514 // Do padding
515 //
516 PadDimensions(expTileMode,
517 pIn->bpp,
518 pIn->flags,
519 numSamples,
520 pOut->pTileInfo,
521 padDims,
522 pIn->mipLevel,
523 &paddedPitch, pOut->pitchAlign,
524 &paddedHeight, pOut->heightAlign,
525 &expNumSlices, microTileThickness);
526
527 if (pIn->flags.qbStereo &&
528 (pOut->pStereoInfo != NULL) &&
529 HwlStereoCheckRightOffsetPadding())
530 {
531 // Eye height's bank bits are different from y == 0?
532 // Since 3D rendering treats right eye buffer starting from y == "eye height" while
533 // display engine treats it to be 0, so the bank bits may be different, we pad
534 // more in height to make sure y == "eye height" has the same bank bits as y == 0.
535 UINT_32 checkMask = pOut->pTileInfo->banks - 1;
536 UINT_32 bankBits = 0;
537 do
538 {
539 bankBits = (paddedHeight / 8 / pOut->pTileInfo->bankHeight) & checkMask;
540
541 if (bankBits)
542 {
543 paddedHeight += pOut->heightAlign;
544 }
545 } while (bankBits);
546 }
547
548 //
549 // Compute the size of a slice.
550 //
551 bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(paddedPitch) *
552 paddedHeight * NextPow2(pIn->bpp) * numSamples);
553
554 pOut->pitch = paddedPitch;
555 // Put this check right here to workaround special mipmap cases which the original height
556 // is needed.
557 // The original height is pre-stored in pOut->height in PostComputeMipLevel and
558 // pOut->pitch is needed in HwlCheckLastMacroTiledLvl, too.
559 if (m_configFlags.checkLast2DLevel && numSamples == 1) // Don't check MSAA
560 {
561 // Set a TRUE in pOut if next Level is the first 1D sub level
562 HwlCheckLastMacroTiledLvl(pIn, pOut);
563 }
564 pOut->height = paddedHeight;
565
566 pOut->depth = expNumSlices;
567
568 pOut->surfSize = bytesPerSlice * expNumSlices;
569
570 pOut->tileMode = expTileMode;
571
572 pOut->depthAlign = microTileThickness;
573
574 } // if (valid)
575
576 return valid;
577 }
578
579 /**
580 ***************************************************************************************************
581 * EgBasedAddrLib::ComputeSurfaceAlignmentsLinear
582 *
583 * @brief
584 * Compute linear surface alignment, calculation results are returned through
585 * output parameters.
586 *
587 * @return
588 * TRUE if no error occurs
589 ***************************************************************************************************
590 */
591 BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsLinear(
592 AddrTileMode tileMode, ///< [in] tile mode
593 UINT_32 bpp, ///< [in] bits per pixel
594 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
595 UINT_32* pBaseAlign, ///< [out] base address alignment in bytes
596 UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels
597 UINT_32* pHeightAlign ///< [out] height alignment in pixels
598 ) const
599 {
600 BOOL_32 valid = TRUE;
601
602 switch (tileMode)
603 {
604 case ADDR_TM_LINEAR_GENERAL:
605 //
606 // The required base alignment and pitch and height granularities is to 1 element.
607 //
608 *pBaseAlign = (bpp > 8) ? bpp / 8 : 1;
609 *pPitchAlign = 1;
610 *pHeightAlign = 1;
611 break;
612 case ADDR_TM_LINEAR_ALIGNED:
613 //
614 // The required alignment for base is the pipe interleave size.
615 // The required granularity for pitch is hwl dependent.
616 // The required granularity for height is one row.
617 //
618 *pBaseAlign = m_pipeInterleaveBytes;
619 *pPitchAlign = HwlGetPitchAlignmentLinear(bpp, flags);
620 *pHeightAlign = 1;
621 break;
622 default:
623 *pBaseAlign = 1;
624 *pPitchAlign = 1;
625 *pHeightAlign = 1;
626 ADDR_UNHANDLED_CASE();
627 break;
628 }
629
630 AdjustPitchAlignment(flags, pPitchAlign);
631
632 return valid;
633 }
634
635 /**
636 ***************************************************************************************************
637 * EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled
638 *
639 * @brief
640 * Compute 1D tiled surface alignment, calculation results are returned through
641 * output parameters.
642 *
643 * @return
644 * TRUE if no error occurs
645 ***************************************************************************************************
646 */
647 BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMicroTiled(
648 AddrTileMode tileMode, ///< [in] tile mode
649 UINT_32 bpp, ///< [in] bits per pixel
650 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
651 UINT_32 mipLevel, ///< [in] mip level
652 UINT_32 numSamples, ///< [in] number of samples
653 UINT_32* pBaseAlign, ///< [out] base address alignment in bytes
654 UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels
655 UINT_32* pHeightAlign ///< [out] height alignment in pixels
656 ) const
657 {
658 BOOL_32 valid = TRUE;
659
660 //
661 // The required alignment for base is the pipe interleave size.
662 //
663 *pBaseAlign = m_pipeInterleaveBytes;
664
665 *pPitchAlign = HwlGetPitchAlignmentMicroTiled(tileMode, bpp, flags, numSamples);
666
667 *pHeightAlign = MicroTileHeight;
668
669 AdjustPitchAlignment(flags, pPitchAlign);
670
671 // ECR#393489
672 // Workaround 2 for 1D tiling - There is HW bug for Carrizo
673 // where it requires the following alignments for 1D tiling.
674 if (flags.czDispCompatible && (mipLevel == 0))
675 {
676 *pBaseAlign = PowTwoAlign(*pBaseAlign, 4096); //Base address MOD 4096 = 0
677 *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 / (BITS_TO_BYTES(bpp))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
678 }
679 // end Carrizo workaround for 1D tilling
680
681 return valid;
682 }
683
684
685 /**
686 ***************************************************************************************************
687 * EgBasedAddrLib::HwlReduceBankWidthHeight
688 *
689 * @brief
690 * Additional checks, reduce bankHeight/bankWidth if needed and possible
691 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
692 *
693 * @return
694 * TRUE if no error occurs
695 ***************************************************************************************************
696 */
697 BOOL_32 EgBasedAddrLib::HwlReduceBankWidthHeight(
698 UINT_32 tileSize, ///< [in] tile size
699 UINT_32 bpp, ///< [in] bits per pixel
700 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
701 UINT_32 numSamples, ///< [in] number of samples
702 UINT_32 bankHeightAlign, ///< [in] bank height alignment
703 UINT_32 pipes, ///< [in] pipes
704 ADDR_TILEINFO* pTileInfo ///< [in/out] bank structure.
705 ) const
706 {
707 UINT_32 macroAspectAlign;
708 BOOL_32 valid = TRUE;
709
710 if (tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize)
711 {
712 BOOL_32 stillGreater = TRUE;
713
714 // Try reducing bankWidth first
715 if (stillGreater && pTileInfo->bankWidth > 1)
716 {
717 while (stillGreater && pTileInfo->bankWidth > 0)
718 {
719 pTileInfo->bankWidth >>= 1;
720
721 if (pTileInfo->bankWidth == 0)
722 {
723 pTileInfo->bankWidth = 1;
724 break;
725 }
726
727 stillGreater =
728 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
729 }
730
731 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
732 bankHeightAlign = Max(1u,
733 m_pipeInterleaveBytes * m_bankInterleave /
734 (tileSize * pTileInfo->bankWidth)
735 );
736
737 // We cannot increase bankHeight so just assert this case.
738 ADDR_ASSERT((pTileInfo->bankHeight % bankHeightAlign) == 0);
739
740 if (numSamples == 1)
741 {
742 macroAspectAlign = Max(1u,
743 m_pipeInterleaveBytes * m_bankInterleave /
744 (tileSize * pipes * pTileInfo->bankWidth)
745 );
746 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio,
747 macroAspectAlign);
748 }
749 }
750
751 // Early quit bank_height degradation for "64" bit z buffer
752 if (flags.depth && bpp >= 64)
753 {
754 stillGreater = FALSE;
755 }
756
757 // Then try reducing bankHeight
758 if (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
759 {
760 while (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
761 {
762 pTileInfo->bankHeight >>= 1;
763
764 if (pTileInfo->bankHeight < bankHeightAlign)
765 {
766 pTileInfo->bankHeight = bankHeightAlign;
767 break;
768 }
769
770 stillGreater =
771 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
772 }
773 }
774
775 valid = !stillGreater;
776
777 // Generate a warning if we still fail to meet this constraint
778 if (!valid)
779 {
780 ADDR_WARN(
781 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
782 tileSize, pTileInfo->bankWidth, pTileInfo->bankHeight, m_rowSize));
783 }
784 }
785
786 return valid;
787 }
788
789 /**
790 ***************************************************************************************************
791 * EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled
792 *
793 * @brief
794 * Compute 2D tiled surface alignment, calculation results are returned through
795 * output parameters.
796 *
797 * @return
798 * TRUE if no error occurs
799 ***************************************************************************************************
800 */
801 BOOL_32 EgBasedAddrLib::ComputeSurfaceAlignmentsMacroTiled(
802 AddrTileMode tileMode, ///< [in] tile mode
803 UINT_32 bpp, ///< [in] bits per pixel
804 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
805 UINT_32 mipLevel, ///< [in] mip level
806 UINT_32 numSamples, ///< [in] number of samples
807 ADDR_TILEINFO* pTileInfo, ///< [in/out] bank structure.
808 UINT_32* pBaseAlign, ///< [out] base address alignment in bytes
809 UINT_32* pPitchAlign, ///< [out] pitch alignment in pixels
810 UINT_32* pHeightAlign ///< [out] height alignment in pixels
811 ) const
812 {
813 BOOL_32 valid = SanityCheckMacroTiled(pTileInfo);
814
815 if (valid)
816 {
817 UINT_32 macroTileWidth;
818 UINT_32 macroTileHeight;
819
820 UINT_32 tileSize;
821 UINT_32 bankHeightAlign;
822 UINT_32 macroAspectAlign;
823
824 UINT_32 thickness = ComputeSurfaceThickness(tileMode);
825 UINT_32 pipes = HwlGetPipes(pTileInfo);
826
827 //
828 // Align bank height first according to latest h/w spec
829 //
830
831 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
832 tileSize = Min(pTileInfo->tileSplitBytes,
833 BITS_TO_BYTES(64 * thickness * bpp * numSamples));
834
835 // bank_height_align =
836 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
837 bankHeightAlign = Max(1u,
838 m_pipeInterleaveBytes * m_bankInterleave /
839 (tileSize * pTileInfo->bankWidth)
840 );
841
842 pTileInfo->bankHeight = PowTwoAlign(pTileInfo->bankHeight, bankHeightAlign);
843
844 // num_pipes * bank_width * macro_tile_aspect >=
845 // (pipe_interleave_size * bank_interleave) / tile_size
846 if (numSamples == 1)
847 {
848 // this restriction is only for mipmap (mipmap's numSamples must be 1)
849 macroAspectAlign = Max(1u,
850 m_pipeInterleaveBytes * m_bankInterleave /
851 (tileSize * pipes * pTileInfo->bankWidth)
852 );
853 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, macroAspectAlign);
854 }
855
856 valid = HwlReduceBankWidthHeight(tileSize,
857 bpp,
858 flags,
859 numSamples,
860 bankHeightAlign,
861 pipes,
862 pTileInfo);
863
864 //
865 // The required granularity for pitch is the macro tile width.
866 //
867 macroTileWidth = MicroTileWidth * pTileInfo->bankWidth * pipes *
868 pTileInfo->macroAspectRatio;
869
870 *pPitchAlign = macroTileWidth;
871
872 AdjustPitchAlignment(flags, pPitchAlign);
873
874 //
875 // The required granularity for height is the macro tile height.
876 //
877 macroTileHeight = MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
878 pTileInfo->macroAspectRatio;
879
880 *pHeightAlign = macroTileHeight;
881
882 //
883 // Compute base alignment
884 //
885 *pBaseAlign = pipes *
886 pTileInfo->bankWidth * pTileInfo->banks * pTileInfo->bankHeight * tileSize;
887
888 if ((mipLevel == 0) && (flags.prt) && (m_chipFamily == ADDR_CHIP_FAMILY_SI))
889 {
890 static const UINT_32 PrtTileSize = 0x10000;
891
892 UINT_32 macroTileSize = macroTileWidth * macroTileHeight * numSamples * bpp / 8;
893
894 if (macroTileSize < PrtTileSize)
895 {
896 UINT_32 numMacroTiles = PrtTileSize / macroTileSize;
897
898 ADDR_ASSERT((PrtTileSize % macroTileSize) == 0);
899
900 *pPitchAlign *= numMacroTiles;
901 *pBaseAlign *= numMacroTiles;
902 }
903 }
904 }
905
906 return valid;
907 }
908
909 /**
910 ***************************************************************************************************
911 * EgBasedAddrLib::SanityCheckMacroTiled
912 *
913 * @brief
914 * Check if macro-tiled parameters are valid
915 * @return
916 * TRUE if valid
917 ***************************************************************************************************
918 */
919 BOOL_32 EgBasedAddrLib::SanityCheckMacroTiled(
920 ADDR_TILEINFO* pTileInfo ///< [in] macro-tiled parameters
921 ) const
922 {
923 BOOL_32 valid = TRUE;
924 UINT_32 numPipes = HwlGetPipes(pTileInfo);
925
926 switch (pTileInfo->banks)
927 {
928 case 2: //fall through
929 case 4: //fall through
930 case 8: //fall through
931 case 16:
932 break;
933 default:
934 valid = FALSE;
935 break;
936
937 }
938
939 if (valid)
940 {
941 switch (pTileInfo->bankWidth)
942 {
943 case 1: //fall through
944 case 2: //fall through
945 case 4: //fall through
946 case 8:
947 break;
948 default:
949 valid = FALSE;
950 break;
951 }
952 }
953
954 if (valid)
955 {
956 switch (pTileInfo->bankHeight)
957 {
958 case 1: //fall through
959 case 2: //fall through
960 case 4: //fall through
961 case 8:
962 break;
963 default:
964 valid = FALSE;
965 break;
966 }
967 }
968
969 if (valid)
970 {
971 switch (pTileInfo->macroAspectRatio)
972 {
973 case 1: //fall through
974 case 2: //fall through
975 case 4: //fall through
976 case 8:
977 break;
978 default:
979 valid = FALSE;
980 break;
981 }
982 }
983
984 if (valid)
985 {
986 if (pTileInfo->banks < pTileInfo->macroAspectRatio)
987 {
988 // This will generate macro tile height <= 1
989 valid = FALSE;
990 }
991 }
992
993 if (valid)
994 {
995 if (pTileInfo->tileSplitBytes > m_rowSize)
996 {
997 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
998 }
999 }
1000
1001 if (valid)
1002 {
1003 valid = HwlSanityCheckMacroTiled(pTileInfo);
1004 }
1005
1006 ADDR_ASSERT(valid == TRUE);
1007
1008 // Add this assert for guidance
1009 ADDR_ASSERT(numPipes * pTileInfo->banks >= 4);
1010
1011 return valid;
1012 }
1013
1014 /**
1015 ***************************************************************************************************
1016 * EgBasedAddrLib::ComputeSurfaceMipLevelTileMode
1017 *
1018 * @brief
1019 * Compute valid tile mode for surface mipmap sub-levels
1020 *
1021 * @return
1022 * Suitable tile mode
1023 ***************************************************************************************************
1024 */
1025 AddrTileMode EgBasedAddrLib::ComputeSurfaceMipLevelTileMode(
1026 AddrTileMode baseTileMode, ///< [in] base tile mode
1027 UINT_32 bpp, ///< [in] bits per pixels
1028 UINT_32 pitch, ///< [in] current level pitch
1029 UINT_32 height, ///< [in] current level height
1030 UINT_32 numSlices, ///< [in] current number of slices
1031 UINT_32 numSamples, ///< [in] number of samples
1032 UINT_32 pitchAlign, ///< [in] pitch alignment
1033 UINT_32 heightAlign, ///< [in] height alignment
1034 ADDR_TILEINFO* pTileInfo ///< [in] ptr to bank structure
1035 ) const
1036 {
1037 UINT_32 bytesPerTile;
1038
1039 AddrTileMode expTileMode = baseTileMode;
1040 UINT_32 microTileThickness = ComputeSurfaceThickness(expTileMode);
1041 UINT_32 interleaveSize = m_pipeInterleaveBytes * m_bankInterleave;
1042
1043 //
1044 // Compute the size of a slice.
1045 //
1046 bytesPerTile = BITS_TO_BYTES(MicroTilePixels * microTileThickness * NextPow2(bpp) * numSamples);
1047
1048 //
1049 // Reduce tiling mode from thick to thin if the number of slices is less than the
1050 // micro tile thickness.
1051 //
1052 if (numSlices < microTileThickness)
1053 {
1054 expTileMode = HwlDegradeThickTileMode(expTileMode, numSlices, &bytesPerTile);
1055 }
1056
1057 if (bytesPerTile > pTileInfo->tileSplitBytes)
1058 {
1059 bytesPerTile = pTileInfo->tileSplitBytes;
1060 }
1061
1062 UINT_32 threshold1 =
1063 bytesPerTile * HwlGetPipes(pTileInfo) * pTileInfo->bankWidth * pTileInfo->macroAspectRatio;
1064
1065 UINT_32 threshold2 =
1066 bytesPerTile * pTileInfo->bankWidth * pTileInfo->bankHeight;
1067
1068 //
1069 // Reduce the tile mode from 2D/3D to 1D in following conditions
1070 //
1071 switch (expTileMode)
1072 {
1073 case ADDR_TM_2D_TILED_THIN1: //fall through
1074 case ADDR_TM_3D_TILED_THIN1:
1075 case ADDR_TM_PRT_TILED_THIN1:
1076 case ADDR_TM_PRT_2D_TILED_THIN1:
1077 case ADDR_TM_PRT_3D_TILED_THIN1:
1078 if ((pitch < pitchAlign) ||
1079 (height < heightAlign) ||
1080 (interleaveSize > threshold1) ||
1081 (interleaveSize > threshold2))
1082 {
1083 expTileMode = ADDR_TM_1D_TILED_THIN1;
1084 }
1085 break;
1086 case ADDR_TM_2D_TILED_THICK: //fall through
1087 case ADDR_TM_3D_TILED_THICK:
1088 case ADDR_TM_2D_TILED_XTHICK:
1089 case ADDR_TM_3D_TILED_XTHICK:
1090 case ADDR_TM_PRT_TILED_THICK:
1091 case ADDR_TM_PRT_2D_TILED_THICK:
1092 case ADDR_TM_PRT_3D_TILED_THICK:
1093 if ((pitch < pitchAlign) ||
1094 (height < heightAlign))
1095 {
1096 expTileMode = ADDR_TM_1D_TILED_THICK;
1097 }
1098 break;
1099 default:
1100 break;
1101 }
1102
1103 return expTileMode;
1104 }
1105
1106 /**
1107 ***************************************************************************************************
1108 * EgBasedAddrLib::HwlDegradeBaseLevel
1109 * @brief
1110 * Check if degrade is needed for base level
1111 * @return
1112 * TRUE if degrade is suggested
1113 ***************************************************************************************************
1114 */
1115 BOOL_32 EgBasedAddrLib::HwlDegradeBaseLevel(
1116 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn) const
1117 {
1118 BOOL_32 degrade = FALSE;
1119 BOOL_32 valid = TRUE;
1120
1121 ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
1122
1123 UINT_32 baseAlign;
1124 UINT_32 pitchAlign;
1125 UINT_32 heightAlign;
1126
1127 ADDR_ASSERT(pIn->pTileInfo);
1128 ADDR_TILEINFO tileInfo = *pIn->pTileInfo;
1129 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};
1130
1131 if (UseTileIndex(pIn->tileIndex))
1132 {
1133 out.tileIndex = pIn->tileIndex;
1134 out.macroModeIndex = TileIndexInvalid;
1135 }
1136
1137 HwlSetupTileInfo(pIn->tileMode,
1138 pIn->flags,
1139 pIn->bpp,
1140 pIn->width,
1141 pIn->height,
1142 pIn->numSamples,
1143 &tileInfo,
1144 &tileInfo,
1145 pIn->tileType,
1146 &out);
1147
1148 valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode,
1149 pIn->bpp,
1150 pIn->flags,
1151 pIn->mipLevel,
1152 pIn->numSamples,
1153 &tileInfo,
1154 &baseAlign,
1155 &pitchAlign,
1156 &heightAlign);
1157
1158 if (valid)
1159 {
1160 degrade = (pIn->width < pitchAlign || pIn->height < heightAlign);
1161 // Check whether 2D tiling still has too much footprint
1162 if (degrade == FALSE)
1163 {
1164 // Only check width and height as slices are aligned to thickness
1165 UINT_64 unalignedSize = pIn->width * pIn->height;
1166
1167 UINT_32 alignedPitch = PowTwoAlign(pIn->width, pitchAlign);
1168 UINT_32 alignedHeight = PowTwoAlign(pIn->height, heightAlign);
1169 UINT_64 alignedSize = alignedPitch * alignedHeight;
1170
1171 // alignedSize > 1.5 * unalignedSize
1172 if (2 * alignedSize > 3 * unalignedSize)
1173 {
1174 degrade = TRUE;
1175 }
1176 }
1177 }
1178 else
1179 {
1180 degrade = TRUE;
1181 }
1182
1183 return degrade;
1184 }
1185
1186 /**
1187 ***************************************************************************************************
1188 * EgBasedAddrLib::HwlDegradeThickTileMode
1189 *
1190 * @brief
1191 * Degrades valid tile mode for thick modes if needed
1192 *
1193 * @return
1194 * Suitable tile mode
1195 ***************************************************************************************************
1196 */
1197 AddrTileMode EgBasedAddrLib::HwlDegradeThickTileMode(
1198 AddrTileMode baseTileMode, ///< [in] base tile mode
1199 UINT_32 numSlices, ///< [in] current number of slices
1200 UINT_32* pBytesPerTile ///< [in/out] pointer to bytes per slice
1201 ) const
1202 {
1203 ADDR_ASSERT(numSlices < ComputeSurfaceThickness(baseTileMode));
1204 // if pBytesPerTile is NULL, this is a don't-care....
1205 UINT_32 bytesPerTile = pBytesPerTile != NULL ? *pBytesPerTile : 64;
1206
1207 AddrTileMode expTileMode = baseTileMode;
1208 switch (baseTileMode)
1209 {
1210 case ADDR_TM_1D_TILED_THICK:
1211 expTileMode = ADDR_TM_1D_TILED_THIN1;
1212 bytesPerTile >>= 2;
1213 break;
1214 case ADDR_TM_2D_TILED_THICK:
1215 expTileMode = ADDR_TM_2D_TILED_THIN1;
1216 bytesPerTile >>= 2;
1217 break;
1218 case ADDR_TM_3D_TILED_THICK:
1219 expTileMode = ADDR_TM_3D_TILED_THIN1;
1220 bytesPerTile >>= 2;
1221 break;
1222 case ADDR_TM_2D_TILED_XTHICK:
1223 if (numSlices < ThickTileThickness)
1224 {
1225 expTileMode = ADDR_TM_2D_TILED_THIN1;
1226 bytesPerTile >>= 3;
1227 }
1228 else
1229 {
1230 expTileMode = ADDR_TM_2D_TILED_THICK;
1231 bytesPerTile >>= 1;
1232 }
1233 break;
1234 case ADDR_TM_3D_TILED_XTHICK:
1235 if (numSlices < ThickTileThickness)
1236 {
1237 expTileMode = ADDR_TM_3D_TILED_THIN1;
1238 bytesPerTile >>= 3;
1239 }
1240 else
1241 {
1242 expTileMode = ADDR_TM_3D_TILED_THICK;
1243 bytesPerTile >>= 1;
1244 }
1245 break;
1246 default:
1247 ADDR_ASSERT_ALWAYS();
1248 break;
1249 }
1250
1251 if (pBytesPerTile != NULL)
1252 {
1253 *pBytesPerTile = bytesPerTile;
1254 }
1255
1256 return expTileMode;
1257 }
1258
1259 /**
1260 ***************************************************************************************************
1261 * EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord
1262 *
1263 * @brief
1264 * Compute surface address from given coord (x, y, slice,sample)
1265 *
1266 * @return
1267 * Address in bytes
1268 ***************************************************************************************************
1269 */
1270 UINT_64 EgBasedAddrLib::DispatchComputeSurfaceAddrFromCoord(
1271 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1272 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1273 ) const
1274 {
1275 UINT_32 x = pIn->x;
1276 UINT_32 y = pIn->y;
1277 UINT_32 slice = pIn->slice;
1278 UINT_32 sample = pIn->sample;
1279 UINT_32 bpp = pIn->bpp;
1280 UINT_32 pitch = pIn->pitch;
1281 UINT_32 height = pIn->height;
1282 UINT_32 numSlices = pIn->numSlices;
1283 UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
1284 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
1285 AddrTileMode tileMode = pIn->tileMode;
1286 AddrTileType microTileType = pIn->tileType;
1287 BOOL_32 ignoreSE = pIn->ignoreSE;
1288 BOOL_32 isDepthSampleOrder = pIn->isDepth;
1289 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
1290
1291 UINT_32* pBitPosition = &pOut->bitPosition;
1292 UINT_64 addr;
1293
1294 #if ADDR_AM_BUILD
1295 UINT_32 addr5Bit = 0;
1296 UINT_32 addr5Swizzle = pIn->addr5Swizzle;
1297 BOOL_32 is32ByteTile = pIn->is32ByteTile;
1298 #endif
1299
1300 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1301 if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
1302 {
1303 isDepthSampleOrder = TRUE;
1304 }
1305
1306 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
1307 {
1308 if (numFrags != numSamples)
1309 {
1310 numSamples = numFrags;
1311 ADDR_ASSERT(sample < numSamples);
1312 }
1313
1314 /// @note
1315 /// 128 bit/thick tiled surface doesn't support display tiling and
1316 /// mipmap chain must have the same tileType, so please fill tileType correctly
1317 if (!IsLinear(pIn->tileMode))
1318 {
1319 if (bpp >= 128 || ComputeSurfaceThickness(tileMode) > 1)
1320 {
1321 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
1322 }
1323 }
1324 }
1325
1326 switch (tileMode)
1327 {
1328 case ADDR_TM_LINEAR_GENERAL://fall through
1329 case ADDR_TM_LINEAR_ALIGNED:
1330 addr = ComputeSurfaceAddrFromCoordLinear(x,
1331 y,
1332 slice,
1333 sample,
1334 bpp,
1335 pitch,
1336 height,
1337 numSlices,
1338 pBitPosition);
1339 break;
1340 case ADDR_TM_1D_TILED_THIN1://fall through
1341 case ADDR_TM_1D_TILED_THICK:
1342 addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
1343 y,
1344 slice,
1345 sample,
1346 bpp,
1347 pitch,
1348 height,
1349 numSamples,
1350 tileMode,
1351 microTileType,
1352 isDepthSampleOrder,
1353 pBitPosition);
1354 break;
1355 case ADDR_TM_2D_TILED_THIN1: //fall through
1356 case ADDR_TM_2D_TILED_THICK: //fall through
1357 case ADDR_TM_3D_TILED_THIN1: //fall through
1358 case ADDR_TM_3D_TILED_THICK: //fall through
1359 case ADDR_TM_2D_TILED_XTHICK: //fall through
1360 case ADDR_TM_3D_TILED_XTHICK: //fall through
1361 case ADDR_TM_PRT_TILED_THIN1: //fall through
1362 case ADDR_TM_PRT_2D_TILED_THIN1://fall through
1363 case ADDR_TM_PRT_3D_TILED_THIN1://fall through
1364 case ADDR_TM_PRT_TILED_THICK: //fall through
1365 case ADDR_TM_PRT_2D_TILED_THICK://fall through
1366 case ADDR_TM_PRT_3D_TILED_THICK:
1367 UINT_32 pipeSwizzle;
1368 UINT_32 bankSwizzle;
1369
1370 if (m_configFlags.useCombinedSwizzle)
1371 {
1372 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
1373 &bankSwizzle, &pipeSwizzle);
1374 }
1375 else
1376 {
1377 pipeSwizzle = pIn->pipeSwizzle;
1378 bankSwizzle = pIn->bankSwizzle;
1379 }
1380
1381 addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
1382 y,
1383 slice,
1384 sample,
1385 bpp,
1386 pitch,
1387 height,
1388 numSamples,
1389 tileMode,
1390 microTileType,
1391 ignoreSE,
1392 isDepthSampleOrder,
1393 pipeSwizzle,
1394 bankSwizzle,
1395 pTileInfo,
1396 pBitPosition);
1397 break;
1398 default:
1399 addr = 0;
1400 ADDR_ASSERT_ALWAYS();
1401 break;
1402 }
1403
1404 #if ADDR_AM_BUILD
1405 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
1406 {
1407 if (addr5Swizzle && isDepthSampleOrder && is32ByteTile)
1408 {
1409 UINT_32 tx = x >> 3;
1410 UINT_32 ty = y >> 3;
1411 UINT_32 tileBits = ((ty&0x3) << 2) | (tx&0x3);
1412
1413 tileBits = tileBits & addr5Swizzle;
1414 addr5Bit = XorReduce(tileBits, 4);
1415
1416 addr = addr | static_cast<UINT_64>(addr5Bit << 5);
1417 }
1418 }
1419 #endif
1420
1421 return addr;
1422 }
1423
1424 /**
1425 ***************************************************************************************************
1426 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
1427 *
1428 * @brief
1429 * Computes the surface address and bit position from a
1430 * coordinate for 2D tilied (macro tiled)
1431 * @return
1432 * The byte address
1433 ***************************************************************************************************
1434 */
1435 UINT_64 EgBasedAddrLib::ComputeSurfaceAddrFromCoordMacroTiled(
1436 UINT_32 x, ///< [in] x coordinate
1437 UINT_32 y, ///< [in] y coordinate
1438 UINT_32 slice, ///< [in] slice index
1439 UINT_32 sample, ///< [in] sample index
1440 UINT_32 bpp, ///< [in] bits per pixel
1441 UINT_32 pitch, ///< [in] surface pitch, in pixels
1442 UINT_32 height, ///< [in] surface height, in pixels
1443 UINT_32 numSamples, ///< [in] number of samples
1444 AddrTileMode tileMode, ///< [in] tile mode
1445 AddrTileType microTileType, ///< [in] micro tiling type
1446 BOOL_32 ignoreSE, ///< [in] TRUE if shader enginers can be ignored
1447 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if it depth sample ordering is used
1448 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
1449 UINT_32 bankSwizzle, ///< [in] bank swizzle
1450 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure
1451 /// **All fields to be valid on entry**
1452 UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this
1453 ) const
1454 {
1455 UINT_64 addr;
1456
1457 UINT_32 microTileBytes;
1458 UINT_32 microTileBits;
1459 UINT_32 sampleOffset;
1460 UINT_32 pixelIndex;
1461 UINT_32 pixelOffset;
1462 UINT_32 elementOffset;
1463 UINT_32 tileSplitSlice;
1464 UINT_32 pipe;
1465 UINT_32 bank;
1466 UINT_64 sliceBytes;
1467 UINT_64 sliceOffset;
1468 UINT_32 macroTilePitch;
1469 UINT_32 macroTileHeight;
1470 UINT_32 macroTilesPerRow;
1471 UINT_32 macroTilesPerSlice;
1472 UINT_64 macroTileBytes;
1473 UINT_32 macroTileIndexX;
1474 UINT_32 macroTileIndexY;
1475 UINT_64 macroTileOffset;
1476 UINT_64 totalOffset;
1477 UINT_64 pipeInterleaveMask;
1478 UINT_64 bankInterleaveMask;
1479 UINT_64 pipeInterleaveOffset;
1480 UINT_32 bankInterleaveOffset;
1481 UINT_64 offset;
1482 UINT_32 tileRowIndex;
1483 UINT_32 tileColumnIndex;
1484 UINT_32 tileIndex;
1485 UINT_32 tileOffset;
1486
1487 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
1488
1489 //
1490 // Compute the number of group, pipe, and bank bits.
1491 //
1492 UINT_32 numPipes = HwlGetPipes(pTileInfo);
1493 UINT_32 numPipeInterleaveBits = Log2(m_pipeInterleaveBytes);
1494 UINT_32 numPipeBits = Log2(numPipes);
1495 UINT_32 numBankInterleaveBits = Log2(m_bankInterleave);
1496 UINT_32 numBankBits = Log2(pTileInfo->banks);
1497
1498 //
1499 // Compute the micro tile size.
1500 //
1501 microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
1502
1503 microTileBytes = microTileBits / 8;
1504 //
1505 // Compute the pixel index within the micro tile.
1506 //
1507 pixelIndex = ComputePixelIndexWithinMicroTile(x,
1508 y,
1509 slice,
1510 bpp,
1511 tileMode,
1512 microTileType);
1513
1514 //
1515 // Compute the sample offset and pixel offset.
1516 //
1517 if (isDepthSampleOrder)
1518 {
1519 //
1520 // For depth surfaces, samples are stored contiguously for each element, so the sample
1521 // offset is the sample number times the element size.
1522 //
1523 sampleOffset = sample * bpp;
1524 pixelOffset = pixelIndex * bpp * numSamples;
1525 }
1526 else
1527 {
1528 //
1529 // For color surfaces, all elements for a particular sample are stored contiguously, so
1530 // the sample offset is the sample number times the micro tile size divided yBit the number
1531 // of samples.
1532 //
1533 sampleOffset = sample * (microTileBits / numSamples);
1534 pixelOffset = pixelIndex * bpp;
1535 }
1536
1537 //
1538 // Compute the element offset.
1539 //
1540 elementOffset = pixelOffset + sampleOffset;
1541
1542 *pBitPosition = static_cast<UINT_32>(elementOffset % 8);
1543
1544 elementOffset /= 8; //bit-to-byte
1545
1546 //
1547 // Determine if tiles need to be split across slices.
1548 //
1549 // If the size of the micro tile is larger than the tile split size, then the tile will be
1550 // split across multiple slices.
1551 //
1552 UINT_32 slicesPerTile = 1;
1553
1554 if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
1555 { //don't support for thick mode
1556
1557 //
1558 // Compute the number of slices per tile.
1559 //
1560 slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
1561
1562 //
1563 // Compute the tile split slice number for use in rotating the bank.
1564 //
1565 tileSplitSlice = elementOffset / pTileInfo->tileSplitBytes;
1566
1567 //
1568 // Adjust the element offset to account for the portion of the tile that is being moved to
1569 // a new slice..
1570 //
1571 elementOffset %= pTileInfo->tileSplitBytes;
1572
1573 //
1574 // Adjust the microTileBytes size to tileSplitBytes size since
1575 // a new slice..
1576 //
1577 microTileBytes = pTileInfo->tileSplitBytes;
1578 }
1579 else
1580 {
1581 tileSplitSlice = 0;
1582 }
1583
1584 //
1585 // Compute macro tile pitch and height.
1586 //
1587 macroTilePitch =
1588 (MicroTileWidth * pTileInfo->bankWidth * numPipes) * pTileInfo->macroAspectRatio;
1589 macroTileHeight =
1590 (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) / pTileInfo->macroAspectRatio;
1591
1592 //
1593 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1594 //
1595 macroTileBytes =
1596 static_cast<UINT_64>(microTileBytes) *
1597 (macroTilePitch / MicroTileWidth) * (macroTileHeight / MicroTileHeight) /
1598 (numPipes * pTileInfo->banks);
1599
1600 //
1601 // Compute the number of macro tiles per row.
1602 //
1603 macroTilesPerRow = pitch / macroTilePitch;
1604
1605 //
1606 // Compute the offset to the macro tile containing the specified coordinate.
1607 //
1608 macroTileIndexX = x / macroTilePitch;
1609 macroTileIndexY = y / macroTileHeight;
1610 macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
1611
1612 //
1613 // Compute the number of macro tiles per slice.
1614 //
1615 macroTilesPerSlice = macroTilesPerRow * (height / macroTileHeight);
1616
1617 //
1618 // Compute the slice size.
1619 //
1620 sliceBytes = macroTilesPerSlice * macroTileBytes;
1621
1622 //
1623 // Compute the slice offset.
1624 //
1625 sliceOffset = sliceBytes * (tileSplitSlice + slicesPerTile * (slice / microTileThickness));
1626
1627 //
1628 // Compute tile offest
1629 //
1630 tileRowIndex = (y / MicroTileHeight) % pTileInfo->bankHeight;
1631 tileColumnIndex = ((x / MicroTileWidth) / numPipes) % pTileInfo->bankWidth;
1632 tileIndex = (tileRowIndex * pTileInfo->bankWidth) + tileColumnIndex;
1633 tileOffset = tileIndex * microTileBytes;
1634
1635 //
1636 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1637 // for the pipe and bank bits in the middle of the address.
1638 //
1639 totalOffset = sliceOffset + macroTileOffset + elementOffset + tileOffset;
1640
1641 //
1642 // Get the pipe and bank.
1643 //
1644
1645 // when the tileMode is PRT type, then adjust x and y coordinates
1646 if (IsPrtNoRotationTileMode(tileMode))
1647 {
1648 x = x % macroTilePitch;
1649 y = y % macroTileHeight;
1650 }
1651
1652 pipe = ComputePipeFromCoord(x,
1653 y,
1654 slice,
1655 tileMode,
1656 pipeSwizzle,
1657 ignoreSE,
1658 pTileInfo);
1659
1660 bank = ComputeBankFromCoord(x,
1661 y,
1662 slice,
1663 tileMode,
1664 bankSwizzle,
1665 tileSplitSlice,
1666 pTileInfo);
1667
1668
1669 //
1670 // Split the offset to put some bits below the pipe+bank bits and some above.
1671 //
1672 pipeInterleaveMask = (1 << numPipeInterleaveBits) - 1;
1673 bankInterleaveMask = (1 << numBankInterleaveBits) - 1;
1674 pipeInterleaveOffset = totalOffset & pipeInterleaveMask;
1675 bankInterleaveOffset = static_cast<UINT_32>((totalOffset >> numPipeInterleaveBits) &
1676 bankInterleaveMask);
1677 offset = totalOffset >> (numPipeInterleaveBits + numBankInterleaveBits);
1678
1679 //
1680 // Assemble the address from its components.
1681 //
1682 addr = pipeInterleaveOffset;
1683 // This is to remove /analyze warnings
1684 UINT_32 pipeBits = pipe << numPipeInterleaveBits;
1685 UINT_32 bankInterleaveBits = bankInterleaveOffset << (numPipeInterleaveBits + numPipeBits);
1686 UINT_32 bankBits = bank << (numPipeInterleaveBits + numPipeBits +
1687 numBankInterleaveBits);
1688 UINT_64 offsetBits = offset << (numPipeInterleaveBits + numPipeBits +
1689 numBankInterleaveBits + numBankBits);
1690
1691 addr |= pipeBits;
1692 addr |= bankInterleaveBits;
1693 addr |= bankBits;
1694 addr |= offsetBits;
1695
1696 return addr;
1697 }
1698
1699 /**
1700 ***************************************************************************************************
1701 * EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled
1702 *
1703 * @brief
1704 * Computes the surface address and bit position from a coordinate for 1D tilied
1705 * (micro tiled)
1706 * @return
1707 * The byte address
1708 ***************************************************************************************************
1709 */
1710 UINT_64 EgBasedAddrLib::ComputeSurfaceAddrFromCoordMicroTiled(
1711 UINT_32 x, ///< [in] x coordinate
1712 UINT_32 y, ///< [in] y coordinate
1713 UINT_32 slice, ///< [in] slice index
1714 UINT_32 sample, ///< [in] sample index
1715 UINT_32 bpp, ///< [in] bits per pixel
1716 UINT_32 pitch, ///< [in] pitch, in pixels
1717 UINT_32 height, ///< [in] height, in pixels
1718 UINT_32 numSamples, ///< [in] number of samples
1719 AddrTileMode tileMode, ///< [in] tile mode
1720 AddrTileType microTileType, ///< [in] micro tiling type
1721 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample ordering is used
1722 UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this
1723 ) const
1724 {
1725 UINT_64 addr = 0;
1726
1727 UINT_32 microTileBytes;
1728 UINT_64 sliceBytes;
1729 UINT_32 microTilesPerRow;
1730 UINT_32 microTileIndexX;
1731 UINT_32 microTileIndexY;
1732 UINT_32 microTileIndexZ;
1733 UINT_64 sliceOffset;
1734 UINT_64 microTileOffset;
1735 UINT_32 sampleOffset;
1736 UINT_32 pixelIndex;
1737 UINT_32 pixelOffset;
1738
1739 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
1740
1741 //
1742 // Compute the micro tile size.
1743 //
1744 microTileBytes = BITS_TO_BYTES(MicroTilePixels * microTileThickness * bpp * numSamples);
1745
1746 //
1747 // Compute the slice size.
1748 //
1749 sliceBytes =
1750 BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples);
1751
1752 //
1753 // Compute the number of micro tiles per row.
1754 //
1755 microTilesPerRow = pitch / MicroTileWidth;
1756
1757 //
1758 // Compute the micro tile index.
1759 //
1760 microTileIndexX = x / MicroTileWidth;
1761 microTileIndexY = y / MicroTileHeight;
1762 microTileIndexZ = slice / microTileThickness;
1763
1764 //
1765 // Compute the slice offset.
1766 //
1767 sliceOffset = static_cast<UINT_64>(microTileIndexZ) * sliceBytes;
1768
1769 //
1770 // Compute the offset to the micro tile containing the specified coordinate.
1771 //
1772 microTileOffset = (static_cast<UINT_64>(microTileIndexY) * microTilesPerRow + microTileIndexX) *
1773 microTileBytes;
1774
1775 //
1776 // Compute the pixel index within the micro tile.
1777 //
1778 pixelIndex = ComputePixelIndexWithinMicroTile(x,
1779 y,
1780 slice,
1781 bpp,
1782 tileMode,
1783 microTileType);
1784
1785 // Compute the sample offset.
1786 //
1787 if (isDepthSampleOrder)
1788 {
1789 //
1790 // For depth surfaces, samples are stored contiguously for each element, so the sample
1791 // offset is the sample number times the element size.
1792 //
1793 sampleOffset = sample * bpp;
1794 pixelOffset = pixelIndex * bpp * numSamples;
1795 }
1796 else
1797 {
1798 //
1799 // For color surfaces, all elements for a particular sample are stored contiguously, so
1800 // the sample offset is the sample number times the micro tile size divided yBit the number
1801 // of samples.
1802 //
1803 sampleOffset = sample * (microTileBytes*8 / numSamples);
1804 pixelOffset = pixelIndex * bpp;
1805 }
1806
1807 //
1808 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1809 //
1810
1811 UINT_32 elemOffset = sampleOffset + pixelOffset;
1812
1813 *pBitPosition = elemOffset % 8;
1814 elemOffset /= 8;
1815
1816 //
1817 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1818 //
1819 addr = sliceOffset + microTileOffset + elemOffset;
1820
1821 return addr;
1822 }
1823
1824 /**
1825 ***************************************************************************************************
1826 * EgBasedAddrLib::HwlComputePixelCoordFromOffset
1827 *
1828 * @brief
1829 * Compute pixel coordinate from offset inside a micro tile
1830 * @return
1831 * N/A
1832 ***************************************************************************************************
1833 */
1834 VOID EgBasedAddrLib::HwlComputePixelCoordFromOffset(
1835 UINT_32 offset, ///< [in] offset inside micro tile in bits
1836 UINT_32 bpp, ///< [in] bits per pixel
1837 UINT_32 numSamples, ///< [in] number of samples
1838 AddrTileMode tileMode, ///< [in] tile mode
1839 UINT_32 tileBase, ///< [in] base offset within a tile
1840 UINT_32 compBits, ///< [in] component bits actually needed(for planar surface)
1841 UINT_32* pX, ///< [out] x coordinate
1842 UINT_32* pY, ///< [out] y coordinate
1843 UINT_32* pSlice, ///< [out] slice index
1844 UINT_32* pSample, ///< [out] sample index
1845 AddrTileType microTileType, ///< [in] micro tiling type
1846 BOOL_32 isDepthSampleOrder ///< [in] TRUE if depth sample order in microtile is used
1847 ) const
1848 {
1849 UINT_32 x = 0;
1850 UINT_32 y = 0;
1851 UINT_32 z = 0;
1852 UINT_32 thickness = ComputeSurfaceThickness(tileMode);
1853
1854 // For planar surface, we adjust offset acoording to tile base
1855 if ((bpp != compBits) && (compBits != 0) && isDepthSampleOrder)
1856 {
1857 offset -= tileBase;
1858
1859 ADDR_ASSERT(microTileType == ADDR_NON_DISPLAYABLE ||
1860 microTileType == ADDR_DEPTH_SAMPLE_ORDER);
1861
1862 bpp = compBits;
1863 }
1864
1865 UINT_32 sampleTileBits;
1866 UINT_32 samplePixelBits;
1867 UINT_32 pixelIndex;
1868
1869 if (isDepthSampleOrder)
1870 {
1871 samplePixelBits = bpp * numSamples;
1872 pixelIndex = offset / samplePixelBits;
1873 *pSample = (offset % samplePixelBits) / bpp;
1874 }
1875 else
1876 {
1877 sampleTileBits = MicroTilePixels * bpp * thickness;
1878 *pSample = offset / sampleTileBits;
1879 pixelIndex = (offset % sampleTileBits) / bpp;
1880 }
1881
1882 if (microTileType != ADDR_THICK)
1883 {
1884 if (microTileType == ADDR_DISPLAYABLE) // displayable
1885 {
1886 switch (bpp)
1887 {
1888 case 8:
1889 x = pixelIndex & 0x7;
1890 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
1891 break;
1892 case 16:
1893 x = pixelIndex & 0x7;
1894 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
1895 break;
1896 case 32:
1897 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
1898 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
1899 break;
1900 case 64:
1901 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
1902 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
1903 break;
1904 case 128:
1905 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,1));
1906 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,0));
1907 break;
1908 default:
1909 break;
1910 }
1911 }
1912 else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
1913 {
1914 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
1915 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
1916 }
1917 else if (microTileType == ADDR_ROTATED)
1918 {
1919 /*
1920 8-Bit Elements
1921 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
1922
1923 16-Bit Elements
1924 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
1925
1926 32-Bit Elements
1927 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
1928
1929 64-Bit Elements
1930 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
1931 */
1932 switch(bpp)
1933 {
1934 case 8:
1935 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
1936 y = pixelIndex & 0x7;
1937 break;
1938 case 16:
1939 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
1940 y = pixelIndex & 0x7;
1941 break;
1942 case 32:
1943 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
1944 y = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
1945 break;
1946 case 64:
1947 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
1948 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
1949 break;
1950 default:
1951 ADDR_ASSERT_ALWAYS();
1952 break;
1953 }
1954 }
1955
1956 if (thickness > 1) // thick
1957 {
1958 z = Bits2Number(3, _BIT(pixelIndex,8),_BIT(pixelIndex,7),_BIT(pixelIndex,6));
1959 }
1960 }
1961 else
1962 {
1963 ADDR_ASSERT((m_chipFamily >= ADDR_CHIP_FAMILY_CI) && (thickness > 1));
1964 /*
1965 8-Bit Elements and 16-Bit Elements
1966 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
1967
1968 32-Bit Elements
1969 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
1970
1971 64-Bit Elements and 128-Bit Elements
1972 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
1973
1974 The equation to compute the element index for the extra thick tile:
1975 element_index[8] = z[2]
1976 */
1977 switch (bpp)
1978 {
1979 case 8:
1980 case 16: // fall-through
1981 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
1982 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
1983 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,4));
1984 break;
1985 case 32:
1986 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
1987 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
1988 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,3));
1989 break;
1990 case 64:
1991 case 128: // fall-through
1992 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,3),_BIT(pixelIndex,0));
1993 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
1994 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,2));
1995 break;
1996 default:
1997 ADDR_ASSERT_ALWAYS();
1998 break;
1999 }
2000
2001 if (thickness == 8)
2002 {
2003 z += Bits2Number(3,_BIT(pixelIndex,8),0,0);
2004 }
2005 }
2006
2007 *pX = x;
2008 *pY = y;
2009 *pSlice += z;
2010 }
2011
2012
2013 /**
2014 ***************************************************************************************************
2015 * EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddrDispatch
2016 *
2017 * @brief
2018 * Compute (x,y,slice,sample) coordinates from surface address
2019 * @return
2020 * N/A
2021 ***************************************************************************************************
2022 */
2023 VOID EgBasedAddrLib::DispatchComputeSurfaceCoordFromAddr(
2024 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
2025 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
2026 ) const
2027 {
2028 UINT_64 addr = pIn->addr;
2029 UINT_32 bitPosition = pIn->bitPosition;
2030 UINT_32 bpp = pIn->bpp;
2031 UINT_32 pitch = pIn->pitch;
2032 UINT_32 height = pIn->height;
2033 UINT_32 numSlices = pIn->numSlices;
2034 UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
2035 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
2036 AddrTileMode tileMode = pIn->tileMode;
2037 UINT_32 tileBase = pIn->tileBase;
2038 UINT_32 compBits = pIn->compBits;
2039 AddrTileType microTileType = pIn->tileType;
2040 BOOL_32 ignoreSE = pIn->ignoreSE;
2041 BOOL_32 isDepthSampleOrder = pIn->isDepth;
2042 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
2043
2044 UINT_32* pX = &pOut->x;
2045 UINT_32* pY = &pOut->y;
2046 UINT_32* pSlice = &pOut->slice;
2047 UINT_32* pSample = &pOut->sample;
2048
2049 if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2050 {
2051 isDepthSampleOrder = TRUE;
2052 }
2053
2054 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
2055 {
2056 if (numFrags != numSamples)
2057 {
2058 numSamples = numFrags;
2059 }
2060
2061 /// @note
2062 /// 128 bit/thick tiled surface doesn't support display tiling and
2063 /// mipmap chain must have the same tileType, so please fill tileType correctly
2064 if (!IsLinear(pIn->tileMode))
2065 {
2066 if (bpp >= 128 || ComputeSurfaceThickness(tileMode) > 1)
2067 {
2068 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
2069 }
2070 }
2071 }
2072
2073 switch (tileMode)
2074 {
2075 case ADDR_TM_LINEAR_GENERAL://fall through
2076 case ADDR_TM_LINEAR_ALIGNED:
2077 ComputeSurfaceCoordFromAddrLinear(addr,
2078 bitPosition,
2079 bpp,
2080 pitch,
2081 height,
2082 numSlices,
2083 pX,
2084 pY,
2085 pSlice,
2086 pSample);
2087 break;
2088 case ADDR_TM_1D_TILED_THIN1://fall through
2089 case ADDR_TM_1D_TILED_THICK:
2090 ComputeSurfaceCoordFromAddrMicroTiled(addr,
2091 bitPosition,
2092 bpp,
2093 pitch,
2094 height,
2095 numSamples,
2096 tileMode,
2097 tileBase,
2098 compBits,
2099 pX,
2100 pY,
2101 pSlice,
2102 pSample,
2103 microTileType,
2104 isDepthSampleOrder);
2105 break;
2106 case ADDR_TM_2D_TILED_THIN1: //fall through
2107 case ADDR_TM_2D_TILED_THICK: //fall through
2108 case ADDR_TM_3D_TILED_THIN1: //fall through
2109 case ADDR_TM_3D_TILED_THICK: //fall through
2110 case ADDR_TM_2D_TILED_XTHICK: //fall through
2111 case ADDR_TM_3D_TILED_XTHICK: //fall through
2112 case ADDR_TM_PRT_TILED_THIN1: //fall through
2113 case ADDR_TM_PRT_2D_TILED_THIN1://fall through
2114 case ADDR_TM_PRT_3D_TILED_THIN1://fall through
2115 case ADDR_TM_PRT_TILED_THICK: //fall through
2116 case ADDR_TM_PRT_2D_TILED_THICK://fall through
2117 case ADDR_TM_PRT_3D_TILED_THICK:
2118 UINT_32 pipeSwizzle;
2119 UINT_32 bankSwizzle;
2120
2121 if (m_configFlags.useCombinedSwizzle)
2122 {
2123 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
2124 &bankSwizzle, &pipeSwizzle);
2125 }
2126 else
2127 {
2128 pipeSwizzle = pIn->pipeSwizzle;
2129 bankSwizzle = pIn->bankSwizzle;
2130 }
2131
2132 ComputeSurfaceCoordFromAddrMacroTiled(addr,
2133 bitPosition,
2134 bpp,
2135 pitch,
2136 height,
2137 numSamples,
2138 tileMode,
2139 tileBase,
2140 compBits,
2141 microTileType,
2142 ignoreSE,
2143 isDepthSampleOrder,
2144 pipeSwizzle,
2145 bankSwizzle,
2146 pTileInfo,
2147 pX,
2148 pY,
2149 pSlice,
2150 pSample);
2151 break;
2152 default:
2153 ADDR_ASSERT_ALWAYS();
2154 }
2155 }
2156
2157
2158 /**
2159 ***************************************************************************************************
2160 * EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled
2161 *
2162 * @brief
2163 * Compute surface coordinates from address for macro tiled surface
2164 * @return
2165 * N/A
2166 ***************************************************************************************************
2167 */
2168 VOID EgBasedAddrLib::ComputeSurfaceCoordFromAddrMacroTiled(
2169 UINT_64 addr, ///< [in] byte address
2170 UINT_32 bitPosition, ///< [in] bit position
2171 UINT_32 bpp, ///< [in] bits per pixel
2172 UINT_32 pitch, ///< [in] pitch in pixels
2173 UINT_32 height, ///< [in] height in pixels
2174 UINT_32 numSamples, ///< [in] number of samples
2175 AddrTileMode tileMode, ///< [in] tile mode
2176 UINT_32 tileBase, ///< [in] tile base offset
2177 UINT_32 compBits, ///< [in] component bits (for planar surface)
2178 AddrTileType microTileType, ///< [in] micro tiling type
2179 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines can be ignored
2180 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample order is used
2181 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2182 UINT_32 bankSwizzle, ///< [in] bank swizzle
2183 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure.
2184 /// **All fields to be valid on entry**
2185 UINT_32* pX, ///< [out] X coord
2186 UINT_32* pY, ///< [out] Y coord
2187 UINT_32* pSlice, ///< [out] slice index
2188 UINT_32* pSample ///< [out] sample index
2189 ) const
2190 {
2191 UINT_32 mx;
2192 UINT_32 my;
2193 UINT_64 tileBits;
2194 UINT_64 macroTileBits;
2195 UINT_32 slices;
2196 UINT_32 tileSlices;
2197 UINT_64 elementOffset;
2198 UINT_64 macroTileIndex;
2199 UINT_32 tileIndex;
2200 UINT_64 totalOffset;
2201
2202
2203 UINT_32 bank;
2204 UINT_32 pipe;
2205 UINT_32 groupBits = m_pipeInterleaveBytes << 3;
2206 UINT_32 pipes = HwlGetPipes(pTileInfo);
2207 UINT_32 banks = pTileInfo->banks;
2208
2209 UINT_32 bankInterleave = m_bankInterleave;
2210
2211 UINT_64 addrBits = BYTES_TO_BITS(addr) + bitPosition;
2212
2213 //
2214 // remove bits for bank and pipe
2215 //
2216 totalOffset = (addrBits % groupBits) +
2217 (((addrBits / groupBits / pipes) % bankInterleave) * groupBits) +
2218 (((addrBits / groupBits / pipes) / bankInterleave) / banks) * groupBits * bankInterleave;
2219
2220 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
2221
2222 UINT_32 microTileBits = bpp * microTileThickness * MicroTilePixels * numSamples;
2223
2224 UINT_32 microTileBytes = BITS_TO_BYTES(microTileBits);
2225 //
2226 // Determine if tiles need to be split across slices.
2227 //
2228 // If the size of the micro tile is larger than the tile split size, then the tile will be
2229 // split across multiple slices.
2230 //
2231 UINT_32 slicesPerTile = 1; //_State->TileSlices
2232
2233 if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
2234 { //don't support for thick mode
2235
2236 //
2237 // Compute the number of slices per tile.
2238 //
2239 slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
2240 }
2241
2242 tileBits = microTileBits / slicesPerTile; // micro tile bits
2243
2244 // in micro tiles because not MicroTileWidth timed.
2245 UINT_32 macroWidth = pTileInfo->bankWidth * pipes * pTileInfo->macroAspectRatio;
2246 // in micro tiles as well
2247 UINT_32 macroHeight = pTileInfo->bankHeight * banks / pTileInfo->macroAspectRatio;
2248
2249 UINT_32 pitchInMacroTiles = pitch / MicroTileWidth / macroWidth;
2250
2251 macroTileBits = (macroWidth * macroHeight) * tileBits / (banks * pipes);
2252
2253 macroTileIndex = totalOffset / macroTileBits;
2254
2255 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2256 UINT_32 macroTilesPerSlice = (pitch / (macroWidth * MicroTileWidth)) * height /
2257 (macroHeight * MicroTileWidth);
2258
2259 slices = static_cast<UINT_32>(macroTileIndex / macroTilesPerSlice);
2260
2261 *pSlice = static_cast<UINT_32>(slices / slicesPerTile * microTileThickness);
2262
2263 //
2264 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2265 //
2266 tileSlices = slices % slicesPerTile;
2267
2268 elementOffset = tileSlices * tileBits;
2269 elementOffset += totalOffset % tileBits;
2270
2271 UINT_32 coordZ = 0;
2272
2273 HwlComputePixelCoordFromOffset(static_cast<UINT_32>(elementOffset),
2274 bpp,
2275 numSamples,
2276 tileMode,
2277 tileBase,
2278 compBits,
2279 pX,
2280 pY,
2281 &coordZ,
2282 pSample,
2283 microTileType,
2284 isDepthSampleOrder);
2285
2286 macroTileIndex = macroTileIndex % macroTilesPerSlice;
2287 *pY += static_cast<UINT_32>(macroTileIndex / pitchInMacroTiles * macroHeight * MicroTileHeight);
2288 *pX += static_cast<UINT_32>(macroTileIndex % pitchInMacroTiles * macroWidth * MicroTileWidth);
2289
2290 *pSlice += coordZ;
2291
2292 tileIndex = static_cast<UINT_32>((totalOffset % macroTileBits) / tileBits);
2293
2294 my = (tileIndex / pTileInfo->bankWidth) % pTileInfo->bankHeight * MicroTileHeight;
2295 mx = (tileIndex % pTileInfo->bankWidth) * pipes * MicroTileWidth;
2296
2297 *pY += my;
2298 *pX += mx;
2299
2300 bank = ComputeBankFromAddr(addr, banks, pipes);
2301 pipe = ComputePipeFromAddr(addr, pipes);
2302
2303 HwlComputeSurfaceCoord2DFromBankPipe(tileMode,
2304 pX,
2305 pY,
2306 *pSlice,
2307 bank,
2308 pipe,
2309 bankSwizzle,
2310 pipeSwizzle,
2311 tileSlices,
2312 ignoreSE,
2313 pTileInfo);
2314 }
2315
2316 /**
2317 ***************************************************************************************************
2318 * EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe
2319 *
2320 * @brief
2321 * Compute surface x,y coordinates from bank/pipe info
2322 * @return
2323 * N/A
2324 ***************************************************************************************************
2325 */
2326 VOID EgBasedAddrLib::ComputeSurfaceCoord2DFromBankPipe(
2327 AddrTileMode tileMode, ///< [in] tile mode
2328 UINT_32 x, ///< [in] x coordinate
2329 UINT_32 y, ///< [in] y coordinate
2330 UINT_32 slice, ///< [in] slice index
2331 UINT_32 bank, ///< [in] bank number
2332 UINT_32 pipe, ///< [in] pipe number
2333 UINT_32 bankSwizzle,///< [in] bank swizzle
2334 UINT_32 pipeSwizzle,///< [in] pipe swizzle
2335 UINT_32 tileSlices, ///< [in] slices in a micro tile
2336 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry**
2337 CoordFromBankPipe* pOutput ///< [out] pointer to extracted x/y bits
2338 ) const
2339 {
2340 UINT_32 yBit3 = 0;
2341 UINT_32 yBit4 = 0;
2342 UINT_32 yBit5 = 0;
2343 UINT_32 yBit6 = 0;
2344
2345 UINT_32 xBit3 = 0;
2346 UINT_32 xBit4 = 0;
2347 UINT_32 xBit5 = 0;
2348
2349 UINT_32 tileSplitRotation;
2350
2351 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2352
2353 UINT_32 bankRotation = ComputeBankRotation(tileMode,
2354 pTileInfo->banks, numPipes);
2355
2356 UINT_32 pipeRotation = ComputePipeRotation(tileMode, numPipes);
2357
2358 UINT_32 xBit = x / (MicroTileWidth * pTileInfo->bankWidth * numPipes);
2359 UINT_32 yBit = y / (MicroTileHeight * pTileInfo->bankHeight);
2360
2361 //calculate the bank and pipe before rotation and swizzle
2362
2363 switch (tileMode)
2364 {
2365 case ADDR_TM_2D_TILED_THIN1: //fall through
2366 case ADDR_TM_2D_TILED_THICK: //fall through
2367 case ADDR_TM_2D_TILED_XTHICK: //fall through
2368 case ADDR_TM_3D_TILED_THIN1: //fall through
2369 case ADDR_TM_3D_TILED_THICK: //fall through
2370 case ADDR_TM_3D_TILED_XTHICK:
2371 tileSplitRotation = ((pTileInfo->banks / 2) + 1);
2372 break;
2373 default:
2374 tileSplitRotation = 0;
2375 break;
2376 }
2377
2378 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
2379
2380 bank ^= tileSplitRotation * tileSlices;
2381 if (pipeRotation == 0)
2382 {
2383 bank ^= bankRotation * (slice / microTileThickness) + bankSwizzle;
2384 bank %= pTileInfo->banks;
2385 pipe ^= pipeSwizzle;
2386 }
2387 else
2388 {
2389 bank ^= bankRotation * (slice / microTileThickness) / numPipes + bankSwizzle;
2390 bank %= pTileInfo->banks;
2391 pipe ^= pipeRotation * (slice / microTileThickness) + pipeSwizzle;
2392 }
2393
2394 if (pTileInfo->macroAspectRatio == 1)
2395 {
2396 switch (pTileInfo->banks)
2397 {
2398 case 2:
2399 yBit3 = _BIT(bank, 0) ^ _BIT(xBit,0);
2400 break;
2401 case 4:
2402 yBit4 = _BIT(bank, 0) ^ _BIT(xBit,0);
2403 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2404 break;
2405 case 8:
2406 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2407 yBit5 = _BIT(bank, 0) ^ _BIT(xBit,0);
2408 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ yBit5;
2409 break;
2410 case 16:
2411 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3);
2412 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2);
2413 yBit6 = _BIT(bank, 0) ^ _BIT(xBit, 0);
2414 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ yBit6;
2415 break;
2416 default:
2417 break;
2418 }
2419
2420 }
2421 else if (pTileInfo->macroAspectRatio == 2)
2422 {
2423 switch (pTileInfo->banks)
2424 {
2425 case 2: //xBit3 = yBit3^b0
2426 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,0);
2427 break;
2428 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2429 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2430 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2431 break;
2432 case 8: //xBit4, xBit5, yBit5 are known
2433 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2434 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2435 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ _BIT(yBit, 2);
2436 break;
2437 case 16://x4,x5,x6,y6 are known
2438 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3); //x3 = y6 ^ b0
2439 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2440 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = x5 ^ b2
2441 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ _BIT(yBit, 3); //y5=x4^y6^b1
2442 break;
2443 default:
2444 break;
2445 }
2446 }
2447 else if (pTileInfo->macroAspectRatio == 4)
2448 {
2449 switch (pTileInfo->banks)
2450 {
2451 case 4: //yBit3, yBit4
2452 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2453 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,0);
2454 break;
2455 case 8: //xBit5, yBit4, yBit5
2456 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2457 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2458 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit,2);
2459 break;
2460 case 16: //xBit5, xBit6, yBit5, yBit6
2461 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = b0 ^ y6
2462 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = b1 ^ y5 ^ y6;
2463 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = b3 ^ x6;
2464 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = b2 ^ x5;
2465 break;
2466 default:
2467 break;
2468 }
2469 }
2470 else if (pTileInfo->macroAspectRatio == 8)
2471 {
2472 switch (pTileInfo->banks)
2473 {
2474 case 8: //yBit3, yBit4, yBit5
2475 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); //x3 = b0 ^ y5;
2476 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit, 2);//x4 = b1 ^ y4 ^ y5;
2477 xBit5 = _BIT(bank, 2) ^ _BIT(yBit,0);
2478 break;
2479 case 16: //xBit6, yBit4, yBit5, yBit6
2480 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = y6 ^ b0
2481 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = y5 ^ y6 ^ b1
2482 xBit5 = _BIT(bank, 2) ^ _BIT(yBit, 1);//x5 = y4 ^ b2
2483 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2484 break;
2485 default:
2486 break;
2487 }
2488 }
2489
2490 pOutput->xBits = xBit;
2491 pOutput->yBits = yBit;
2492
2493 pOutput->xBit3 = xBit3;
2494 pOutput->xBit4 = xBit4;
2495 pOutput->xBit5 = xBit5;
2496 pOutput->yBit3 = yBit3;
2497 pOutput->yBit4 = yBit4;
2498 pOutput->yBit5 = yBit5;
2499 pOutput->yBit6 = yBit6;
2500 }
2501
2502 /**
2503 ***************************************************************************************************
2504 * EgBasedAddrLib::HwlExtractBankPipeSwizzle
2505 * @brief
2506 * Entry of EgBasedAddrLib ExtractBankPipeSwizzle
2507 * @return
2508 * ADDR_E_RETURNCODE
2509 ***************************************************************************************************
2510 */
2511 ADDR_E_RETURNCODE EgBasedAddrLib::HwlExtractBankPipeSwizzle(
2512 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
2513 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
2514 ) const
2515 {
2516 ExtractBankPipeSwizzle(pIn->base256b,
2517 pIn->pTileInfo,
2518 &pOut->bankSwizzle,
2519 &pOut->pipeSwizzle);
2520
2521 return ADDR_OK;
2522 }
2523
2524
2525 /**
2526 ***************************************************************************************************
2527 * EgBasedAddrLib::HwlCombineBankPipeSwizzle
2528 * @brief
2529 * Combine bank/pipe swizzle
2530 * @return
2531 * ADDR_E_RETURNCODE
2532 ***************************************************************************************************
2533 */
2534 ADDR_E_RETURNCODE EgBasedAddrLib::HwlCombineBankPipeSwizzle(
2535 UINT_32 bankSwizzle, ///< [in] bank swizzle
2536 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2537 ADDR_TILEINFO* pTileInfo, ///< [in] tile info
2538 UINT_64 baseAddr, ///< [in] base address
2539 UINT_32* pTileSwizzle ///< [out] combined swizzle
2540 ) const
2541 {
2542 ADDR_E_RETURNCODE retCode = ADDR_OK;
2543
2544 if (pTileSwizzle)
2545 {
2546 *pTileSwizzle = GetBankPipeSwizzle(bankSwizzle, pipeSwizzle, baseAddr, pTileInfo);
2547 }
2548 else
2549 {
2550 retCode = ADDR_INVALIDPARAMS;
2551 }
2552
2553 return retCode;
2554 }
2555
2556 /**
2557 ***************************************************************************************************
2558 * EgBasedAddrLib::HwlComputeBaseSwizzle
2559 * @brief
2560 * Compute base swizzle
2561 * @return
2562 * ADDR_E_RETURNCODE
2563 ***************************************************************************************************
2564 */
2565 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeBaseSwizzle(
2566 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
2567 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut
2568 ) const
2569 {
2570 UINT_32 bankSwizzle = 0;
2571 UINT_32 pipeSwizzle = 0;
2572 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
2573
2574 ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
2575 ADDR_ASSERT(pIn->pTileInfo);
2576
2577 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2578 static const UINT_8 bankRotationArray[4][16] = {
2579 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2580 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2581 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2582 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2583 };
2584
2585 UINT_32 banks = pTileInfo ? pTileInfo->banks : 2;
2586 UINT_32 hwNumBanks;
2587
2588 // Uses less bank swizzle bits
2589 if (pIn->option.reduceBankBit && banks > 2)
2590 {
2591 banks >>= 1;
2592 }
2593
2594 switch (banks)
2595 {
2596 case 2:
2597 hwNumBanks = 0;
2598 break;
2599 case 4:
2600 hwNumBanks = 1;
2601 break;
2602 case 8:
2603 hwNumBanks = 2;
2604 break;
2605 case 16:
2606 hwNumBanks = 3;
2607 break;
2608 default:
2609 ADDR_ASSERT_ALWAYS();
2610 hwNumBanks = 0;
2611 break;
2612 }
2613
2614 if (pIn->option.genOption == ADDR_SWIZZLE_GEN_LINEAR)
2615 {
2616 bankSwizzle = pIn->surfIndex & (banks - 1);
2617 }
2618 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2619 {
2620 bankSwizzle = bankRotationArray[hwNumBanks][pIn->surfIndex & (banks - 1)];
2621 }
2622
2623 if (IsMacro3dTiled(pIn->tileMode))
2624 {
2625 pipeSwizzle = pIn->surfIndex & (HwlGetPipes(pTileInfo) - 1);
2626 }
2627
2628 return HwlCombineBankPipeSwizzle(bankSwizzle, pipeSwizzle, pTileInfo, 0, &pOut->tileSwizzle);
2629 }
2630
2631 /**
2632 ***************************************************************************************************
2633 * EgBasedAddrLib::ExtractBankPipeSwizzle
2634 * @brief
2635 * Extract bank/pipe swizzle from base256b
2636 * @return
2637 * N/A
2638 ***************************************************************************************************
2639 */
2640 VOID EgBasedAddrLib::ExtractBankPipeSwizzle(
2641 UINT_32 base256b, ///< [in] input base256b register value
2642 ADDR_TILEINFO* pTileInfo, ///< [in] 2D tile parameters. Client must provide all data
2643 UINT_32* pBankSwizzle, ///< [out] bank swizzle
2644 UINT_32* pPipeSwizzle ///< [out] pipe swizzle
2645 ) const
2646 {
2647 UINT_32 bankSwizzle = 0;
2648 UINT_32 pipeSwizzle = 0;
2649
2650 if (base256b != 0)
2651 {
2652 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2653 UINT_32 bankBits = QLog2(pTileInfo->banks);
2654 UINT_32 pipeBits = QLog2(numPipes);
2655 UINT_32 groupBytes = m_pipeInterleaveBytes;
2656 UINT_32 bankInterleave = m_bankInterleave;
2657
2658 pipeSwizzle =
2659 (base256b / (groupBytes >> 8)) & ((1<<pipeBits)-1);
2660
2661 bankSwizzle =
2662 (base256b / (groupBytes >> 8) / numPipes / bankInterleave) & ((1 << bankBits) - 1);
2663 }
2664
2665 *pPipeSwizzle = pipeSwizzle;
2666 *pBankSwizzle = bankSwizzle;
2667 }
2668
2669 /**
2670 ***************************************************************************************************
2671 * EgBasedAddrLib::GetBankPipeSwizzle
2672 * @brief
2673 * Combine bank/pipe swizzle
2674 * @return
2675 * Base256b bits (only filled bank/pipe bits)
2676 ***************************************************************************************************
2677 */
2678 UINT_32 EgBasedAddrLib::GetBankPipeSwizzle(
2679 UINT_32 bankSwizzle, ///< [in] bank swizzle
2680 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2681 UINT_64 baseAddr, ///< [in] base address
2682 ADDR_TILEINFO* pTileInfo ///< [in] tile info
2683 ) const
2684 {
2685 UINT_32 pipeBits = QLog2(HwlGetPipes(pTileInfo));
2686 UINT_32 bankInterleaveBits = QLog2(m_bankInterleave);
2687 UINT_32 tileSwizzle = pipeSwizzle + ((bankSwizzle << bankInterleaveBits) << pipeBits);
2688
2689 baseAddr ^= tileSwizzle * m_pipeInterleaveBytes;
2690 baseAddr >>= 8;
2691
2692 return static_cast<UINT_32>(baseAddr);
2693 }
2694
2695 /**
2696 ***************************************************************************************************
2697 * EgBasedAddrLib::ComputeSliceTileSwizzle
2698 * @brief
2699 * Compute cubemap/3d texture faces/slices tile swizzle
2700 * @return
2701 * Tile swizzle
2702 ***************************************************************************************************
2703 */
2704 UINT_32 EgBasedAddrLib::ComputeSliceTileSwizzle(
2705 AddrTileMode tileMode, ///< [in] Tile mode
2706 UINT_32 baseSwizzle, ///< [in] Base swizzle
2707 UINT_32 slice, ///< [in] Slice index, Cubemap face index, 0 means +X
2708 UINT_64 baseAddr, ///< [in] Base address
2709 ADDR_TILEINFO* pTileInfo ///< [in] Bank structure
2710 ) const
2711 {
2712 UINT_32 tileSwizzle = 0;
2713
2714 if (IsMacroTiled(tileMode)) // Swizzle only for macro tile mode
2715 {
2716 UINT_32 firstSlice = slice / ComputeSurfaceThickness(tileMode);
2717
2718 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2719 UINT_32 numBanks = pTileInfo->banks;
2720
2721 UINT_32 pipeRotation;
2722 UINT_32 bankRotation;
2723
2724 UINT_32 bankSwizzle = 0;
2725 UINT_32 pipeSwizzle = 0;
2726
2727 pipeRotation = ComputePipeRotation(tileMode, numPipes);
2728 bankRotation = ComputeBankRotation(tileMode, numBanks, numPipes);
2729
2730 if (baseSwizzle != 0)
2731 {
2732 ExtractBankPipeSwizzle(baseSwizzle,
2733 pTileInfo,
2734 &bankSwizzle,
2735 &pipeSwizzle);
2736 }
2737
2738 if (pipeRotation == 0) //2D mode
2739 {
2740 bankSwizzle += firstSlice * bankRotation;
2741 bankSwizzle %= numBanks;
2742 }
2743 else //3D mode
2744 {
2745 pipeSwizzle += firstSlice * pipeRotation;
2746 pipeSwizzle %= numPipes;
2747 bankSwizzle += firstSlice * bankRotation / numPipes;
2748 bankSwizzle %= numBanks;
2749 }
2750
2751 tileSwizzle = GetBankPipeSwizzle(bankSwizzle,
2752 pipeSwizzle,
2753 baseAddr,
2754 pTileInfo);
2755 }
2756
2757 return tileSwizzle;
2758 }
2759
2760 /**
2761 ***************************************************************************************************
2762 * EgBasedAddrLib::HwlComputeQbStereoRightSwizzle
2763 *
2764 * @brief
2765 * Compute right eye swizzle
2766 * @return
2767 * swizzle
2768 ***************************************************************************************************
2769 */
2770 UINT_32 EgBasedAddrLib::HwlComputeQbStereoRightSwizzle(
2771 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo ///< [in] Surface info, must be valid
2772 ) const
2773 {
2774 UINT_32 bankBits = 0;
2775 UINT_32 swizzle = 0;
2776
2777 // The assumption is default swizzle for left eye is 0
2778 if (IsMacroTiled(pInfo->tileMode) && pInfo->pStereoInfo && pInfo->pTileInfo)
2779 {
2780 bankBits = ComputeBankFromCoord(0, pInfo->height, 0,
2781 pInfo->tileMode, 0, 0, pInfo->pTileInfo);
2782
2783 if (bankBits)
2784 {
2785 HwlCombineBankPipeSwizzle(bankBits, 0, pInfo->pTileInfo, 0, &swizzle);
2786 }
2787 }
2788
2789 return swizzle;
2790 }
2791
2792 /**
2793 ***************************************************************************************************
2794 * EgBasedAddrLib::ComputeBankFromCoord
2795 *
2796 * @brief
2797 * Compute bank number from coordinates
2798 * @return
2799 * Bank number
2800 ***************************************************************************************************
2801 */
2802 UINT_32 EgBasedAddrLib::ComputeBankFromCoord(
2803 UINT_32 x, ///< [in] x coordinate
2804 UINT_32 y, ///< [in] y coordinate
2805 UINT_32 slice, ///< [in] slice index
2806 AddrTileMode tileMode, ///< [in] tile mode
2807 UINT_32 bankSwizzle, ///< [in] bank swizzle
2808 UINT_32 tileSplitSlice, ///< [in] If the size of the pixel offset is larger than the
2809 /// tile split size, then the pixel will be moved to a separate
2810 /// slice. This value equals pixelOffset / tileSplitBytes
2811 /// in this case. Otherwise this is 0.
2812 ADDR_TILEINFO* pTileInfo ///< [in] tile info
2813 ) const
2814 {
2815 UINT_32 pipes = HwlGetPipes(pTileInfo);
2816 UINT_32 bankBit0 = 0;
2817 UINT_32 bankBit1 = 0;
2818 UINT_32 bankBit2 = 0;
2819 UINT_32 bankBit3 = 0;
2820 UINT_32 sliceRotation;
2821 UINT_32 tileSplitRotation;
2822 UINT_32 bank;
2823 UINT_32 numBanks = pTileInfo->banks;
2824 UINT_32 bankWidth = pTileInfo->bankWidth;
2825 UINT_32 bankHeight = pTileInfo->bankHeight;
2826
2827 UINT_32 tx = x / MicroTileWidth / (bankWidth * pipes);
2828 UINT_32 ty = y / MicroTileHeight / bankHeight;
2829
2830 UINT_32 x3 = _BIT(tx,0);
2831 UINT_32 x4 = _BIT(tx,1);
2832 UINT_32 x5 = _BIT(tx,2);
2833 UINT_32 x6 = _BIT(tx,3);
2834 UINT_32 y3 = _BIT(ty,0);
2835 UINT_32 y4 = _BIT(ty,1);
2836 UINT_32 y5 = _BIT(ty,2);
2837 UINT_32 y6 = _BIT(ty,3);
2838
2839 switch (numBanks)
2840 {
2841 case 16:
2842 bankBit0 = x3 ^ y6;
2843 bankBit1 = x4 ^ y5 ^ y6;
2844 bankBit2 = x5 ^ y4;
2845 bankBit3 = x6 ^ y3;
2846 break;
2847 case 8:
2848 bankBit0 = x3 ^ y5;
2849 bankBit1 = x4 ^ y4 ^ y5;
2850 bankBit2 = x5 ^ y3;
2851 break;
2852 case 4:
2853 bankBit0 = x3 ^ y4;
2854 bankBit1 = x4 ^ y3;
2855 break;
2856 case 2:
2857 bankBit0 = x3 ^ y3;
2858 break;
2859 default:
2860 ADDR_ASSERT_ALWAYS();
2861 break;
2862 }
2863
2864 bank = bankBit0 | (bankBit1 << 1) | (bankBit2 << 2) | (bankBit3 << 3);
2865
2866 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
2867
2868 bank = HwlPreAdjustBank((x / MicroTileWidth), bank, pTileInfo);
2869 //
2870 // Compute bank rotation for the slice.
2871 //
2872 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
2873
2874 switch (tileMode)
2875 {
2876 case ADDR_TM_2D_TILED_THIN1: // fall through
2877 case ADDR_TM_2D_TILED_THICK: // fall through
2878 case ADDR_TM_2D_TILED_XTHICK:
2879 sliceRotation = ((numBanks / 2) - 1) * (slice / microTileThickness);
2880 break;
2881 case ADDR_TM_3D_TILED_THIN1: // fall through
2882 case ADDR_TM_3D_TILED_THICK: // fall through
2883 case ADDR_TM_3D_TILED_XTHICK:
2884 sliceRotation =
2885 Max(1u, (pipes / 2) - 1) * (slice / microTileThickness) / pipes;
2886 break;
2887 default:
2888 sliceRotation = 0;
2889 break;
2890 }
2891
2892
2893 //
2894 // Compute bank rotation for the tile split slice.
2895 //
2896 // The sample slice will be non-zero if samples must be split across multiple slices.
2897 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
2898 // the split size (set in GB_ADDR_CONFIG).
2899 //
2900 switch (tileMode)
2901 {
2902 case ADDR_TM_2D_TILED_THIN1: //fall through
2903 case ADDR_TM_3D_TILED_THIN1: //fall through
2904 case ADDR_TM_PRT_2D_TILED_THIN1: //fall through
2905 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
2906 tileSplitRotation = ((numBanks / 2) + 1) * tileSplitSlice;
2907 break;
2908 default:
2909 tileSplitRotation = 0;
2910 break;
2911 }
2912
2913 //
2914 // Apply bank rotation for the slice and tile split slice.
2915 //
2916 bank ^= bankSwizzle + sliceRotation;
2917 bank ^= tileSplitRotation;
2918
2919 bank &= (numBanks - 1);
2920
2921 return bank;
2922 }
2923
2924 /**
2925 ***************************************************************************************************
2926 * EgBasedAddrLib::ComputeBankFromAddr
2927 *
2928 * @brief
2929 * Compute the bank number from an address
2930 * @return
2931 * Bank number
2932 ***************************************************************************************************
2933 */
2934 UINT_32 EgBasedAddrLib::ComputeBankFromAddr(
2935 UINT_64 addr, ///< [in] address
2936 UINT_32 numBanks, ///< [in] number of banks
2937 UINT_32 numPipes ///< [in] number of pipes
2938 ) const
2939 {
2940 UINT_32 bank;
2941
2942 //
2943 // The LSBs of the address are arranged as follows:
2944 // bank | bankInterleave | pipe | pipeInterleave
2945 //
2946 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
2947 // mask the bank bits.
2948 //
2949 bank = static_cast<UINT_32>(
2950 (addr >> Log2(m_pipeInterleaveBytes * numPipes * m_bankInterleave)) &
2951 (numBanks - 1)
2952 );
2953
2954 return bank;
2955 }
2956
2957 /**
2958 ***************************************************************************************************
2959 * EgBasedAddrLib::ComputePipeRotation
2960 *
2961 * @brief
2962 * Compute pipe rotation value
2963 * @return
2964 * Pipe rotation
2965 ***************************************************************************************************
2966 */
2967 UINT_32 EgBasedAddrLib::ComputePipeRotation(
2968 AddrTileMode tileMode, ///< [in] tile mode
2969 UINT_32 numPipes ///< [in] number of pipes
2970 ) const
2971 {
2972 UINT_32 rotation;
2973
2974 switch (tileMode)
2975 {
2976 case ADDR_TM_3D_TILED_THIN1: //fall through
2977 case ADDR_TM_3D_TILED_THICK: //fall through
2978 case ADDR_TM_3D_TILED_XTHICK: //fall through
2979 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
2980 case ADDR_TM_PRT_3D_TILED_THICK:
2981 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);
2982 break;
2983 default:
2984 rotation = 0;
2985 }
2986
2987 return rotation;
2988 }
2989
2990
2991
2992 /**
2993 ***************************************************************************************************
2994 * EgBasedAddrLib::ComputeBankRotation
2995 *
2996 * @brief
2997 * Compute bank rotation value
2998 * @return
2999 * Bank rotation
3000 ***************************************************************************************************
3001 */
3002 UINT_32 EgBasedAddrLib::ComputeBankRotation(
3003 AddrTileMode tileMode, ///< [in] tile mode
3004 UINT_32 numBanks, ///< [in] number of banks
3005 UINT_32 numPipes ///< [in] number of pipes
3006 ) const
3007 {
3008 UINT_32 rotation;
3009
3010 switch (tileMode)
3011 {
3012 case ADDR_TM_2D_TILED_THIN1: // fall through
3013 case ADDR_TM_2D_TILED_THICK: // fall through
3014 case ADDR_TM_2D_TILED_XTHICK:
3015 case ADDR_TM_PRT_2D_TILED_THIN1:
3016 case ADDR_TM_PRT_2D_TILED_THICK:
3017 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3018 rotation = numBanks / 2 - 1;
3019 break;
3020 case ADDR_TM_3D_TILED_THIN1: // fall through
3021 case ADDR_TM_3D_TILED_THICK: // fall through
3022 case ADDR_TM_3D_TILED_XTHICK:
3023 case ADDR_TM_PRT_3D_TILED_THIN1:
3024 case ADDR_TM_PRT_3D_TILED_THICK:
3025 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1); // rotate pipes & banks
3026 break;
3027 default:
3028 rotation = 0;
3029 }
3030
3031 return rotation;
3032 }
3033
3034
3035 /**
3036 ***************************************************************************************************
3037 * EgBasedAddrLib::ComputeHtileBytes
3038 *
3039 * @brief
3040 * Compute htile size in bytes
3041 *
3042 * @return
3043 * Htile size in bytes
3044 ***************************************************************************************************
3045 */
3046 UINT_64 EgBasedAddrLib::ComputeHtileBytes(
3047 UINT_32 pitch, ///< [in] pitch
3048 UINT_32 height, ///< [in] height
3049 UINT_32 bpp, ///< [in] bits per pixel
3050 BOOL_32 isLinear, ///< [in] if it is linear mode
3051 UINT_32 numSlices, ///< [in] number of slices
3052 UINT_64* sliceBytes, ///< [out] bytes per slice
3053 UINT_32 baseAlign ///< [in] base alignments
3054 ) const
3055 {
3056 UINT_64 surfBytes;
3057
3058 const UINT_64 HtileCacheLineSize = BITS_TO_BYTES(HtileCacheBits);
3059
3060 *sliceBytes = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp / 64);
3061
3062 if (m_configFlags.useHtileSliceAlign)
3063 {
3064 // Align the sliceSize to htilecachelinesize * pipes at first
3065 *sliceBytes = PowTwoAlign(*sliceBytes, HtileCacheLineSize * m_pipes);
3066 surfBytes = *sliceBytes * numSlices;
3067 }
3068 else
3069 {
3070 // Align the surfSize to htilecachelinesize * pipes at last
3071 surfBytes = *sliceBytes * numSlices;
3072 surfBytes = PowTwoAlign(surfBytes, HtileCacheLineSize * m_pipes);
3073 }
3074
3075 return surfBytes;
3076 }
3077
3078 /**
3079 ***************************************************************************************************
3080 * EgBasedAddrLib::DispatchComputeFmaskInfo
3081 *
3082 * @brief
3083 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3084 * meanwhile output suitable tile mode and alignments as well. Results are returned
3085 * through output parameters.
3086 *
3087 * @return
3088 * ADDR_E_RETURNCODE
3089 ***************************************************************************************************
3090 */
3091 ADDR_E_RETURNCODE EgBasedAddrLib::DispatchComputeFmaskInfo(
3092 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
3093 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut) ///< [out] output structure
3094 {
3095 ADDR_E_RETURNCODE retCode = ADDR_OK;
3096
3097 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn = {0};
3098 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut = {0};
3099
3100 // Setup input structure
3101 surfIn.tileMode = pIn->tileMode;
3102 surfIn.width = pIn->pitch;
3103 surfIn.height = pIn->height;
3104 surfIn.numSlices = pIn->numSlices;
3105 surfIn.pTileInfo = pIn->pTileInfo;
3106 surfIn.tileType = ADDR_NON_DISPLAYABLE;
3107 surfIn.flags.fmask = 1;
3108
3109 // Setup output structure
3110 surfOut.pTileInfo = pOut->pTileInfo;
3111
3112 // Setup hwl specific fields
3113 HwlFmaskPreThunkSurfInfo(pIn, pOut, &surfIn, &surfOut);
3114
3115 surfIn.bpp = HwlComputeFmaskBits(pIn, &surfIn.numSamples);
3116
3117 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3118 surfOut.numSamples = surfIn.numSamples;
3119
3120 retCode = HwlComputeSurfaceInfo(&surfIn, &surfOut);
3121
3122 // Save bpp field for surface dump support
3123 surfOut.bpp = surfIn.bpp;
3124
3125 if (retCode == ADDR_OK)
3126 {
3127 pOut->bpp = surfOut.bpp;
3128 pOut->pitch = surfOut.pitch;
3129 pOut->height = surfOut.height;
3130 pOut->numSlices = surfOut.depth;
3131 pOut->fmaskBytes = surfOut.surfSize;
3132 pOut->baseAlign = surfOut.baseAlign;
3133 pOut->pitchAlign = surfOut.pitchAlign;
3134 pOut->heightAlign = surfOut.heightAlign;
3135
3136 if (surfOut.depth > 1)
3137 {
3138 // For fmask, expNumSlices is stored in depth.
3139 pOut->sliceSize = surfOut.surfSize / surfOut.depth;
3140 }
3141 else
3142 {
3143 pOut->sliceSize = surfOut.surfSize;
3144 }
3145
3146 // Save numSamples field for surface dump support
3147 pOut->numSamples = surfOut.numSamples;
3148
3149 HwlFmaskPostThunkSurfInfo(&surfOut, pOut);
3150 }
3151
3152 return retCode;
3153 }
3154
3155 /**
3156 ***************************************************************************************************
3157 * EgBasedAddrLib::HwlFmaskSurfaceInfo
3158 * @brief
3159 * Entry of EgBasedAddrLib ComputeFmaskInfo
3160 * @return
3161 * ADDR_E_RETURNCODE
3162 ***************************************************************************************************
3163 */
3164 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskInfo(
3165 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
3166 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
3167 )
3168 {
3169 ADDR_E_RETURNCODE retCode = ADDR_OK;
3170
3171 ADDR_TILEINFO tileInfo = {0};
3172
3173 // Use internal tile info if pOut does not have a valid pTileInfo
3174 if (pOut->pTileInfo == NULL)
3175 {
3176 pOut->pTileInfo = &tileInfo;
3177 }
3178
3179 retCode = DispatchComputeFmaskInfo(pIn, pOut);
3180
3181 if (retCode == ADDR_OK)
3182 {
3183 pOut->tileIndex =
3184 HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
3185 pOut->tileIndex);
3186 }
3187
3188 // Resets pTileInfo to NULL if the internal tile info is used
3189 if (pOut->pTileInfo == &tileInfo)
3190 {
3191 pOut->pTileInfo = NULL;
3192 }
3193
3194 return retCode;
3195 }
3196
3197 /**
3198 ***************************************************************************************************
3199 * EgBasedAddrLib::HwlComputeFmaskAddrFromCoord
3200 * @brief
3201 * Entry of EgBasedAddrLib ComputeFmaskAddrFromCoord
3202 * @return
3203 * ADDR_E_RETURNCODE
3204 ***************************************************************************************************
3205 */
3206 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskAddrFromCoord(
3207 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3208 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3209 ) const
3210 {
3211 ADDR_E_RETURNCODE retCode = ADDR_OK;
3212
3213 #if ADDR_AM_BUILD
3214 if ((pIn->x > pIn->pitch) ||
3215 (pIn->y > pIn->height) ||
3216 (pIn->numSamples > m_maxSamples) ||
3217 (pIn->sample >= m_maxSamples))
3218 {
3219 retCode = ADDR_INVALIDPARAMS;
3220 }
3221 else
3222 {
3223 pOut->addr = DispatchComputeFmaskAddrFromCoord(pIn, pOut);
3224 }
3225 #endif
3226
3227 return retCode;
3228 }
3229
3230 /**
3231 ***************************************************************************************************
3232 * EgBasedAddrLib::HwlComputeFmaskCoordFromAddr
3233 * @brief
3234 * Entry of EgBasedAddrLib ComputeFmaskCoordFromAddr
3235 * @return
3236 * ADDR_E_RETURNCODE
3237 ***************************************************************************************************
3238 */
3239 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeFmaskCoordFromAddr(
3240 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
3241 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
3242 ) const
3243 {
3244 ADDR_E_RETURNCODE retCode = ADDR_OK;
3245
3246 #if ADDR_AM_BUILD
3247 if ((pIn->bitPosition >= 8) ||
3248 (pIn->numSamples > m_maxSamples))
3249 {
3250 retCode = ADDR_INVALIDPARAMS;
3251 }
3252 else
3253 {
3254 DispatchComputeFmaskCoordFromAddr(pIn, pOut);
3255 }
3256 #endif
3257
3258 return retCode;
3259 }
3260
3261 #if ADDR_AM_BUILD
3262 /**
3263 ***************************************************************************************************
3264 * EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord
3265 *
3266 * @brief
3267 * Computes the FMASK address and bit position from a coordinate.
3268 * @return
3269 * The byte address
3270 ***************************************************************************************************
3271 */
3272 UINT_64 EgBasedAddrLib::DispatchComputeFmaskAddrFromCoord(
3273 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3274 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3275 ) const
3276 {
3277 UINT_32 x = pIn->x;
3278 UINT_32 y = pIn->y;
3279 UINT_32 slice = pIn->slice;
3280 UINT_32 sample = pIn->sample;
3281 UINT_32 plane = pIn->plane;
3282 UINT_32 pitch = pIn->pitch;
3283 UINT_32 height = pIn->height;
3284 UINT_32 numSamples = pIn->numSamples;
3285 AddrTileMode tileMode = pIn->tileMode;
3286 BOOL_32 ignoreSE = pIn->ignoreSE;
3287 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
3288 BOOL_32 resolved = pIn->resolved;
3289
3290 UINT_32* pBitPosition = &pOut->bitPosition;
3291 UINT_64 addr = 0;
3292
3293 ADDR_ASSERT(numSamples > 1);
3294 ADDR_ASSERT(ComputeSurfaceThickness(tileMode) == 1);
3295
3296 switch (tileMode)
3297 {
3298 case ADDR_TM_1D_TILED_THIN1:
3299 addr = ComputeFmaskAddrFromCoordMicroTiled(x,
3300 y,
3301 slice,
3302 sample,
3303 plane,
3304 pitch,
3305 height,
3306 numSamples,
3307 tileMode,
3308 resolved,
3309 pBitPosition);
3310 break;
3311 case ADDR_TM_2D_TILED_THIN1: //fall through
3312 case ADDR_TM_3D_TILED_THIN1:
3313 UINT_32 pipeSwizzle;
3314 UINT_32 bankSwizzle;
3315
3316 if (m_configFlags.useCombinedSwizzle)
3317 {
3318 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
3319 &bankSwizzle, &pipeSwizzle);
3320 }
3321 else
3322 {
3323 pipeSwizzle = pIn->pipeSwizzle;
3324 bankSwizzle = pIn->bankSwizzle;
3325 }
3326
3327 addr = ComputeFmaskAddrFromCoordMacroTiled(x,
3328 y,
3329 slice,
3330 sample,
3331 plane,
3332 pitch,
3333 height,
3334 numSamples,
3335 tileMode,
3336 pipeSwizzle,
3337 bankSwizzle,
3338 ignoreSE,
3339 pTileInfo,
3340 resolved,
3341 pBitPosition);
3342 break;
3343 default:
3344 *pBitPosition = 0;
3345 break;
3346 }
3347
3348 return addr;
3349 }
3350
3351 /**
3352 ***************************************************************************************************
3353 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled
3354 *
3355 * @brief
3356 * Computes the FMASK address and bit position from a coordinate for 1D tilied (micro
3357 * tiled)
3358 * @return
3359 * The byte address
3360 ***************************************************************************************************
3361 */
3362 UINT_64 EgBasedAddrLib::ComputeFmaskAddrFromCoordMicroTiled(
3363 UINT_32 x, ///< [in] x coordinate
3364 UINT_32 y, ///< [in] y coordinate
3365 UINT_32 slice, ///< [in] slice index
3366 UINT_32 sample, ///< [in] sample number
3367 UINT_32 plane, ///< [in] plane number
3368 UINT_32 pitch, ///< [in] surface pitch in pixels
3369 UINT_32 height, ///< [in] surface height in pixels
3370 UINT_32 numSamples, ///< [in] number of samples
3371 AddrTileMode tileMode, ///< [in] tile mode
3372 BOOL_32 resolved, ///< [in] TRUE if this is for resolved fmask
3373 UINT_32* pBitPosition ///< [out] pointer to returned bit position
3374 ) const
3375 {
3376 UINT_64 addr = 0;
3377 UINT_32 effectiveBpp;
3378 UINT_32 effectiveSamples;
3379
3380 //
3381 // 2xAA use the same layout as 4xAA
3382 //
3383 if (numSamples == 2)
3384 {
3385 numSamples = 4;
3386 }
3387
3388 //
3389 // Compute the number of planes.
3390 //
3391 if (!resolved)
3392 {
3393 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
3394 effectiveBpp = numSamples;
3395
3396 //
3397 // Compute the address just like a color surface with numSamples bits per element and
3398 // numPlanes samples.
3399 //
3400 addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
3401 y,
3402 slice,
3403 plane, // sample
3404 effectiveBpp,
3405 pitch,
3406 height,
3407 effectiveSamples,
3408 tileMode,
3409 ADDR_NON_DISPLAYABLE,
3410 FALSE,
3411 pBitPosition);
3412
3413 //
3414 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3415 //
3416
3417 //
3418 // Compute the pixel index with in the micro tile
3419 //
3420 UINT_32 pixelIndex = ComputePixelIndexWithinMicroTile(x % 8,
3421 y % 8,
3422 slice,
3423 1,
3424 tileMode,
3425 ADDR_NON_DISPLAYABLE);
3426
3427 *pBitPosition = ((pixelIndex * numSamples) + sample) & (BITS_PER_BYTE-1);
3428
3429 UINT_64 bitAddr = BYTES_TO_BITS(addr) + *pBitPosition;
3430
3431 addr = bitAddr / 8;
3432 }
3433 else
3434 {
3435 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
3436 effectiveSamples = 1;
3437
3438 //
3439 // Compute the address just like a color surface with numSamples bits per element and
3440 // numPlanes samples.
3441 //
3442 addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
3443 y,
3444 slice,
3445 sample,
3446 effectiveBpp,
3447 pitch,
3448 height,
3449 effectiveSamples,
3450 tileMode,
3451 ADDR_NON_DISPLAYABLE,
3452 TRUE,
3453 pBitPosition);
3454 }
3455
3456 return addr;
3457 }
3458
3459 /**
3460 ***************************************************************************************************
3461 * EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled
3462 *
3463 * @brief
3464 * Computes the FMASK address and bit position from a coordinate for 2D tilied (macro
3465 * tiled)
3466 * @return
3467 * The byte address
3468 ***************************************************************************************************
3469 */
3470 UINT_64 EgBasedAddrLib::ComputeFmaskAddrFromCoordMacroTiled(
3471 UINT_32 x, ///< [in] x coordinate
3472 UINT_32 y, ///< [in] y coordinate
3473 UINT_32 slice, ///< [in] slice index
3474 UINT_32 sample, ///< [in] sample number
3475 UINT_32 plane, ///< [in] plane number
3476 UINT_32 pitch, ///< [in] surface pitch in pixels
3477 UINT_32 height, ///< [in] surface height in pixels
3478 UINT_32 numSamples, ///< [in] number of samples
3479 AddrTileMode tileMode, ///< [in] tile mode
3480 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
3481 UINT_32 bankSwizzle, ///< [in] bank swizzle
3482 BOOL_32 ignoreSE, ///< [in] TRUE if ignore shader engine
3483 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure.**All fields to be valid on entry**
3484 BOOL_32 resolved, ///< [in] TRUE if this is for resolved fmask
3485 UINT_32* pBitPosition ///< [out] pointer to returned bit position
3486 ) const
3487 {
3488 UINT_64 addr = 0;
3489 UINT_32 effectiveBpp;
3490 UINT_32 effectiveSamples;
3491
3492 //
3493 // 2xAA use the same layout as 4xAA
3494 //
3495 if (numSamples == 2)
3496 {
3497 numSamples = 4;
3498 }
3499
3500 //
3501 // Compute the number of planes.
3502 //
3503 if (!resolved)
3504 {
3505 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
3506 effectiveBpp = numSamples;
3507
3508 //
3509 // Compute the address just like a color surface with numSamples bits per element and
3510 // numPlanes samples.
3511 //
3512 addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
3513 y,
3514 slice,
3515 plane, // sample
3516 effectiveBpp,
3517 pitch,
3518 height,
3519 effectiveSamples,
3520 tileMode,
3521 ADDR_NON_DISPLAYABLE,// isdisp
3522 ignoreSE,// ignore_shader
3523 FALSE,// depth_sample_order
3524 pipeSwizzle,
3525 bankSwizzle,
3526 pTileInfo,
3527 pBitPosition);
3528
3529 //
3530 // Compute the real bit position. Each (sample, plane) is stored with one bit per sample.
3531 //
3532
3533
3534 //
3535 // Compute the pixel index with in the micro tile
3536 //
3537 UINT_32 pixelIndex = ComputePixelIndexWithinMicroTile(x ,
3538 y ,
3539 slice,
3540 effectiveBpp,
3541 tileMode,
3542 ADDR_NON_DISPLAYABLE);
3543
3544 *pBitPosition = ((pixelIndex * numSamples) + sample) & (BITS_PER_BYTE-1);
3545
3546 UINT_64 bitAddr = BYTES_TO_BITS(addr) + *pBitPosition;
3547
3548 addr = bitAddr / 8;
3549
3550 }
3551 else
3552 {
3553 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
3554 effectiveSamples = 1;
3555
3556 //
3557 // Compute the address just like a color surface with numSamples bits per element and
3558 // numPlanes samples.
3559 //
3560 addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
3561 y,
3562 slice,
3563 sample,
3564 effectiveBpp,
3565 pitch,
3566 height,
3567 effectiveSamples,
3568 tileMode,
3569 ADDR_NON_DISPLAYABLE,
3570 ignoreSE,
3571 TRUE,
3572 pipeSwizzle,
3573 bankSwizzle,
3574 pTileInfo,
3575 pBitPosition);
3576 }
3577
3578 return addr;
3579 }
3580
3581 /**
3582 ***************************************************************************************************
3583 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled
3584 *
3585 * @brief
3586 * Compute (x,y,slice,sample,plane) coordinates from fmask address
3587 * @return
3588 * N/A
3589 *
3590 ***************************************************************************************************
3591 */
3592 VOID EgBasedAddrLib::ComputeFmaskCoordFromAddrMicroTiled(
3593 UINT_64 addr, ///< [in] byte address
3594 UINT_32 bitPosition,///< [in] bit position
3595 UINT_32 pitch, ///< [in] pitch in pixels
3596 UINT_32 height, ///< [in] height in pixels
3597 UINT_32 numSamples, ///< [in] number of samples (of color buffer)
3598 AddrTileMode tileMode, ///< [in] tile mode
3599 BOOL_32 resolved, ///< [in] TRUE if it is resolved fmask
3600 UINT_32* pX, ///< [out] X coord
3601 UINT_32* pY, ///< [out] Y coord
3602 UINT_32* pSlice, ///< [out] slice index
3603 UINT_32* pSample, ///< [out] sample index
3604 UINT_32* pPlane ///< [out] plane index
3605 ) const
3606 {
3607 UINT_32 effectiveBpp;
3608 UINT_32 effectiveSamples;
3609
3610 // 2xAA use the same layout as 4xAA
3611 if (numSamples == 2)
3612 {
3613 numSamples = 4;
3614 }
3615
3616 if (!resolved)
3617 {
3618 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
3619 effectiveBpp = numSamples;
3620
3621 ComputeSurfaceCoordFromAddrMicroTiled(addr,
3622 bitPosition,
3623 effectiveBpp,
3624 pitch,
3625 height,
3626 effectiveSamples,
3627 tileMode,
3628 0, // tileBase
3629 0, // compBits
3630 pX,
3631 pY,
3632 pSlice,
3633 pPlane,
3634 ADDR_NON_DISPLAYABLE, // microTileType
3635 FALSE // isDepthSampleOrder
3636 );
3637
3638
3639 if ( pSample )
3640 {
3641 *pSample = bitPosition % numSamples;
3642 }
3643 }
3644 else
3645 {
3646 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
3647 effectiveSamples = 1;
3648
3649 ComputeSurfaceCoordFromAddrMicroTiled(addr,
3650 bitPosition,
3651 effectiveBpp,
3652 pitch,
3653 height,
3654 effectiveSamples,
3655 tileMode,
3656 0, // tileBase
3657 0, // compBits
3658 pX,
3659 pY,
3660 pSlice,
3661 pSample,
3662 ADDR_NON_DISPLAYABLE, // microTileType
3663 TRUE // isDepthSampleOrder
3664 );
3665 }
3666 }
3667
3668 /**
3669 ***************************************************************************************************
3670 * EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled
3671 *
3672 * @brief
3673 * Compute (x,y,slice,sample,plane) coordinates from
3674 * fmask address
3675 * @return
3676 * N/A
3677 *
3678 ***************************************************************************************************
3679 */
3680 VOID EgBasedAddrLib::ComputeFmaskCoordFromAddrMacroTiled(
3681 UINT_64 addr, ///< [in] byte address
3682 UINT_32 bitPosition,///< [in] bit position
3683 UINT_32 pitch, ///< [in] pitch in pixels
3684 UINT_32 height, ///< [in] height in pixels
3685 UINT_32 numSamples, ///< [in] number of samples (of color buffer)
3686 AddrTileMode tileMode, ///< [in] tile mode
3687 UINT_32 pipeSwizzle,///< [in] pipe swizzle
3688 UINT_32 bankSwizzle,///< [in] bank swizzle
3689 BOOL_32 ignoreSE, ///< [in] TRUE if ignore shader engine
3690 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry**
3691 BOOL_32 resolved, ///< [in] TRUE if it is resolved fmask
3692 UINT_32* pX, ///< [out] X coord
3693 UINT_32* pY, ///< [out] Y coord
3694 UINT_32* pSlice, ///< [out] slice index
3695 UINT_32* pSample, ///< [out] sample index
3696 UINT_32* pPlane ///< [out] plane index
3697 ) const
3698 {
3699 UINT_32 effectiveBpp;
3700 UINT_32 effectiveSamples;
3701
3702 // 2xAA use the same layout as 4xAA
3703 if (numSamples == 2)
3704 {
3705 numSamples = 4;
3706 }
3707
3708 //
3709 // Compute the number of planes.
3710 //
3711 if (!resolved)
3712 {
3713 effectiveSamples = ComputeFmaskNumPlanesFromNumSamples(numSamples);
3714 effectiveBpp = numSamples;
3715
3716 ComputeSurfaceCoordFromAddrMacroTiled(addr,
3717 bitPosition,
3718 effectiveBpp,
3719 pitch,
3720 height,
3721 effectiveSamples,
3722 tileMode,
3723 0, // No tileBase
3724 0, // No compBits
3725 ADDR_NON_DISPLAYABLE,
3726 ignoreSE,
3727 FALSE,
3728 pipeSwizzle,
3729 bankSwizzle,
3730 pTileInfo,
3731 pX,
3732 pY,
3733 pSlice,
3734 pPlane);
3735
3736 if (pSample)
3737 {
3738 *pSample = bitPosition % numSamples;
3739 }
3740 }
3741 else
3742 {
3743 effectiveBpp = ComputeFmaskResolvedBppFromNumSamples(numSamples);
3744 effectiveSamples = 1;
3745
3746 ComputeSurfaceCoordFromAddrMacroTiled(addr,
3747 bitPosition,
3748 effectiveBpp,
3749 pitch,
3750 height,
3751 effectiveSamples,
3752 tileMode,
3753 0, // No tileBase
3754 0, // No compBits
3755 ADDR_NON_DISPLAYABLE,
3756 ignoreSE,
3757 TRUE,
3758 pipeSwizzle,
3759 bankSwizzle,
3760 pTileInfo,
3761 pX,
3762 pY,
3763 pSlice,
3764 pSample);
3765 }
3766 }
3767
3768 /**
3769 ***************************************************************************************************
3770 * EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr
3771 *
3772 * @brief
3773 * Compute (x,y,slice,sample,plane) coordinates from
3774 * fmask address
3775 * @return
3776 * N/A
3777 *
3778 ***************************************************************************************************
3779 */
3780 VOID EgBasedAddrLib::DispatchComputeFmaskCoordFromAddr(
3781 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
3782 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
3783 ) const
3784 {
3785 UINT_64 addr = pIn->addr;
3786 UINT_32 bitPosition = pIn->bitPosition;
3787 UINT_32 pitch = pIn->pitch;
3788 UINT_32 height = pIn->height;
3789 UINT_32 numSamples = pIn->numSamples;
3790 AddrTileMode tileMode = pIn->tileMode;
3791 BOOL_32 ignoreSE = pIn->ignoreSE;
3792 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
3793 BOOL_32 resolved = pIn->resolved;
3794
3795 UINT_32* pX = &pOut->x;
3796 UINT_32* pY = &pOut->y;
3797 UINT_32* pSlice = &pOut->slice;
3798 UINT_32* pSample = &pOut->sample;
3799 UINT_32* pPlane = &pOut->plane;
3800
3801 switch (tileMode)
3802 {
3803 case ADDR_TM_1D_TILED_THIN1:
3804 ComputeFmaskCoordFromAddrMicroTiled(addr,
3805 bitPosition,
3806 pitch,
3807 height,
3808 numSamples,
3809 tileMode,
3810 resolved,
3811 pX,
3812 pY,
3813 pSlice,
3814 pSample,
3815 pPlane);
3816 break;
3817 case ADDR_TM_2D_TILED_THIN1://fall through
3818 case ADDR_TM_3D_TILED_THIN1:
3819 UINT_32 pipeSwizzle;
3820 UINT_32 bankSwizzle;
3821
3822 if (m_configFlags.useCombinedSwizzle)
3823 {
3824 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
3825 &bankSwizzle, &pipeSwizzle);
3826 }
3827 else
3828 {
3829 pipeSwizzle = pIn->pipeSwizzle;
3830 bankSwizzle = pIn->bankSwizzle;
3831 }
3832
3833 ComputeFmaskCoordFromAddrMacroTiled(addr,
3834 bitPosition,
3835 pitch,
3836 height,
3837 numSamples,
3838 tileMode,
3839 pipeSwizzle,
3840 bankSwizzle,
3841 ignoreSE,
3842 pTileInfo,
3843 resolved,
3844 pX,
3845 pY,
3846 pSlice,
3847 pSample,
3848 pPlane);
3849 break;
3850 default:
3851 ADDR_ASSERT_ALWAYS();
3852 break;
3853
3854 }
3855 }
3856 #endif
3857
3858 /**
3859 ***************************************************************************************************
3860 * EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples
3861 *
3862 * @brief
3863 * Compute fmask number of planes from number of samples
3864 *
3865 * @return
3866 * Number of planes
3867 ***************************************************************************************************
3868 */
3869 UINT_32 EgBasedAddrLib::ComputeFmaskNumPlanesFromNumSamples(
3870 UINT_32 numSamples) ///< [in] number of samples
3871 {
3872 UINT_32 numPlanes;
3873
3874 //
3875 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3876 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3877 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3878 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3879 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3880 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3881 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3882 // This was changed for R8xx to simplify the logic in the CB.
3883 //
3884 switch (numSamples)
3885 {
3886 case 2:
3887 numPlanes = 1;
3888 break;
3889 case 4:
3890 numPlanes = 2;
3891 break;
3892 case 8:
3893 numPlanes = 4;
3894 break;
3895 default:
3896 ADDR_UNHANDLED_CASE();
3897 numPlanes = 0;
3898 break;
3899 }
3900 return numPlanes;
3901 }
3902
3903 /**
3904 ***************************************************************************************************
3905 * EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples
3906 *
3907 * @brief
3908 * Compute resolved fmask effective bpp based on number of samples
3909 *
3910 * @return
3911 * bpp
3912 ***************************************************************************************************
3913 */
3914 UINT_32 EgBasedAddrLib::ComputeFmaskResolvedBppFromNumSamples(
3915 UINT_32 numSamples) ///< number of samples
3916 {
3917 UINT_32 bpp;
3918
3919 //
3920 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3921 // so that the texture unit can read compressed multi-sample color data.
3922 // These surfaces store each index value packed per element.
3923 // Each element contains at least num_samples * log2(num_samples) bits.
3924 // Resolved FMASK surfaces are addressed as follows:
3925 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3926 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3927 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3928
3929 switch (numSamples)
3930 {
3931 case 2:
3932 bpp = 8;
3933 break;
3934 case 4:
3935 bpp = 8;
3936 break;
3937 case 8:
3938 bpp = 32;
3939 break;
3940 default:
3941 ADDR_UNHANDLED_CASE();
3942 bpp = 0;
3943 break;
3944 }
3945 return bpp;
3946 }
3947
3948 /**
3949 ***************************************************************************************************
3950 * EgBasedAddrLib::IsTileInfoAllZero
3951 *
3952 * @brief
3953 * Return TRUE if all field are zero
3954 * @note
3955 * Since NULL input is consider to be all zero
3956 ***************************************************************************************************
3957 */
3958 BOOL_32 EgBasedAddrLib::IsTileInfoAllZero(
3959 ADDR_TILEINFO* pTileInfo)
3960 {
3961 BOOL_32 allZero = TRUE;
3962
3963 if (pTileInfo)
3964 {
3965 if ((pTileInfo->banks != 0) ||
3966 (pTileInfo->bankWidth != 0) ||
3967 (pTileInfo->bankHeight != 0) ||
3968 (pTileInfo->macroAspectRatio != 0) ||
3969 (pTileInfo->tileSplitBytes != 0) ||
3970 (pTileInfo->pipeConfig != 0)
3971 )
3972 {
3973 allZero = FALSE;
3974 }
3975 }
3976
3977 return allZero;
3978 }
3979
3980 /**
3981 ***************************************************************************************************
3982 * EgBasedAddrLib::HwlTileInfoEqual
3983 *
3984 * @brief
3985 * Return TRUE if all field are equal
3986 * @note
3987 * Only takes care of current HWL's data
3988 ***************************************************************************************************
3989 */
3990 BOOL_32 EgBasedAddrLib::HwlTileInfoEqual(
3991 const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
3992 const ADDR_TILEINFO* pRight ///<[in] Right compare operand
3993 ) const
3994 {
3995 BOOL_32 equal = FALSE;
3996
3997 if (pLeft->banks == pRight->banks &&
3998 pLeft->bankWidth == pRight->bankWidth &&
3999 pLeft->bankHeight == pRight->bankHeight &&
4000 pLeft->macroAspectRatio == pRight->macroAspectRatio &&
4001 pLeft->tileSplitBytes == pRight->tileSplitBytes)
4002 {
4003 equal = TRUE;
4004 }
4005
4006 return equal;
4007 }
4008
4009 /**
4010 ***************************************************************************************************
4011 * EgBasedAddrLib::HwlConvertTileInfoToHW
4012 * @brief
4013 * Entry of EgBasedAddrLib ConvertTileInfoToHW
4014 * @return
4015 * ADDR_E_RETURNCODE
4016 ***************************************************************************************************
4017 */
4018 ADDR_E_RETURNCODE EgBasedAddrLib::HwlConvertTileInfoToHW(
4019 const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
4020 ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
4021 ) const
4022 {
4023 ADDR_E_RETURNCODE retCode = ADDR_OK;
4024
4025 ADDR_TILEINFO *pTileInfoIn = pIn->pTileInfo;
4026 ADDR_TILEINFO *pTileInfoOut = pOut->pTileInfo;
4027
4028 if ((pTileInfoIn != NULL) && (pTileInfoOut != NULL))
4029 {
4030 if (pIn->reverse == FALSE)
4031 {
4032 switch (pTileInfoIn->banks)
4033 {
4034 case 2:
4035 pTileInfoOut->banks = 0;
4036 break;
4037 case 4:
4038 pTileInfoOut->banks = 1;
4039 break;
4040 case 8:
4041 pTileInfoOut->banks = 2;
4042 break;
4043 case 16:
4044 pTileInfoOut->banks = 3;
4045 break;
4046 default:
4047 ADDR_ASSERT_ALWAYS();
4048 retCode = ADDR_INVALIDPARAMS;
4049 pTileInfoOut->banks = 0;
4050 break;
4051 }
4052
4053 switch (pTileInfoIn->bankWidth)
4054 {
4055 case 1:
4056 pTileInfoOut->bankWidth = 0;
4057 break;
4058 case 2:
4059 pTileInfoOut->bankWidth = 1;
4060 break;
4061 case 4:
4062 pTileInfoOut->bankWidth = 2;
4063 break;
4064 case 8:
4065 pTileInfoOut->bankWidth = 3;
4066 break;
4067 default:
4068 ADDR_ASSERT_ALWAYS();
4069 retCode = ADDR_INVALIDPARAMS;
4070 pTileInfoOut->bankWidth = 0;
4071 break;
4072 }
4073
4074 switch (pTileInfoIn->bankHeight)
4075 {
4076 case 1:
4077 pTileInfoOut->bankHeight = 0;
4078 break;
4079 case 2:
4080 pTileInfoOut->bankHeight = 1;
4081 break;
4082 case 4:
4083 pTileInfoOut->bankHeight = 2;
4084 break;
4085 case 8:
4086 pTileInfoOut->bankHeight = 3;
4087 break;
4088 default:
4089 ADDR_ASSERT_ALWAYS();
4090 retCode = ADDR_INVALIDPARAMS;
4091 pTileInfoOut->bankHeight = 0;
4092 break;
4093 }
4094
4095 switch (pTileInfoIn->macroAspectRatio)
4096 {
4097 case 1:
4098 pTileInfoOut->macroAspectRatio = 0;
4099 break;
4100 case 2:
4101 pTileInfoOut->macroAspectRatio = 1;
4102 break;
4103 case 4:
4104 pTileInfoOut->macroAspectRatio = 2;
4105 break;
4106 case 8:
4107 pTileInfoOut->macroAspectRatio = 3;
4108 break;
4109 default:
4110 ADDR_ASSERT_ALWAYS();
4111 retCode = ADDR_INVALIDPARAMS;
4112 pTileInfoOut->macroAspectRatio = 0;
4113 break;
4114 }
4115
4116 switch (pTileInfoIn->tileSplitBytes)
4117 {
4118 case 64:
4119 pTileInfoOut->tileSplitBytes = 0;
4120 break;
4121 case 128:
4122 pTileInfoOut->tileSplitBytes = 1;
4123 break;
4124 case 256:
4125 pTileInfoOut->tileSplitBytes = 2;
4126 break;
4127 case 512:
4128 pTileInfoOut->tileSplitBytes = 3;
4129 break;
4130 case 1024:
4131 pTileInfoOut->tileSplitBytes = 4;
4132 break;
4133 case 2048:
4134 pTileInfoOut->tileSplitBytes = 5;
4135 break;
4136 case 4096:
4137 pTileInfoOut->tileSplitBytes = 6;
4138 break;
4139 default:
4140 ADDR_ASSERT_ALWAYS();
4141 retCode = ADDR_INVALIDPARAMS;
4142 pTileInfoOut->tileSplitBytes = 0;
4143 break;
4144 }
4145 }
4146 else
4147 {
4148 switch (pTileInfoIn->banks)
4149 {
4150 case 0:
4151 pTileInfoOut->banks = 2;
4152 break;
4153 case 1:
4154 pTileInfoOut->banks = 4;
4155 break;
4156 case 2:
4157 pTileInfoOut->banks = 8;
4158 break;
4159 case 3:
4160 pTileInfoOut->banks = 16;
4161 break;
4162 default:
4163 ADDR_ASSERT_ALWAYS();
4164 retCode = ADDR_INVALIDPARAMS;
4165 pTileInfoOut->banks = 2;
4166 break;
4167 }
4168
4169 switch (pTileInfoIn->bankWidth)
4170 {
4171 case 0:
4172 pTileInfoOut->bankWidth = 1;
4173 break;
4174 case 1:
4175 pTileInfoOut->bankWidth = 2;
4176 break;
4177 case 2:
4178 pTileInfoOut->bankWidth = 4;
4179 break;
4180 case 3:
4181 pTileInfoOut->bankWidth = 8;
4182 break;
4183 default:
4184 ADDR_ASSERT_ALWAYS();
4185 retCode = ADDR_INVALIDPARAMS;
4186 pTileInfoOut->bankWidth = 1;
4187 break;
4188 }
4189
4190 switch (pTileInfoIn->bankHeight)
4191 {
4192 case 0:
4193 pTileInfoOut->bankHeight = 1;
4194 break;
4195 case 1:
4196 pTileInfoOut->bankHeight = 2;
4197 break;
4198 case 2:
4199 pTileInfoOut->bankHeight = 4;
4200 break;
4201 case 3:
4202 pTileInfoOut->bankHeight = 8;
4203 break;
4204 default:
4205 ADDR_ASSERT_ALWAYS();
4206 retCode = ADDR_INVALIDPARAMS;
4207 pTileInfoOut->bankHeight = 1;
4208 break;
4209 }
4210
4211 switch (pTileInfoIn->macroAspectRatio)
4212 {
4213 case 0:
4214 pTileInfoOut->macroAspectRatio = 1;
4215 break;
4216 case 1:
4217 pTileInfoOut->macroAspectRatio = 2;
4218 break;
4219 case 2:
4220 pTileInfoOut->macroAspectRatio = 4;
4221 break;
4222 case 3:
4223 pTileInfoOut->macroAspectRatio = 8;
4224 break;
4225 default:
4226 ADDR_ASSERT_ALWAYS();
4227 retCode = ADDR_INVALIDPARAMS;
4228 pTileInfoOut->macroAspectRatio = 1;
4229 break;
4230 }
4231
4232 switch (pTileInfoIn->tileSplitBytes)
4233 {
4234 case 0:
4235 pTileInfoOut->tileSplitBytes = 64;
4236 break;
4237 case 1:
4238 pTileInfoOut->tileSplitBytes = 128;
4239 break;
4240 case 2:
4241 pTileInfoOut->tileSplitBytes = 256;
4242 break;
4243 case 3:
4244 pTileInfoOut->tileSplitBytes = 512;
4245 break;
4246 case 4:
4247 pTileInfoOut->tileSplitBytes = 1024;
4248 break;
4249 case 5:
4250 pTileInfoOut->tileSplitBytes = 2048;
4251 break;
4252 case 6:
4253 pTileInfoOut->tileSplitBytes = 4096;
4254 break;
4255 default:
4256 ADDR_ASSERT_ALWAYS();
4257 retCode = ADDR_INVALIDPARAMS;
4258 pTileInfoOut->tileSplitBytes = 64;
4259 break;
4260 }
4261 }
4262
4263 if (pTileInfoIn != pTileInfoOut)
4264 {
4265 pTileInfoOut->pipeConfig = pTileInfoIn->pipeConfig;
4266 }
4267 }
4268 else
4269 {
4270 ADDR_ASSERT_ALWAYS();
4271 retCode = ADDR_INVALIDPARAMS;
4272 }
4273
4274 return retCode;
4275 }
4276
4277 /**
4278 ***************************************************************************************************
4279 * EgBasedAddrLib::HwlComputeSurfaceInfo
4280 * @brief
4281 * Entry of EgBasedAddrLib ComputeSurfaceInfo
4282 * @return
4283 * ADDR_E_RETURNCODE
4284 ***************************************************************************************************
4285 */
4286 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceInfo(
4287 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
4288 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
4289 ) const
4290 {
4291 ADDR_E_RETURNCODE retCode = ADDR_OK;
4292
4293 if (pIn->numSamples < pIn->numFrags)
4294 {
4295 retCode = ADDR_INVALIDPARAMS;
4296 }
4297
4298 ADDR_TILEINFO tileInfo = {0};
4299
4300 if (retCode == ADDR_OK)
4301 {
4302 // Uses internal tile info if pOut does not have a valid pTileInfo
4303 if (pOut->pTileInfo == NULL)
4304 {
4305 pOut->pTileInfo = &tileInfo;
4306 }
4307
4308 if (!DispatchComputeSurfaceInfo(pIn, pOut))
4309 {
4310 retCode = ADDR_INVALIDPARAMS;
4311 }
4312
4313 // Returns an index
4314 pOut->tileIndex = HwlPostCheckTileIndex(pOut->pTileInfo,
4315 pOut->tileMode,
4316 pOut->tileType,
4317 pOut->tileIndex);
4318
4319 if (IsMacroTiled(pOut->tileMode) && (pOut->macroModeIndex == TileIndexInvalid))
4320 {
4321 pOut->macroModeIndex = HwlComputeMacroModeIndex(pOut->tileIndex,
4322 pIn->flags,
4323 pIn->bpp,
4324 pIn->numSamples,
4325 pOut->pTileInfo);
4326 }
4327
4328 // Resets pTileInfo to NULL if the internal tile info is used
4329 if (pOut->pTileInfo == &tileInfo)
4330 {
4331 #if DEBUG
4332 // Client does not pass in a valid pTileInfo
4333 if (IsMacroTiled(pOut->tileMode))
4334 {
4335 // If a valid index is returned, then no pTileInfo is okay
4336 ADDR_ASSERT(!m_configFlags.useTileIndex || pOut->tileIndex != TileIndexInvalid);
4337
4338 if (!IsTileInfoAllZero(pIn->pTileInfo))
4339 {
4340 // The initial value of pIn->pTileInfo is copied to tileInfo
4341 // We do not expect any of these value to be changed nor any 0 of inputs
4342 ADDR_ASSERT(tileInfo.banks == pIn->pTileInfo->banks);
4343 ADDR_ASSERT(tileInfo.bankWidth == pIn->pTileInfo->bankWidth);
4344 ADDR_ASSERT(tileInfo.bankHeight == pIn->pTileInfo->bankHeight);
4345 ADDR_ASSERT(tileInfo.macroAspectRatio == pIn->pTileInfo->macroAspectRatio);
4346 ADDR_ASSERT(tileInfo.tileSplitBytes == pIn->pTileInfo->tileSplitBytes);
4347 }
4348 }
4349 #endif
4350 pOut->pTileInfo = NULL;
4351 }
4352 }
4353
4354 return retCode;
4355 }
4356
4357 /**
4358 ***************************************************************************************************
4359 * EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord
4360 * @brief
4361 * Entry of EgBasedAddrLib ComputeSurfaceAddrFromCoord
4362 * @return
4363 * ADDR_E_RETURNCODE
4364 ***************************************************************************************************
4365 */
4366 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceAddrFromCoord(
4367 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
4368 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
4369 ) const
4370 {
4371 ADDR_E_RETURNCODE retCode = ADDR_OK;
4372
4373 if (
4374 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
4375 (pIn->x > pIn->pitch) ||
4376 (pIn->y > pIn->height) ||
4377 #endif
4378 (pIn->numSamples > m_maxSamples))
4379 {
4380 retCode = ADDR_INVALIDPARAMS;
4381 }
4382 else
4383 {
4384 pOut->addr = DispatchComputeSurfaceAddrFromCoord(pIn, pOut);
4385 }
4386
4387 return retCode;
4388 }
4389
4390 /**
4391 ***************************************************************************************************
4392 * EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr
4393 * @brief
4394 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
4395 * @return
4396 * ADDR_E_RETURNCODE
4397 ***************************************************************************************************
4398 */
4399 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSurfaceCoordFromAddr(
4400 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
4401 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
4402 ) const
4403 {
4404 ADDR_E_RETURNCODE retCode = ADDR_OK;
4405
4406 if ((pIn->bitPosition >= 8) ||
4407 (pIn->numSamples > m_maxSamples))
4408 {
4409 retCode = ADDR_INVALIDPARAMS;
4410 }
4411 else
4412 {
4413 DispatchComputeSurfaceCoordFromAddr(pIn, pOut);
4414 }
4415 return retCode;
4416 }
4417
4418 /**
4419 ***************************************************************************************************
4420 * EgBasedAddrLib::HwlComputeSliceTileSwizzle
4421 * @brief
4422 * Entry of EgBasedAddrLib ComputeSurfaceCoordFromAddr
4423 * @return
4424 * ADDR_E_RETURNCODE
4425 ***************************************************************************************************
4426 */
4427 ADDR_E_RETURNCODE EgBasedAddrLib::HwlComputeSliceTileSwizzle(
4428 const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure
4429 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure
4430 ) const
4431 {
4432 ADDR_E_RETURNCODE retCode = ADDR_OK;
4433
4434 if (pIn->pTileInfo && (pIn->pTileInfo->banks > 0))
4435 {
4436
4437 pOut->tileSwizzle = ComputeSliceTileSwizzle(pIn->tileMode,
4438 pIn->baseSwizzle,
4439 pIn->slice,
4440 pIn->baseAddr,
4441 pIn->pTileInfo);
4442 }
4443 else
4444 {
4445 retCode = ADDR_INVALIDPARAMS;
4446 }
4447
4448 return retCode;
4449 }
4450
4451 /**
4452 ***************************************************************************************************
4453 * EgBasedAddrLib::HwlComputeHtileBpp
4454 *
4455 * @brief
4456 * Compute htile bpp
4457 *
4458 * @return
4459 * Htile bpp
4460 ***************************************************************************************************
4461 */
4462 UINT_32 EgBasedAddrLib::HwlComputeHtileBpp(
4463 BOOL_32 isWidth8, ///< [in] TRUE if block width is 8
4464 BOOL_32 isHeight8 ///< [in] TRUE if block height is 8
4465 ) const
4466 {
4467 // only support 8x8 mode
4468 ADDR_ASSERT(isWidth8 && isHeight8);
4469 return 32;
4470 }
4471
4472 /**
4473 ***************************************************************************************************
4474 * EgBasedAddrLib::HwlComputeHtileBaseAlign
4475 *
4476 * @brief
4477 * Compute htile base alignment
4478 *
4479 * @return
4480 * Htile base alignment
4481 ***************************************************************************************************
4482 */
4483 UINT_32 EgBasedAddrLib::HwlComputeHtileBaseAlign(
4484 BOOL_32 isTcCompatible, ///< [in] if TC compatible
4485 BOOL_32 isLinear, ///< [in] if it is linear mode
4486 ADDR_TILEINFO* pTileInfo ///< [in] Tile info
4487 ) const
4488 {
4489 UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
4490
4491 if (isTcCompatible)
4492 {
4493 ADDR_ASSERT(pTileInfo != NULL);
4494 if (pTileInfo)
4495 {
4496 baseAlign *= pTileInfo->banks;
4497 }
4498 }
4499
4500 return baseAlign;
4501 }
4502
4503 /**
4504 ***************************************************************************************************
4505 * EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled
4506 *
4507 * @brief
4508 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4509 * output parameters.
4510 *
4511 * @return
4512 * pitch alignment
4513 ***************************************************************************************************
4514 */
4515 UINT_32 EgBasedAddrLib::HwlGetPitchAlignmentMicroTiled(
4516 AddrTileMode tileMode, ///< [in] tile mode
4517 UINT_32 bpp, ///< [in] bits per pixel
4518 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
4519 UINT_32 numSamples ///< [in] number of samples
4520 ) const
4521 {
4522 UINT_32 pitchAlign;
4523
4524 UINT_32 microTileThickness = ComputeSurfaceThickness(tileMode);
4525
4526 UINT_32 pixelsPerMicroTile;
4527 UINT_32 pixelsPerPipeInterleave;
4528 UINT_32 microTilesPerPipeInterleave;
4529
4530 //
4531 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4532 // stencil buffer since pitch alignment is related to bpp.
4533 // For a depth only buffer do not set this.
4534 //
4535 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4536 // sampled with mipmap.
4537 //
4538 if (flags.depth && !flags.noStencil)
4539 {
4540 bpp = 8;
4541 }
4542
4543 pixelsPerMicroTile = MicroTilePixels * microTileThickness;
4544 pixelsPerPipeInterleave = BYTES_TO_BITS(m_pipeInterleaveBytes) / (bpp * numSamples);
4545 microTilesPerPipeInterleave = pixelsPerPipeInterleave / pixelsPerMicroTile;
4546
4547 pitchAlign = Max(MicroTileWidth, microTilesPerPipeInterleave * MicroTileWidth);
4548
4549 return pitchAlign;
4550 }
4551
4552 /**
4553 ***************************************************************************************************
4554 * EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled
4555 *
4556 * @brief
4557 * Adjust 1D tiled surface pitch and slice size
4558 *
4559 * @return
4560 * Logical slice size in bytes
4561 ***************************************************************************************************
4562 */
4563 UINT_64 EgBasedAddrLib::HwlGetSizeAdjustmentMicroTiled(
4564 UINT_32 thickness, ///< [in] thickness
4565 UINT_32 bpp, ///< [in] bits per pixel
4566 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
4567 UINT_32 numSamples, ///< [in] number of samples
4568 UINT_32 baseAlign, ///< [in] base alignment
4569 UINT_32 pitchAlign, ///< [in] pitch alignment
4570 UINT_32* pPitch, ///< [in/out] pointer to pitch
4571 UINT_32* pHeight ///< [in/out] pointer to height
4572 ) const
4573 {
4574 UINT_64 logicalSliceSize;
4575 UINT_64 physicalSliceSize;
4576
4577 UINT_32 pitch = *pPitch;
4578 UINT_32 height = *pHeight;
4579
4580 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4581 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
4582
4583 // Physical slice: multiplied by thickness
4584 physicalSliceSize = logicalSliceSize * thickness;
4585
4586 //
4587 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4588 //
4589 ADDR_ASSERT((physicalSliceSize % baseAlign) == 0)
4590
4591 return logicalSliceSize;
4592 }
4593