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