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