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