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