amd/addrlib: add gfx10 support
[mesa.git] / src / amd / addrlib / src / r800 / egbaddrlib.cpp
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 #include "util/macros.h"
36
37 namespace Addr
38 {
39 namespace V1
40 {
41
42 /**
43 ****************************************************************************************************
44 * EgBasedLib::EgBasedLib
45 *
46 * @brief
47 * Constructor
48 *
49 * @note
50 *
51 ****************************************************************************************************
52 */
53 EgBasedLib::EgBasedLib(const Client* pClient)
54 :
55 Lib(pClient),
56 m_ranks(0),
57 m_logicalBanks(0),
58 m_bankInterleave(1)
59 {
60 }
61
62 /**
63 ****************************************************************************************************
64 * EgBasedLib::~EgBasedLib
65 *
66 * @brief
67 * Destructor
68 ****************************************************************************************************
69 */
70 EgBasedLib::~EgBasedLib()
71 {
72 }
73
74 /**
75 ****************************************************************************************************
76 * EgBasedLib::DispatchComputeSurfaceInfo
77 *
78 * @brief
79 * Compute surface sizes include padded pitch,height,slices,total size in bytes,
80 * meanwhile output suitable tile mode and base alignment might be changed in this
81 * call as well. Results are returned through output parameters.
82 *
83 * @return
84 * TRUE if no error occurs
85 ****************************************************************************************************
86 */
87 BOOL_32 EgBasedLib::DispatchComputeSurfaceInfo(
88 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
89 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
90 ) const
91 {
92 AddrTileMode tileMode = pIn->tileMode;
93 UINT_32 bpp = pIn->bpp;
94 UINT_32 numSamples = pIn->numSamples;
95 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
96 UINT_32 pitch = pIn->width;
97 UINT_32 height = pIn->height;
98 UINT_32 numSlices = pIn->numSlices;
99 UINT_32 mipLevel = pIn->mipLevel;
100 ADDR_SURFACE_FLAGS flags = pIn->flags;
101
102 ADDR_TILEINFO tileInfoDef = {0};
103 ADDR_TILEINFO* pTileInfo = &tileInfoDef;
104 UINT_32 padDims = 0;
105 BOOL_32 valid;
106
107 if (pIn->flags.disallowLargeThickDegrade == 0)
108 {
109 tileMode = DegradeLargeThickTile(tileMode, bpp);
110 }
111
112 // Only override numSamples for NI above
113 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
114 {
115 if (numFrags != numSamples) // This means EQAA
116 {
117 // The real surface size needed is determined by number of fragments
118 numSamples = numFrags;
119 }
120
121 // Save altered numSamples in pOut
122 pOut->numSamples = numSamples;
123 }
124
125 // Caller makes sure pOut->pTileInfo is not NULL, see HwlComputeSurfaceInfo
126 ADDR_ASSERT(pOut->pTileInfo);
127
128 if (pOut->pTileInfo != NULL)
129 {
130 pTileInfo = pOut->pTileInfo;
131 }
132
133 // Set default values
134 if (pIn->pTileInfo != NULL)
135 {
136 if (pTileInfo != pIn->pTileInfo)
137 {
138 *pTileInfo = *pIn->pTileInfo;
139 }
140 }
141 else
142 {
143 memset(pTileInfo, 0, sizeof(ADDR_TILEINFO));
144 }
145
146 // For macro tile mode, we should calculate default tiling parameters
147 HwlSetupTileInfo(tileMode,
148 flags,
149 bpp,
150 pitch,
151 height,
152 numSamples,
153 pIn->pTileInfo,
154 pTileInfo,
155 pIn->tileType,
156 pOut);
157
158 if (flags.cube)
159 {
160 if (mipLevel == 0)
161 {
162 padDims = 2;
163 }
164
165 if (numSlices == 1)
166 {
167 // This is calculating one face, remove cube flag
168 flags.cube = 0;
169 }
170 }
171
172 switch (tileMode)
173 {
174 case ADDR_TM_LINEAR_GENERAL://fall through
175 case ADDR_TM_LINEAR_ALIGNED:
176 valid = ComputeSurfaceInfoLinear(pIn, pOut, padDims);
177 break;
178
179 case ADDR_TM_1D_TILED_THIN1://fall through
180 case ADDR_TM_1D_TILED_THICK:
181 valid = ComputeSurfaceInfoMicroTiled(pIn, pOut, padDims, tileMode);
182 break;
183
184 case ADDR_TM_2D_TILED_THIN1: //fall through
185 case ADDR_TM_2D_TILED_THICK: //fall through
186 case ADDR_TM_3D_TILED_THIN1: //fall through
187 case ADDR_TM_3D_TILED_THICK: //fall through
188 case ADDR_TM_2D_TILED_XTHICK: //fall through
189 case ADDR_TM_3D_TILED_XTHICK: //fall through
190 case ADDR_TM_PRT_TILED_THIN1: //fall through
191 case ADDR_TM_PRT_2D_TILED_THIN1://fall through
192 case ADDR_TM_PRT_3D_TILED_THIN1://fall through
193 case ADDR_TM_PRT_TILED_THICK: //fall through
194 case ADDR_TM_PRT_2D_TILED_THICK://fall through
195 case ADDR_TM_PRT_3D_TILED_THICK:
196 valid = ComputeSurfaceInfoMacroTiled(pIn, pOut, padDims, tileMode);
197 break;
198
199 default:
200 valid = FALSE;
201 ADDR_ASSERT_ALWAYS();
202 break;
203 }
204
205 return valid;
206 }
207
208 /**
209 ****************************************************************************************************
210 * EgBasedLib::ComputeSurfaceInfoLinear
211 *
212 * @brief
213 * Compute linear surface sizes include padded pitch, height, slices, total size in
214 * bytes, meanwhile alignments as well. Since it is linear mode, so output tile mode
215 * will not be changed here. Results are returned through output parameters.
216 *
217 * @return
218 * TRUE if no error occurs
219 ****************************************************************************************************
220 */
221 BOOL_32 EgBasedLib::ComputeSurfaceInfoLinear(
222 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
223 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
224 UINT_32 padDims ///< [in] Dimensions to padd
225 ) const
226 {
227 UINT_32 expPitch = pIn->width;
228 UINT_32 expHeight = pIn->height;
229 UINT_32 expNumSlices = pIn->numSlices;
230
231 // No linear MSAA on real H/W, keep this for TGL
232 UINT_32 numSamples = pOut->numSamples;
233
234 const UINT_32 microTileThickness = 1;
235
236 //
237 // Compute the surface alignments.
238 //
239 ComputeSurfaceAlignmentsLinear(pIn->tileMode,
240 pIn->bpp,
241 pIn->flags,
242 &pOut->baseAlign,
243 &pOut->pitchAlign,
244 &pOut->heightAlign);
245
246 if ((pIn->tileMode == ADDR_TM_LINEAR_GENERAL) && pIn->flags.color && (pIn->height > 1))
247 {
248 #if !ALT_TEST
249 // When linear_general surface is accessed in multiple lines, it requires 8 pixels in pitch
250 // alignment since PITCH_TILE_MAX is in unit of 8 pixels.
251 // It is OK if it is accessed per line.
252 ADDR_ASSERT((pIn->width % 8) == 0);
253 #endif
254 }
255
256 pOut->depthAlign = microTileThickness;
257
258 expPitch = HwlPreHandleBaseLvl3xPitch(pIn, expPitch);
259
260 //
261 // Pad pitch and height to the required granularities.
262 //
263 PadDimensions(pIn->tileMode,
264 pIn->bpp,
265 pIn->flags,
266 numSamples,
267 pOut->pTileInfo,
268 padDims,
269 pIn->mipLevel,
270 &expPitch, &pOut->pitchAlign,
271 &expHeight, pOut->heightAlign,
272 &expNumSlices, microTileThickness);
273
274 expPitch = HwlPostHandleBaseLvl3xPitch(pIn, expPitch);
275
276 //
277 // Adjust per HWL
278 //
279
280 UINT_64 logicalSliceSize;
281
282 logicalSliceSize = HwlGetSizeAdjustmentLinear(pIn->tileMode,
283 pIn->bpp,
284 numSamples,
285 pOut->baseAlign,
286 pOut->pitchAlign,
287 &expPitch,
288 &expHeight,
289 &pOut->heightAlign);
290
291 if ((pIn->pitchAlign != 0) || (pIn->heightAlign != 0))
292 {
293 if (pIn->pitchAlign != 0)
294 {
295 ADDR_ASSERT((pIn->pitchAlign % pOut->pitchAlign) == 0);
296 pOut->pitchAlign = pIn->pitchAlign;
297
298 if (IsPow2(pOut->pitchAlign))
299 {
300 expPitch = PowTwoAlign(expPitch, pOut->pitchAlign);
301 }
302 else
303 {
304 expPitch += pOut->pitchAlign - 1;
305 expPitch /= pOut->pitchAlign;
306 expPitch *= pOut->pitchAlign;
307 }
308 }
309
310 if (pIn->heightAlign != 0)
311 {
312 ADDR_ASSERT((pIn->heightAlign % pOut->heightAlign) == 0);
313 pOut->heightAlign = pIn->heightAlign;
314
315 if (IsPow2(pOut->heightAlign))
316 {
317 expHeight = PowTwoAlign(expHeight, pOut->heightAlign);
318 }
319 else
320 {
321 expHeight += pOut->heightAlign - 1;
322 expHeight /= pOut->heightAlign;
323 expHeight *= pOut->heightAlign;
324 }
325 }
326
327 logicalSliceSize = BITS_TO_BYTES(expPitch * expHeight * pIn->bpp);
328 }
329
330 pOut->pitch = expPitch;
331 pOut->height = expHeight;
332 pOut->depth = expNumSlices;
333
334 pOut->surfSize = logicalSliceSize * expNumSlices;
335
336 pOut->tileMode = pIn->tileMode;
337
338 return TRUE;
339 }
340
341 /**
342 ****************************************************************************************************
343 * EgBasedLib::ComputeSurfaceInfoMicroTiled
344 *
345 * @brief
346 * Compute 1D/Micro Tiled surface sizes include padded pitch, height, slices, total
347 * size in bytes, meanwhile alignments as well. Results are returned through output
348 * parameters.
349 *
350 * @return
351 * TRUE if no error occurs
352 ****************************************************************************************************
353 */
354 BOOL_32 EgBasedLib::ComputeSurfaceInfoMicroTiled(
355 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] Input structure
356 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut, ///< [out] Output structure
357 UINT_32 padDims, ///< [in] Dimensions to padd
358 AddrTileMode expTileMode ///< [in] Expected tile mode
359 ) const
360 {
361 BOOL_32 valid = TRUE;
362
363 UINT_32 microTileThickness;
364 UINT_32 expPitch = pIn->width;
365 UINT_32 expHeight = pIn->height;
366 UINT_32 expNumSlices = pIn->numSlices;
367
368 // No 1D MSAA on real H/W, keep this for TGL
369 UINT_32 numSamples = pOut->numSamples;
370
371 //
372 // Compute the micro tile thickness.
373 //
374 microTileThickness = Thickness(expTileMode);
375
376 //
377 // Extra override for mip levels
378 //
379 if (pIn->mipLevel > 0)
380 {
381 //
382 // Reduce tiling mode from thick to thin if the number of slices is less than the
383 // micro tile thickness.
384 //
385 if ((expTileMode == ADDR_TM_1D_TILED_THICK) &&
386 (expNumSlices < ThickTileThickness))
387 {
388 expTileMode = HwlDegradeThickTileMode(ADDR_TM_1D_TILED_THICK, expNumSlices, NULL);
389 if (expTileMode != ADDR_TM_1D_TILED_THICK)
390 {
391 microTileThickness = 1;
392 }
393 }
394 }
395
396 //
397 // Compute the surface restrictions.
398 //
399 ComputeSurfaceAlignmentsMicroTiled(expTileMode,
400 pIn->bpp,
401 pIn->flags,
402 pIn->mipLevel,
403 numSamples,
404 &pOut->baseAlign,
405 &pOut->pitchAlign,
406 &pOut->heightAlign);
407
408 pOut->depthAlign = microTileThickness;
409
410 //
411 // Pad pitch and height to the required granularities.
412 // Compute surface size.
413 // Return parameters.
414 //
415 PadDimensions(expTileMode,
416 pIn->bpp,
417 pIn->flags,
418 numSamples,
419 pOut->pTileInfo,
420 padDims,
421 pIn->mipLevel,
422 &expPitch, &pOut->pitchAlign,
423 &expHeight, pOut->heightAlign,
424 &expNumSlices, microTileThickness);
425
426 //
427 // Get HWL specific pitch adjustment
428 //
429 UINT_64 logicalSliceSize = HwlGetSizeAdjustmentMicroTiled(microTileThickness,
430 pIn->bpp,
431 pIn->flags,
432 numSamples,
433 pOut->baseAlign,
434 pOut->pitchAlign,
435 &expPitch,
436 &expHeight);
437
438 pOut->pitch = expPitch;
439 pOut->height = expHeight;
440 pOut->depth = expNumSlices;
441
442 pOut->surfSize = logicalSliceSize * expNumSlices;
443
444 pOut->tileMode = expTileMode;
445
446 return valid;
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 */
462 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 */
663 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 */
719 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 * EgBasedLib::HwlReduceBankWidthHeight
756 *
757 * @brief
758 * Additional checks, reduce bankHeight/bankWidth if needed and possible
759 * tileSize*BANK_WIDTH*BANK_HEIGHT <= ROW_SIZE
760 *
761 * @return
762 * TRUE if no error occurs
763 ****************************************************************************************************
764 */
765 BOOL_32 EgBasedLib::HwlReduceBankWidthHeight(
766 UINT_32 tileSize, ///< [in] tile size
767 UINT_32 bpp, ///< [in] bits per pixel
768 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
769 UINT_32 numSamples, ///< [in] number of samples
770 UINT_32 bankHeightAlign, ///< [in] bank height alignment
771 UINT_32 pipes, ///< [in] pipes
772 ADDR_TILEINFO* pTileInfo ///< [in,out] bank structure.
773 ) const
774 {
775 UINT_32 macroAspectAlign;
776 BOOL_32 valid = TRUE;
777
778 if (tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize)
779 {
780 BOOL_32 stillGreater = TRUE;
781
782 // Try reducing bankWidth first
783 if (stillGreater && pTileInfo->bankWidth > 1)
784 {
785 while (stillGreater && pTileInfo->bankWidth > 0)
786 {
787 pTileInfo->bankWidth >>= 1;
788
789 if (pTileInfo->bankWidth == 0)
790 {
791 pTileInfo->bankWidth = 1;
792 break;
793 }
794
795 stillGreater =
796 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
797 }
798
799 // bankWidth is reduced above, so we need to recalculate bankHeight and ratio
800 bankHeightAlign = Max(1u,
801 m_pipeInterleaveBytes * m_bankInterleave /
802 (tileSize * pTileInfo->bankWidth)
803 );
804
805 // We cannot increase bankHeight so just assert this case.
806 ADDR_ASSERT((pTileInfo->bankHeight % bankHeightAlign) == 0);
807
808 if (numSamples == 1)
809 {
810 macroAspectAlign = Max(1u,
811 m_pipeInterleaveBytes * m_bankInterleave /
812 (tileSize * pipes * pTileInfo->bankWidth)
813 );
814 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio,
815 macroAspectAlign);
816 }
817 }
818
819 // Early quit bank_height degradation for "64" bit z buffer
820 if (flags.depth && bpp >= 64)
821 {
822 stillGreater = FALSE;
823 }
824
825 // Then try reducing bankHeight
826 if (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
827 {
828 while (stillGreater && pTileInfo->bankHeight > bankHeightAlign)
829 {
830 pTileInfo->bankHeight >>= 1;
831
832 if (pTileInfo->bankHeight < bankHeightAlign)
833 {
834 pTileInfo->bankHeight = bankHeightAlign;
835 break;
836 }
837
838 stillGreater =
839 tileSize * pTileInfo->bankWidth * pTileInfo->bankHeight > m_rowSize;
840 }
841 }
842
843 valid = !stillGreater;
844
845 // Generate a warning if we still fail to meet this constraint
846 if (valid == FALSE)
847 {
848 ADDR_WARN(
849 0, ("TILE_SIZE(%d)*BANK_WIDTH(%d)*BANK_HEIGHT(%d) <= ROW_SIZE(%d)",
850 tileSize, pTileInfo->bankWidth, pTileInfo->bankHeight, m_rowSize));
851 }
852 }
853
854 return valid;
855 }
856
857 /**
858 ****************************************************************************************************
859 * EgBasedLib::ComputeSurfaceAlignmentsMacroTiled
860 *
861 * @brief
862 * Compute 2D tiled surface alignment, calculation results are returned through
863 * output parameters.
864 *
865 * @return
866 * TRUE if no error occurs
867 ****************************************************************************************************
868 */
869 BOOL_32 EgBasedLib::ComputeSurfaceAlignmentsMacroTiled(
870 AddrTileMode tileMode, ///< [in] tile mode
871 UINT_32 bpp, ///< [in] bits per pixel
872 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
873 UINT_32 mipLevel, ///< [in] mip level
874 UINT_32 numSamples, ///< [in] number of samples
875 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] Surface output
876 ) const
877 {
878 ADDR_TILEINFO* pTileInfo = pOut->pTileInfo;
879
880 BOOL_32 valid = SanityCheckMacroTiled(pTileInfo);
881
882 if (valid)
883 {
884 UINT_32 macroTileWidth;
885 UINT_32 macroTileHeight;
886
887 UINT_32 tileSize;
888 UINT_32 bankHeightAlign;
889 UINT_32 macroAspectAlign;
890
891 UINT_32 thickness = Thickness(tileMode);
892 UINT_32 pipes = HwlGetPipes(pTileInfo);
893
894 //
895 // Align bank height first according to latest h/w spec
896 //
897
898 // tile_size = MIN(tile_split, 64 * tile_thickness * element_bytes * num_samples)
899 tileSize = Min(pTileInfo->tileSplitBytes,
900 BITS_TO_BYTES(64 * thickness * bpp * numSamples));
901
902 // bank_height_align =
903 // MAX(1, (pipe_interleave_bytes * bank_interleave)/(tile_size*bank_width))
904 bankHeightAlign = Max(1u,
905 m_pipeInterleaveBytes * m_bankInterleave /
906 (tileSize * pTileInfo->bankWidth)
907 );
908
909 pTileInfo->bankHeight = PowTwoAlign(pTileInfo->bankHeight, bankHeightAlign);
910
911 // num_pipes * bank_width * macro_tile_aspect >=
912 // (pipe_interleave_size * bank_interleave) / tile_size
913 if (numSamples == 1)
914 {
915 // this restriction is only for mipmap (mipmap's numSamples must be 1)
916 macroAspectAlign = Max(1u,
917 m_pipeInterleaveBytes * m_bankInterleave /
918 (tileSize * pipes * pTileInfo->bankWidth)
919 );
920 pTileInfo->macroAspectRatio = PowTwoAlign(pTileInfo->macroAspectRatio, macroAspectAlign);
921 }
922
923 valid = HwlReduceBankWidthHeight(tileSize,
924 bpp,
925 flags,
926 numSamples,
927 bankHeightAlign,
928 pipes,
929 pTileInfo);
930
931 //
932 // The required granularity for pitch is the macro tile width.
933 //
934 macroTileWidth = MicroTileWidth * pTileInfo->bankWidth * pipes *
935 pTileInfo->macroAspectRatio;
936
937 pOut->pitchAlign = macroTileWidth;
938 pOut->blockWidth = macroTileWidth;
939
940 AdjustPitchAlignment(flags, &pOut->pitchAlign);
941
942 //
943 // The required granularity for height is the macro tile height.
944 //
945 macroTileHeight = MicroTileHeight * pTileInfo->bankHeight * pTileInfo->banks /
946 pTileInfo->macroAspectRatio;
947
948 pOut->heightAlign = macroTileHeight;
949 pOut->blockHeight = macroTileHeight;
950
951 //
952 // Compute base alignment
953 //
954 pOut->baseAlign =
955 pipes * pTileInfo->bankWidth * pTileInfo->banks * pTileInfo->bankHeight * tileSize;
956
957 HwlComputeSurfaceAlignmentsMacroTiled(tileMode, bpp, flags, mipLevel, numSamples, pOut);
958 }
959
960 return valid;
961 }
962
963 /**
964 ****************************************************************************************************
965 * EgBasedLib::SanityCheckMacroTiled
966 *
967 * @brief
968 * Check if macro-tiled parameters are valid
969 * @return
970 * TRUE if valid
971 ****************************************************************************************************
972 */
973 BOOL_32 EgBasedLib::SanityCheckMacroTiled(
974 ADDR_TILEINFO* pTileInfo ///< [in] macro-tiled parameters
975 ) const
976 {
977 BOOL_32 valid = TRUE;
978 MAYBE_UNUSED UINT_32 numPipes = HwlGetPipes(pTileInfo);
979
980 switch (pTileInfo->banks)
981 {
982 case 2: //fall through
983 case 4: //fall through
984 case 8: //fall through
985 case 16:
986 break;
987 default:
988 valid = FALSE;
989 break;
990
991 }
992
993 if (valid)
994 {
995 switch (pTileInfo->bankWidth)
996 {
997 case 1: //fall through
998 case 2: //fall through
999 case 4: //fall through
1000 case 8:
1001 break;
1002 default:
1003 valid = FALSE;
1004 break;
1005 }
1006 }
1007
1008 if (valid)
1009 {
1010 switch (pTileInfo->bankHeight)
1011 {
1012 case 1: //fall through
1013 case 2: //fall through
1014 case 4: //fall through
1015 case 8:
1016 break;
1017 default:
1018 valid = FALSE;
1019 break;
1020 }
1021 }
1022
1023 if (valid)
1024 {
1025 switch (pTileInfo->macroAspectRatio)
1026 {
1027 case 1: //fall through
1028 case 2: //fall through
1029 case 4: //fall through
1030 case 8:
1031 break;
1032 default:
1033 valid = FALSE;
1034 break;
1035 }
1036 }
1037
1038 if (valid)
1039 {
1040 if (pTileInfo->banks < pTileInfo->macroAspectRatio)
1041 {
1042 // This will generate macro tile height <= 1
1043 valid = FALSE;
1044 }
1045 }
1046
1047 if (valid)
1048 {
1049 if (pTileInfo->tileSplitBytes > m_rowSize)
1050 {
1051 ADDR_WARN(0, ("tileSplitBytes is bigger than row size"));
1052 }
1053 }
1054
1055 if (valid)
1056 {
1057 valid = HwlSanityCheckMacroTiled(pTileInfo);
1058 }
1059
1060 ADDR_ASSERT(valid == TRUE);
1061
1062 // Add this assert for guidance
1063 ADDR_ASSERT(numPipes * pTileInfo->banks >= 4);
1064
1065 return valid;
1066 }
1067
1068 /**
1069 ****************************************************************************************************
1070 * EgBasedLib::ComputeSurfaceMipLevelTileMode
1071 *
1072 * @brief
1073 * Compute valid tile mode for surface mipmap sub-levels
1074 *
1075 * @return
1076 * Suitable tile mode
1077 ****************************************************************************************************
1078 */
1079 AddrTileMode EgBasedLib::ComputeSurfaceMipLevelTileMode(
1080 AddrTileMode baseTileMode, ///< [in] base tile mode
1081 UINT_32 bpp, ///< [in] bits per pixels
1082 UINT_32 pitch, ///< [in] current level pitch
1083 UINT_32 height, ///< [in] current level height
1084 UINT_32 numSlices, ///< [in] current number of slices
1085 UINT_32 numSamples, ///< [in] number of samples
1086 UINT_32 pitchAlign, ///< [in] pitch alignment
1087 UINT_32 heightAlign, ///< [in] height alignment
1088 ADDR_TILEINFO* pTileInfo ///< [in] ptr to bank structure
1089 ) const
1090 {
1091 UINT_64 bytesPerSlice;
1092 (void)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 */
1172 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 */
1235 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 */
1308 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 */
1449 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 */
1581 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 // Split the offset to put some bits below the pipe+bank bits and some above.
1816 //
1817 pipeInterleaveMask = (1 << numPipeInterleaveBits) - 1;
1818 bankInterleaveMask = (1 << numBankInterleaveBits) - 1;
1819 pipeInterleaveOffset = totalOffset & pipeInterleaveMask;
1820 bankInterleaveOffset = static_cast<UINT_32>((totalOffset >> numPipeInterleaveBits) &
1821 bankInterleaveMask);
1822 offset = totalOffset >> (numPipeInterleaveBits + numBankInterleaveBits);
1823
1824 //
1825 // Assemble the address from its components.
1826 //
1827 addr = pipeInterleaveOffset;
1828 // This is to remove /analyze warnings
1829 UINT_32 pipeBits = pipe << numPipeInterleaveBits;
1830 UINT_32 bankInterleaveBits = bankInterleaveOffset << (numPipeInterleaveBits + numPipeBits);
1831 UINT_32 bankBits = bank << (numPipeInterleaveBits + numPipeBits +
1832 numBankInterleaveBits);
1833 UINT_64 offsetBits = offset << (numPipeInterleaveBits + numPipeBits +
1834 numBankInterleaveBits + numBankBits);
1835
1836 addr |= pipeBits;
1837 addr |= bankInterleaveBits;
1838 addr |= bankBits;
1839 addr |= offsetBits;
1840
1841 return addr;
1842 }
1843
1844 /**
1845 ****************************************************************************************************
1846 * EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled
1847 *
1848 * @brief
1849 * Computes the surface address and bit position from a coordinate for 1D tilied
1850 * (micro tiled)
1851 * @return
1852 * The byte address
1853 ****************************************************************************************************
1854 */
1855 UINT_64 EgBasedLib::ComputeSurfaceAddrFromCoordMicroTiled(
1856 UINT_32 x, ///< [in] x coordinate
1857 UINT_32 y, ///< [in] y coordinate
1858 UINT_32 slice, ///< [in] slice index
1859 UINT_32 sample, ///< [in] sample index
1860 UINT_32 bpp, ///< [in] bits per pixel
1861 UINT_32 pitch, ///< [in] pitch, in pixels
1862 UINT_32 height, ///< [in] height, in pixels
1863 UINT_32 numSamples, ///< [in] number of samples
1864 AddrTileMode tileMode, ///< [in] tile mode
1865 AddrTileType microTileType, ///< [in] micro tiling type
1866 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample ordering is used
1867 UINT_32* pBitPosition ///< [out] bit position, e.g. FMT_1 will use this
1868 ) const
1869 {
1870 UINT_64 addr = 0;
1871
1872 UINT_32 microTileBytes;
1873 UINT_64 sliceBytes;
1874 UINT_32 microTilesPerRow;
1875 UINT_32 microTileIndexX;
1876 UINT_32 microTileIndexY;
1877 UINT_32 microTileIndexZ;
1878 UINT_64 sliceOffset;
1879 UINT_64 microTileOffset;
1880 UINT_32 sampleOffset;
1881 UINT_32 pixelIndex;
1882 UINT_32 pixelOffset;
1883
1884 UINT_32 microTileThickness = Thickness(tileMode);
1885
1886 //
1887 // Compute the micro tile size.
1888 //
1889 microTileBytes = BITS_TO_BYTES(MicroTilePixels * microTileThickness * bpp * numSamples);
1890
1891 //
1892 // Compute the slice size.
1893 //
1894 sliceBytes =
1895 BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples);
1896
1897 //
1898 // Compute the number of micro tiles per row.
1899 //
1900 microTilesPerRow = pitch / MicroTileWidth;
1901
1902 //
1903 // Compute the micro tile index.
1904 //
1905 microTileIndexX = x / MicroTileWidth;
1906 microTileIndexY = y / MicroTileHeight;
1907 microTileIndexZ = slice / microTileThickness;
1908
1909 //
1910 // Compute the slice offset.
1911 //
1912 sliceOffset = static_cast<UINT_64>(microTileIndexZ) * sliceBytes;
1913
1914 //
1915 // Compute the offset to the micro tile containing the specified coordinate.
1916 //
1917 microTileOffset = (static_cast<UINT_64>(microTileIndexY) * microTilesPerRow + microTileIndexX) *
1918 microTileBytes;
1919
1920 //
1921 // Compute the pixel index within the micro tile.
1922 //
1923 pixelIndex = ComputePixelIndexWithinMicroTile(x,
1924 y,
1925 slice,
1926 bpp,
1927 tileMode,
1928 microTileType);
1929
1930 // Compute the sample offset.
1931 //
1932 if (isDepthSampleOrder)
1933 {
1934 //
1935 // For depth surfaces, samples are stored contiguously for each element, so the sample
1936 // offset is the sample number times the element size.
1937 //
1938 sampleOffset = sample * bpp;
1939 pixelOffset = pixelIndex * bpp * numSamples;
1940 }
1941 else
1942 {
1943 //
1944 // For color surfaces, all elements for a particular sample are stored contiguously, so
1945 // the sample offset is the sample number times the micro tile size divided yBit the number
1946 // of samples.
1947 //
1948 sampleOffset = sample * (microTileBytes*8 / numSamples);
1949 pixelOffset = pixelIndex * bpp;
1950 }
1951
1952 //
1953 // Compute the bit position of the pixel. Each element is stored with one bit per sample.
1954 //
1955
1956 UINT_32 elemOffset = sampleOffset + pixelOffset;
1957
1958 *pBitPosition = elemOffset % 8;
1959 elemOffset /= 8;
1960
1961 //
1962 // Combine the slice offset, micro tile offset, sample offset, and pixel offsets.
1963 //
1964 addr = sliceOffset + microTileOffset + elemOffset;
1965
1966 return addr;
1967 }
1968
1969 /**
1970 ****************************************************************************************************
1971 * EgBasedLib::HwlComputePixelCoordFromOffset
1972 *
1973 * @brief
1974 * Compute pixel coordinate from offset inside a micro tile
1975 * @return
1976 * N/A
1977 ****************************************************************************************************
1978 */
1979 VOID EgBasedLib::HwlComputePixelCoordFromOffset(
1980 UINT_32 offset, ///< [in] offset inside micro tile in bits
1981 UINT_32 bpp, ///< [in] bits per pixel
1982 UINT_32 numSamples, ///< [in] number of samples
1983 AddrTileMode tileMode, ///< [in] tile mode
1984 UINT_32 tileBase, ///< [in] base offset within a tile
1985 UINT_32 compBits, ///< [in] component bits actually needed(for planar surface)
1986 UINT_32* pX, ///< [out] x coordinate
1987 UINT_32* pY, ///< [out] y coordinate
1988 UINT_32* pSlice, ///< [out] slice index
1989 UINT_32* pSample, ///< [out] sample index
1990 AddrTileType microTileType, ///< [in] micro tiling type
1991 BOOL_32 isDepthSampleOrder ///< [in] TRUE if depth sample order in microtile is used
1992 ) const
1993 {
1994 UINT_32 x = 0;
1995 UINT_32 y = 0;
1996 UINT_32 z = 0;
1997 UINT_32 thickness = Thickness(tileMode);
1998
1999 // For planar surface, we adjust offset acoording to tile base
2000 if ((bpp != compBits) && (compBits != 0) && isDepthSampleOrder)
2001 {
2002 offset -= tileBase;
2003
2004 ADDR_ASSERT(microTileType == ADDR_NON_DISPLAYABLE ||
2005 microTileType == ADDR_DEPTH_SAMPLE_ORDER);
2006
2007 bpp = compBits;
2008 }
2009
2010 UINT_32 sampleTileBits;
2011 UINT_32 samplePixelBits;
2012 UINT_32 pixelIndex;
2013
2014 if (isDepthSampleOrder)
2015 {
2016 samplePixelBits = bpp * numSamples;
2017 pixelIndex = offset / samplePixelBits;
2018 *pSample = (offset % samplePixelBits) / bpp;
2019 }
2020 else
2021 {
2022 sampleTileBits = MicroTilePixels * bpp * thickness;
2023 *pSample = offset / sampleTileBits;
2024 pixelIndex = (offset % sampleTileBits) / bpp;
2025 }
2026
2027 if (microTileType != ADDR_THICK)
2028 {
2029 if (microTileType == ADDR_DISPLAYABLE) // displayable
2030 {
2031 switch (bpp)
2032 {
2033 case 8:
2034 x = pixelIndex & 0x7;
2035 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
2036 break;
2037 case 16:
2038 x = pixelIndex & 0x7;
2039 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
2040 break;
2041 case 32:
2042 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
2043 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
2044 break;
2045 case 64:
2046 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2047 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2048 break;
2049 case 128:
2050 x = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,2),_BIT(pixelIndex,1));
2051 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,0));
2052 break;
2053 default:
2054 break;
2055 }
2056 }
2057 else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2058 {
2059 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2060 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2061 }
2062 else if (microTileType == ADDR_ROTATED)
2063 {
2064 /*
2065 8-Bit Elements
2066 element_index[5:0] = { x[2], x[0], x[1], y[2], y[1], y[0] }
2067
2068 16-Bit Elements
2069 element_index[5:0] = { x[2], x[1], x[0], y[2], y[1], y[0] }
2070
2071 32-Bit Elements
2072 element_index[5:0] = { x[2], x[1], y[2], x[0], y[1], y[0] }
2073
2074 64-Bit Elements
2075 element_index[5:0] = { y[2], x[2], x[1], y[1], x[0], y[0] }
2076 */
2077 switch(bpp)
2078 {
2079 case 8:
2080 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,3),_BIT(pixelIndex,4));
2081 y = pixelIndex & 0x7;
2082 break;
2083 case 16:
2084 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,3));
2085 y = pixelIndex & 0x7;
2086 break;
2087 case 32:
2088 x = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,4),_BIT(pixelIndex,2));
2089 y = Bits2Number(3, _BIT(pixelIndex,3),_BIT(pixelIndex,1),_BIT(pixelIndex,0));
2090 break;
2091 case 64:
2092 x = Bits2Number(3, _BIT(pixelIndex,4),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2093 y = Bits2Number(3, _BIT(pixelIndex,5),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2094 break;
2095 default:
2096 ADDR_ASSERT_ALWAYS();
2097 break;
2098 }
2099 }
2100
2101 if (thickness > 1) // thick
2102 {
2103 z = Bits2Number(3, _BIT(pixelIndex,8),_BIT(pixelIndex,7),_BIT(pixelIndex,6));
2104 }
2105 }
2106 else
2107 {
2108 ADDR_ASSERT((m_chipFamily >= ADDR_CHIP_FAMILY_CI) && (thickness > 1));
2109 /*
2110 8-Bit Elements and 16-Bit Elements
2111 element_index[7:0] = { y[2], x[2], z[1], z[0], y[1], x[1], y[0], x[0] }
2112
2113 32-Bit Elements
2114 element_index[7:0] = { y[2], x[2], z[1], y[1], z[0], x[1], y[0], x[0] }
2115
2116 64-Bit Elements and 128-Bit Elements
2117 element_index[7:0] = { y[2], x[2], z[1], y[1], x[1], z[0], y[0], x[0] }
2118
2119 The equation to compute the element index for the extra thick tile:
2120 element_index[8] = z[2]
2121 */
2122 switch (bpp)
2123 {
2124 case 8:
2125 case 16: // fall-through
2126 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2127 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,3),_BIT(pixelIndex,1));
2128 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,4));
2129 break;
2130 case 32:
2131 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,2),_BIT(pixelIndex,0));
2132 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2133 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,3));
2134 break;
2135 case 64:
2136 case 128: // fall-through
2137 x = Bits2Number(3, _BIT(pixelIndex,6),_BIT(pixelIndex,3),_BIT(pixelIndex,0));
2138 y = Bits2Number(3, _BIT(pixelIndex,7),_BIT(pixelIndex,4),_BIT(pixelIndex,1));
2139 z = Bits2Number(2, _BIT(pixelIndex,5),_BIT(pixelIndex,2));
2140 break;
2141 default:
2142 ADDR_ASSERT_ALWAYS();
2143 break;
2144 }
2145
2146 if (thickness == 8)
2147 {
2148 z += Bits2Number(3,_BIT(pixelIndex,8),0,0);
2149 }
2150 }
2151
2152 *pX = x;
2153 *pY = y;
2154 *pSlice += z;
2155 }
2156
2157 /**
2158 ****************************************************************************************************
2159 * EgBasedLib::DispatchComputeSurfaceCoordFromAddrDispatch
2160 *
2161 * @brief
2162 * Compute (x,y,slice,sample) coordinates from surface address
2163 * @return
2164 * N/A
2165 ****************************************************************************************************
2166 */
2167 VOID EgBasedLib::DispatchComputeSurfaceCoordFromAddr(
2168 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
2169 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
2170 ) const
2171 {
2172 UINT_64 addr = pIn->addr;
2173 UINT_32 bitPosition = pIn->bitPosition;
2174 UINT_32 bpp = pIn->bpp;
2175 UINT_32 pitch = pIn->pitch;
2176 UINT_32 height = pIn->height;
2177 UINT_32 numSlices = pIn->numSlices;
2178 UINT_32 numSamples = ((pIn->numSamples == 0) ? 1 : pIn->numSamples);
2179 UINT_32 numFrags = ((pIn->numFrags == 0) ? numSamples : pIn->numFrags);
2180 AddrTileMode tileMode = pIn->tileMode;
2181 UINT_32 tileBase = pIn->tileBase;
2182 UINT_32 compBits = pIn->compBits;
2183 AddrTileType microTileType = pIn->tileType;
2184 BOOL_32 ignoreSE = pIn->ignoreSE;
2185 BOOL_32 isDepthSampleOrder = pIn->isDepth;
2186 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
2187
2188 UINT_32* pX = &pOut->x;
2189 UINT_32* pY = &pOut->y;
2190 UINT_32* pSlice = &pOut->slice;
2191 UINT_32* pSample = &pOut->sample;
2192
2193 if (microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2194 {
2195 isDepthSampleOrder = TRUE;
2196 }
2197
2198 if (m_chipFamily >= ADDR_CHIP_FAMILY_NI)
2199 {
2200 if (numFrags != numSamples)
2201 {
2202 numSamples = numFrags;
2203 }
2204
2205 /// @note
2206 /// 128 bit/thick tiled surface doesn't support display tiling and
2207 /// mipmap chain must have the same tileType, so please fill tileType correctly
2208 if (IsLinear(pIn->tileMode) == FALSE)
2209 {
2210 if (bpp >= 128 || Thickness(tileMode) > 1)
2211 {
2212 ADDR_ASSERT(microTileType != ADDR_DISPLAYABLE);
2213 }
2214 }
2215 }
2216
2217 switch (tileMode)
2218 {
2219 case ADDR_TM_LINEAR_GENERAL://fall through
2220 case ADDR_TM_LINEAR_ALIGNED:
2221 ComputeSurfaceCoordFromAddrLinear(addr,
2222 bitPosition,
2223 bpp,
2224 pitch,
2225 height,
2226 numSlices,
2227 pX,
2228 pY,
2229 pSlice,
2230 pSample);
2231 break;
2232 case ADDR_TM_1D_TILED_THIN1://fall through
2233 case ADDR_TM_1D_TILED_THICK:
2234 ComputeSurfaceCoordFromAddrMicroTiled(addr,
2235 bitPosition,
2236 bpp,
2237 pitch,
2238 height,
2239 numSamples,
2240 tileMode,
2241 tileBase,
2242 compBits,
2243 pX,
2244 pY,
2245 pSlice,
2246 pSample,
2247 microTileType,
2248 isDepthSampleOrder);
2249 break;
2250 case ADDR_TM_2D_TILED_THIN1: //fall through
2251 case ADDR_TM_2D_TILED_THICK: //fall through
2252 case ADDR_TM_3D_TILED_THIN1: //fall through
2253 case ADDR_TM_3D_TILED_THICK: //fall through
2254 case ADDR_TM_2D_TILED_XTHICK: //fall through
2255 case ADDR_TM_3D_TILED_XTHICK: //fall through
2256 case ADDR_TM_PRT_TILED_THIN1: //fall through
2257 case ADDR_TM_PRT_2D_TILED_THIN1://fall through
2258 case ADDR_TM_PRT_3D_TILED_THIN1://fall through
2259 case ADDR_TM_PRT_TILED_THICK: //fall through
2260 case ADDR_TM_PRT_2D_TILED_THICK://fall through
2261 case ADDR_TM_PRT_3D_TILED_THICK:
2262 UINT_32 pipeSwizzle;
2263 UINT_32 bankSwizzle;
2264
2265 if (m_configFlags.useCombinedSwizzle)
2266 {
2267 ExtractBankPipeSwizzle(pIn->tileSwizzle, pIn->pTileInfo,
2268 &bankSwizzle, &pipeSwizzle);
2269 }
2270 else
2271 {
2272 pipeSwizzle = pIn->pipeSwizzle;
2273 bankSwizzle = pIn->bankSwizzle;
2274 }
2275
2276 ComputeSurfaceCoordFromAddrMacroTiled(addr,
2277 bitPosition,
2278 bpp,
2279 pitch,
2280 height,
2281 numSamples,
2282 tileMode,
2283 tileBase,
2284 compBits,
2285 microTileType,
2286 ignoreSE,
2287 isDepthSampleOrder,
2288 pipeSwizzle,
2289 bankSwizzle,
2290 pTileInfo,
2291 pX,
2292 pY,
2293 pSlice,
2294 pSample);
2295 break;
2296 default:
2297 ADDR_ASSERT_ALWAYS();
2298 }
2299 }
2300
2301 /**
2302 ****************************************************************************************************
2303 * EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled
2304 *
2305 * @brief
2306 * Compute surface coordinates from address for macro tiled surface
2307 * @return
2308 * N/A
2309 ****************************************************************************************************
2310 */
2311 VOID EgBasedLib::ComputeSurfaceCoordFromAddrMacroTiled(
2312 UINT_64 addr, ///< [in] byte address
2313 UINT_32 bitPosition, ///< [in] bit position
2314 UINT_32 bpp, ///< [in] bits per pixel
2315 UINT_32 pitch, ///< [in] pitch in pixels
2316 UINT_32 height, ///< [in] height in pixels
2317 UINT_32 numSamples, ///< [in] number of samples
2318 AddrTileMode tileMode, ///< [in] tile mode
2319 UINT_32 tileBase, ///< [in] tile base offset
2320 UINT_32 compBits, ///< [in] component bits (for planar surface)
2321 AddrTileType microTileType, ///< [in] micro tiling type
2322 BOOL_32 ignoreSE, ///< [in] TRUE if shader engines can be ignored
2323 BOOL_32 isDepthSampleOrder, ///< [in] TRUE if depth sample order is used
2324 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2325 UINT_32 bankSwizzle, ///< [in] bank swizzle
2326 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure.
2327 /// **All fields to be valid on entry**
2328 UINT_32* pX, ///< [out] X coord
2329 UINT_32* pY, ///< [out] Y coord
2330 UINT_32* pSlice, ///< [out] slice index
2331 UINT_32* pSample ///< [out] sample index
2332 ) const
2333 {
2334 UINT_32 mx;
2335 UINT_32 my;
2336 UINT_64 tileBits;
2337 UINT_64 macroTileBits;
2338 UINT_32 slices;
2339 UINT_32 tileSlices;
2340 UINT_64 elementOffset;
2341 UINT_64 macroTileIndex;
2342 UINT_32 tileIndex;
2343 UINT_64 totalOffset;
2344
2345 UINT_32 bank;
2346 UINT_32 pipe;
2347 UINT_32 groupBits = m_pipeInterleaveBytes << 3;
2348 UINT_32 pipes = HwlGetPipes(pTileInfo);
2349 UINT_32 banks = pTileInfo->banks;
2350
2351 UINT_32 bankInterleave = m_bankInterleave;
2352
2353 UINT_64 addrBits = BYTES_TO_BITS(addr) + bitPosition;
2354
2355 //
2356 // remove bits for bank and pipe
2357 //
2358 totalOffset = (addrBits % groupBits) +
2359 (((addrBits / groupBits / pipes) % bankInterleave) * groupBits) +
2360 (((addrBits / groupBits / pipes) / bankInterleave) / banks) * groupBits * bankInterleave;
2361
2362 UINT_32 microTileThickness = Thickness(tileMode);
2363
2364 UINT_32 microTileBits = bpp * microTileThickness * MicroTilePixels * numSamples;
2365
2366 UINT_32 microTileBytes = BITS_TO_BYTES(microTileBits);
2367 //
2368 // Determine if tiles need to be split across slices.
2369 //
2370 // If the size of the micro tile is larger than the tile split size, then the tile will be
2371 // split across multiple slices.
2372 //
2373 UINT_32 slicesPerTile = 1; //_State->TileSlices
2374
2375 if ((microTileBytes > pTileInfo->tileSplitBytes) && (microTileThickness == 1))
2376 { //don't support for thick mode
2377
2378 //
2379 // Compute the number of slices per tile.
2380 //
2381 slicesPerTile = microTileBytes / pTileInfo->tileSplitBytes;
2382 }
2383
2384 tileBits = microTileBits / slicesPerTile; // micro tile bits
2385
2386 // in micro tiles because not MicroTileWidth timed.
2387 UINT_32 macroWidth = pTileInfo->bankWidth * pipes * pTileInfo->macroAspectRatio;
2388 // in micro tiles as well
2389 UINT_32 macroHeight = pTileInfo->bankHeight * banks / pTileInfo->macroAspectRatio;
2390
2391 UINT_32 pitchInMacroTiles = pitch / MicroTileWidth / macroWidth;
2392
2393 macroTileBits = (macroWidth * macroHeight) * tileBits / (banks * pipes);
2394
2395 macroTileIndex = totalOffset / macroTileBits;
2396
2397 // pitchMacros * height / heightMacros; macroTilesPerSlice == _State->SliceMacros
2398 UINT_32 macroTilesPerSlice = (pitch / (macroWidth * MicroTileWidth)) * height /
2399 (macroHeight * MicroTileWidth);
2400
2401 slices = static_cast<UINT_32>(macroTileIndex / macroTilesPerSlice);
2402
2403 *pSlice = static_cast<UINT_32>(slices / slicesPerTile * microTileThickness);
2404
2405 //
2406 // calculate element offset and x[2:0], y[2:0], z[1:0] for thick
2407 //
2408 tileSlices = slices % slicesPerTile;
2409
2410 elementOffset = tileSlices * tileBits;
2411 elementOffset += totalOffset % tileBits;
2412
2413 UINT_32 coordZ = 0;
2414
2415 HwlComputePixelCoordFromOffset(static_cast<UINT_32>(elementOffset),
2416 bpp,
2417 numSamples,
2418 tileMode,
2419 tileBase,
2420 compBits,
2421 pX,
2422 pY,
2423 &coordZ,
2424 pSample,
2425 microTileType,
2426 isDepthSampleOrder);
2427
2428 macroTileIndex = macroTileIndex % macroTilesPerSlice;
2429 *pY += static_cast<UINT_32>(macroTileIndex / pitchInMacroTiles * macroHeight * MicroTileHeight);
2430 *pX += static_cast<UINT_32>(macroTileIndex % pitchInMacroTiles * macroWidth * MicroTileWidth);
2431
2432 *pSlice += coordZ;
2433
2434 tileIndex = static_cast<UINT_32>((totalOffset % macroTileBits) / tileBits);
2435
2436 my = (tileIndex / pTileInfo->bankWidth) % pTileInfo->bankHeight * MicroTileHeight;
2437 mx = (tileIndex % pTileInfo->bankWidth) * pipes * MicroTileWidth;
2438
2439 *pY += my;
2440 *pX += mx;
2441
2442 bank = ComputeBankFromAddr(addr, banks, pipes);
2443 pipe = ComputePipeFromAddr(addr, pipes);
2444
2445 HwlComputeSurfaceCoord2DFromBankPipe(tileMode,
2446 pX,
2447 pY,
2448 *pSlice,
2449 bank,
2450 pipe,
2451 bankSwizzle,
2452 pipeSwizzle,
2453 tileSlices,
2454 ignoreSE,
2455 pTileInfo);
2456 }
2457
2458 /**
2459 ****************************************************************************************************
2460 * EgBasedLib::ComputeSurfaceCoord2DFromBankPipe
2461 *
2462 * @brief
2463 * Compute surface x,y coordinates from bank/pipe info
2464 * @return
2465 * N/A
2466 ****************************************************************************************************
2467 */
2468 VOID EgBasedLib::ComputeSurfaceCoord2DFromBankPipe(
2469 AddrTileMode tileMode, ///< [in] tile mode
2470 UINT_32 x, ///< [in] x coordinate
2471 UINT_32 y, ///< [in] y coordinate
2472 UINT_32 slice, ///< [in] slice index
2473 UINT_32 bank, ///< [in] bank number
2474 UINT_32 pipe, ///< [in] pipe number
2475 UINT_32 bankSwizzle,///< [in] bank swizzle
2476 UINT_32 pipeSwizzle,///< [in] pipe swizzle
2477 UINT_32 tileSlices, ///< [in] slices in a micro tile
2478 ADDR_TILEINFO* pTileInfo, ///< [in] bank structure. **All fields to be valid on entry**
2479 CoordFromBankPipe* pOutput ///< [out] pointer to extracted x/y bits
2480 ) const
2481 {
2482 UINT_32 yBit3 = 0;
2483 UINT_32 yBit4 = 0;
2484 UINT_32 yBit5 = 0;
2485 UINT_32 yBit6 = 0;
2486
2487 UINT_32 xBit3 = 0;
2488 UINT_32 xBit4 = 0;
2489 UINT_32 xBit5 = 0;
2490
2491 UINT_32 tileSplitRotation;
2492
2493 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2494
2495 UINT_32 bankRotation = ComputeBankRotation(tileMode,
2496 pTileInfo->banks, numPipes);
2497
2498 UINT_32 pipeRotation = ComputePipeRotation(tileMode, numPipes);
2499
2500 UINT_32 xBit = x / (MicroTileWidth * pTileInfo->bankWidth * numPipes);
2501 UINT_32 yBit = y / (MicroTileHeight * pTileInfo->bankHeight);
2502
2503 //calculate the bank and pipe before rotation and swizzle
2504
2505 switch (tileMode)
2506 {
2507 case ADDR_TM_2D_TILED_THIN1: //fall through
2508 case ADDR_TM_2D_TILED_THICK: //fall through
2509 case ADDR_TM_2D_TILED_XTHICK: //fall through
2510 case ADDR_TM_3D_TILED_THIN1: //fall through
2511 case ADDR_TM_3D_TILED_THICK: //fall through
2512 case ADDR_TM_3D_TILED_XTHICK:
2513 tileSplitRotation = ((pTileInfo->banks / 2) + 1);
2514 break;
2515 default:
2516 tileSplitRotation = 0;
2517 break;
2518 }
2519
2520 UINT_32 microTileThickness = Thickness(tileMode);
2521
2522 bank ^= tileSplitRotation * tileSlices;
2523 if (pipeRotation == 0)
2524 {
2525 bank ^= bankRotation * (slice / microTileThickness) + bankSwizzle;
2526 bank %= pTileInfo->banks;
2527 pipe ^= pipeSwizzle;
2528 }
2529 else
2530 {
2531 bank ^= bankRotation * (slice / microTileThickness) / numPipes + bankSwizzle;
2532 bank %= pTileInfo->banks;
2533 pipe ^= pipeRotation * (slice / microTileThickness) + pipeSwizzle;
2534 }
2535
2536 if (pTileInfo->macroAspectRatio == 1)
2537 {
2538 switch (pTileInfo->banks)
2539 {
2540 case 2:
2541 yBit3 = _BIT(bank, 0) ^ _BIT(xBit,0);
2542 break;
2543 case 4:
2544 yBit4 = _BIT(bank, 0) ^ _BIT(xBit,0);
2545 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2546 break;
2547 case 8:
2548 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2549 yBit5 = _BIT(bank, 0) ^ _BIT(xBit,0);
2550 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ yBit5;
2551 break;
2552 case 16:
2553 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3);
2554 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2);
2555 yBit6 = _BIT(bank, 0) ^ _BIT(xBit, 0);
2556 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ yBit6;
2557 break;
2558 default:
2559 break;
2560 }
2561
2562 }
2563 else if (pTileInfo->macroAspectRatio == 2)
2564 {
2565 switch (pTileInfo->banks)
2566 {
2567 case 2: //xBit3 = yBit3^b0
2568 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,0);
2569 break;
2570 case 4: //xBit3=yBit4^b0; yBit3=xBit4^b1
2571 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2572 yBit3 = _BIT(bank, 1) ^ _BIT(xBit,1);
2573 break;
2574 case 8: //xBit4, xBit5, yBit5 are known
2575 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2576 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2577 yBit4 = _BIT(bank, 1) ^ _BIT(xBit,1) ^ _BIT(yBit, 2);
2578 break;
2579 case 16://x4,x5,x6,y6 are known
2580 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3); //x3 = y6 ^ b0
2581 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2582 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = x5 ^ b2
2583 yBit5 = _BIT(bank, 1) ^ _BIT(xBit, 1) ^ _BIT(yBit, 3); //y5=x4^y6^b1
2584 break;
2585 default:
2586 break;
2587 }
2588 }
2589 else if (pTileInfo->macroAspectRatio == 4)
2590 {
2591 switch (pTileInfo->banks)
2592 {
2593 case 4: //yBit3, yBit4
2594 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,1);
2595 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,0);
2596 break;
2597 case 8: //xBit5, yBit4, yBit5
2598 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2);
2599 yBit3 = _BIT(bank, 2) ^ _BIT(xBit,2);
2600 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit,2);
2601 break;
2602 case 16: //xBit5, xBit6, yBit5, yBit6
2603 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = b0 ^ y6
2604 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = b1 ^ y5 ^ y6;
2605 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = b3 ^ x6;
2606 yBit4 = _BIT(bank, 2) ^ _BIT(xBit, 2); //y4 = b2 ^ x5;
2607 break;
2608 default:
2609 break;
2610 }
2611 }
2612 else if (pTileInfo->macroAspectRatio == 8)
2613 {
2614 switch (pTileInfo->banks)
2615 {
2616 case 8: //yBit3, yBit4, yBit5
2617 xBit3 = _BIT(bank, 0) ^ _BIT(yBit,2); //x3 = b0 ^ y5;
2618 xBit4 = _BIT(bank, 1) ^ _BIT(yBit,1) ^ _BIT(yBit, 2);//x4 = b1 ^ y4 ^ y5;
2619 xBit5 = _BIT(bank, 2) ^ _BIT(yBit,0);
2620 break;
2621 case 16: //xBit6, yBit4, yBit5, yBit6
2622 xBit3 = _BIT(bank, 0) ^ _BIT(yBit, 3);//x3 = y6 ^ b0
2623 xBit4 = _BIT(bank, 1) ^ _BIT(yBit, 2) ^ _BIT(yBit, 3);//x4 = y5 ^ y6 ^ b1
2624 xBit5 = _BIT(bank, 2) ^ _BIT(yBit, 1);//x5 = y4 ^ b2
2625 yBit3 = _BIT(bank, 3) ^ _BIT(xBit, 3); //y3 = x6 ^ b3
2626 break;
2627 default:
2628 break;
2629 }
2630 }
2631
2632 pOutput->xBits = xBit;
2633 pOutput->yBits = yBit;
2634
2635 pOutput->xBit3 = xBit3;
2636 pOutput->xBit4 = xBit4;
2637 pOutput->xBit5 = xBit5;
2638 pOutput->yBit3 = yBit3;
2639 pOutput->yBit4 = yBit4;
2640 pOutput->yBit5 = yBit5;
2641 pOutput->yBit6 = yBit6;
2642 }
2643
2644 /**
2645 ****************************************************************************************************
2646 * EgBasedLib::HwlExtractBankPipeSwizzle
2647 * @brief
2648 * Entry of EgBasedLib ExtractBankPipeSwizzle
2649 * @return
2650 * ADDR_E_RETURNCODE
2651 ****************************************************************************************************
2652 */
2653 ADDR_E_RETURNCODE EgBasedLib::HwlExtractBankPipeSwizzle(
2654 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
2655 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
2656 ) const
2657 {
2658 ExtractBankPipeSwizzle(pIn->base256b,
2659 pIn->pTileInfo,
2660 &pOut->bankSwizzle,
2661 &pOut->pipeSwizzle);
2662
2663 return ADDR_OK;
2664 }
2665
2666 /**
2667 ****************************************************************************************************
2668 * EgBasedLib::HwlCombineBankPipeSwizzle
2669 * @brief
2670 * Combine bank/pipe swizzle
2671 * @return
2672 * ADDR_E_RETURNCODE
2673 ****************************************************************************************************
2674 */
2675 ADDR_E_RETURNCODE EgBasedLib::HwlCombineBankPipeSwizzle(
2676 UINT_32 bankSwizzle, ///< [in] bank swizzle
2677 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2678 ADDR_TILEINFO* pTileInfo, ///< [in] tile info
2679 UINT_64 baseAddr, ///< [in] base address
2680 UINT_32* pTileSwizzle ///< [out] combined swizzle
2681 ) const
2682 {
2683 ADDR_E_RETURNCODE retCode = ADDR_OK;
2684
2685 if (pTileSwizzle)
2686 {
2687 *pTileSwizzle = GetBankPipeSwizzle(bankSwizzle, pipeSwizzle, baseAddr, pTileInfo);
2688 }
2689 else
2690 {
2691 retCode = ADDR_INVALIDPARAMS;
2692 }
2693
2694 return retCode;
2695 }
2696
2697 /**
2698 ****************************************************************************************************
2699 * EgBasedLib::HwlComputeBaseSwizzle
2700 * @brief
2701 * Compute base swizzle
2702 * @return
2703 * ADDR_E_RETURNCODE
2704 ****************************************************************************************************
2705 */
2706 ADDR_E_RETURNCODE EgBasedLib::HwlComputeBaseSwizzle(
2707 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
2708 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut
2709 ) const
2710 {
2711 UINT_32 bankSwizzle = 0;
2712 UINT_32 pipeSwizzle = 0;
2713 ADDR_TILEINFO* pTileInfo = pIn->pTileInfo;
2714
2715 ADDR_ASSERT(IsMacroTiled(pIn->tileMode));
2716 ADDR_ASSERT(pIn->pTileInfo);
2717
2718 /// This is a legacy misreading of h/w doc, use it as it doesn't hurt.
2719 static const UINT_8 bankRotationArray[4][16] = {
2720 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_2_BANK
2721 { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_4_BANK
2722 { 0, 3, 6, 1, 4, 7, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0 }, // ADDR_SURF_8_BANK
2723 { 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 }, // ADDR_SURF_16_BANK
2724 };
2725
2726 UINT_32 pipes = HwlGetPipes(pTileInfo);
2727 (void)pipes;
2728 UINT_32 banks = pTileInfo ? pTileInfo->banks : 2;
2729 UINT_32 hwNumBanks;
2730
2731 // Uses less bank swizzle bits
2732 if (pIn->option.reduceBankBit && banks > 2)
2733 {
2734 banks >>= 1;
2735 }
2736
2737 switch (banks)
2738 {
2739 case 2:
2740 hwNumBanks = 0;
2741 break;
2742 case 4:
2743 hwNumBanks = 1;
2744 break;
2745 case 8:
2746 hwNumBanks = 2;
2747 break;
2748 case 16:
2749 hwNumBanks = 3;
2750 break;
2751 default:
2752 ADDR_ASSERT_ALWAYS();
2753 hwNumBanks = 0;
2754 break;
2755 }
2756
2757 if (pIn->option.genOption == ADDR_SWIZZLE_GEN_LINEAR)
2758 {
2759 bankSwizzle = pIn->surfIndex & (banks - 1);
2760 }
2761 else // (pIn->option.genOption == ADDR_SWIZZLE_GEN_DEFAULT)
2762 {
2763 bankSwizzle = bankRotationArray[hwNumBanks][pIn->surfIndex & (banks - 1)];
2764 }
2765
2766 if (IsMacro3dTiled(pIn->tileMode))
2767 {
2768 pipeSwizzle = pIn->surfIndex & (HwlGetPipes(pTileInfo) - 1);
2769 }
2770
2771 return HwlCombineBankPipeSwizzle(bankSwizzle, pipeSwizzle, pTileInfo, 0, &pOut->tileSwizzle);
2772 }
2773
2774 /**
2775 ****************************************************************************************************
2776 * EgBasedLib::ExtractBankPipeSwizzle
2777 * @brief
2778 * Extract bank/pipe swizzle from base256b
2779 * @return
2780 * N/A
2781 ****************************************************************************************************
2782 */
2783 VOID EgBasedLib::ExtractBankPipeSwizzle(
2784 UINT_32 base256b, ///< [in] input base256b register value
2785 ADDR_TILEINFO* pTileInfo, ///< [in] 2D tile parameters. Client must provide all data
2786 UINT_32* pBankSwizzle, ///< [out] bank swizzle
2787 UINT_32* pPipeSwizzle ///< [out] pipe swizzle
2788 ) const
2789 {
2790 UINT_32 bankSwizzle = 0;
2791 UINT_32 pipeSwizzle = 0;
2792
2793 if (base256b != 0)
2794 {
2795 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2796 UINT_32 bankBits = QLog2(pTileInfo->banks);
2797 UINT_32 pipeBits = QLog2(numPipes);
2798 UINT_32 groupBytes = m_pipeInterleaveBytes;
2799 UINT_32 bankInterleave = m_bankInterleave;
2800
2801 pipeSwizzle =
2802 (base256b / (groupBytes >> 8)) & ((1<<pipeBits)-1);
2803
2804 bankSwizzle =
2805 (base256b / (groupBytes >> 8) / numPipes / bankInterleave) & ((1 << bankBits) - 1);
2806 }
2807
2808 *pPipeSwizzle = pipeSwizzle;
2809 *pBankSwizzle = bankSwizzle;
2810 }
2811
2812 /**
2813 ****************************************************************************************************
2814 * EgBasedLib::GetBankPipeSwizzle
2815 * @brief
2816 * Combine bank/pipe swizzle
2817 * @return
2818 * Base256b bits (only filled bank/pipe bits)
2819 ****************************************************************************************************
2820 */
2821 UINT_32 EgBasedLib::GetBankPipeSwizzle(
2822 UINT_32 bankSwizzle, ///< [in] bank swizzle
2823 UINT_32 pipeSwizzle, ///< [in] pipe swizzle
2824 UINT_64 baseAddr, ///< [in] base address
2825 ADDR_TILEINFO* pTileInfo ///< [in] tile info
2826 ) const
2827 {
2828 UINT_32 pipeBits = QLog2(HwlGetPipes(pTileInfo));
2829 UINT_32 bankInterleaveBits = QLog2(m_bankInterleave);
2830 UINT_32 tileSwizzle = pipeSwizzle + ((bankSwizzle << bankInterleaveBits) << pipeBits);
2831
2832 baseAddr ^= tileSwizzle * m_pipeInterleaveBytes;
2833 baseAddr >>= 8;
2834
2835 return static_cast<UINT_32>(baseAddr);
2836 }
2837
2838 /**
2839 ****************************************************************************************************
2840 * EgBasedLib::ComputeSliceTileSwizzle
2841 * @brief
2842 * Compute cubemap/3d texture faces/slices tile swizzle
2843 * @return
2844 * Tile swizzle
2845 ****************************************************************************************************
2846 */
2847 UINT_32 EgBasedLib::ComputeSliceTileSwizzle(
2848 AddrTileMode tileMode, ///< [in] Tile mode
2849 UINT_32 baseSwizzle, ///< [in] Base swizzle
2850 UINT_32 slice, ///< [in] Slice index, Cubemap face index, 0 means +X
2851 UINT_64 baseAddr, ///< [in] Base address
2852 ADDR_TILEINFO* pTileInfo ///< [in] Bank structure
2853 ) const
2854 {
2855 UINT_32 tileSwizzle = 0;
2856
2857 if (IsMacroTiled(tileMode)) // Swizzle only for macro tile mode
2858 {
2859 UINT_32 firstSlice = slice / Thickness(tileMode);
2860
2861 UINT_32 numPipes = HwlGetPipes(pTileInfo);
2862 UINT_32 numBanks = pTileInfo->banks;
2863
2864 UINT_32 pipeRotation;
2865 UINT_32 bankRotation;
2866
2867 UINT_32 bankSwizzle = 0;
2868 UINT_32 pipeSwizzle = 0;
2869
2870 pipeRotation = ComputePipeRotation(tileMode, numPipes);
2871 bankRotation = ComputeBankRotation(tileMode, numBanks, numPipes);
2872
2873 if (baseSwizzle != 0)
2874 {
2875 ExtractBankPipeSwizzle(baseSwizzle,
2876 pTileInfo,
2877 &bankSwizzle,
2878 &pipeSwizzle);
2879 }
2880
2881 if (pipeRotation == 0) //2D mode
2882 {
2883 bankSwizzle += firstSlice * bankRotation;
2884 bankSwizzle %= numBanks;
2885 }
2886 else //3D mode
2887 {
2888 pipeSwizzle += firstSlice * pipeRotation;
2889 pipeSwizzle %= numPipes;
2890 bankSwizzle += firstSlice * bankRotation / numPipes;
2891 bankSwizzle %= numBanks;
2892 }
2893
2894 tileSwizzle = GetBankPipeSwizzle(bankSwizzle,
2895 pipeSwizzle,
2896 baseAddr,
2897 pTileInfo);
2898 }
2899
2900 return tileSwizzle;
2901 }
2902
2903 /**
2904 ****************************************************************************************************
2905 * EgBasedLib::HwlComputeQbStereoRightSwizzle
2906 *
2907 * @brief
2908 * Compute right eye swizzle
2909 * @return
2910 * swizzle
2911 ****************************************************************************************************
2912 */
2913 UINT_32 EgBasedLib::HwlComputeQbStereoRightSwizzle(
2914 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pInfo ///< [in] Surface info, must be valid
2915 ) const
2916 {
2917 UINT_32 bankBits = 0;
2918 UINT_32 swizzle = 0;
2919
2920 // The assumption is default swizzle for left eye is 0
2921 if (IsMacroTiled(pInfo->tileMode) && pInfo->pStereoInfo && pInfo->pTileInfo)
2922 {
2923 bankBits = ComputeBankFromCoord(0, pInfo->height, 0,
2924 pInfo->tileMode, 0, 0, pInfo->pTileInfo);
2925
2926 if (bankBits)
2927 {
2928 HwlCombineBankPipeSwizzle(bankBits, 0, pInfo->pTileInfo, 0, &swizzle);
2929 }
2930 }
2931
2932 return swizzle;
2933 }
2934
2935 /**
2936 ****************************************************************************************************
2937 * EgBasedLib::ComputeBankFromCoord
2938 *
2939 * @brief
2940 * Compute bank number from coordinates
2941 * @return
2942 * Bank number
2943 ****************************************************************************************************
2944 */
2945 UINT_32 EgBasedLib::ComputeBankFromCoord(
2946 UINT_32 x, ///< [in] x coordinate
2947 UINT_32 y, ///< [in] y coordinate
2948 UINT_32 slice, ///< [in] slice index
2949 AddrTileMode tileMode, ///< [in] tile mode
2950 UINT_32 bankSwizzle, ///< [in] bank swizzle
2951 UINT_32 tileSplitSlice, ///< [in] If the size of the pixel offset is larger than the
2952 /// tile split size, then the pixel will be moved to a separate
2953 /// slice. This value equals pixelOffset / tileSplitBytes
2954 /// in this case. Otherwise this is 0.
2955 ADDR_TILEINFO* pTileInfo ///< [in] tile info
2956 ) const
2957 {
2958 UINT_32 pipes = HwlGetPipes(pTileInfo);
2959 UINT_32 bankBit0 = 0;
2960 UINT_32 bankBit1 = 0;
2961 UINT_32 bankBit2 = 0;
2962 UINT_32 bankBit3 = 0;
2963 UINT_32 sliceRotation;
2964 UINT_32 tileSplitRotation;
2965 UINT_32 bank;
2966 UINT_32 numBanks = pTileInfo->banks;
2967 UINT_32 bankWidth = pTileInfo->bankWidth;
2968 UINT_32 bankHeight = pTileInfo->bankHeight;
2969
2970 UINT_32 tx = x / MicroTileWidth / (bankWidth * pipes);
2971 UINT_32 ty = y / MicroTileHeight / bankHeight;
2972
2973 UINT_32 x3 = _BIT(tx,0);
2974 UINT_32 x4 = _BIT(tx,1);
2975 UINT_32 x5 = _BIT(tx,2);
2976 UINT_32 x6 = _BIT(tx,3);
2977 UINT_32 y3 = _BIT(ty,0);
2978 UINT_32 y4 = _BIT(ty,1);
2979 UINT_32 y5 = _BIT(ty,2);
2980 UINT_32 y6 = _BIT(ty,3);
2981
2982 switch (numBanks)
2983 {
2984 case 16:
2985 bankBit0 = x3 ^ y6;
2986 bankBit1 = x4 ^ y5 ^ y6;
2987 bankBit2 = x5 ^ y4;
2988 bankBit3 = x6 ^ y3;
2989 break;
2990 case 8:
2991 bankBit0 = x3 ^ y5;
2992 bankBit1 = x4 ^ y4 ^ y5;
2993 bankBit2 = x5 ^ y3;
2994 break;
2995 case 4:
2996 bankBit0 = x3 ^ y4;
2997 bankBit1 = x4 ^ y3;
2998 break;
2999 case 2:
3000 bankBit0 = x3 ^ y3;
3001 break;
3002 default:
3003 ADDR_ASSERT_ALWAYS();
3004 break;
3005 }
3006
3007 bank = bankBit0 | (bankBit1 << 1) | (bankBit2 << 2) | (bankBit3 << 3);
3008
3009 //Bits2Number(4, bankBit3, bankBit2, bankBit1, bankBit0);
3010
3011 bank = HwlPreAdjustBank((x / MicroTileWidth), bank, pTileInfo);
3012 //
3013 // Compute bank rotation for the slice.
3014 //
3015 UINT_32 microTileThickness = Thickness(tileMode);
3016
3017 switch (tileMode)
3018 {
3019 case ADDR_TM_2D_TILED_THIN1: // fall through
3020 case ADDR_TM_2D_TILED_THICK: // fall through
3021 case ADDR_TM_2D_TILED_XTHICK:
3022 sliceRotation = ((numBanks / 2) - 1) * (slice / microTileThickness);
3023 break;
3024 case ADDR_TM_3D_TILED_THIN1: // fall through
3025 case ADDR_TM_3D_TILED_THICK: // fall through
3026 case ADDR_TM_3D_TILED_XTHICK:
3027 sliceRotation =
3028 Max(1u, (pipes / 2) - 1) * (slice / microTileThickness) / pipes;
3029 break;
3030 default:
3031 sliceRotation = 0;
3032 break;
3033 }
3034
3035 //
3036 // Compute bank rotation for the tile split slice.
3037 //
3038 // The sample slice will be non-zero if samples must be split across multiple slices.
3039 // This situation arises when the micro tile size multiplied yBit the number of samples exceeds
3040 // the split size (set in GB_ADDR_CONFIG).
3041 //
3042 switch (tileMode)
3043 {
3044 case ADDR_TM_2D_TILED_THIN1: //fall through
3045 case ADDR_TM_3D_TILED_THIN1: //fall through
3046 case ADDR_TM_PRT_2D_TILED_THIN1: //fall through
3047 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
3048 tileSplitRotation = ((numBanks / 2) + 1) * tileSplitSlice;
3049 break;
3050 default:
3051 tileSplitRotation = 0;
3052 break;
3053 }
3054
3055 //
3056 // Apply bank rotation for the slice and tile split slice.
3057 //
3058 bank ^= bankSwizzle + sliceRotation;
3059 bank ^= tileSplitRotation;
3060
3061 bank &= (numBanks - 1);
3062
3063 return bank;
3064 }
3065
3066 /**
3067 ****************************************************************************************************
3068 * EgBasedLib::ComputeBankFromAddr
3069 *
3070 * @brief
3071 * Compute the bank number from an address
3072 * @return
3073 * Bank number
3074 ****************************************************************************************************
3075 */
3076 UINT_32 EgBasedLib::ComputeBankFromAddr(
3077 UINT_64 addr, ///< [in] address
3078 UINT_32 numBanks, ///< [in] number of banks
3079 UINT_32 numPipes ///< [in] number of pipes
3080 ) const
3081 {
3082 UINT_32 bank;
3083
3084 //
3085 // The LSBs of the address are arranged as follows:
3086 // bank | bankInterleave | pipe | pipeInterleave
3087 //
3088 // To get the bank number, shift off the pipe interleave, pipe, and bank interlave bits and
3089 // mask the bank bits.
3090 //
3091 bank = static_cast<UINT_32>(
3092 (addr >> Log2(m_pipeInterleaveBytes * numPipes * m_bankInterleave)) &
3093 (numBanks - 1)
3094 );
3095
3096 return bank;
3097 }
3098
3099 /**
3100 ****************************************************************************************************
3101 * EgBasedLib::ComputePipeRotation
3102 *
3103 * @brief
3104 * Compute pipe rotation value
3105 * @return
3106 * Pipe rotation
3107 ****************************************************************************************************
3108 */
3109 UINT_32 EgBasedLib::ComputePipeRotation(
3110 AddrTileMode tileMode, ///< [in] tile mode
3111 UINT_32 numPipes ///< [in] number of pipes
3112 ) const
3113 {
3114 UINT_32 rotation;
3115
3116 switch (tileMode)
3117 {
3118 case ADDR_TM_3D_TILED_THIN1: //fall through
3119 case ADDR_TM_3D_TILED_THICK: //fall through
3120 case ADDR_TM_3D_TILED_XTHICK: //fall through
3121 case ADDR_TM_PRT_3D_TILED_THIN1: //fall through
3122 case ADDR_TM_PRT_3D_TILED_THICK:
3123 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1);
3124 break;
3125 default:
3126 rotation = 0;
3127 }
3128
3129 return rotation;
3130 }
3131
3132 /**
3133 ****************************************************************************************************
3134 * EgBasedLib::ComputeBankRotation
3135 *
3136 * @brief
3137 * Compute bank rotation value
3138 * @return
3139 * Bank rotation
3140 ****************************************************************************************************
3141 */
3142 UINT_32 EgBasedLib::ComputeBankRotation(
3143 AddrTileMode tileMode, ///< [in] tile mode
3144 UINT_32 numBanks, ///< [in] number of banks
3145 UINT_32 numPipes ///< [in] number of pipes
3146 ) const
3147 {
3148 UINT_32 rotation;
3149
3150 switch (tileMode)
3151 {
3152 case ADDR_TM_2D_TILED_THIN1: // fall through
3153 case ADDR_TM_2D_TILED_THICK: // fall through
3154 case ADDR_TM_2D_TILED_XTHICK:
3155 case ADDR_TM_PRT_2D_TILED_THIN1:
3156 case ADDR_TM_PRT_2D_TILED_THICK:
3157 // Rotate banks per Z-slice yBit 1 for 4-bank or 3 for 8-bank
3158 rotation = numBanks / 2 - 1;
3159 break;
3160 case ADDR_TM_3D_TILED_THIN1: // fall through
3161 case ADDR_TM_3D_TILED_THICK: // fall through
3162 case ADDR_TM_3D_TILED_XTHICK:
3163 case ADDR_TM_PRT_3D_TILED_THIN1:
3164 case ADDR_TM_PRT_3D_TILED_THICK:
3165 rotation = (numPipes < 4) ? 1 : (numPipes / 2 - 1); // rotate pipes & banks
3166 break;
3167 default:
3168 rotation = 0;
3169 }
3170
3171 return rotation;
3172 }
3173
3174 /**
3175 ****************************************************************************************************
3176 * EgBasedLib::ComputeHtileBytes
3177 *
3178 * @brief
3179 * Compute htile size in bytes
3180 *
3181 * @return
3182 * Htile size in bytes
3183 ****************************************************************************************************
3184 */
3185 UINT_64 EgBasedLib::ComputeHtileBytes(
3186 UINT_32 pitch, ///< [in] pitch
3187 UINT_32 height, ///< [in] height
3188 UINT_32 bpp, ///< [in] bits per pixel
3189 BOOL_32 isLinear, ///< [in] if it is linear mode
3190 UINT_32 numSlices, ///< [in] number of slices
3191 UINT_64* sliceBytes, ///< [out] bytes per slice
3192 UINT_32 baseAlign ///< [in] base alignments
3193 ) const
3194 {
3195 UINT_64 surfBytes;
3196
3197 const UINT_64 HtileCacheLineSize = BITS_TO_BYTES(HtileCacheBits);
3198
3199 *sliceBytes = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp / 64);
3200
3201 if (m_configFlags.useHtileSliceAlign)
3202 {
3203 // Align the sliceSize to htilecachelinesize * pipes at first
3204 *sliceBytes = PowTwoAlign(*sliceBytes, HtileCacheLineSize * m_pipes);
3205 surfBytes = *sliceBytes * numSlices;
3206 }
3207 else
3208 {
3209 // Align the surfSize to htilecachelinesize * pipes at last
3210 surfBytes = *sliceBytes * numSlices;
3211 surfBytes = PowTwoAlign(surfBytes, HtileCacheLineSize * m_pipes);
3212 }
3213
3214 return surfBytes;
3215 }
3216
3217 /**
3218 ****************************************************************************************************
3219 * EgBasedLib::DispatchComputeFmaskInfo
3220 *
3221 * @brief
3222 * Compute fmask sizes include padded pitch, height, slices, total size in bytes,
3223 * meanwhile output suitable tile mode and alignments as well. Results are returned
3224 * through output parameters.
3225 *
3226 * @return
3227 * ADDR_E_RETURNCODE
3228 ****************************************************************************************************
3229 */
3230 ADDR_E_RETURNCODE EgBasedLib::DispatchComputeFmaskInfo(
3231 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
3232 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut) ///< [out] output structure
3233 {
3234 ADDR_E_RETURNCODE retCode = ADDR_OK;
3235
3236 ADDR_COMPUTE_SURFACE_INFO_INPUT surfIn = {0};
3237 ADDR_COMPUTE_SURFACE_INFO_OUTPUT surfOut = {0};
3238
3239 // Setup input structure
3240 surfIn.tileMode = pIn->tileMode;
3241 surfIn.width = pIn->pitch;
3242 surfIn.height = pIn->height;
3243 surfIn.numSlices = pIn->numSlices;
3244 surfIn.pTileInfo = pIn->pTileInfo;
3245 surfIn.tileType = ADDR_NON_DISPLAYABLE;
3246 surfIn.flags.fmask = 1;
3247
3248 // Setup output structure
3249 surfOut.pTileInfo = pOut->pTileInfo;
3250
3251 // Setup hwl specific fields
3252 HwlFmaskPreThunkSurfInfo(pIn, pOut, &surfIn, &surfOut);
3253
3254 surfIn.bpp = HwlComputeFmaskBits(pIn, &surfIn.numSamples);
3255
3256 // ComputeSurfaceInfo needs numSamples in surfOut as surface routines need adjusted numSamples
3257 surfOut.numSamples = surfIn.numSamples;
3258
3259 retCode = HwlComputeSurfaceInfo(&surfIn, &surfOut);
3260
3261 // Save bpp field for surface dump support
3262 surfOut.bpp = surfIn.bpp;
3263
3264 if (retCode == ADDR_OK)
3265 {
3266 pOut->bpp = surfOut.bpp;
3267 pOut->pitch = surfOut.pitch;
3268 pOut->height = surfOut.height;
3269 pOut->numSlices = surfOut.depth;
3270 pOut->fmaskBytes = surfOut.surfSize;
3271 pOut->baseAlign = surfOut.baseAlign;
3272 pOut->pitchAlign = surfOut.pitchAlign;
3273 pOut->heightAlign = surfOut.heightAlign;
3274
3275 if (surfOut.depth > 1)
3276 {
3277 // For fmask, expNumSlices is stored in depth.
3278 pOut->sliceSize = surfOut.surfSize / surfOut.depth;
3279 }
3280 else
3281 {
3282 pOut->sliceSize = surfOut.surfSize;
3283 }
3284
3285 // Save numSamples field for surface dump support
3286 pOut->numSamples = surfOut.numSamples;
3287
3288 HwlFmaskPostThunkSurfInfo(&surfOut, pOut);
3289 }
3290
3291 return retCode;
3292 }
3293
3294 /**
3295 ****************************************************************************************************
3296 * EgBasedLib::HwlFmaskSurfaceInfo
3297 * @brief
3298 * Entry of EgBasedLib ComputeFmaskInfo
3299 * @return
3300 * ADDR_E_RETURNCODE
3301 ****************************************************************************************************
3302 */
3303 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskInfo(
3304 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
3305 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
3306 )
3307 {
3308 ADDR_E_RETURNCODE retCode = ADDR_OK;
3309
3310 ADDR_TILEINFO tileInfo = {0};
3311
3312 // Use internal tile info if pOut does not have a valid pTileInfo
3313 if (pOut->pTileInfo == NULL)
3314 {
3315 pOut->pTileInfo = &tileInfo;
3316 }
3317
3318 retCode = DispatchComputeFmaskInfo(pIn, pOut);
3319
3320 if (retCode == ADDR_OK)
3321 {
3322 pOut->tileIndex =
3323 HwlPostCheckTileIndex(pOut->pTileInfo, pIn->tileMode, ADDR_NON_DISPLAYABLE,
3324 pOut->tileIndex);
3325 }
3326
3327 // Resets pTileInfo to NULL if the internal tile info is used
3328 if (pOut->pTileInfo == &tileInfo)
3329 {
3330 pOut->pTileInfo = NULL;
3331 }
3332
3333 return retCode;
3334 }
3335
3336 /**
3337 ****************************************************************************************************
3338 * EgBasedLib::HwlComputeFmaskAddrFromCoord
3339 * @brief
3340 * Entry of EgBasedLib ComputeFmaskAddrFromCoord
3341 * @return
3342 * ADDR_E_RETURNCODE
3343 ****************************************************************************************************
3344 */
3345 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskAddrFromCoord(
3346 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3347 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3348 ) const
3349 {
3350 ADDR_E_RETURNCODE retCode = ADDR_OK;
3351
3352 return retCode;
3353 }
3354
3355 /**
3356 ****************************************************************************************************
3357 * EgBasedLib::HwlComputeFmaskCoordFromAddr
3358 * @brief
3359 * Entry of EgBasedLib ComputeFmaskCoordFromAddr
3360 * @return
3361 * ADDR_E_RETURNCODE
3362 ****************************************************************************************************
3363 */
3364 ADDR_E_RETURNCODE EgBasedLib::HwlComputeFmaskCoordFromAddr(
3365 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
3366 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
3367 ) const
3368 {
3369 ADDR_E_RETURNCODE retCode = ADDR_OK;
3370
3371 return retCode;
3372 }
3373
3374 /**
3375 ****************************************************************************************************
3376 * EgBasedLib::ComputeFmaskNumPlanesFromNumSamples
3377 *
3378 * @brief
3379 * Compute fmask number of planes from number of samples
3380 *
3381 * @return
3382 * Number of planes
3383 ****************************************************************************************************
3384 */
3385 UINT_32 EgBasedLib::ComputeFmaskNumPlanesFromNumSamples(
3386 UINT_32 numSamples) ///< [in] number of samples
3387 {
3388 UINT_32 numPlanes;
3389
3390 //
3391 // FMASK is stored such that each micro tile is composed of elements containing N bits, where
3392 // N is the number of samples. There is a micro tile for each bit in the FMASK address, and
3393 // micro tiles for each address bit, sometimes referred to as a plane, are stored sequentially.
3394 // The FMASK for a 2-sample surface looks like a general surface with 2 bits per element.
3395 // The FMASK for a 4-sample surface looks like a general surface with 4 bits per element and
3396 // 2 samples. The FMASK for an 8-sample surface looks like a general surface with 8 bits per
3397 // element and 4 samples. R6xx and R7xx only stored 3 planes for 8-sample FMASK surfaces.
3398 // This was changed for R8xx to simplify the logic in the CB.
3399 //
3400 switch (numSamples)
3401 {
3402 case 2:
3403 numPlanes = 1;
3404 break;
3405 case 4:
3406 numPlanes = 2;
3407 break;
3408 case 8:
3409 numPlanes = 4;
3410 break;
3411 default:
3412 ADDR_UNHANDLED_CASE();
3413 numPlanes = 0;
3414 break;
3415 }
3416 return numPlanes;
3417 }
3418
3419 /**
3420 ****************************************************************************************************
3421 * EgBasedLib::ComputeFmaskResolvedBppFromNumSamples
3422 *
3423 * @brief
3424 * Compute resolved fmask effective bpp based on number of samples
3425 *
3426 * @return
3427 * bpp
3428 ****************************************************************************************************
3429 */
3430 UINT_32 EgBasedLib::ComputeFmaskResolvedBppFromNumSamples(
3431 UINT_32 numSamples) ///< number of samples
3432 {
3433 UINT_32 bpp;
3434
3435 //
3436 // Resolved FMASK surfaces are generated yBit the CB and read yBit the texture unit
3437 // so that the texture unit can read compressed multi-sample color data.
3438 // These surfaces store each index value packed per element.
3439 // Each element contains at least num_samples * log2(num_samples) bits.
3440 // Resolved FMASK surfaces are addressed as follows:
3441 // 2-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3442 // 4-sample Addressed similarly to a color surface with 8 bits per element and 1 sample.
3443 // 8-sample Addressed similarly to a color surface with 32 bits per element and 1 sample.
3444
3445 switch (numSamples)
3446 {
3447 case 2:
3448 bpp = 8;
3449 break;
3450 case 4:
3451 bpp = 8;
3452 break;
3453 case 8:
3454 bpp = 32;
3455 break;
3456 default:
3457 ADDR_UNHANDLED_CASE();
3458 bpp = 0;
3459 break;
3460 }
3461 return bpp;
3462 }
3463
3464 /**
3465 ****************************************************************************************************
3466 * EgBasedLib::IsTileInfoAllZero
3467 *
3468 * @brief
3469 * Return TRUE if all field are zero
3470 * @note
3471 * Since NULL input is consider to be all zero
3472 ****************************************************************************************************
3473 */
3474 BOOL_32 EgBasedLib::IsTileInfoAllZero(
3475 const ADDR_TILEINFO* pTileInfo)
3476 {
3477 BOOL_32 allZero = TRUE;
3478
3479 if (pTileInfo)
3480 {
3481 if ((pTileInfo->banks != 0) ||
3482 (pTileInfo->bankWidth != 0) ||
3483 (pTileInfo->bankHeight != 0) ||
3484 (pTileInfo->macroAspectRatio != 0) ||
3485 (pTileInfo->tileSplitBytes != 0) ||
3486 (pTileInfo->pipeConfig != 0)
3487 )
3488 {
3489 allZero = FALSE;
3490 }
3491 }
3492
3493 return allZero;
3494 }
3495
3496 /**
3497 ****************************************************************************************************
3498 * EgBasedLib::HwlTileInfoEqual
3499 *
3500 * @brief
3501 * Return TRUE if all field are equal
3502 * @note
3503 * Only takes care of current HWL's data
3504 ****************************************************************************************************
3505 */
3506 BOOL_32 EgBasedLib::HwlTileInfoEqual(
3507 const ADDR_TILEINFO* pLeft, ///<[in] Left compare operand
3508 const ADDR_TILEINFO* pRight ///<[in] Right compare operand
3509 ) const
3510 {
3511 BOOL_32 equal = FALSE;
3512
3513 if (pLeft->banks == pRight->banks &&
3514 pLeft->bankWidth == pRight->bankWidth &&
3515 pLeft->bankHeight == pRight->bankHeight &&
3516 pLeft->macroAspectRatio == pRight->macroAspectRatio &&
3517 pLeft->tileSplitBytes == pRight->tileSplitBytes)
3518 {
3519 equal = TRUE;
3520 }
3521
3522 return equal;
3523 }
3524
3525 /**
3526 ****************************************************************************************************
3527 * EgBasedLib::HwlConvertTileInfoToHW
3528 * @brief
3529 * Entry of EgBasedLib ConvertTileInfoToHW
3530 * @return
3531 * ADDR_E_RETURNCODE
3532 ****************************************************************************************************
3533 */
3534 ADDR_E_RETURNCODE EgBasedLib::HwlConvertTileInfoToHW(
3535 const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
3536 ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
3537 ) const
3538 {
3539 ADDR_E_RETURNCODE retCode = ADDR_OK;
3540
3541 ADDR_TILEINFO *pTileInfoIn = pIn->pTileInfo;
3542 ADDR_TILEINFO *pTileInfoOut = pOut->pTileInfo;
3543
3544 if ((pTileInfoIn != NULL) && (pTileInfoOut != NULL))
3545 {
3546 if (pIn->reverse == FALSE)
3547 {
3548 switch (pTileInfoIn->banks)
3549 {
3550 case 2:
3551 pTileInfoOut->banks = 0;
3552 break;
3553 case 4:
3554 pTileInfoOut->banks = 1;
3555 break;
3556 case 8:
3557 pTileInfoOut->banks = 2;
3558 break;
3559 case 16:
3560 pTileInfoOut->banks = 3;
3561 break;
3562 default:
3563 ADDR_ASSERT_ALWAYS();
3564 retCode = ADDR_INVALIDPARAMS;
3565 pTileInfoOut->banks = 0;
3566 break;
3567 }
3568
3569 switch (pTileInfoIn->bankWidth)
3570 {
3571 case 1:
3572 pTileInfoOut->bankWidth = 0;
3573 break;
3574 case 2:
3575 pTileInfoOut->bankWidth = 1;
3576 break;
3577 case 4:
3578 pTileInfoOut->bankWidth = 2;
3579 break;
3580 case 8:
3581 pTileInfoOut->bankWidth = 3;
3582 break;
3583 default:
3584 ADDR_ASSERT_ALWAYS();
3585 retCode = ADDR_INVALIDPARAMS;
3586 pTileInfoOut->bankWidth = 0;
3587 break;
3588 }
3589
3590 switch (pTileInfoIn->bankHeight)
3591 {
3592 case 1:
3593 pTileInfoOut->bankHeight = 0;
3594 break;
3595 case 2:
3596 pTileInfoOut->bankHeight = 1;
3597 break;
3598 case 4:
3599 pTileInfoOut->bankHeight = 2;
3600 break;
3601 case 8:
3602 pTileInfoOut->bankHeight = 3;
3603 break;
3604 default:
3605 ADDR_ASSERT_ALWAYS();
3606 retCode = ADDR_INVALIDPARAMS;
3607 pTileInfoOut->bankHeight = 0;
3608 break;
3609 }
3610
3611 switch (pTileInfoIn->macroAspectRatio)
3612 {
3613 case 1:
3614 pTileInfoOut->macroAspectRatio = 0;
3615 break;
3616 case 2:
3617 pTileInfoOut->macroAspectRatio = 1;
3618 break;
3619 case 4:
3620 pTileInfoOut->macroAspectRatio = 2;
3621 break;
3622 case 8:
3623 pTileInfoOut->macroAspectRatio = 3;
3624 break;
3625 default:
3626 ADDR_ASSERT_ALWAYS();
3627 retCode = ADDR_INVALIDPARAMS;
3628 pTileInfoOut->macroAspectRatio = 0;
3629 break;
3630 }
3631
3632 switch (pTileInfoIn->tileSplitBytes)
3633 {
3634 case 64:
3635 pTileInfoOut->tileSplitBytes = 0;
3636 break;
3637 case 128:
3638 pTileInfoOut->tileSplitBytes = 1;
3639 break;
3640 case 256:
3641 pTileInfoOut->tileSplitBytes = 2;
3642 break;
3643 case 512:
3644 pTileInfoOut->tileSplitBytes = 3;
3645 break;
3646 case 1024:
3647 pTileInfoOut->tileSplitBytes = 4;
3648 break;
3649 case 2048:
3650 pTileInfoOut->tileSplitBytes = 5;
3651 break;
3652 case 4096:
3653 pTileInfoOut->tileSplitBytes = 6;
3654 break;
3655 default:
3656 ADDR_ASSERT_ALWAYS();
3657 retCode = ADDR_INVALIDPARAMS;
3658 pTileInfoOut->tileSplitBytes = 0;
3659 break;
3660 }
3661 }
3662 else
3663 {
3664 switch (pTileInfoIn->banks)
3665 {
3666 case 0:
3667 pTileInfoOut->banks = 2;
3668 break;
3669 case 1:
3670 pTileInfoOut->banks = 4;
3671 break;
3672 case 2:
3673 pTileInfoOut->banks = 8;
3674 break;
3675 case 3:
3676 pTileInfoOut->banks = 16;
3677 break;
3678 default:
3679 ADDR_ASSERT_ALWAYS();
3680 retCode = ADDR_INVALIDPARAMS;
3681 pTileInfoOut->banks = 2;
3682 break;
3683 }
3684
3685 switch (pTileInfoIn->bankWidth)
3686 {
3687 case 0:
3688 pTileInfoOut->bankWidth = 1;
3689 break;
3690 case 1:
3691 pTileInfoOut->bankWidth = 2;
3692 break;
3693 case 2:
3694 pTileInfoOut->bankWidth = 4;
3695 break;
3696 case 3:
3697 pTileInfoOut->bankWidth = 8;
3698 break;
3699 default:
3700 ADDR_ASSERT_ALWAYS();
3701 retCode = ADDR_INVALIDPARAMS;
3702 pTileInfoOut->bankWidth = 1;
3703 break;
3704 }
3705
3706 switch (pTileInfoIn->bankHeight)
3707 {
3708 case 0:
3709 pTileInfoOut->bankHeight = 1;
3710 break;
3711 case 1:
3712 pTileInfoOut->bankHeight = 2;
3713 break;
3714 case 2:
3715 pTileInfoOut->bankHeight = 4;
3716 break;
3717 case 3:
3718 pTileInfoOut->bankHeight = 8;
3719 break;
3720 default:
3721 ADDR_ASSERT_ALWAYS();
3722 retCode = ADDR_INVALIDPARAMS;
3723 pTileInfoOut->bankHeight = 1;
3724 break;
3725 }
3726
3727 switch (pTileInfoIn->macroAspectRatio)
3728 {
3729 case 0:
3730 pTileInfoOut->macroAspectRatio = 1;
3731 break;
3732 case 1:
3733 pTileInfoOut->macroAspectRatio = 2;
3734 break;
3735 case 2:
3736 pTileInfoOut->macroAspectRatio = 4;
3737 break;
3738 case 3:
3739 pTileInfoOut->macroAspectRatio = 8;
3740 break;
3741 default:
3742 ADDR_ASSERT_ALWAYS();
3743 retCode = ADDR_INVALIDPARAMS;
3744 pTileInfoOut->macroAspectRatio = 1;
3745 break;
3746 }
3747
3748 switch (pTileInfoIn->tileSplitBytes)
3749 {
3750 case 0:
3751 pTileInfoOut->tileSplitBytes = 64;
3752 break;
3753 case 1:
3754 pTileInfoOut->tileSplitBytes = 128;
3755 break;
3756 case 2:
3757 pTileInfoOut->tileSplitBytes = 256;
3758 break;
3759 case 3:
3760 pTileInfoOut->tileSplitBytes = 512;
3761 break;
3762 case 4:
3763 pTileInfoOut->tileSplitBytes = 1024;
3764 break;
3765 case 5:
3766 pTileInfoOut->tileSplitBytes = 2048;
3767 break;
3768 case 6:
3769 pTileInfoOut->tileSplitBytes = 4096;
3770 break;
3771 default:
3772 ADDR_ASSERT_ALWAYS();
3773 retCode = ADDR_INVALIDPARAMS;
3774 pTileInfoOut->tileSplitBytes = 64;
3775 break;
3776 }
3777 }
3778
3779 if (pTileInfoIn != pTileInfoOut)
3780 {
3781 pTileInfoOut->pipeConfig = pTileInfoIn->pipeConfig;
3782 }
3783 }
3784 else
3785 {
3786 ADDR_ASSERT_ALWAYS();
3787 retCode = ADDR_INVALIDPARAMS;
3788 }
3789
3790 return retCode;
3791 }
3792
3793 /**
3794 ****************************************************************************************************
3795 * EgBasedLib::HwlComputeSurfaceInfo
3796 * @brief
3797 * Entry of EgBasedLib ComputeSurfaceInfo
3798 * @return
3799 * ADDR_E_RETURNCODE
3800 ****************************************************************************************************
3801 */
3802 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceInfo(
3803 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
3804 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
3805 ) const
3806 {
3807 ADDR_E_RETURNCODE retCode = ADDR_OK;
3808
3809 if (pIn->numSamples < pIn->numFrags)
3810 {
3811 retCode = ADDR_INVALIDPARAMS;
3812 }
3813
3814 ADDR_TILEINFO tileInfo = {0};
3815
3816 if (retCode == ADDR_OK)
3817 {
3818 // Uses internal tile info if pOut does not have a valid pTileInfo
3819 if (pOut->pTileInfo == NULL)
3820 {
3821 pOut->pTileInfo = &tileInfo;
3822 }
3823
3824 if (DispatchComputeSurfaceInfo(pIn, pOut) == FALSE)
3825 {
3826 retCode = ADDR_INVALIDPARAMS;
3827 }
3828
3829 // In case client uses tile info as input and would like to calculate a correct size and
3830 // alignment together with tile info as output when the tile info is not suppose to have any
3831 // matching indices in tile mode tables.
3832 if (pIn->flags.skipIndicesOutput == FALSE)
3833 {
3834 // Returns an index
3835 pOut->tileIndex = HwlPostCheckTileIndex(pOut->pTileInfo,
3836 pOut->tileMode,
3837 pOut->tileType,
3838 pOut->tileIndex);
3839
3840 if (IsMacroTiled(pOut->tileMode) && (pOut->macroModeIndex == TileIndexInvalid))
3841 {
3842 pOut->macroModeIndex = HwlComputeMacroModeIndex(pOut->tileIndex,
3843 pIn->flags,
3844 pIn->bpp,
3845 pIn->numSamples,
3846 pOut->pTileInfo);
3847 }
3848 }
3849
3850 // Resets pTileInfo to NULL if the internal tile info is used
3851 if (pOut->pTileInfo == &tileInfo)
3852 {
3853 #if DEBUG
3854 // Client does not pass in a valid pTileInfo
3855 if (IsMacroTiled(pOut->tileMode))
3856 {
3857 // If a valid index is returned, then no pTileInfo is okay
3858 ADDR_ASSERT((m_configFlags.useTileIndex == FALSE) ||
3859 (pOut->tileIndex != TileIndexInvalid));
3860
3861 if (IsTileInfoAllZero(pIn->pTileInfo) == FALSE)
3862 {
3863 // The initial value of pIn->pTileInfo is copied to tileInfo
3864 // We do not expect any of these value to be changed nor any 0 of inputs
3865 ADDR_ASSERT(tileInfo.banks == pIn->pTileInfo->banks);
3866 ADDR_ASSERT(tileInfo.bankWidth == pIn->pTileInfo->bankWidth);
3867 ADDR_ASSERT(tileInfo.bankHeight == pIn->pTileInfo->bankHeight);
3868 ADDR_ASSERT(tileInfo.macroAspectRatio == pIn->pTileInfo->macroAspectRatio);
3869 ADDR_ASSERT(tileInfo.tileSplitBytes == pIn->pTileInfo->tileSplitBytes);
3870 }
3871 }
3872 #endif
3873 pOut->pTileInfo = NULL;
3874 }
3875 }
3876
3877 return retCode;
3878 }
3879
3880 /**
3881 ****************************************************************************************************
3882 * EgBasedLib::HwlComputeSurfaceAddrFromCoord
3883 * @brief
3884 * Entry of EgBasedLib ComputeSurfaceAddrFromCoord
3885 * @return
3886 * ADDR_E_RETURNCODE
3887 ****************************************************************************************************
3888 */
3889 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceAddrFromCoord(
3890 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3891 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3892 ) const
3893 {
3894 ADDR_E_RETURNCODE retCode = ADDR_OK;
3895
3896 if (
3897 #if !ALT_TEST // Overflow test needs this out-of-boundary coord
3898 (pIn->x > pIn->pitch) ||
3899 (pIn->y > pIn->height) ||
3900 #endif
3901 (pIn->numSamples > m_maxSamples))
3902 {
3903 retCode = ADDR_INVALIDPARAMS;
3904 }
3905 else
3906 {
3907 pOut->addr = DispatchComputeSurfaceAddrFromCoord(pIn, pOut);
3908 }
3909
3910 return retCode;
3911 }
3912
3913 /**
3914 ****************************************************************************************************
3915 * EgBasedLib::HwlComputeSurfaceCoordFromAddr
3916 * @brief
3917 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3918 * @return
3919 * ADDR_E_RETURNCODE
3920 ****************************************************************************************************
3921 */
3922 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSurfaceCoordFromAddr(
3923 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
3924 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
3925 ) const
3926 {
3927 ADDR_E_RETURNCODE retCode = ADDR_OK;
3928
3929 if ((pIn->bitPosition >= 8) ||
3930 (pIn->numSamples > m_maxSamples))
3931 {
3932 retCode = ADDR_INVALIDPARAMS;
3933 }
3934 else
3935 {
3936 DispatchComputeSurfaceCoordFromAddr(pIn, pOut);
3937 }
3938 return retCode;
3939 }
3940
3941 /**
3942 ****************************************************************************************************
3943 * EgBasedLib::HwlComputeSliceTileSwizzle
3944 * @brief
3945 * Entry of EgBasedLib ComputeSurfaceCoordFromAddr
3946 * @return
3947 * ADDR_E_RETURNCODE
3948 ****************************************************************************************************
3949 */
3950 ADDR_E_RETURNCODE EgBasedLib::HwlComputeSliceTileSwizzle(
3951 const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure
3952 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure
3953 ) const
3954 {
3955 ADDR_E_RETURNCODE retCode = ADDR_OK;
3956
3957 if (pIn->pTileInfo && (pIn->pTileInfo->banks > 0))
3958 {
3959
3960 pOut->tileSwizzle = ComputeSliceTileSwizzle(pIn->tileMode,
3961 pIn->baseSwizzle,
3962 pIn->slice,
3963 pIn->baseAddr,
3964 pIn->pTileInfo);
3965 }
3966 else
3967 {
3968 retCode = ADDR_INVALIDPARAMS;
3969 }
3970
3971 return retCode;
3972 }
3973
3974 /**
3975 ****************************************************************************************************
3976 * EgBasedLib::HwlComputeHtileBpp
3977 *
3978 * @brief
3979 * Compute htile bpp
3980 *
3981 * @return
3982 * Htile bpp
3983 ****************************************************************************************************
3984 */
3985 UINT_32 EgBasedLib::HwlComputeHtileBpp(
3986 BOOL_32 isWidth8, ///< [in] TRUE if block width is 8
3987 BOOL_32 isHeight8 ///< [in] TRUE if block height is 8
3988 ) const
3989 {
3990 // only support 8x8 mode
3991 ADDR_ASSERT(isWidth8 && isHeight8);
3992 return 32;
3993 }
3994
3995 /**
3996 ****************************************************************************************************
3997 * EgBasedLib::HwlComputeHtileBaseAlign
3998 *
3999 * @brief
4000 * Compute htile base alignment
4001 *
4002 * @return
4003 * Htile base alignment
4004 ****************************************************************************************************
4005 */
4006 UINT_32 EgBasedLib::HwlComputeHtileBaseAlign(
4007 BOOL_32 isTcCompatible, ///< [in] if TC compatible
4008 BOOL_32 isLinear, ///< [in] if it is linear mode
4009 ADDR_TILEINFO* pTileInfo ///< [in] Tile info
4010 ) const
4011 {
4012 UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
4013
4014 if (isTcCompatible)
4015 {
4016 ADDR_ASSERT(pTileInfo != NULL);
4017 if (pTileInfo)
4018 {
4019 baseAlign *= pTileInfo->banks;
4020 }
4021 }
4022
4023 return baseAlign;
4024 }
4025
4026 /**
4027 ****************************************************************************************************
4028 * EgBasedLib::HwlGetPitchAlignmentMicroTiled
4029 *
4030 * @brief
4031 * Compute 1D tiled surface pitch alignment, calculation results are returned through
4032 * output parameters.
4033 *
4034 * @return
4035 * pitch alignment
4036 ****************************************************************************************************
4037 */
4038 UINT_32 EgBasedLib::HwlGetPitchAlignmentMicroTiled(
4039 AddrTileMode tileMode, ///< [in] tile mode
4040 UINT_32 bpp, ///< [in] bits per pixel
4041 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
4042 UINT_32 numSamples ///< [in] number of samples
4043 ) const
4044 {
4045 UINT_32 pitchAlign;
4046
4047 UINT_32 microTileThickness = Thickness(tileMode);
4048
4049 UINT_32 pixelsPerMicroTile;
4050 UINT_32 pixelsPerPipeInterleave;
4051 UINT_32 microTilesPerPipeInterleave;
4052
4053 //
4054 // Special workaround for depth/stencil buffer, use 8 bpp to meet larger requirement for
4055 // stencil buffer since pitch alignment is related to bpp.
4056 // For a depth only buffer do not set this.
4057 //
4058 // Note: this actually does not work for mipmap but mipmap depth texture is not really
4059 // sampled with mipmap.
4060 //
4061 if (flags.depth && (flags.noStencil == FALSE))
4062 {
4063 bpp = 8;
4064 }
4065
4066 pixelsPerMicroTile = MicroTilePixels * microTileThickness;
4067 pixelsPerPipeInterleave = BYTES_TO_BITS(m_pipeInterleaveBytes) / (bpp * numSamples);
4068 microTilesPerPipeInterleave = pixelsPerPipeInterleave / pixelsPerMicroTile;
4069
4070 pitchAlign = Max(MicroTileWidth, microTilesPerPipeInterleave * MicroTileWidth);
4071
4072 return pitchAlign;
4073 }
4074
4075 /**
4076 ****************************************************************************************************
4077 * EgBasedLib::HwlGetSizeAdjustmentMicroTiled
4078 *
4079 * @brief
4080 * Adjust 1D tiled surface pitch and slice size
4081 *
4082 * @return
4083 * Logical slice size in bytes
4084 ****************************************************************************************************
4085 */
4086 UINT_64 EgBasedLib::HwlGetSizeAdjustmentMicroTiled(
4087 UINT_32 thickness, ///< [in] thickness
4088 UINT_32 bpp, ///< [in] bits per pixel
4089 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
4090 UINT_32 numSamples, ///< [in] number of samples
4091 UINT_32 baseAlign, ///< [in] base alignment
4092 UINT_32 pitchAlign, ///< [in] pitch alignment
4093 UINT_32* pPitch, ///< [in,out] pointer to pitch
4094 UINT_32* pHeight ///< [in,out] pointer to height
4095 ) const
4096 {
4097 UINT_64 logicalSliceSize;
4098 MAYBE_UNUSED UINT_64 physicalSliceSize;
4099
4100 UINT_32 pitch = *pPitch;
4101 UINT_32 height = *pHeight;
4102
4103 // Logical slice: pitch * height * bpp * numSamples (no 1D MSAA so actually numSamples == 1)
4104 logicalSliceSize = BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * bpp * numSamples);
4105
4106 // Physical slice: multiplied by thickness
4107 physicalSliceSize = logicalSliceSize * thickness;
4108
4109 //
4110 // R800 will always pad physical slice size to baseAlign which is pipe_interleave_bytes
4111 //
4112 ADDR_ASSERT((physicalSliceSize % baseAlign) == 0);
4113
4114 return logicalSliceSize;
4115 }
4116
4117 /**
4118 ****************************************************************************************************
4119 * EgBasedLib::HwlStereoCheckRightOffsetPadding
4120 *
4121 * @brief
4122 * check if the height needs extra padding for stereo right eye offset, to avoid swizzling
4123 *
4124 * @return
4125 * TRUE is the extra padding is needed
4126 *
4127 ****************************************************************************************************
4128 */
4129 UINT_32 EgBasedLib::HwlStereoCheckRightOffsetPadding(
4130 ADDR_TILEINFO* pTileInfo ///< Tiling info
4131 ) const
4132 {
4133 UINT_32 stereoHeightAlign = 0;
4134
4135 if (pTileInfo->macroAspectRatio > 2)
4136 {
4137 // Since 3D rendering treats right eye surface starting from y == "eye height" while
4138 // display engine treats it to be 0, so the bank bits may be different.
4139 // Additional padding in height is required to make sure it's possible
4140 // to achieve synonym by adjusting bank swizzle of right eye surface.
4141
4142 static const UINT_32 StereoAspectRatio = 2;
4143 stereoHeightAlign = pTileInfo->banks *
4144 pTileInfo->bankHeight *
4145 MicroTileHeight /
4146 StereoAspectRatio;
4147 }
4148
4149 return stereoHeightAlign;
4150 }
4151
4152 } // V1
4153 } // Addr