amd: update addrlib
[mesa.git] / src / amd / addrlib / src / r800 / egbaddrlib.cpp
1 /*
2 * Copyright © 2007-2019 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 if (flags.czDispCompatible && (mipLevel == 0))
745 {
746 *pBaseAlign = PowTwoAlign(*pBaseAlign, 4096); //Base address MOD 4096 = 0
747 *pPitchAlign = PowTwoAlign(*pPitchAlign, 512 / (BITS_TO_BYTES(bpp))); //(8 lines * pitch * bytes per pixel) MOD 4096 = 0
748 }
749 // end Carrizo workaround for 1D tilling
750
751 return valid;
752 }
753
754 /**
755 ****************************************************************************************************
756 * EgBasedLib::HwlReduceBankWidthHeight
757 *
758 * @brief
759 * Additional checks, reduce bankHeight/bankWidth if needed and possible
760 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
761 *
762 * @return
763 * TRUE if no error occurs
764 ****************************************************************************************************
765 */
766 BOOL_32 EgBasedLib::HwlReduceBankWidthHeight(
767 UINT_32 tileSize, ///< [in] tile size
768 UINT_32 bpp, ///< [in] bits per pixel
769 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
770 UINT_32 numSamples, ///< [in] number of samples
771 UINT_32 bankHeightAlign, ///< [in] bank height alignment
772 UINT_32 pipes, ///< [in] pipes
773 ADDR_TILEINFO* pTileInfo ///< [in,out] bank structure.
774 ) const
775 {
776 UINT_32 macroAspectAlign;
777 BOOL_32 valid = TRUE;
778
779 if (tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize)
780 {
781 BOOL_32 stillGreater = TRUE;
782
783 // Try reducing bankWidth first
784 if (stillGreater && pTileInfo->bankWidth > 1)
785 {
786 while (stillGreater && pTileInfo->bankWidth > 0)
787 {
788 pTileInfo->bankWidth >>= 1;
789
790 if (pTileInfo->bankWidth == 0)
791 {
792 pTileInfo->bankWidth = 1;
793 break;
794 }
795
796 stillGreater =
797 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
798 }
799
800 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
801 bankHeightAlign = Max(1u,
802 m_pipeInterleaveBytes * m_bankInterleave /
803 (tileSize * pTileInfo->bankWidth)
804 );
805
806 // We cannot increase bankHeight so just assert this case.
807 ADDR_ASSERT((pTileInfo->bankHeight % bankHeightAlign) == 0);
808
809 if (numSamples == 1)
810 {
811 macroAspectAlign = Max(1u,
812 m_pipeInterleaveBytes * m_bankInterleave /
813 (tileSize * pipes * pTileInfo->bankWidth)
814 );
815 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio,
816 macroAspectAlign);
817 }
818 }
819
820 // Early quit bank_height degradation for "64" bit z buffer
821 if (flags.depth && bpp >= 64)
822 {
823 stillGreater = FALSE;
824 }
825
826 // Then try reducing bankHeight
827 if (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
828 {
829 while (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
830 {
831 pTileInfo->bankHeight >>= 1;
832
833 if (pTileInfo->bankHeight < bankHeightAlign)
834 {
835 pTileInfo->bankHeight = bankHeightAlign;
836 break;
837 }
838
839 stillGreater =
840 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
841 }
842 }
843
844 valid = !stillGreater;
845
846 // Generate a warning if we still fail to meet this constraint
847 if (valid == FALSE)
848 {
849 ADDR_WARN(
850 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
851 tileSize, pTileInfo->bankWidth, pTileInfo->bankHeight, m_rowSize));
852 }
853 }
854
855 return valid;
856 }
857
858 /**
859 ****************************************************************************************************
860 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
861 *
862 * @brief
863 * Compute 2D tiled surface alignment, calculation results are returned through
864 * output parameters.
865 *
866 * @return
867 * TRUE if no error occurs
868 ****************************************************************************************************
869 */
870 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
871 AddrTileMode tileMode, ///< [in] tile mode
872 UINT_32 bpp, ///< [in] bits per pixel
873 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
874 UINT_32 mipLevel, ///< [in] mip level
875 UINT_32 numSamples, ///< [in] number of samples
876 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] Surface output
877 ) const
878 {
879 ADDR_TILEINFO* pTileInfo = pOut->pTileInfo;
880
881 BOOL_32 valid = SanityCheckMacroTiled(pTileInfo);
882
883 if (valid)
884 {
885 UINT_32 macroTileWidth;
886 UINT_32 macroTileHeight;
887
888 UINT_32 tileSize;
889 UINT_32 bankHeightAlign;
890 UINT_32 macroAspectAlign;
891
892 UINT_32 thickness = Thickness(tileMode);
893 UINT_32 pipes = HwlGetPipes(pTileInfo);
894
895 //
896 // Align bank height first according to latest h/w spec
897 //
898
899 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
900 tileSize = Min(pTileInfo->tileSplitBytes,
901 BITS_TO_BYTES(64 * thickness * bpp * numSamples));
902
903 // bank_height_align =
904 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
905 bankHeightAlign = Max(1u,
906 m_pipeInterleaveBytes * m_bankInterleave /
907 (tileSize * pTileInfo->bankWidth)
908 );
909
910 pTileInfo->bankHeight = PowTwoAlign(pTileInfo->bankHeight, bankHeightAlign);
911
912 // num_pipes * bank_width * macro_tile_aspect >=
913 // (pipe_interleave_size * bank_interleave) / tile_size
914 if (numSamples == 1)
915 {
916 // this restriction is only for mipmap (mipmap's numSamples must be 1)
917 macroAspectAlign = Max(1u,
918 m_pipeInterleaveBytes * m_bankInterleave /
919 (tileSize * pipes * pTileInfo->bankWidth)
920 );
921 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, macroAspectAlign);
922 }
923
924 valid = HwlReduceBankWidthHeight(tileSize,
925 bpp,
926 flags,
927 numSamples,
928 bankHeightAlign,
929 pipes,
930 pTileInfo);
931
932 //
933 // The required granularity for pitch is the macro tile width.
934 //
935 macroTileWidth = MicroTileWidth * pTileInfo->bankWidth * pipes *
936 pTileInfo->macroAspectRatio;
937
938 pOut->pitchAlign = macroTileWidth;
939 pOut->blockWidth = macroTileWidth;
940
941 AdjustPitchAlignment(flags, &pOut->pitchAlign);
942
943 //
944 // The required granularity for height is the macro tile height.
945 //
946 macroTileHeight = MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
947 pTileInfo->macroAspectRatio;
948
949 pOut->heightAlign = macroTileHeight;
950 pOut->blockHeight = macroTileHeight;
951
952 //
953 // Compute base alignment
954 //
955 pOut->baseAlign =
956 pipes * pTileInfo->bankWidth * pTileInfo->banks * pTileInfo->bankHeight * tileSize;
957
958 HwlComputeSurfaceAlignmentsMacroTiled(tileMode, bpp, flags, mipLevel, numSamples, pOut);
959 }
960
961 return valid;
962 }
963
964 /**
965 ****************************************************************************************************
966 * EgBasedLib::SanityCheckMacroTiled
967 *
968 * @brief
969 * Check if macro-tiled parameters are valid
970 * @return
971 * TRUE if valid
972 ****************************************************************************************************
973 */
974 BOOL_32 EgBasedLib::SanityCheckMacroTiled(
975 ADDR_TILEINFO* pTileInfo ///< [in] macro-tiled parameters
976 ) const
977 {
978 BOOL_32 valid = TRUE;
979 MAYBE_UNUSED UINT_32 numPipes = HwlGetPipes(pTileInfo);
980
981 switch (pTileInfo->banks)
982 {
983 case 2: //fall through
984 case 4: //fall through
985 case 8: //fall through
986 case 16:
987 break;
988 default:
989 valid = FALSE;
990 break;
991
992 }
993
994 if (valid)
995 {
996 switch (pTileInfo->bankWidth)
997 {
998 case 1: //fall through
999 case 2: //fall through
1000 case 4: //fall through
1001 case 8:
1002 break;
1003 default:
1004 valid = FALSE;
1005 break;
1006 }
1007 }
1008
1009 if (valid)
1010 {
1011 switch (pTileInfo->bankHeight)
1012 {
1013 case 1: //fall through
1014 case 2: //fall through
1015 case 4: //fall through
1016 case 8:
1017 break;
1018 default:
1019 valid = FALSE;
1020 break;
1021 }
1022 }
1023
1024 if (valid)
1025 {
1026 switch (pTileInfo->macroAspectRatio)
1027 {
1028 case 1: //fall through
1029 case 2: //fall through
1030 case 4: //fall through
1031 case 8:
1032 break;
1033 default:
1034 valid = FALSE;
1035 break;
1036 }
1037 }
1038
1039 if (valid)
1040 {
1041 if (pTileInfo->banks < pTileInfo->macroAspectRatio)
1042 {
1043 // This will generate macro tile height <= 1
1044 valid = FALSE;
1045 }
1046 }
1047
1048 if (valid)
1049 {
1050 if (pTileInfo->tileSplitBytes > m_rowSize)
1051 {
1052 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1053 }
1054 }
1055
1056 if (valid)
1057 {
1058 valid = HwlSanityCheckMacroTiled(pTileInfo);
1059 }
1060
1061 ADDR_ASSERT(valid == TRUE);
1062
1063 // Add this assert for guidance
1064 ADDR_ASSERT(numPipes * pTileInfo->banks >= 4);
1065
1066 return valid;
1067 }
1068
1069 /**
1070 ****************************************************************************************************
1071 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1072 *
1073 * @brief
1074 * Compute valid tile mode for surface mipmap sub-levels
1075 *
1076 * @return
1077 * Suitable tile mode
1078 ****************************************************************************************************
1079 */
1080 AddrTileMode EgBasedLib::ComputeSurfaceMipLevelTileMode(
1081 AddrTileMode baseTileMode, ///< [in] base tile mode
1082 UINT_32 bpp, ///< [in] bits per pixels
1083 UINT_32 pitch, ///< [in] current level pitch
1084 UINT_32 height, ///< [in] current level height
1085 UINT_32 numSlices, ///< [in] current number of slices
1086 UINT_32 numSamples, ///< [in] number of samples
1087 UINT_32 pitchAlign, ///< [in] pitch alignment
1088 UINT_32 heightAlign, ///< [in] height alignment
1089 ADDR_TILEINFO* pTileInfo ///< [in] ptr to bank structure
1090 ) const
1091 {
1092 UINT_64 bytesPerSlice;
1093 (void)bytesPerSlice;
1094 UINT_32 bytesPerTile;
1095
1096 AddrTileMode expTileMode = baseTileMode;
1097 UINT_32 microTileThickness = Thickness(expTileMode);
1098 UINT_32 interleaveSize = m_pipeInterleaveBytes * m_bankInterleave;
1099
1100 //
1101 // Compute the size of a slice.
1102 //
1103 bytesPerSlice = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
1104 bytesPerTile = BITS_TO_BYTES(MicroTilePixels * microTileThickness * NextPow2(bpp) * numSamples);
1105
1106 //
1107 // Reduce tiling mode from thick to thin if the number of slices is less than the
1108 // micro tile thickness.
1109 //
1110 if (numSlices < microTileThickness)
1111 {
1112 expTileMode = HwlDegradeThickTileMode(expTileMode, numSlices, &bytesPerTile);
1113 }
1114
1115 if (bytesPerTile > pTileInfo->tileSplitBytes)
1116 {
1117 bytesPerTile = pTileInfo->tileSplitBytes;
1118 }
1119
1120 UINT_32 threshold1 =
1121 bytesPerTile * HwlGetPipes(pTileInfo) * pTileInfo->bankWidth * pTileInfo->macroAspectRatio;
1122
1123 UINT_32 threshold2 =
1124 bytesPerTile * pTileInfo->bankWidth * pTileInfo->bankHeight;
1125
1126 //
1127 // Reduce the tile mode from 2D/3D to 1D in following conditions
1128 //
1129 switch (expTileMode)
1130 {
1131 case ADDR_TM_2D_TILED_THIN1: //fall through
1132 case ADDR_TM_3D_TILED_THIN1:
1133 case ADDR_TM_PRT_TILED_THIN1:
1134 case ADDR_TM_PRT_2D_TILED_THIN1:
1135 case ADDR_TM_PRT_3D_TILED_THIN1:
1136 if ((pitch < pitchAlign) ||
1137 (height < heightAlign) ||
1138 (interleaveSize > threshold1) ||
1139 (interleaveSize > threshold2))
1140 {
1141 expTileMode = ADDR_TM_1D_TILED_THIN1;
1142 }
1143 break;
1144 case ADDR_TM_2D_TILED_THICK: //fall through
1145 case ADDR_TM_3D_TILED_THICK:
1146 case ADDR_TM_2D_TILED_XTHICK:
1147 case ADDR_TM_3D_TILED_XTHICK:
1148 case ADDR_TM_PRT_TILED_THICK:
1149 case ADDR_TM_PRT_2D_TILED_THICK:
1150 case ADDR_TM_PRT_3D_TILED_THICK:
1151 if ((pitch < pitchAlign) ||
1152 (height < heightAlign))
1153 {
1154 expTileMode = ADDR_TM_1D_TILED_THICK;
1155 }
1156 break;
1157 default:
1158 break;
1159 }
1160
1161 return expTileMode;
1162 }
1163
1164 /**
1165 ****************************************************************************************************
1166 * EgBasedLib::HwlGetAlignmentInfoMacroTiled
1167 * @brief
1168 * Get alignment info for giving tile mode
1169 * @return
1170 * TRUE if getting alignment is OK
1171 ****************************************************************************************************
1172 */
1173 BOOL_32 EgBasedLib::HwlGetAlignmentInfoMacroTiled(
1174 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] create surface info
1175 UINT_32* pPitchAlign, ///< [out] pitch alignment
1176 UINT_32* pHeightAlign, ///< [out] height alignment
1177 UINT_32* pSizeAlign ///< [out] size alignment
1178 ) const
1179 {
1180 BOOL_32 valid = TRUE;
1181
1182 ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
1183
1184 UINT_32 numSamples = (pIn->numFrags == 0) ? pIn->numSamples : pIn->numFrags;
1185
1186 ADDR_ASSERT(pIn->pTileInfo);
1187 ADDR_TILEINFO tileInfo = *pIn->pTileInfo;
1188 ADDR_COMPUTE_SURFACE_INFO_OUTPUT out = {0};
1189 out.pTileInfo = &tileInfo;
1190
1191 if (UseTileIndex(pIn->tileIndex))
1192 {
1193 out.tileIndex = pIn->tileIndex;
1194 out.macroModeIndex = TileIndexInvalid;
1195 }
1196
1197 HwlSetupTileInfo(pIn->tileMode,
1198 pIn->flags,
1199 pIn->bpp,
1200 pIn->width,
1201 pIn->height,
1202 numSamples,
1203 &tileInfo,
1204 &tileInfo,
1205 pIn->tileType,
1206 &out);
1207
1208 valid = ComputeSurfaceAlignmentsMacroTiled(pIn->tileMode,
1209 pIn->bpp,
1210 pIn->flags,
1211 pIn->mipLevel,
1212 numSamples,
1213 &out);
1214
1215 if (valid)
1216 {
1217 *pPitchAlign = out.pitchAlign;
1218 *pHeightAlign = out.heightAlign;
1219 *pSizeAlign = out.baseAlign;
1220 }
1221
1222 return valid;
1223 }
1224
1225 /**
1226 ****************************************************************************************************
1227 * EgBasedLib::HwlDegradeThickTileMode
1228 *
1229 * @brief
1230 * Degrades valid tile mode for thick modes if needed
1231 *
1232 * @return
1233 * Suitable tile mode
1234 ****************************************************************************************************
1235 */
1236 AddrTileMode EgBasedLib::HwlDegradeThickTileMode(
1237 AddrTileMode baseTileMode, ///< [in] base tile mode
1238 UINT_32 numSlices, ///< [in] current number of slices
1239 UINT_32* pBytesPerTile ///< [in,out] pointer to bytes per slice
1240 ) const
1241 {
1242 ADDR_ASSERT(numSlices < Thickness(baseTileMode));
1243 // if pBytesPerTile is NULL, this is a don't-care....
1244 UINT_32 bytesPerTile = pBytesPerTile != NULL ? *pBytesPerTile : 64;
1245
1246 AddrTileMode expTileMode = baseTileMode;
1247 switch (baseTileMode)
1248 {
1249 case ADDR_TM_1D_TILED_THICK:
1250 expTileMode = ADDR_TM_1D_TILED_THIN1;
1251 bytesPerTile >>= 2;
1252 break;
1253 case ADDR_TM_2D_TILED_THICK:
1254 expTileMode = ADDR_TM_2D_TILED_THIN1;
1255 bytesPerTile >>= 2;
1256 break;
1257 case ADDR_TM_3D_TILED_THICK:
1258 expTileMode = ADDR_TM_3D_TILED_THIN1;
1259 bytesPerTile >>= 2;
1260 break;
1261 case ADDR_TM_2D_TILED_XTHICK:
1262 if (numSlices < ThickTileThickness)
1263 {
1264 expTileMode = ADDR_TM_2D_TILED_THIN1;
1265 bytesPerTile >>= 3;
1266 }
1267 else
1268 {
1269 expTileMode = ADDR_TM_2D_TILED_THICK;
1270 bytesPerTile >>= 1;
1271 }
1272 break;
1273 case ADDR_TM_3D_TILED_XTHICK:
1274 if (numSlices < ThickTileThickness)
1275 {
1276 expTileMode = ADDR_TM_3D_TILED_THIN1;
1277 bytesPerTile >>= 3;
1278 }
1279 else
1280 {
1281 expTileMode = ADDR_TM_3D_TILED_THICK;
1282 bytesPerTile >>= 1;
1283 }
1284 break;
1285 default:
1286 ADDR_ASSERT_ALWAYS();
1287 break;
1288 }
1289
1290 if (pBytesPerTile != NULL)
1291 {
1292 *pBytesPerTile = bytesPerTile;
1293 }
1294
1295 return expTileMode;
1296 }
1297
1298 /**
1299 ****************************************************************************************************
1300 * EgBasedLib::DispatchComputeSurfaceAddrFromCoord
1301 *
1302 * @brief
1303 * Compute surface address from given coord (x, y, slice,sample)
1304 *
1305 * @return
1306 * Address in bytes
1307 ****************************************************************************************************
1308 */
1309 UINT_64 EgBasedLib::DispatchComputeSurfaceAddrFromCoord(
1310 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1311 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1312 ) const
1313 {
1314 UINT_32 x = pIn->x;
1315 UINT_32 y = pIn->y;
1316 UINT_32 slice = pIn->slice;
1317 UINT_32 sample = pIn->sample;
1318 UINT_32 bpp = pIn->bpp;
1319 UINT_32 pitch = pIn->pitch;
1320 UINT_32 height = pIn->height;
1321 UINT_32 numSlices = pIn->numSlices;
1322 UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
1323 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
1324 AddrTileMode tileMode = pIn->tileMode;
1325 AddrTileType microTileType = pIn->tileType;
1326 BOOL_32 ignoreSE = pIn->ignoreSE;
1327 BOOL_32 isDepthSampleOrder = pIn->isDepth;
1328 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
1329
1330 UINT_32* pBitPosition = &pOut->bitPosition;
1331 UINT_64 addr;
1332
1333 // ADDR_DEPTH_SAMPLE_ORDER = non-disp + depth-sample-order
1334 if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
1335 {
1336 isDepthSampleOrder = TRUE;
1337 }
1338
1339 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
1340 {
1341 if (numFrags != numSamples)
1342 {
1343 numSamples = numFrags;
1344 ADDR_ASSERT(sample < numSamples);
1345 }
1346
1347 /// @note
1348 /// 128 bit/thick tiled surface doesn't support display tiling and
1349 /// mipmap chain must have the same tileType, so please fill tileType correctly
1350 if (IsLinear(pIn->tileMode) == FALSE)
1351 {
1352 if (bpp >= 128 || Thickness(tileMode) > 1)
1353 {
1354 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
1355 }
1356 }
1357 }
1358
1359 switch (tileMode)
1360 {
1361 case ADDR_TM_LINEAR_GENERAL://fall through
1362 case ADDR_TM_LINEAR_ALIGNED:
1363 addr = ComputeSurfaceAddrFromCoordLinear(x,
1364 y,
1365 slice,
1366 sample,
1367 bpp,
1368 pitch,
1369 height,
1370 numSlices,
1371 pBitPosition);
1372 break;
1373 case ADDR_TM_1D_TILED_THIN1://fall through
1374 case ADDR_TM_1D_TILED_THICK:
1375 addr = ComputeSurfaceAddrFromCoordMicroTiled(x,
1376 y,
1377 slice,
1378 sample,
1379 bpp,
1380 pitch,
1381 height,
1382 numSamples,
1383 tileMode,
1384 microTileType,
1385 isDepthSampleOrder,
1386 pBitPosition);
1387 break;
1388 case ADDR_TM_2D_TILED_THIN1: //fall through
1389 case ADDR_TM_2D_TILED_THICK: //fall through
1390 case ADDR_TM_3D_TILED_THIN1: //fall through
1391 case ADDR_TM_3D_TILED_THICK: //fall through
1392 case ADDR_TM_2D_TILED_XTHICK: //fall through
1393 case ADDR_TM_3D_TILED_XTHICK: //fall through
1394 case ADDR_TM_PRT_TILED_THIN1: //fall through
1395 case ADDR_TM_PRT_2D_TILED_THIN1://fall through
1396 case ADDR_TM_PRT_3D_TILED_THIN1://fall through
1397 case ADDR_TM_PRT_TILED_THICK: //fall through
1398 case ADDR_TM_PRT_2D_TILED_THICK://fall through
1399 case ADDR_TM_PRT_3D_TILED_THICK:
1400 UINT_32 pipeSwizzle;
1401 UINT_32 bankSwizzle;
1402
1403 if (m_configFlags.useCombinedSwizzle)
1404 {
1405 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
1406 &bankSwizzle, &pipeSwizzle);
1407 }
1408 else
1409 {
1410 pipeSwizzle = pIn->pipeSwizzle;
1411 bankSwizzle = pIn->bankSwizzle;
1412 }
1413
1414 addr = ComputeSurfaceAddrFromCoordMacroTiled(x,
1415 y,
1416 slice,
1417 sample,
1418 bpp,
1419 pitch,
1420 height,
1421 numSamples,
1422 tileMode,
1423 microTileType,
1424 ignoreSE,
1425 isDepthSampleOrder,
1426 pipeSwizzle,
1427 bankSwizzle,
1428 pTileInfo,
1429 pBitPosition);
1430 break;
1431 default:
1432 addr = 0;
1433 ADDR_ASSERT_ALWAYS();
1434 break;
1435 }
1436
1437 return addr;
1438 }
1439
1440 /**
1441 ****************************************************************************************************
1442 * EgBasedLib::ComputeMacroTileEquation
1443 *
1444 * @brief
1445 * Computes the address equation in macro tile
1446 * @return
1447 * If equation can be computed
1448 ****************************************************************************************************
1449 */
1450 ADDR_E_RETURNCODE EgBasedLib::ComputeMacroTileEquation(
1451 UINT_32 log2BytesPP, ///< [in] log2 of bytes per pixel
1452 AddrTileMode tileMode, ///< [in] tile mode
1453 AddrTileType microTileType, ///< [in] micro tiling type
1454 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure
1455 ADDR_EQUATION* pEquation ///< [out] Equation for addressing in macro tile
1456 ) const
1457 {
1458 ADDR_E_RETURNCODE retCode;
1459
1460 // Element equation within a tile
1461 retCode = ComputeMicroTileEquation(log2BytesPP, tileMode, microTileType, pEquation);
1462
1463 if (retCode == ADDR_OK)
1464 {
1465 // Tile equesiton with signle pipe bank
1466 UINT_32 numPipes = HwlGetPipes(pTileInfo);
1467 UINT_32 numPipeBits = Log2(numPipes);
1468
1469 for (UINT_32 i = 0; i < Log2(pTileInfo->bankWidth); i++)
1470 {
1471 pEquation->addr[pEquation->numBits].valid = 1;
1472 pEquation->addr[pEquation->numBits].channel = 0;
1473 pEquation->addr[pEquation->numBits].index = i + log2BytesPP + 3 + numPipeBits;
1474 pEquation->numBits++;
1475 }
1476
1477 for (UINT_32 i = 0; i < Log2(pTileInfo->bankHeight); i++)
1478 {
1479 pEquation->addr[pEquation->numBits].valid = 1;
1480 pEquation->addr[pEquation->numBits].channel = 1;
1481 pEquation->addr[pEquation->numBits].index = i + 3;
1482 pEquation->numBits++;
1483 }
1484
1485 ADDR_EQUATION equation;
1486 memset(&equation, 0, sizeof(ADDR_EQUATION));
1487
1488 UINT_32 thresholdX = 32;
1489 UINT_32 thresholdY = 32;
1490
1491 if (IsPrtNoRotationTileMode(tileMode))
1492 {
1493 UINT_32 macroTilePitch =
1494 (MicroTileWidth * pTileInfo->bankWidth * numPipes) * pTileInfo->macroAspectRatio;
1495 UINT_32 macroTileHeight =
1496 (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) /
1497 pTileInfo->macroAspectRatio;
1498 thresholdX = Log2(macroTilePitch);
1499 thresholdY = Log2(macroTileHeight);
1500 }
1501
1502 // Pipe equation
1503 retCode = ComputePipeEquation(log2BytesPP, thresholdX, thresholdY, pTileInfo, &equation);
1504
1505 if (retCode == ADDR_OK)
1506 {
1507 UINT_32 pipeBitStart = Log2(m_pipeInterleaveBytes);
1508
1509 if (pEquation->numBits > pipeBitStart)
1510 {
1511 UINT_32 numLeftShift = pEquation->numBits - pipeBitStart;
1512
1513 for (UINT_32 i = 0; i < numLeftShift; i++)
1514 {
1515 pEquation->addr[pEquation->numBits + equation.numBits - i - 1] =
1516 pEquation->addr[pEquation->numBits - i - 1];
1517 pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] =
1518 pEquation->xor1[pEquation->numBits - i - 1];
1519 pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] =
1520 pEquation->xor2[pEquation->numBits - i - 1];
1521 }
1522 }
1523
1524 for (UINT_32 i = 0; i < equation.numBits; i++)
1525 {
1526 pEquation->addr[pipeBitStart + i] = equation.addr[i];
1527 pEquation->xor1[pipeBitStart + i] = equation.xor1[i];
1528 pEquation->xor2[pipeBitStart + i] = equation.xor2[i];
1529 pEquation->numBits++;
1530 }
1531
1532 // Bank equation
1533 memset(&equation, 0, sizeof(ADDR_EQUATION));
1534
1535 retCode = ComputeBankEquation(log2BytesPP, thresholdX, thresholdY,
1536 pTileInfo, &equation);
1537
1538 if (retCode == ADDR_OK)
1539 {
1540 UINT_32 bankBitStart = pipeBitStart + numPipeBits + Log2(m_bankInterleave);
1541
1542 if (pEquation->numBits > bankBitStart)
1543 {
1544 UINT_32 numLeftShift = pEquation->numBits - bankBitStart;
1545
1546 for (UINT_32 i = 0; i < numLeftShift; i++)
1547 {
1548 pEquation->addr[pEquation->numBits + equation.numBits - i - 1] =
1549 pEquation->addr[pEquation->numBits - i - 1];
1550 pEquation->xor1[pEquation->numBits + equation.numBits - i - 1] =
1551 pEquation->xor1[pEquation->numBits - i - 1];
1552 pEquation->xor2[pEquation->numBits + equation.numBits - i - 1] =
1553 pEquation->xor2[pEquation->numBits - i - 1];
1554 }
1555 }
1556
1557 for (UINT_32 i = 0; i < equation.numBits; i++)
1558 {
1559 pEquation->addr[bankBitStart + i] = equation.addr[i];
1560 pEquation->xor1[bankBitStart + i] = equation.xor1[i];
1561 pEquation->xor2[bankBitStart + i] = equation.xor2[i];
1562 pEquation->numBits++;
1563 }
1564 }
1565 }
1566 }
1567
1568 return retCode;
1569 }
1570
1571 /**
1572 ****************************************************************************************************
1573 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1574 *
1575 * @brief
1576 * Computes the surface address and bit position from a
1577 * coordinate for 2D tilied (macro tiled)
1578 * @return
1579 * The byte address
1580 ****************************************************************************************************
1581 */
1582 UINT_64 EgBasedLib::ComputeSurfaceAddrFromCoordMacroTiled(
1583 UINT_32 x, ///< [in] x coordinate
1584 UINT_32 y, ///< [in] y coordinate
1585 UINT_32 slice, ///< [in] slice index
1586 UINT_32 sample, ///< [in] sample index
1587 UINT_32 bpp, ///< [in] bits per pixel
1588 UINT_32 pitch, ///< [in] surface pitch, in pixels
1589 UINT_32 height, ///< [in] surface height, in pixels
1590 UINT_32 numSamples, ///< [in] number of samples
1591 AddrTileMode tileMode, ///< [in] tile mode
1592 AddrTileType microTileType, ///< [in] micro tiling type
1593 BOOL_32 ignoreSE, ///< [in] TRUE if shader enginers can be ignored
1594 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if it depth sample ordering is used
1595 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
1596 UINT_32 bankSwizzle, ///< [in] bank swizzle
1597 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure
1598 /// **All fields to be valid on entry**
1599 UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this
1600 ) const
1601 {
1602 UINT_64 addr;
1603
1604 UINT_32 microTileBytes;
1605 UINT_32 microTileBits;
1606 UINT_32 sampleOffset;
1607 UINT_32 pixelIndex;
1608 UINT_32 pixelOffset;
1609 UINT_32 elementOffset;
1610 UINT_32 tileSplitSlice;
1611 UINT_32 pipe;
1612 UINT_32 bank;
1613 UINT_64 sliceBytes;
1614 UINT_64 sliceOffset;
1615 UINT_32 macroTilePitch;
1616 UINT_32 macroTileHeight;
1617 UINT_32 macroTilesPerRow;
1618 UINT_32 macroTilesPerSlice;
1619 UINT_64 macroTileBytes;
1620 UINT_32 macroTileIndexX;
1621 UINT_32 macroTileIndexY;
1622 UINT_64 macroTileOffset;
1623 UINT_64 totalOffset;
1624 UINT_64 pipeInterleaveMask;
1625 UINT_64 bankInterleaveMask;
1626 UINT_64 pipeInterleaveOffset;
1627 UINT_32 bankInterleaveOffset;
1628 UINT_64 offset;
1629 UINT_32 tileRowIndex;
1630 UINT_32 tileColumnIndex;
1631 UINT_32 tileIndex;
1632 UINT_32 tileOffset;
1633
1634 UINT_32 microTileThickness = Thickness(tileMode);
1635
1636 //
1637 // Compute the number of group, pipe, and bank bits.
1638 //
1639 UINT_32 numPipes = HwlGetPipes(pTileInfo);
1640 UINT_32 numPipeInterleaveBits = Log2(m_pipeInterleaveBytes);
1641 UINT_32 numPipeBits = Log2(numPipes);
1642 UINT_32 numBankInterleaveBits = Log2(m_bankInterleave);
1643 UINT_32 numBankBits = Log2(pTileInfo->banks);
1644
1645 //
1646 // Compute the micro tile size.
1647 //
1648 microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
1649
1650 microTileBytes = microTileBits / 8;
1651 //
1652 // Compute the pixel index within the micro tile.
1653 //
1654 pixelIndex = ComputePixelIndexWithinMicroTile(x,
1655 y,
1656 slice,
1657 bpp,
1658 tileMode,
1659 microTileType);
1660
1661 //
1662 // Compute the sample offset and pixel offset.
1663 //
1664 if (isDepthSampleOrder)
1665 {
1666 //
1667 // For depth surfaces, samples are stored contiguously for each element, so the sample
1668 // offset is the sample number times the element size.
1669 //
1670 sampleOffset = sample * bpp;
1671 pixelOffset = pixelIndex * bpp * numSamples;
1672 }
1673 else
1674 {
1675 //
1676 // For color surfaces, all elements for a particular sample are stored contiguously, so
1677 // the sample offset is the sample number times the micro tile size divided yBit the number
1678 // of samples.
1679 //
1680 sampleOffset = sample * (microTileBits / numSamples);
1681 pixelOffset = pixelIndex * bpp;
1682 }
1683
1684 //
1685 // Compute the element offset.
1686 //
1687 elementOffset = pixelOffset + sampleOffset;
1688
1689 *pBitPosition = static_cast<UINT_32>(elementOffset % 8);
1690
1691 elementOffset /= 8; //bit-to-byte
1692
1693 //
1694 // Determine if tiles need to be split across slices.
1695 //
1696 // If the size of the micro tile is larger than the tile split size, then the tile will be
1697 // split across multiple slices.
1698 //
1699 UINT_32 slicesPerTile = 1;
1700
1701 if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
1702 { //don't support for thick mode
1703
1704 //
1705 // Compute the number of slices per tile.
1706 //
1707 slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
1708
1709 //
1710 // Compute the tile split slice number for use in rotating the bank.
1711 //
1712 tileSplitSlice = elementOffset / pTileInfo->tileSplitBytes;
1713
1714 //
1715 // Adjust the element offset to account for the portion of the tile that is being moved to
1716 // a new slice..
1717 //
1718 elementOffset %= pTileInfo->tileSplitBytes;
1719
1720 //
1721 // Adjust the microTileBytes size to tileSplitBytes size since
1722 // a new slice..
1723 //
1724 microTileBytes = pTileInfo->tileSplitBytes;
1725 }
1726 else
1727 {
1728 tileSplitSlice = 0;
1729 }
1730
1731 //
1732 // Compute macro tile pitch and height.
1733 //
1734 macroTilePitch =
1735 (MicroTileWidth * pTileInfo->bankWidth * numPipes) * pTileInfo->macroAspectRatio;
1736 macroTileHeight =
1737 (MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks) / pTileInfo->macroAspectRatio;
1738
1739 //
1740 // Compute the number of bytes per macro tile. Note: bytes of the same bank/pipe actually
1741 //
1742 macroTileBytes =
1743 static_cast<UINT_64>(microTileBytes) *
1744 (macroTilePitch / MicroTileWidth) * (macroTileHeight / MicroTileHeight) /
1745 (numPipes * pTileInfo->banks);
1746
1747 //
1748 // Compute the number of macro tiles per row.
1749 //
1750 macroTilesPerRow = pitch / macroTilePitch;
1751
1752 //
1753 // Compute the offset to the macro tile containing the specified coordinate.
1754 //
1755 macroTileIndexX = x / macroTilePitch;
1756 macroTileIndexY = y / macroTileHeight;
1757 macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
1758
1759 //
1760 // Compute the number of macro tiles per slice.
1761 //
1762 macroTilesPerSlice = macroTilesPerRow * (height / macroTileHeight);
1763
1764 //
1765 // Compute the slice size.
1766 //
1767 sliceBytes = macroTilesPerSlice * macroTileBytes;
1768
1769 //
1770 // Compute the slice offset.
1771 //
1772 sliceOffset = sliceBytes * (tileSplitSlice + slicesPerTile * (slice / microTileThickness));
1773
1774 //
1775 // Compute tile offest
1776 //
1777 tileRowIndex = (y / MicroTileHeight) % pTileInfo->bankHeight;
1778 tileColumnIndex = ((x / MicroTileWidth) / numPipes) % pTileInfo->bankWidth;
1779 tileIndex = (tileRowIndex * pTileInfo->bankWidth) + tileColumnIndex;
1780 tileOffset = tileIndex * microTileBytes;
1781
1782 //
1783 // Combine the slice offset and macro tile offset with the pixel and sample offsets, accounting
1784 // for the pipe and bank bits in the middle of the address.
1785 //
1786 totalOffset = sliceOffset + macroTileOffset + elementOffset + tileOffset;
1787
1788 //
1789 // Get the pipe and bank.
1790 //
1791
1792 // when the tileMode is PRT type, then adjust x and y coordinates
1793 if (IsPrtNoRotationTileMode(tileMode))
1794 {
1795 x = x % macroTilePitch;
1796 y = y % macroTileHeight;
1797 }
1798
1799 pipe = ComputePipeFromCoord(x,
1800 y,
1801 slice,
1802 tileMode,
1803 pipeSwizzle,
1804 ignoreSE,
1805 pTileInfo);
1806
1807 bank = ComputeBankFromCoord(x,
1808 y,
1809 slice,
1810 tileMode,
1811 bankSwizzle,
1812 tileSplitSlice,
1813 pTileInfo);
1814
1815 //
1816 // Split the offset to put some bits below the pipe+bank bits and some above.
1817 //
1818 pipeInterleaveMask = (1 << numPipeInterleaveBits) - 1;
1819 bankInterleaveMask = (1 << numBankInterleaveBits) - 1;
1820 pipeInterleaveOffset = totalOffset & pipeInterleaveMask;
1821 bankInterleaveOffset = static_cast<UINT_32>((totalOffset >> numPipeInterleaveBits) &
1822 bankInterleaveMask);
1823 offset = totalOffset >> (numPipeInterleaveBits + numBankInterleaveBits);
1824
1825 //
1826 // Assemble the address from its components.
1827 //
1828 addr = pipeInterleaveOffset;
1829 // This is to remove /analyze warnings
1830 UINT_32 pipeBits = pipe << numPipeInterleaveBits;
1831 UINT_32 bankInterleaveBits = bankInterleaveOffset << (numPipeInterleaveBits + numPipeBits);
1832 UINT_32 bankBits = bank << (numPipeInterleaveBits + numPipeBits +
1833 numBankInterleaveBits);
1834 UINT_64 offsetBits = offset << (numPipeInterleaveBits + numPipeBits +
1835 numBankInterleaveBits + numBankBits);
1836
1837 addr |= pipeBits;
1838 addr |= bankInterleaveBits;
1839 addr |= bankBits;
1840 addr |= offsetBits;
1841
1842 return addr;
1843 }
1844
1845 /**
1846 ****************************************************************************************************
1847 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1848 *
1849 * @brief
1850 * Computes the surface address and bit position from a coordinate for 1D tilied
1851 * (micro tiled)
1852 * @return
1853 * The byte address
1854 ****************************************************************************************************
1855 */
1856 UINT_64 EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1857 UINT_32 x, ///< [in] x coordinate
1858 UINT_32 y, ///< [in] y coordinate
1859 UINT_32 slice, ///< [in] slice index
1860 UINT_32 sample, ///< [in] sample index
1861 UINT_32 bpp, ///< [in] bits per pixel
1862 UINT_32 pitch, ///< [in] pitch, in pixels
1863 UINT_32 height, ///< [in] height, in pixels
1864 UINT_32 numSamples, ///< [in] number of samples
1865 AddrTileMode tileMode, ///< [in] tile mode
1866 AddrTileType microTileType, ///< [in] micro tiling type
1867 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample ordering is used
1868 UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this
1869 ) const
1870 {
1871 UINT_64 addr = 0;
1872
1873 UINT_32 microTileBytes;
1874 UINT_64 sliceBytes;
1875 UINT_32 microTilesPerRow;
1876 UINT_32 microTileIndexX;
1877 UINT_32 microTileIndexY;
1878 UINT_32 microTileIndexZ;
1879 UINT_64 sliceOffset;
1880 UINT_64 microTileOffset;
1881 UINT_32 sampleOffset;
1882 UINT_32 pixelIndex;
1883 UINT_32 pixelOffset;
1884
1885 UINT_32 microTileThickness = Thickness(tileMode);
1886
1887 //
1888 // Compute the micro tile size.
1889 //
1890 microTileBytes = BITS_TO_BYTES(MicroTilePixels * microTileThickness * bpp * numSamples);
1891
1892 //
1893 // Compute the slice size.
1894 //
1895 sliceBytes =
1896 BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples);
1897
1898 //
1899 // Compute the number of micro tiles per row.
1900 //
1901 microTilesPerRow = pitch / MicroTileWidth;
1902
1903 //
1904 // Compute the micro tile index.
1905 //
1906 microTileIndexX = x / MicroTileWidth;
1907 microTileIndexY = y / MicroTileHeight;
1908 microTileIndexZ = slice / microTileThickness;
1909
1910 //
1911 // Compute the slice offset.
1912 //
1913 sliceOffset = static_cast<UINT_64>(microTileIndexZ) * sliceBytes;
1914
1915 //
1916 // Compute the offset to the micro tile containing the specified coordinate.
1917 //
1918 microTileOffset = (static_cast<UINT_64>(microTileIndexY) * microTilesPerRow + microTileIndexX) *
1919 microTileBytes;
1920
1921 //
1922 // Compute the pixel index within the micro tile.
1923 //
1924 pixelIndex = ComputePixelIndexWithinMicroTile(x,
1925 y,
1926 slice,
1927 bpp,
1928 tileMode,
1929 microTileType);
1930
1931 // Compute the sample offset.
1932 //
1933 if (isDepthSampleOrder)
1934 {
1935 //
1936 // For depth surfaces, samples are stored contiguously for each element, so the sample
1937 // offset is the sample number times the element size.
1938 //
1939 sampleOffset = sample * bpp;
1940 pixelOffset = pixelIndex * bpp * numSamples;
1941 }
1942 else
1943 {
1944 //
1945 // For color surfaces, all elements for a particular sample are stored contiguously, so
1946 // the sample offset is the sample number times the micro tile size divided yBit the number
1947 // of samples.
1948 //
1949 sampleOffset = sample * (microTileBytes*8 / numSamples);
1950 pixelOffset = pixelIndex * bpp;
1951 }
1952
1953 //
1954 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1955 //
1956
1957 UINT_32 elemOffset = sampleOffset + pixelOffset;
1958
1959 *pBitPosition = elemOffset % 8;
1960 elemOffset /= 8;
1961
1962 //
1963 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1964 //
1965 addr = sliceOffset + microTileOffset + elemOffset;
1966
1967 return addr;
1968 }
1969
1970 /**
1971 ****************************************************************************************************
1972 * EgBasedLib::HwlComputePixelCoordFromOffset
1973 *
1974 * @brief
1975 * Compute pixel coordinate from offset inside a micro tile
1976 * @return
1977 * N/A
1978 ****************************************************************************************************
1979 */
1980 VOID EgBasedLib::HwlComputePixelCoordFromOffset(
1981 UINT_32 offset, ///< [in] offset inside micro tile in bits
1982 UINT_32 bpp, ///< [in] bits per pixel
1983 UINT_32 numSamples, ///< [in] number of samples
1984 AddrTileMode tileMode, ///< [in] tile mode
1985 UINT_32 tileBase, ///< [in] base offset within a tile
1986 UINT_32 compBits, ///< [in] component bits actually needed(for planar surface)
1987 UINT_32* pX, ///< [out] x coordinate
1988 UINT_32* pY, ///< [out] y coordinate
1989 UINT_32* pSlice, ///< [out] slice index
1990 UINT_32* pSample, ///< [out] sample index
1991 AddrTileType microTileType, ///< [in] micro tiling type
1992 BOOL_32 isDepthSampleOrder ///< [in] TRUE if depth sample order in microtile is used
1993 ) const
1994 {
1995 UINT_32 x = 0;
1996 UINT_32 y = 0;
1997 UINT_32 z = 0;
1998 UINT_32 thickness = Thickness(tileMode);
1999
2000 // For planar surface, we adjust offset acoording to tile base
2001 if ((bpp != compBits) && (compBits != 0) && isDepthSampleOrder)
2002 {
2003 offset -= tileBase;
2004
2005 ADDR_ASSERT(microTileType == ADDR_NON_DISPLAYABLE ||
2006 microTileType == ADDR_DEPTH_SAMPLE_ORDER);
2007
2008 bpp = compBits;
2009 }
2010
2011 UINT_32 sampleTileBits;
2012 UINT_32 samplePixelBits;
2013 UINT_32 pixelIndex;
2014
2015 if (isDepthSampleOrder)
2016 {
2017 samplePixelBits = bpp * numSamples;
2018 pixelIndex = offset / samplePixelBits;
2019 *pSample = (offset % samplePixelBits) / bpp;
2020 }
2021 else
2022 {
2023 sampleTileBits = MicroTilePixels * bpp * thickness;
2024 *pSample = offset / sampleTileBits;
2025 pixelIndex = (offset % sampleTileBits) / bpp;
2026 }
2027
2028 if (microTileType != ADDR_THICK)
2029 {
2030 if (microTileType == ADDR_DISPLAYABLE) // displayable
2031 {
2032 switch (bpp)
2033 {
2034 case 8:
2035 x = pixelIndex & 0x7;
2036 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
2037 break;
2038 case 16:
2039 x = pixelIndex & 0x7;
2040 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
2041 break;
2042 case 32:
2043 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
2044 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
2045 break;
2046 case 64:
2047 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2048 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2049 break;
2050 case 128:
2051 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,1));
2052 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,0));
2053 break;
2054 default:
2055 break;
2056 }
2057 }
2058 else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2059 {
2060 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2061 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2062 }
2063 else if (microTileType == ADDR_ROTATED)
2064 {
2065 /*
2066 8-Bit Elements
2067 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2068
2069 16-Bit Elements
2070 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2071
2072 32-Bit Elements
2073 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2074
2075 64-Bit Elements
2076 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2077 */
2078 switch(bpp)
2079 {
2080 case 8:
2081 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
2082 y = pixelIndex & 0x7;
2083 break;
2084 case 16:
2085 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
2086 y = pixelIndex & 0x7;
2087 break;
2088 case 32:
2089 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
2090 y = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
2091 break;
2092 case 64:
2093 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2094 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2095 break;
2096 default:
2097 ADDR_ASSERT_ALWAYS();
2098 break;
2099 }
2100 }
2101
2102 if (thickness > 1) // thick
2103 {
2104 z = Bits2Number(3, _BIT(pixelIndex,8),_BIT(pixelIndex,7),_BIT(pixelIndex,6));
2105 }
2106 }
2107 else
2108 {
2109 ADDR_ASSERT((m_chipFamily >= ADDR_CHIP_FAMILY_CI) && (thickness > 1));
2110 /*
2111 8-Bit Elements and 16-Bit Elements
2112 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2113
2114 32-Bit Elements
2115 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2116
2117 64-Bit Elements and 128-Bit Elements
2118 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2119
2120 The equation to compute the element index for the extra thick tile:
2121 element_index[8] = z[2]
2122 */
2123 switch (bpp)
2124 {
2125 case 8:
2126 case 16: // fall-through
2127 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2128 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2129 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,4));
2130 break;
2131 case 32:
2132 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2133 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2134 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,3));
2135 break;
2136 case 64:
2137 case 128: // fall-through
2138 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,3),_BIT(pixelIndex,0));
2139 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2140 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,2));
2141 break;
2142 default:
2143 ADDR_ASSERT_ALWAYS();
2144 break;
2145 }
2146
2147 if (thickness == 8)
2148 {
2149 z += Bits2Number(3,_BIT(pixelIndex,8),0,0);
2150 }
2151 }
2152
2153 *pX = x;
2154 *pY = y;
2155 *pSlice += z;
2156 }
2157
2158 /**
2159 ****************************************************************************************************
2160 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2161 *
2162 * @brief
2163 * Compute (x,y,slice,sample) coordinates from surface address
2164 * @return
2165 * N/A
2166 ****************************************************************************************************
2167 */
2168 VOID EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2169 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
2170 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
2171 ) const
2172 {
2173 UINT_64 addr = pIn->addr;
2174 UINT_32 bitPosition = pIn->bitPosition;
2175 UINT_32 bpp = pIn->bpp;
2176 UINT_32 pitch = pIn->pitch;
2177 UINT_32 height = pIn->height;
2178 UINT_32 numSlices = pIn->numSlices;
2179 UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
2180 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
2181 AddrTileMode tileMode = pIn->tileMode;
2182 UINT_32 tileBase = pIn->tileBase;
2183 UINT_32 compBits = pIn->compBits;
2184 AddrTileType microTileType = pIn->tileType;
2185 BOOL_32 ignoreSE = pIn->ignoreSE;
2186 BOOL_32 isDepthSampleOrder = pIn->isDepth;
2187 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
2188
2189 UINT_32* pX = &pOut->x;
2190 UINT_32* pY = &pOut->y;
2191 UINT_32* pSlice = &pOut->slice;
2192 UINT_32* pSample = &pOut->sample;
2193
2194 if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2195 {
2196 isDepthSampleOrder = TRUE;
2197 }
2198
2199 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
2200 {
2201 if (numFrags != numSamples)
2202 {
2203 numSamples = numFrags;
2204 }
2205
2206 /// @note
2207 /// 128 bit/thick tiled surface doesn't support display tiling and
2208 /// mipmap chain must have the same tileType, so please fill tileType correctly
2209 if (IsLinear(pIn->tileMode) == FALSE)
2210 {
2211 if (bpp >= 128 || Thickness(tileMode) > 1)
2212 {
2213 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
2214 }
2215 }
2216 }
2217
2218 switch (tileMode)
2219 {
2220 case ADDR_TM_LINEAR_GENERAL://fall through
2221 case ADDR_TM_LINEAR_ALIGNED:
2222 ComputeSurfaceCoordFromAddrLinear(addr,
2223 bitPosition,
2224 bpp,
2225 pitch,
2226 height,
2227 numSlices,
2228 pX,
2229 pY,
2230 pSlice,
2231 pSample);
2232 break;
2233 case ADDR_TM_1D_TILED_THIN1://fall through
2234 case ADDR_TM_1D_TILED_THICK:
2235 ComputeSurfaceCoordFromAddrMicroTiled(addr,
2236 bitPosition,
2237 bpp,
2238 pitch,
2239 height,
2240 numSamples,
2241 tileMode,
2242 tileBase,
2243 compBits,
2244 pX,
2245 pY,
2246 pSlice,
2247 pSample,
2248 microTileType,
2249 isDepthSampleOrder);
2250 break;
2251 case ADDR_TM_2D_TILED_THIN1: //fall through
2252 case ADDR_TM_2D_TILED_THICK: //fall through
2253 case ADDR_TM_3D_TILED_THIN1: //fall through
2254 case ADDR_TM_3D_TILED_THICK: //fall through
2255 case ADDR_TM_2D_TILED_XTHICK: //fall through
2256 case ADDR_TM_3D_TILED_XTHICK: //fall through
2257 case ADDR_TM_PRT_TILED_THIN1: //fall through
2258 case ADDR_TM_PRT_2D_TILED_THIN1://fall through
2259 case ADDR_TM_PRT_3D_TILED_THIN1://fall through
2260 case ADDR_TM_PRT_TILED_THICK: //fall through
2261 case ADDR_TM_PRT_2D_TILED_THICK://fall through
2262 case ADDR_TM_PRT_3D_TILED_THICK:
2263 UINT_32 pipeSwizzle;
2264 UINT_32 bankSwizzle;
2265
2266 if (m_configFlags.useCombinedSwizzle)
2267 {
2268 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
2269 &bankSwizzle, &pipeSwizzle);
2270 }
2271 else
2272 {
2273 pipeSwizzle = pIn->pipeSwizzle;
2274 bankSwizzle = pIn->bankSwizzle;
2275 }
2276
2277 ComputeSurfaceCoordFromAddrMacroTiled(addr,
2278 bitPosition,
2279 bpp,
2280 pitch,
2281 height,
2282 numSamples,
2283 tileMode,
2284 tileBase,
2285 compBits,
2286 microTileType,
2287 ignoreSE,
2288 isDepthSampleOrder,
2289 pipeSwizzle,
2290 bankSwizzle,
2291 pTileInfo,
2292 pX,
2293 pY,
2294 pSlice,
2295 pSample);
2296 break;
2297 default:
2298 ADDR_ASSERT_ALWAYS();
2299 }
2300 }
2301
2302 /**
2303 ****************************************************************************************************
2304 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2305 *
2306 * @brief
2307 * Compute surface coordinates from address for macro tiled surface
2308 * @return
2309 * N/A
2310 ****************************************************************************************************
2311 */
2312 VOID EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2313 UINT_64 addr, ///< [in] byte address
2314 UINT_32 bitPosition, ///< [in] bit position
2315 UINT_32 bpp, ///< [in] bits per pixel
2316 UINT_32 pitch, ///< [in] pitch in pixels
2317 UINT_32 height, ///< [in] height in pixels
2318 UINT_32 numSamples, ///< [in] number of samples
2319 AddrTileMode tileMode, ///< [in] tile mode
2320 UINT_32 tileBase, ///< [in] tile base offset
2321 UINT_32 compBits, ///< [in] component bits (for planar surface)
2322 AddrTileType microTileType, ///< [in] micro tiling type
2323 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines can be ignored
2324 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample order is used
2325 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2326 UINT_32 bankSwizzle, ///< [in] bank swizzle
2327 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure.
2328 /// **All fields to be valid on entry**
2329 UINT_32* pX, ///< [out] X coord
2330 UINT_32* pY, ///< [out] Y coord
2331 UINT_32* pSlice, ///< [out] slice index
2332 UINT_32* pSample ///< [out] sample index
2333 ) const
2334 {
2335 UINT_32 mx;
2336 UINT_32 my;
2337 UINT_64 tileBits;
2338 UINT_64 macroTileBits;
2339 UINT_32 slices;
2340 UINT_32 tileSlices;
2341 UINT_64 elementOffset;
2342 UINT_64 macroTileIndex;
2343 UINT_32 tileIndex;
2344 UINT_64 totalOffset;
2345
2346 UINT_32 bank;
2347 UINT_32 pipe;
2348 UINT_32 groupBits = m_pipeInterleaveBytes << 3;
2349 UINT_32 pipes = HwlGetPipes(pTileInfo);
2350 UINT_32 banks = pTileInfo->banks;
2351
2352 UINT_32 bankInterleave = m_bankInterleave;
2353
2354 UINT_64 addrBits = BYTES_TO_BITS(addr) + bitPosition;
2355
2356 //
2357 // remove bits for bank and pipe
2358 //
2359 totalOffset = (addrBits % groupBits) +
2360 (((addrBits / groupBits / pipes) % bankInterleave) * groupBits) +
2361 (((addrBits / groupBits / pipes) / bankInterleave) / banks) * groupBits * bankInterleave;
2362
2363 UINT_32 microTileThickness = Thickness(tileMode);
2364
2365 UINT_32 microTileBits = bpp * microTileThickness * MicroTilePixels * numSamples;
2366
2367 UINT_32 microTileBytes = BITS_TO_BYTES(microTileBits);
2368 //
2369 // Determine if tiles need to be split across slices.
2370 //
2371 // If the size of the micro tile is larger than the tile split size, then the tile will be
2372 // split across multiple slices.
2373 //
2374 UINT_32 slicesPerTile = 1; //_State->TileSlices
2375
2376 if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
2377 { //don't support for thick mode
2378
2379 //
2380 // Compute the number of slices per tile.
2381 //
2382 slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
2383 }
2384
2385 tileBits = microTileBits / slicesPerTile; // micro tile bits
2386
2387 // in micro tiles because not MicroTileWidth timed.
2388 UINT_32 macroWidth = pTileInfo->bankWidth * pipes * pTileInfo->macroAspectRatio;
2389 // in micro tiles as well
2390 UINT_32 macroHeight = pTileInfo->bankHeight * banks / pTileInfo->macroAspectRatio;
2391
2392 UINT_32 pitchInMacroTiles = pitch / MicroTileWidth / macroWidth;
2393
2394 macroTileBits = (macroWidth * macroHeight) * tileBits / (banks * pipes);
2395
2396 macroTileIndex = totalOffset / macroTileBits;
2397
2398 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2399 UINT_32 macroTilesPerSlice = (pitch / (macroWidth * MicroTileWidth)) * height /
2400 (macroHeight * MicroTileWidth);
2401
2402 slices = static_cast<UINT_32>(macroTileIndex / macroTilesPerSlice);
2403
2404 *pSlice = static_cast<UINT_32>(slices / slicesPerTile * microTileThickness);
2405
2406 //
2407 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2408 //
2409 tileSlices = slices % slicesPerTile;
2410
2411 elementOffset = tileSlices * tileBits;
2412 elementOffset += totalOffset % tileBits;
2413
2414 UINT_32 coordZ = 0;
2415
2416 HwlComputePixelCoordFromOffset(static_cast<UINT_32>(elementOffset),
2417 bpp,
2418 numSamples,
2419 tileMode,
2420 tileBase,
2421 compBits,
2422 pX,
2423 pY,
2424 &coordZ,
2425 pSample,
2426 microTileType,
2427 isDepthSampleOrder);
2428
2429 macroTileIndex = macroTileIndex % macroTilesPerSlice;
2430 *pY += static_cast<UINT_32>(macroTileIndex / pitchInMacroTiles * macroHeight * MicroTileHeight);
2431 *pX += static_cast<UINT_32>(macroTileIndex % pitchInMacroTiles * macroWidth * MicroTileWidth);
2432
2433 *pSlice += coordZ;
2434
2435 tileIndex = static_cast<UINT_32>((totalOffset % macroTileBits) / tileBits);
2436
2437 my = (tileIndex / pTileInfo->bankWidth) % pTileInfo->bankHeight * MicroTileHeight;
2438 mx = (tileIndex % pTileInfo->bankWidth) * pipes * MicroTileWidth;
2439
2440 *pY += my;
2441 *pX += mx;
2442
2443 bank = ComputeBankFromAddr(addr, banks, pipes);
2444 pipe = ComputePipeFromAddr(addr, pipes);
2445
2446 HwlComputeSurfaceCoord2DFromBankPipe(tileMode,
2447 pX,
2448 pY,
2449 *pSlice,
2450 bank,
2451 pipe,
2452 bankSwizzle,
2453 pipeSwizzle,
2454 tileSlices,
2455 ignoreSE,
2456 pTileInfo);
2457 }
2458
2459 /**
2460 ****************************************************************************************************
2461 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2462 *
2463 * @brief
2464 * Compute surface x,y coordinates from bank/pipe info
2465 * @return
2466 * N/A
2467 ****************************************************************************************************
2468 */
2469 VOID EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2470 AddrTileMode tileMode, ///< [in] tile mode
2471 UINT_32 x, ///< [in] x coordinate
2472 UINT_32 y, ///< [in] y coordinate
2473 UINT_32 slice, ///< [in] slice index
2474 UINT_32 bank, ///< [in] bank number
2475 UINT_32 pipe, ///< [in] pipe number
2476 UINT_32 bankSwizzle,///< [in] bank swizzle
2477 UINT_32 pipeSwizzle,///< [in] pipe swizzle
2478 UINT_32 tileSlices, ///< [in] slices in a micro tile
2479 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry**
2480 CoordFromBankPipe* pOutput ///< [out] pointer to extracted x/y bits
2481 ) const
2482 {
2483 UINT_32 yBit3 = 0;
2484 UINT_32 yBit4 = 0;
2485 UINT_32 yBit5 = 0;
2486 UINT_32 yBit6 = 0;
2487
2488 UINT_32 xBit3 = 0;
2489 UINT_32 xBit4 = 0;
2490 UINT_32 xBit5 = 0;
2491
2492 UINT_32 tileSplitRotation;
2493
2494 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2495
2496 UINT_32 bankRotation = ComputeBankRotation(tileMode,
2497 pTileInfo->banks, numPipes);
2498
2499 UINT_32 pipeRotation = ComputePipeRotation(tileMode, numPipes);
2500
2501 UINT_32 xBit = x / (MicroTileWidth * pTileInfo->bankWidth * numPipes);
2502 UINT_32 yBit = y / (MicroTileHeight * pTileInfo->bankHeight);
2503
2504 //calculate the bank and pipe before rotation and swizzle
2505
2506 switch (tileMode)
2507 {
2508 case ADDR_TM_2D_TILED_THIN1: //fall through
2509 case ADDR_TM_2D_TILED_THICK: //fall through
2510 case ADDR_TM_2D_TILED_XTHICK: //fall through
2511 case ADDR_TM_3D_TILED_THIN1: //fall through
2512 case ADDR_TM_3D_TILED_THICK: //fall through
2513 case ADDR_TM_3D_TILED_XTHICK:
2514 tileSplitRotation = ((pTileInfo->banks / 2) + 1);
2515 break;
2516 default:
2517 tileSplitRotation = 0;
2518 break;
2519 }
2520
2521 UINT_32 microTileThickness = Thickness(tileMode);
2522
2523 bank ^= tileSplitRotation * tileSlices;
2524 if (pipeRotation == 0)
2525 {
2526 bank ^= bankRotation * (slice / microTileThickness) + bankSwizzle;
2527 bank %= pTileInfo->banks;
2528 pipe ^= pipeSwizzle;
2529 }
2530 else
2531 {
2532 bank ^= bankRotation * (slice / microTileThickness) / numPipes + bankSwizzle;
2533 bank %= pTileInfo->banks;
2534 pipe ^= pipeRotation * (slice / microTileThickness) + pipeSwizzle;
2535 }
2536
2537 if (pTileInfo->macroAspectRatio == 1)
2538 {
2539 switch (pTileInfo->banks)
2540 {
2541 case 2:
2542 yBit3 = _BIT(bank, 0) ^ _BIT(xBit,0);
2543 break;
2544 case 4:
2545 yBit4 = _BIT(bank, 0) ^ _BIT(xBit,0);
2546 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2547 break;
2548 case 8:
2549 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2550 yBit5 = _BIT(bank, 0) ^ _BIT(xBit,0);
2551 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ yBit5;
2552 break;
2553 case 16:
2554 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3);
2555 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2);
2556 yBit6 = _BIT(bank, 0) ^ _BIT(xBit, 0);
2557 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ yBit6;
2558 break;
2559 default:
2560 break;
2561 }
2562
2563 }
2564 else if (pTileInfo->macroAspectRatio == 2)
2565 {
2566 switch (pTileInfo->banks)
2567 {
2568 case 2: //xBit3 = yBit3^b0
2569 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,0);
2570 break;
2571 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2572 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2573 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2574 break;
2575 case 8: //xBit4, xBit5, yBit5 are known
2576 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2577 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2578 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ _BIT(yBit, 2);
2579 break;
2580 case 16://x4,x5,x6,y6 are known
2581 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3); //x3 = y6 ^ b0
2582 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2583 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = x5 ^ b2
2584 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ _BIT(yBit, 3); //y5=x4^y6^b1
2585 break;
2586 default:
2587 break;
2588 }
2589 }
2590 else if (pTileInfo->macroAspectRatio == 4)
2591 {
2592 switch (pTileInfo->banks)
2593 {
2594 case 4: //yBit3, yBit4
2595 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2596 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,0);
2597 break;
2598 case 8: //xBit5, yBit4, yBit5
2599 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2600 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2601 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit,2);
2602 break;
2603 case 16: //xBit5, xBit6, yBit5, yBit6
2604 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = b0 ^ y6
2605 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = b1 ^ y5 ^ y6;
2606 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = b3 ^ x6;
2607 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = b2 ^ x5;
2608 break;
2609 default:
2610 break;
2611 }
2612 }
2613 else if (pTileInfo->macroAspectRatio == 8)
2614 {
2615 switch (pTileInfo->banks)
2616 {
2617 case 8: //yBit3, yBit4, yBit5
2618 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); //x3 = b0 ^ y5;
2619 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit, 2);//x4 = b1 ^ y4 ^ y5;
2620 xBit5 = _BIT(bank, 2) ^ _BIT(yBit,0);
2621 break;
2622 case 16: //xBit6, yBit4, yBit5, yBit6
2623 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = y6 ^ b0
2624 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = y5 ^ y6 ^ b1
2625 xBit5 = _BIT(bank, 2) ^ _BIT(yBit, 1);//x5 = y4 ^ b2
2626 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2627 break;
2628 default:
2629 break;
2630 }
2631 }
2632
2633 pOutput->xBits = xBit;
2634 pOutput->yBits = yBit;
2635
2636 pOutput->xBit3 = xBit3;
2637 pOutput->xBit4 = xBit4;
2638 pOutput->xBit5 = xBit5;
2639 pOutput->yBit3 = yBit3;
2640 pOutput->yBit4 = yBit4;
2641 pOutput->yBit5 = yBit5;
2642 pOutput->yBit6 = yBit6;
2643 }
2644
2645 /**
2646 ****************************************************************************************************
2647 * EgBasedLib::HwlExtractBankPipeSwizzle
2648 * @brief
2649 * Entry of EgBasedLib ExtractBankPipeSwizzle
2650 * @return
2651 * ADDR_E_RETURNCODE
2652 ****************************************************************************************************
2653 */
2654 ADDR_E_RETURNCODE EgBasedLib::HwlExtractBankPipeSwizzle(
2655 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
2656 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
2657 ) const
2658 {
2659 ExtractBankPipeSwizzle(pIn->base256b,
2660 pIn->pTileInfo,
2661 &pOut->bankSwizzle,
2662 &pOut->pipeSwizzle);
2663
2664 return ADDR_OK;
2665 }
2666
2667 /**
2668 ****************************************************************************************************
2669 * EgBasedLib::HwlCombineBankPipeSwizzle
2670 * @brief
2671 * Combine bank/pipe swizzle
2672 * @return
2673 * ADDR_E_RETURNCODE
2674 ****************************************************************************************************
2675 */
2676 ADDR_E_RETURNCODE EgBasedLib::HwlCombineBankPipeSwizzle(
2677 UINT_32 bankSwizzle, ///< [in] bank swizzle
2678 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2679 ADDR_TILEINFO* pTileInfo, ///< [in] tile info
2680 UINT_64 baseAddr, ///< [in] base address
2681 UINT_32* pTileSwizzle ///< [out] combined swizzle
2682 ) const
2683 {
2684 ADDR_E_RETURNCODE retCode = ADDR_OK;
2685
2686 if (pTileSwizzle)
2687 {
2688 *pTileSwizzle = GetBankPipeSwizzle(bankSwizzle, pipeSwizzle, baseAddr, pTileInfo);
2689 }
2690 else
2691 {
2692 retCode = ADDR_INVALIDPARAMS;
2693 }
2694
2695 return retCode;
2696 }
2697
2698 /**
2699 ****************************************************************************************************
2700 * EgBasedLib::HwlComputeBaseSwizzle
2701 * @brief
2702 * Compute base swizzle
2703 * @return
2704 * ADDR_E_RETURNCODE
2705 ****************************************************************************************************
2706 */
2707 ADDR_E_RETURNCODE EgBasedLib::HwlComputeBaseSwizzle(
2708 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
2709 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut
2710 ) const
2711 {
2712 UINT_32 bankSwizzle = 0;
2713 UINT_32 pipeSwizzle = 0;
2714 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
2715
2716 ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
2717 ADDR_ASSERT(pIn->pTileInfo);
2718
2719 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2720 static const UINT_8 bankRotationArray[4][16] = {
2721 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2722 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2723 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2724 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2725 };
2726
2727 UINT_32 pipes = HwlGetPipes(pTileInfo);
2728 (void)pipes;
2729 UINT_32 banks = pTileInfo ? pTileInfo->banks : 2;
2730 UINT_32 hwNumBanks;
2731
2732 // Uses less bank swizzle bits
2733 if (pIn->option.reduceBankBit && banks > 2)
2734 {
2735 banks >>= 1;
2736 }
2737
2738 switch (banks)
2739 {
2740 case 2:
2741 hwNumBanks = 0;
2742 break;
2743 case 4:
2744 hwNumBanks = 1;
2745 break;
2746 case 8:
2747 hwNumBanks = 2;
2748 break;
2749 case 16:
2750 hwNumBanks = 3;
2751 break;
2752 default:
2753 ADDR_ASSERT_ALWAYS();
2754 hwNumBanks = 0;
2755 break;
2756 }
2757
2758 if (pIn->option.genOption == ADDR_SWIZZLE_GEN_LINEAR)
2759 {
2760 bankSwizzle = pIn->surfIndex & (banks - 1);
2761 }
2762 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2763 {
2764 bankSwizzle = bankRotationArray[hwNumBanks][pIn->surfIndex & (banks - 1)];
2765 }
2766
2767 if (IsMacro3dTiled(pIn->tileMode))
2768 {
2769 pipeSwizzle = pIn->surfIndex & (HwlGetPipes(pTileInfo) - 1);
2770 }
2771
2772 return HwlCombineBankPipeSwizzle(bankSwizzle, pipeSwizzle, pTileInfo, 0, &pOut->tileSwizzle);
2773 }
2774
2775 /**
2776 ****************************************************************************************************
2777 * EgBasedLib::ExtractBankPipeSwizzle
2778 * @brief
2779 * Extract bank/pipe swizzle from base256b
2780 * @return
2781 * N/A
2782 ****************************************************************************************************
2783 */
2784 VOID EgBasedLib::ExtractBankPipeSwizzle(
2785 UINT_32 base256b, ///< [in] input base256b register value
2786 ADDR_TILEINFO* pTileInfo, ///< [in] 2D tile parameters. Client must provide all data
2787 UINT_32* pBankSwizzle, ///< [out] bank swizzle
2788 UINT_32* pPipeSwizzle ///< [out] pipe swizzle
2789 ) const
2790 {
2791 UINT_32 bankSwizzle = 0;
2792 UINT_32 pipeSwizzle = 0;
2793
2794 if (base256b != 0)
2795 {
2796 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2797 UINT_32 bankBits = QLog2(pTileInfo->banks);
2798 UINT_32 pipeBits = QLog2(numPipes);
2799 UINT_32 groupBytes = m_pipeInterleaveBytes;
2800 UINT_32 bankInterleave = m_bankInterleave;
2801
2802 pipeSwizzle =
2803 (base256b / (groupBytes >> 8)) & ((1<<pipeBits)-1);
2804
2805 bankSwizzle =
2806 (base256b / (groupBytes >> 8) / numPipes / bankInterleave) & ((1 << bankBits) - 1);
2807 }
2808
2809 *pPipeSwizzle = pipeSwizzle;
2810 *pBankSwizzle = bankSwizzle;
2811 }
2812
2813 /**
2814 ****************************************************************************************************
2815 * EgBasedLib::GetBankPipeSwizzle
2816 * @brief
2817 * Combine bank/pipe swizzle
2818 * @return
2819 * Base256b bits (only filled bank/pipe bits)
2820 ****************************************************************************************************
2821 */
2822 UINT_32 EgBasedLib::GetBankPipeSwizzle(
2823 UINT_32 bankSwizzle, ///< [in] bank swizzle
2824 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2825 UINT_64 baseAddr, ///< [in] base address
2826 ADDR_TILEINFO* pTileInfo ///< [in] tile info
2827 ) const
2828 {
2829 UINT_32 pipeBits = QLog2(HwlGetPipes(pTileInfo));
2830 UINT_32 bankInterleaveBits = QLog2(m_bankInterleave);
2831 UINT_32 tileSwizzle = pipeSwizzle + ((bankSwizzle << bankInterleaveBits) << pipeBits);
2832
2833 baseAddr ^= tileSwizzle * m_pipeInterleaveBytes;
2834 baseAddr >>= 8;
2835
2836 return static_cast<UINT_32>(baseAddr);
2837 }
2838
2839 /**
2840 ****************************************************************************************************
2841 * EgBasedLib::ComputeSliceTileSwizzle
2842 * @brief
2843 * Compute cubemap/3d texture faces/slices tile swizzle
2844 * @return
2845 * Tile swizzle
2846 ****************************************************************************************************
2847 */
2848 UINT_32 EgBasedLib::ComputeSliceTileSwizzle(
2849 AddrTileMode tileMode, ///< [in] Tile mode
2850 UINT_32 baseSwizzle, ///< [in] Base swizzle
2851 UINT_32 slice, ///< [in] Slice index, Cubemap face index, 0 means +X
2852 UINT_64 baseAddr, ///< [in] Base address
2853 ADDR_TILEINFO* pTileInfo ///< [in] Bank structure
2854 ) const
2855 {
2856 UINT_32 tileSwizzle = 0;
2857
2858 if (IsMacroTiled(tileMode)) // Swizzle only for macro tile mode
2859 {
2860 UINT_32 firstSlice = slice / Thickness(tileMode);
2861
2862 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2863 UINT_32 numBanks = pTileInfo->banks;
2864
2865 UINT_32 pipeRotation;
2866 UINT_32 bankRotation;
2867
2868 UINT_32 bankSwizzle = 0;
2869 UINT_32 pipeSwizzle = 0;
2870
2871 pipeRotation = ComputePipeRotation(tileMode, numPipes);
2872 bankRotation = ComputeBankRotation(tileMode, numBanks, numPipes);
2873
2874 if (baseSwizzle != 0)
2875 {
2876 ExtractBankPipeSwizzle(baseSwizzle,
2877 pTileInfo,
2878 &bankSwizzle,
2879 &pipeSwizzle);
2880 }
2881
2882 if (pipeRotation == 0) //2D mode
2883 {
2884 bankSwizzle += firstSlice * bankRotation;
2885 bankSwizzle %= numBanks;
2886 }
2887 else //3D mode
2888 {
2889 pipeSwizzle += firstSlice * pipeRotation;
2890 pipeSwizzle %= numPipes;
2891 bankSwizzle += firstSlice * bankRotation / numPipes;
2892 bankSwizzle %= numBanks;
2893 }
2894
2895 tileSwizzle = GetBankPipeSwizzle(bankSwizzle,
2896 pipeSwizzle,
2897 baseAddr,
2898 pTileInfo);
2899 }
2900
2901 return tileSwizzle;
2902 }
2903
2904 /**
2905 ****************************************************************************************************
2906 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2907 *
2908 * @brief
2909 * Compute right eye swizzle
2910 * @return
2911 * swizzle
2912 ****************************************************************************************************
2913 */
2914 UINT_32 EgBasedLib::HwlComputeQbStereoRightSwizzle(
2915 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo ///< [in] Surface info, must be valid
2916 ) const
2917 {
2918 UINT_32 bankBits = 0;
2919 UINT_32 swizzle = 0;
2920
2921 // The assumption is default swizzle for left eye is 0
2922 if (IsMacroTiled(pInfo->tileMode) && pInfo->pStereoInfo && pInfo->pTileInfo)
2923 {
2924 bankBits = ComputeBankFromCoord(0, pInfo->height, 0,
2925 pInfo->tileMode, 0, 0, pInfo->pTileInfo);
2926
2927 if (bankBits)
2928 {
2929 HwlCombineBankPipeSwizzle(bankBits, 0, pInfo->pTileInfo, 0, &swizzle);
2930 }
2931 }
2932
2933 return swizzle;
2934 }
2935
2936 /**
2937 ****************************************************************************************************
2938 * EgBasedLib::ComputeBankFromCoord
2939 *
2940 * @brief
2941 * Compute bank number from coordinates
2942 * @return
2943 * Bank number
2944 ****************************************************************************************************
2945 */
2946 UINT_32 EgBasedLib::ComputeBankFromCoord(
2947 UINT_32 x, ///< [in] x coordinate
2948 UINT_32 y, ///< [in] y coordinate
2949 UINT_32 slice, ///< [in] slice index
2950 AddrTileMode tileMode, ///< [in] tile mode
2951 UINT_32 bankSwizzle, ///< [in] bank swizzle
2952 UINT_32 tileSplitSlice, ///< [in] If the size of the pixel offset is larger than the
2953 /// tile split size, then the pixel will be moved to a separate
2954 /// slice. This value equals pixelOffset / tileSplitBytes
2955 /// in this case. Otherwise this is 0.
2956 ADDR_TILEINFO* pTileInfo ///< [in] tile info
2957 ) const
2958 {
2959 UINT_32 pipes = HwlGetPipes(pTileInfo);
2960 UINT_32 bankBit0 = 0;
2961 UINT_32 bankBit1 = 0;
2962 UINT_32 bankBit2 = 0;
2963 UINT_32 bankBit3 = 0;
2964 UINT_32 sliceRotation;
2965 UINT_32 tileSplitRotation;
2966 UINT_32 bank;
2967 UINT_32 numBanks = pTileInfo->banks;
2968 UINT_32 bankWidth = pTileInfo->bankWidth;
2969 UINT_32 bankHeight = pTileInfo->bankHeight;
2970
2971 UINT_32 tx = x / MicroTileWidth / (bankWidth * pipes);
2972 UINT_32 ty = y / MicroTileHeight / bankHeight;
2973
2974 UINT_32 x3 = _BIT(tx,0);
2975 UINT_32 x4 = _BIT(tx,1);
2976 UINT_32 x5 = _BIT(tx,2);
2977 UINT_32 x6 = _BIT(tx,3);
2978 UINT_32 y3 = _BIT(ty,0);
2979 UINT_32 y4 = _BIT(ty,1);
2980 UINT_32 y5 = _BIT(ty,2);
2981 UINT_32 y6 = _BIT(ty,3);
2982
2983 switch (numBanks)
2984 {
2985 case 16:
2986 bankBit0 = x3 ^ y6;
2987 bankBit1 = x4 ^ y5 ^ y6;
2988 bankBit2 = x5 ^ y4;
2989 bankBit3 = x6 ^ y3;
2990 break;
2991 case 8:
2992 bankBit0 = x3 ^ y5;
2993 bankBit1 = x4 ^ y4 ^ y5;
2994 bankBit2 = x5 ^ y3;
2995 break;
2996 case 4:
2997 bankBit0 = x3 ^ y4;
2998 bankBit1 = x4 ^ y3;
2999 break;
3000 case 2:
3001 bankBit0 = x3 ^ y3;
3002 break;
3003 default:
3004 ADDR_ASSERT_ALWAYS();
3005 break;
3006 }
3007
3008 bank = bankBit0 | (bankBit1 << 1) | (bankBit2 << 2) | (bankBit3 << 3);
3009
3010 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3011
3012 bank = HwlPreAdjustBank((x / MicroTileWidth), bank, pTileInfo);
3013 //
3014 // Compute bank rotation for the slice.
3015 //
3016 UINT_32 microTileThickness = Thickness(tileMode);
3017
3018 switch (tileMode)
3019 {
3020 case ADDR_TM_2D_TILED_THIN1: // fall through
3021 case ADDR_TM_2D_TILED_THICK: // fall through
3022 case ADDR_TM_2D_TILED_XTHICK:
3023 sliceRotation = ((numBanks / 2) - 1) * (slice / microTileThickness);
3024 break;
3025 case ADDR_TM_3D_TILED_THIN1: // fall through
3026 case ADDR_TM_3D_TILED_THICK: // fall through
3027 case ADDR_TM_3D_TILED_XTHICK:
3028 sliceRotation =
3029 Max(1u, (pipes / 2) - 1) * (slice / microTileThickness) / pipes;
3030 break;
3031 default:
3032 sliceRotation = 0;
3033 break;
3034 }
3035
3036 //
3037 // Compute bank rotation for the tile split slice.
3038 //
3039 // The sample slice will be non-zero if samples must be split across multiple slices.
3040 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3041 // the split size (set in GB_ADDR_CONFIG).
3042 //
3043 switch (tileMode)
3044 {
3045 case ADDR_TM_2D_TILED_THIN1: //fall through
3046 case ADDR_TM_3D_TILED_THIN1: //fall through
3047 case ADDR_TM_PRT_2D_TILED_THIN1: //fall through
3048 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
3049 tileSplitRotation = ((numBanks / 2) + 1) * tileSplitSlice;
3050 break;
3051 default:
3052 tileSplitRotation = 0;
3053 break;
3054 }
3055
3056 //
3057 // Apply bank rotation for the slice and tile split slice.
3058 //
3059 bank ^= bankSwizzle + sliceRotation;
3060 bank ^= tileSplitRotation;
3061
3062 bank &= (numBanks - 1);
3063
3064 return bank;
3065 }
3066
3067 /**
3068 ****************************************************************************************************
3069 * EgBasedLib::ComputeBankFromAddr
3070 *
3071 * @brief
3072 * Compute the bank number from an address
3073 * @return
3074 * Bank number
3075 ****************************************************************************************************
3076 */
3077 UINT_32 EgBasedLib::ComputeBankFromAddr(
3078 UINT_64 addr, ///< [in] address
3079 UINT_32 numBanks, ///< [in] number of banks
3080 UINT_32 numPipes ///< [in] number of pipes
3081 ) const
3082 {
3083 UINT_32 bank;
3084
3085 //
3086 // The LSBs of the address are arranged as follows:
3087 // bank | bankInterleave | pipe | pipeInterleave
3088 //
3089 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3090 // mask the bank bits.
3091 //
3092 bank = static_cast<UINT_32>(
3093 (addr >> Log2(m_pipeInterleaveBytes * numPipes * m_bankInterleave)) &
3094 (numBanks - 1)
3095 );
3096
3097 return bank;
3098 }
3099
3100 /**
3101 ****************************************************************************************************
3102 * EgBasedLib::ComputePipeRotation
3103 *
3104 * @brief
3105 * Compute pipe rotation value
3106 * @return
3107 * Pipe rotation
3108 ****************************************************************************************************
3109 */
3110 UINT_32 EgBasedLib::ComputePipeRotation(
3111 AddrTileMode tileMode, ///< [in] tile mode
3112 UINT_32 numPipes ///< [in] number of pipes
3113 ) const
3114 {
3115 UINT_32 rotation;
3116
3117 switch (tileMode)
3118 {
3119 case ADDR_TM_3D_TILED_THIN1: //fall through
3120 case ADDR_TM_3D_TILED_THICK: //fall through
3121 case ADDR_TM_3D_TILED_XTHICK: //fall through
3122 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
3123 case ADDR_TM_PRT_3D_TILED_THICK:
3124 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);
3125 break;
3126 default:
3127 rotation = 0;
3128 }
3129
3130 return rotation;
3131 }
3132
3133 /**
3134 ****************************************************************************************************
3135 * EgBasedLib::ComputeBankRotation
3136 *
3137 * @brief
3138 * Compute bank rotation value
3139 * @return
3140 * Bank rotation
3141 ****************************************************************************************************
3142 */
3143 UINT_32 EgBasedLib::ComputeBankRotation(
3144 AddrTileMode tileMode, ///< [in] tile mode
3145 UINT_32 numBanks, ///< [in] number of banks
3146 UINT_32 numPipes ///< [in] number of pipes
3147 ) const
3148 {
3149 UINT_32 rotation;
3150
3151 switch (tileMode)
3152 {
3153 case ADDR_TM_2D_TILED_THIN1: // fall through
3154 case ADDR_TM_2D_TILED_THICK: // fall through
3155 case ADDR_TM_2D_TILED_XTHICK:
3156 case ADDR_TM_PRT_2D_TILED_THIN1:
3157 case ADDR_TM_PRT_2D_TILED_THICK:
3158 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3159 rotation = numBanks / 2 - 1;
3160 break;
3161 case ADDR_TM_3D_TILED_THIN1: // fall through
3162 case ADDR_TM_3D_TILED_THICK: // fall through
3163 case ADDR_TM_3D_TILED_XTHICK:
3164 case ADDR_TM_PRT_3D_TILED_THIN1:
3165 case ADDR_TM_PRT_3D_TILED_THICK:
3166 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1); // rotate pipes & banks
3167 break;
3168 default:
3169 rotation = 0;
3170 }
3171
3172 return rotation;
3173 }
3174
3175 /**
3176 ****************************************************************************************************
3177 * EgBasedLib::ComputeHtileBytes
3178 *
3179 * @brief
3180 * Compute htile size in bytes
3181 *
3182 * @return
3183 * Htile size in bytes
3184 ****************************************************************************************************
3185 */
3186 UINT_64 EgBasedLib::ComputeHtileBytes(
3187 UINT_32 pitch, ///< [in] pitch
3188 UINT_32 height, ///< [in] height
3189 UINT_32 bpp, ///< [in] bits per pixel
3190 BOOL_32 isLinear, ///< [in] if it is linear mode
3191 UINT_32 numSlices, ///< [in] number of slices
3192 UINT_64* sliceBytes, ///< [out] bytes per slice
3193 UINT_32 baseAlign ///< [in] base alignments
3194 ) const
3195 {
3196 UINT_64 surfBytes;
3197
3198 const UINT_64 HtileCacheLineSize = BITS_TO_BYTES(HtileCacheBits);
3199
3200 *sliceBytes = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp / 64);
3201
3202 if (m_configFlags.useHtileSliceAlign)
3203 {
3204 // Align the sliceSize to htilecachelinesize * pipes at first
3205 *sliceBytes = PowTwoAlign(*sliceBytes, HtileCacheLineSize * m_pipes);
3206 surfBytes = *sliceBytes * numSlices;
3207 }
3208 else
3209 {
3210 // Align the surfSize to htilecachelinesize * pipes at last
3211 surfBytes = *sliceBytes * numSlices;
3212 surfBytes = PowTwoAlign(surfBytes, HtileCacheLineSize * m_pipes);
3213 }
3214
3215 return surfBytes;
3216 }
3217
3218 /**
3219 ****************************************************************************************************
3220 * EgBasedLib::DispatchComputeFmaskInfo
3221 *
3222 * @brief
3223 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3224 * meanwhile output suitable tile mode and alignments as well. Results are returned
3225 * through output parameters.
3226 *
3227 * @return
3228 * ADDR_E_RETURNCODE
3229 ****************************************************************************************************
3230 */
3231 ADDR_E_RETURNCODE EgBasedLib::DispatchComputeFmaskInfo(
3232 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
3233 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut) ///< [out] output structure
3234 {
3235 ADDR_E_RETURNCODE retCode = ADDR_OK;
3236
3237 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn = {0};
3238 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut = {0};
3239
3240 // Setup input structure
3241 surfIn.tileMode = pIn->tileMode;
3242 surfIn.width = pIn->pitch;
3243 surfIn.height = pIn->height;
3244 surfIn.numSlices = pIn->numSlices;
3245 surfIn.pTileInfo = pIn->pTileInfo;
3246 surfIn.tileType = ADDR_NON_DISPLAYABLE;
3247 surfIn.flags.fmask = 1;
3248
3249 // Setup output structure
3250 surfOut.pTileInfo = pOut->pTileInfo;
3251
3252 // Setup hwl specific fields
3253 HwlFmaskPreThunkSurfInfo(pIn, pOut, &surfIn, &surfOut);
3254
3255 surfIn.bpp = HwlComputeFmaskBits(pIn, &surfIn.numSamples);
3256
3257 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3258 surfOut.numSamples = surfIn.numSamples;
3259
3260 retCode = HwlComputeSurfaceInfo(&surfIn, &surfOut);
3261
3262 // Save bpp field for surface dump support
3263 surfOut.bpp = surfIn.bpp;
3264
3265 if (retCode == ADDR_OK)
3266 {
3267 pOut->bpp = surfOut.bpp;
3268 pOut->pitch = surfOut.pitch;
3269 pOut->height = surfOut.height;
3270 pOut->numSlices = surfOut.depth;
3271 pOut->fmaskBytes = surfOut.surfSize;
3272 pOut->baseAlign = surfOut.baseAlign;
3273 pOut->pitchAlign = surfOut.pitchAlign;
3274 pOut->heightAlign = surfOut.heightAlign;
3275
3276 if (surfOut.depth > 1)
3277 {
3278 // For fmask, expNumSlices is stored in depth.
3279 pOut->sliceSize = surfOut.surfSize / surfOut.depth;
3280 }
3281 else
3282 {
3283 pOut->sliceSize = surfOut.surfSize;
3284 }
3285
3286 // Save numSamples field for surface dump support
3287 pOut->numSamples = surfOut.numSamples;
3288
3289 HwlFmaskPostThunkSurfInfo(&surfOut, pOut);
3290 }
3291
3292 return retCode;
3293 }
3294
3295 /**
3296 ****************************************************************************************************
3297 * EgBasedLib::HwlFmaskSurfaceInfo
3298 * @brief
3299 * Entry of EgBasedLib ComputeFmaskInfo
3300 * @return
3301 * ADDR_E_RETURNCODE
3302 ****************************************************************************************************
3303 */
3304 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskInfo(
3305 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
3306 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
3307 )
3308 {
3309 ADDR_E_RETURNCODE retCode = ADDR_OK;
3310
3311 ADDR_TILEINFO tileInfo = {0};
3312
3313 // Use internal tile info if pOut does not have a valid pTileInfo
3314 if (pOut->pTileInfo == NULL)
3315 {
3316 pOut->pTileInfo = &tileInfo;
3317 }
3318
3319 retCode = DispatchComputeFmaskInfo(pIn, pOut);
3320
3321 if (retCode == ADDR_OK)
3322 {
3323 pOut->tileIndex =
3324 HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
3325 pOut->tileIndex);
3326 }
3327
3328 // Resets pTileInfo to NULL if the internal tile info is used
3329 if (pOut->pTileInfo == &tileInfo)
3330 {
3331 pOut->pTileInfo = NULL;
3332 }
3333
3334 return retCode;
3335 }
3336
3337 /**
3338 ****************************************************************************************************
3339 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3340 * @brief
3341 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3342 * @return
3343 * ADDR_E_RETURNCODE
3344 ****************************************************************************************************
3345 */
3346 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskAddrFromCoord(
3347 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3348 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3349 ) const
3350 {
3351 ADDR_E_RETURNCODE retCode = ADDR_OK;
3352
3353 return retCode;
3354 }
3355
3356 /**
3357 ****************************************************************************************************
3358 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3359 * @brief
3360 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3361 * @return
3362 * ADDR_E_RETURNCODE
3363 ****************************************************************************************************
3364 */
3365 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskCoordFromAddr(
3366 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
3367 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
3368 ) const
3369 {
3370 ADDR_E_RETURNCODE retCode = ADDR_OK;
3371
3372 return retCode;
3373 }
3374
3375 /**
3376 ****************************************************************************************************
3377 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
3378 *
3379 * @brief
3380 * Compute fmask number of planes from number of samples
3381 *
3382 * @return
3383 * Number of planes
3384 ****************************************************************************************************
3385 */
3386 UINT_32 EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
3387 UINT_32 numSamples) ///< [in] number of samples
3388 {
3389 UINT_32 numPlanes;
3390
3391 //
3392 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3393 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3394 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3395 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3396 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3397 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3398 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3399 // This was changed for R8xx to simplify the logic in the CB.
3400 //
3401 switch (numSamples)
3402 {
3403 case 2:
3404 numPlanes = 1;
3405 break;
3406 case 4:
3407 numPlanes = 2;
3408 break;
3409 case 8:
3410 numPlanes = 4;
3411 break;
3412 default:
3413 ADDR_UNHANDLED_CASE();
3414 numPlanes = 0;
3415 break;
3416 }
3417 return numPlanes;
3418 }
3419
3420 /**
3421 ****************************************************************************************************
3422 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
3423 *
3424 * @brief
3425 * Compute resolved fmask effective bpp based on number of samples
3426 *
3427 * @return
3428 * bpp
3429 ****************************************************************************************************
3430 */
3431 UINT_32 EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
3432 UINT_32 numSamples) ///< number of samples
3433 {
3434 UINT_32 bpp;
3435
3436 //
3437 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3438 // so that the texture unit can read compressed multi-sample color data.
3439 // These surfaces store each index value packed per element.
3440 // Each element contains at least num_samples * log2(num_samples) bits.
3441 // Resolved FMASK surfaces are addressed as follows:
3442 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3443 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3444 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3445
3446 switch (numSamples)
3447 {
3448 case 2:
3449 bpp = 8;
3450 break;
3451 case 4:
3452 bpp = 8;
3453 break;
3454 case 8:
3455 bpp = 32;
3456 break;
3457 default:
3458 ADDR_UNHANDLED_CASE();
3459 bpp = 0;
3460 break;
3461 }
3462 return bpp;
3463 }
3464
3465 /**
3466 ****************************************************************************************************
3467 * EgBasedLib::IsTileInfoAllZero
3468 *
3469 * @brief
3470 * Return TRUE if all field are zero
3471 * @note
3472 * Since NULL input is consider to be all zero
3473 ****************************************************************************************************
3474 */
3475 BOOL_32 EgBasedLib::IsTileInfoAllZero(
3476 const ADDR_TILEINFO* pTileInfo)
3477 {
3478 BOOL_32 allZero = TRUE;
3479
3480 if (pTileInfo)
3481 {
3482 if ((pTileInfo->banks != 0) ||
3483 (pTileInfo->bankWidth != 0) ||
3484 (pTileInfo->bankHeight != 0) ||
3485 (pTileInfo->macroAspectRatio != 0) ||
3486 (pTileInfo->tileSplitBytes != 0) ||
3487 (pTileInfo->pipeConfig != 0)
3488 )
3489 {
3490 allZero = FALSE;
3491 }
3492 }
3493
3494 return allZero;
3495 }
3496
3497 /**
3498 ****************************************************************************************************
3499 * EgBasedLib::HwlTileInfoEqual
3500 *
3501 * @brief
3502 * Return TRUE if all field are equal
3503 * @note
3504 * Only takes care of current HWL's data
3505 ****************************************************************************************************
3506 */
3507 BOOL_32 EgBasedLib::HwlTileInfoEqual(
3508 const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
3509 const ADDR_TILEINFO* pRight ///<[in] Right compare operand
3510 ) const
3511 {
3512 BOOL_32 equal = FALSE;
3513
3514 if (pLeft->banks == pRight->banks &&
3515 pLeft->bankWidth == pRight->bankWidth &&
3516 pLeft->bankHeight == pRight->bankHeight &&
3517 pLeft->macroAspectRatio == pRight->macroAspectRatio &&
3518 pLeft->tileSplitBytes == pRight->tileSplitBytes)
3519 {
3520 equal = TRUE;
3521 }
3522
3523 return equal;
3524 }
3525
3526 /**
3527 ****************************************************************************************************
3528 * EgBasedLib::HwlConvertTileInfoToHW
3529 * @brief
3530 * Entry of EgBasedLib ConvertTileInfoToHW
3531 * @return
3532 * ADDR_E_RETURNCODE
3533 ****************************************************************************************************
3534 */
3535 ADDR_E_RETURNCODE EgBasedLib::HwlConvertTileInfoToHW(
3536 const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
3537 ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
3538 ) const
3539 {
3540 ADDR_E_RETURNCODE retCode = ADDR_OK;
3541
3542 ADDR_TILEINFO *pTileInfoIn = pIn->pTileInfo;
3543 ADDR_TILEINFO *pTileInfoOut = pOut->pTileInfo;
3544
3545 if ((pTileInfoIn != NULL) && (pTileInfoOut != NULL))
3546 {
3547 if (pIn->reverse == FALSE)
3548 {
3549 switch (pTileInfoIn->banks)
3550 {
3551 case 2:
3552 pTileInfoOut->banks = 0;
3553 break;
3554 case 4:
3555 pTileInfoOut->banks = 1;
3556 break;
3557 case 8:
3558 pTileInfoOut->banks = 2;
3559 break;
3560 case 16:
3561 pTileInfoOut->banks = 3;
3562 break;
3563 default:
3564 ADDR_ASSERT_ALWAYS();
3565 retCode = ADDR_INVALIDPARAMS;
3566 pTileInfoOut->banks = 0;
3567 break;
3568 }
3569
3570 switch (pTileInfoIn->bankWidth)
3571 {
3572 case 1:
3573 pTileInfoOut->bankWidth = 0;
3574 break;
3575 case 2:
3576 pTileInfoOut->bankWidth = 1;
3577 break;
3578 case 4:
3579 pTileInfoOut->bankWidth = 2;
3580 break;
3581 case 8:
3582 pTileInfoOut->bankWidth = 3;
3583 break;
3584 default:
3585 ADDR_ASSERT_ALWAYS();
3586 retCode = ADDR_INVALIDPARAMS;
3587 pTileInfoOut->bankWidth = 0;
3588 break;
3589 }
3590
3591 switch (pTileInfoIn->bankHeight)
3592 {
3593 case 1:
3594 pTileInfoOut->bankHeight = 0;
3595 break;
3596 case 2:
3597 pTileInfoOut->bankHeight = 1;
3598 break;
3599 case 4:
3600 pTileInfoOut->bankHeight = 2;
3601 break;
3602 case 8:
3603 pTileInfoOut->bankHeight = 3;
3604 break;
3605 default:
3606 ADDR_ASSERT_ALWAYS();
3607 retCode = ADDR_INVALIDPARAMS;
3608 pTileInfoOut->bankHeight = 0;
3609 break;
3610 }
3611
3612 switch (pTileInfoIn->macroAspectRatio)
3613 {
3614 case 1:
3615 pTileInfoOut->macroAspectRatio = 0;
3616 break;
3617 case 2:
3618 pTileInfoOut->macroAspectRatio = 1;
3619 break;
3620 case 4:
3621 pTileInfoOut->macroAspectRatio = 2;
3622 break;
3623 case 8:
3624 pTileInfoOut->macroAspectRatio = 3;
3625 break;
3626 default:
3627 ADDR_ASSERT_ALWAYS();
3628 retCode = ADDR_INVALIDPARAMS;
3629 pTileInfoOut->macroAspectRatio = 0;
3630 break;
3631 }
3632
3633 switch (pTileInfoIn->tileSplitBytes)
3634 {
3635 case 64:
3636 pTileInfoOut->tileSplitBytes = 0;
3637 break;
3638 case 128:
3639 pTileInfoOut->tileSplitBytes = 1;
3640 break;
3641 case 256:
3642 pTileInfoOut->tileSplitBytes = 2;
3643 break;
3644 case 512:
3645 pTileInfoOut->tileSplitBytes = 3;
3646 break;
3647 case 1024:
3648 pTileInfoOut->tileSplitBytes = 4;
3649 break;
3650 case 2048:
3651 pTileInfoOut->tileSplitBytes = 5;
3652 break;
3653 case 4096:
3654 pTileInfoOut->tileSplitBytes = 6;
3655 break;
3656 default:
3657 ADDR_ASSERT_ALWAYS();
3658 retCode = ADDR_INVALIDPARAMS;
3659 pTileInfoOut->tileSplitBytes = 0;
3660 break;
3661 }
3662 }
3663 else
3664 {
3665 switch (pTileInfoIn->banks)
3666 {
3667 case 0:
3668 pTileInfoOut->banks = 2;
3669 break;
3670 case 1:
3671 pTileInfoOut->banks = 4;
3672 break;
3673 case 2:
3674 pTileInfoOut->banks = 8;
3675 break;
3676 case 3:
3677 pTileInfoOut->banks = 16;
3678 break;
3679 default:
3680 ADDR_ASSERT_ALWAYS();
3681 retCode = ADDR_INVALIDPARAMS;
3682 pTileInfoOut->banks = 2;
3683 break;
3684 }
3685
3686 switch (pTileInfoIn->bankWidth)
3687 {
3688 case 0:
3689 pTileInfoOut->bankWidth = 1;
3690 break;
3691 case 1:
3692 pTileInfoOut->bankWidth = 2;
3693 break;
3694 case 2:
3695 pTileInfoOut->bankWidth = 4;
3696 break;
3697 case 3:
3698 pTileInfoOut->bankWidth = 8;
3699 break;
3700 default:
3701 ADDR_ASSERT_ALWAYS();
3702 retCode = ADDR_INVALIDPARAMS;
3703 pTileInfoOut->bankWidth = 1;
3704 break;
3705 }
3706
3707 switch (pTileInfoIn->bankHeight)
3708 {
3709 case 0:
3710 pTileInfoOut->bankHeight = 1;
3711 break;
3712 case 1:
3713 pTileInfoOut->bankHeight = 2;
3714 break;
3715 case 2:
3716 pTileInfoOut->bankHeight = 4;
3717 break;
3718 case 3:
3719 pTileInfoOut->bankHeight = 8;
3720 break;
3721 default:
3722 ADDR_ASSERT_ALWAYS();
3723 retCode = ADDR_INVALIDPARAMS;
3724 pTileInfoOut->bankHeight = 1;
3725 break;
3726 }
3727
3728 switch (pTileInfoIn->macroAspectRatio)
3729 {
3730 case 0:
3731 pTileInfoOut->macroAspectRatio = 1;
3732 break;
3733 case 1:
3734 pTileInfoOut->macroAspectRatio = 2;
3735 break;
3736 case 2:
3737 pTileInfoOut->macroAspectRatio = 4;
3738 break;
3739 case 3:
3740 pTileInfoOut->macroAspectRatio = 8;
3741 break;
3742 default:
3743 ADDR_ASSERT_ALWAYS();
3744 retCode = ADDR_INVALIDPARAMS;
3745 pTileInfoOut->macroAspectRatio = 1;
3746 break;
3747 }
3748
3749 switch (pTileInfoIn->tileSplitBytes)
3750 {
3751 case 0:
3752 pTileInfoOut->tileSplitBytes = 64;
3753 break;
3754 case 1:
3755 pTileInfoOut->tileSplitBytes = 128;
3756 break;
3757 case 2:
3758 pTileInfoOut->tileSplitBytes = 256;
3759 break;
3760 case 3:
3761 pTileInfoOut->tileSplitBytes = 512;
3762 break;
3763 case 4:
3764 pTileInfoOut->tileSplitBytes = 1024;
3765 break;
3766 case 5:
3767 pTileInfoOut->tileSplitBytes = 2048;
3768 break;
3769 case 6:
3770 pTileInfoOut->tileSplitBytes = 4096;
3771 break;
3772 default:
3773 ADDR_ASSERT_ALWAYS();
3774 retCode = ADDR_INVALIDPARAMS;
3775 pTileInfoOut->tileSplitBytes = 64;
3776 break;
3777 }
3778 }
3779
3780 if (pTileInfoIn != pTileInfoOut)
3781 {
3782 pTileInfoOut->pipeConfig = pTileInfoIn->pipeConfig;
3783 }
3784 }
3785 else
3786 {
3787 ADDR_ASSERT_ALWAYS();
3788 retCode = ADDR_INVALIDPARAMS;
3789 }
3790
3791 return retCode;
3792 }
3793
3794 /**
3795 ****************************************************************************************************
3796 * EgBasedLib::HwlComputeSurfaceInfo
3797 * @brief
3798 * Entry of EgBasedLib ComputeSurfaceInfo
3799 * @return
3800 * ADDR_E_RETURNCODE
3801 ****************************************************************************************************
3802 */
3803 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceInfo(
3804 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
3805 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
3806 ) const
3807 {
3808 ADDR_E_RETURNCODE retCode = ADDR_OK;
3809
3810 if (pIn->numSamples < pIn->numFrags)
3811 {
3812 retCode = ADDR_INVALIDPARAMS;
3813 }
3814
3815 ADDR_TILEINFO tileInfo = {0};
3816
3817 if (retCode == ADDR_OK)
3818 {
3819 // Uses internal tile info if pOut does not have a valid pTileInfo
3820 if (pOut->pTileInfo == NULL)
3821 {
3822 pOut->pTileInfo = &tileInfo;
3823 }
3824
3825 if (DispatchComputeSurfaceInfo(pIn, pOut) == FALSE)
3826 {
3827 retCode = ADDR_INVALIDPARAMS;
3828 }
3829
3830 // In case client uses tile info as input and would like to calculate a correct size and
3831 // alignment together with tile info as output when the tile info is not suppose to have any
3832 // matching indices in tile mode tables.
3833 if (pIn->flags.skipIndicesOutput == FALSE)
3834 {
3835 // Returns an index
3836 pOut->tileIndex = HwlPostCheckTileIndex(pOut->pTileInfo,
3837 pOut->tileMode,
3838 pOut->tileType,
3839 pOut->tileIndex);
3840
3841 if (IsMacroTiled(pOut->tileMode) && (pOut->macroModeIndex == TileIndexInvalid))
3842 {
3843 pOut->macroModeIndex = HwlComputeMacroModeIndex(pOut->tileIndex,
3844 pIn->flags,
3845 pIn->bpp,
3846 pIn->numSamples,
3847 pOut->pTileInfo);
3848 }
3849 }
3850
3851 // Resets pTileInfo to NULL if the internal tile info is used
3852 if (pOut->pTileInfo == &tileInfo)
3853 {
3854 #if DEBUG
3855 // Client does not pass in a valid pTileInfo
3856 if (IsMacroTiled(pOut->tileMode))
3857 {
3858 // If a valid index is returned, then no pTileInfo is okay
3859 ADDR_ASSERT((m_configFlags.useTileIndex == FALSE) ||
3860 (pOut->tileIndex != TileIndexInvalid));
3861
3862 if (IsTileInfoAllZero(pIn->pTileInfo) == FALSE)
3863 {
3864 // The initial value of pIn->pTileInfo is copied to tileInfo
3865 // We do not expect any of these value to be changed nor any 0 of inputs
3866 ADDR_ASSERT(tileInfo.banks == pIn->pTileInfo->banks);
3867 ADDR_ASSERT(tileInfo.bankWidth == pIn->pTileInfo->bankWidth);
3868 ADDR_ASSERT(tileInfo.bankHeight == pIn->pTileInfo->bankHeight);
3869 ADDR_ASSERT(tileInfo.macroAspectRatio == pIn->pTileInfo->macroAspectRatio);
3870 ADDR_ASSERT(tileInfo.tileSplitBytes == pIn->pTileInfo->tileSplitBytes);
3871 }
3872 }
3873 #endif
3874 pOut->pTileInfo = NULL;
3875 }
3876 }
3877
3878 return retCode;
3879 }
3880
3881 /**
3882 ****************************************************************************************************
3883 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
3884 * @brief
3885 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
3886 * @return
3887 * ADDR_E_RETURNCODE
3888 ****************************************************************************************************
3889 */
3890 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceAddrFromCoord(
3891 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3892 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3893 ) const
3894 {
3895 ADDR_E_RETURNCODE retCode = ADDR_OK;
3896
3897 if (
3898 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
3899 (pIn->x > pIn->pitch) ||
3900 (pIn->y > pIn->height) ||
3901 #endif
3902 (pIn->numSamples > m_maxSamples))
3903 {
3904 retCode = ADDR_INVALIDPARAMS;
3905 }
3906 else
3907 {
3908 pOut->addr = DispatchComputeSurfaceAddrFromCoord(pIn, pOut);
3909 }
3910
3911 return retCode;
3912 }
3913
3914 /**
3915 ****************************************************************************************************
3916 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
3917 * @brief
3918 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3919 * @return
3920 * ADDR_E_RETURNCODE
3921 ****************************************************************************************************
3922 */
3923 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceCoordFromAddr(
3924 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
3925 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
3926 ) const
3927 {
3928 ADDR_E_RETURNCODE retCode = ADDR_OK;
3929
3930 if ((pIn->bitPosition >= 8) ||
3931 (pIn->numSamples > m_maxSamples))
3932 {
3933 retCode = ADDR_INVALIDPARAMS;
3934 }
3935 else
3936 {
3937 DispatchComputeSurfaceCoordFromAddr(pIn, pOut);
3938 }
3939 return retCode;
3940 }
3941
3942 /**
3943 ****************************************************************************************************
3944 * EgBasedLib::HwlComputeSliceTileSwizzle
3945 * @brief
3946 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3947 * @return
3948 * ADDR_E_RETURNCODE
3949 ****************************************************************************************************
3950 */
3951 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSliceTileSwizzle(
3952 const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure
3953 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure
3954 ) const
3955 {
3956 ADDR_E_RETURNCODE retCode = ADDR_OK;
3957
3958 if (pIn->pTileInfo && (pIn->pTileInfo->banks > 0))
3959 {
3960
3961 pOut->tileSwizzle = ComputeSliceTileSwizzle(pIn->tileMode,
3962 pIn->baseSwizzle,
3963 pIn->slice,
3964 pIn->baseAddr,
3965 pIn->pTileInfo);
3966 }
3967 else
3968 {
3969 retCode = ADDR_INVALIDPARAMS;
3970 }
3971
3972 return retCode;
3973 }
3974
3975 /**
3976 ****************************************************************************************************
3977 * EgBasedLib::HwlComputeHtileBpp
3978 *
3979 * @brief
3980 * Compute htile bpp
3981 *
3982 * @return
3983 * Htile bpp
3984 ****************************************************************************************************
3985 */
3986 UINT_32 EgBasedLib::HwlComputeHtileBpp(
3987 BOOL_32 isWidth8, ///< [in] TRUE if block width is 8
3988 BOOL_32 isHeight8 ///< [in] TRUE if block height is 8
3989 ) const
3990 {
3991 // only support 8x8 mode
3992 ADDR_ASSERT(isWidth8 && isHeight8);
3993 return 32;
3994 }
3995
3996 /**
3997 ****************************************************************************************************
3998 * EgBasedLib::HwlComputeHtileBaseAlign
3999 *
4000 * @brief
4001 * Compute htile base alignment
4002 *
4003 * @return
4004 * Htile base alignment
4005 ****************************************************************************************************
4006 */
4007 UINT_32 EgBasedLib::HwlComputeHtileBaseAlign(
4008 BOOL_32 isTcCompatible, ///< [in] if TC compatible
4009 BOOL_32 isLinear, ///< [in] if it is linear mode
4010 ADDR_TILEINFO* pTileInfo ///< [in] Tile info
4011 ) const
4012 {
4013 UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
4014
4015 if (isTcCompatible)
4016 {
4017 ADDR_ASSERT(pTileInfo != NULL);
4018 if (pTileInfo)
4019 {
4020 baseAlign *= pTileInfo->banks;
4021 }
4022 }
4023
4024 return baseAlign;
4025 }
4026
4027 /**
4028 ****************************************************************************************************
4029 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4030 *
4031 * @brief
4032 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4033 * output parameters.
4034 *
4035 * @return
4036 * pitch alignment
4037 ****************************************************************************************************
4038 */
4039 UINT_32 EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4040 AddrTileMode tileMode, ///< [in] tile mode
4041 UINT_32 bpp, ///< [in] bits per pixel
4042 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
4043 UINT_32 numSamples ///< [in] number of samples
4044 ) const
4045 {
4046 UINT_32 pitchAlign;
4047
4048 UINT_32 microTileThickness = Thickness(tileMode);
4049
4050 UINT_32 pixelsPerMicroTile;
4051 UINT_32 pixelsPerPipeInterleave;
4052 UINT_32 microTilesPerPipeInterleave;
4053
4054 //
4055 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4056 // stencil buffer since pitch alignment is related to bpp.
4057 // For a depth only buffer do not set this.
4058 //
4059 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4060 // sampled with mipmap.
4061 //
4062 if (flags.depth && (flags.noStencil == FALSE))
4063 {
4064 bpp = 8;
4065 }
4066
4067 pixelsPerMicroTile = MicroTilePixels * microTileThickness;
4068 pixelsPerPipeInterleave = BYTES_TO_BITS(m_pipeInterleaveBytes) / (bpp * numSamples);
4069 microTilesPerPipeInterleave = pixelsPerPipeInterleave / pixelsPerMicroTile;
4070
4071 pitchAlign = Max(MicroTileWidth, microTilesPerPipeInterleave * MicroTileWidth);
4072
4073 return pitchAlign;
4074 }
4075
4076 /**
4077 ****************************************************************************************************
4078 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4079 *
4080 * @brief
4081 * Adjust 1D tiled surface pitch and slice size
4082 *
4083 * @return
4084 * Logical slice size in bytes
4085 ****************************************************************************************************
4086 */
4087 UINT_64 EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4088 UINT_32 thickness, ///< [in] thickness
4089 UINT_32 bpp, ///< [in] bits per pixel
4090 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
4091 UINT_32 numSamples, ///< [in] number of samples
4092 UINT_32 baseAlign, ///< [in] base alignment
4093 UINT_32 pitchAlign, ///< [in] pitch alignment
4094 UINT_32* pPitch, ///< [in,out] pointer to pitch
4095 UINT_32* pHeight ///< [in,out] pointer to height
4096 ) const
4097 {
4098 UINT_64 logicalSliceSize;
4099 MAYBE_UNUSED UINT_64 physicalSliceSize;
4100
4101 UINT_32 pitch = *pPitch;
4102 UINT_32 height = *pHeight;
4103
4104 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4105 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
4106
4107 // Physical slice: multiplied by thickness
4108 physicalSliceSize = logicalSliceSize * thickness;
4109
4110 //
4111 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4112 //
4113 ADDR_ASSERT((physicalSliceSize % baseAlign) == 0);
4114
4115 return logicalSliceSize;
4116 }
4117
4118 /**
4119 ****************************************************************************************************
4120 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4121 *
4122 * @brief
4123 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4124 *
4125 * @return
4126 * TRUE is the extra padding is needed
4127 *
4128 ****************************************************************************************************
4129 */
4130 UINT_32 EgBasedLib::HwlStereoCheckRightOffsetPadding(
4131 ADDR_TILEINFO* pTileInfo ///< Tiling info
4132 ) const
4133 {
4134 UINT_32 stereoHeightAlign = 0;
4135
4136 if (pTileInfo->macroAspectRatio > 2)
4137 {
4138 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4139 // display engine treats it to be 0, so the bank bits may be different.
4140 // Additional padding in height is required to make sure it's possible
4141 // to achieve synonym by adjusting bank swizzle of right eye surface.
4142
4143 static const UINT_32 StereoAspectRatio = 2;
4144 stereoHeightAlign = pTileInfo->banks *
4145 pTileInfo->bankHeight *
4146 MicroTileHeight /
4147 StereoAspectRatio;
4148 }
4149
4150 return stereoHeightAlign;
4151 }
4152
4153 } // V1
4154 } // Addr