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