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