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