1 /*
2 ************************************************************************************************************************
3 *
4 * Copyright (C) 2007-2022 Advanced Micro Devices, Inc. All rights reserved.
5 * SPDX-License-Identifier: MIT
6 *
7 ***********************************************************************************************************************/
8
9 /**
10 ****************************************************************************************************
11 * @file addr1lib.cpp
12 * @brief Contains the implementation for the Addr::V1::Lib base class.
13 ****************************************************************************************************
14 */
15
16 #include "addrinterface.h"
17 #include "addrlib1.h"
18 #include "addrcommon.h"
19
20 namespace Addr
21 {
22 namespace V1
23 {
24
25 ////////////////////////////////////////////////////////////////////////////////////////////////////
26 // Static Const Member
27 ////////////////////////////////////////////////////////////////////////////////////////////////////
28
29 const TileModeFlags Lib::ModeFlags[ADDR_TM_COUNT] =
30 {// T L 1 2 3 P Pr B
31 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_GENERAL
32 {1, 1, 0, 0, 0, 0, 0, 0}, // ADDR_TM_LINEAR_ALIGNED
33 {1, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THIN1
34 {4, 0, 1, 0, 0, 0, 0, 0}, // ADDR_TM_1D_TILED_THICK
35 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN1
36 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN2
37 {1, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THIN4
38 {4, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_THICK
39 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN1
40 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN2
41 {1, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THIN4
42 {4, 0, 0, 1, 0, 0, 0, 1}, // ADDR_TM_2B_TILED_THICK
43 {1, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THIN1
44 {4, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_THICK
45 {1, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THIN1
46 {4, 0, 0, 1, 1, 0, 0, 1}, // ADDR_TM_3B_TILED_THICK
47 {8, 0, 0, 1, 0, 0, 0, 0}, // ADDR_TM_2D_TILED_XTHICK
48 {8, 0, 0, 1, 1, 0, 0, 0}, // ADDR_TM_3D_TILED_XTHICK
49 {1, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_POWER_SAVE
50 {1, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THIN1
51 {1, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THIN1
52 {1, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THIN1
53 {4, 0, 0, 1, 0, 1, 1, 0}, // ADDR_TM_PRT_TILED_THICK
54 {4, 0, 0, 1, 0, 1, 0, 0}, // ADDR_TM_PRT_2D_TILED_THICK
55 {4, 0, 0, 1, 1, 1, 0, 0}, // ADDR_TM_PRT_3D_TILED_THICK
56 {0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_TM_UNKNOWN
57 };
58
59 ////////////////////////////////////////////////////////////////////////////////////////////////////
60 // Constructor/Destructor
61 ////////////////////////////////////////////////////////////////////////////////////////////////////
62
63 /**
64 ****************************************************************************************************
65 * Lib::AddrLib1
66 *
67 * @brief
68 * Constructor for the AddrLib1 class
69 *
70 ****************************************************************************************************
71 */
Lib()72 Lib::Lib()
73 :
74 Addr::Lib()
75 {
76 }
77
78 /**
79 ****************************************************************************************************
80 * Lib::Lib
81 *
82 * @brief
83 * Constructor for the Addr::V1::Lib class with hClient as parameter
84 *
85 ****************************************************************************************************
86 */
Lib(const Client * pClient)87 Lib::Lib(const Client* pClient)
88 :
89 Addr::Lib(pClient)
90 {
91 }
92
93 /**
94 ****************************************************************************************************
95 * Lib::~AddrLib1
96 *
97 * @brief
98 * Destructor for the AddrLib1 class
99 *
100 ****************************************************************************************************
101 */
~Lib()102 Lib::~Lib()
103 {
104 }
105
106 /**
107 ****************************************************************************************************
108 * Lib::GetLib
109 *
110 * @brief
111 * Get AddrLib1 pointer
112 *
113 * @return
114 * An Addr::V1::Lib class pointer
115 ****************************************************************************************************
116 */
GetLib(ADDR_HANDLE hLib)117 Lib* Lib::GetLib(
118 ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE
119 {
120 Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);
121 if ((pAddrLib != NULL) &&
122 ((pAddrLib->GetChipFamily() == ADDR_CHIP_FAMILY_IVLD) ||
123 (pAddrLib->GetChipFamily() > ADDR_CHIP_FAMILY_VI)))
124 {
125 // only valid and pre-VI ASIC can use AddrLib1 function.
126 ADDR_ASSERT_ALWAYS();
127 hLib = NULL;
128 }
129 return static_cast<Lib*>(pAddrLib);
130 }
131
132
133 ////////////////////////////////////////////////////////////////////////////////////////////////////
134 // Surface Methods
135 ////////////////////////////////////////////////////////////////////////////////////////////////////
136
137
138 /**
139 ****************************************************************************************************
140 * Lib::ComputeSurfaceInfo
141 *
142 * @brief
143 * Interface function stub of AddrComputeSurfaceInfo.
144 *
145 * @return
146 * ADDR_E_RETURNCODE
147 ****************************************************************************************************
148 */
ComputeSurfaceInfo(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const149 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
150 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
151 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
152 ) const
153 {
154 ADDR_E_RETURNCODE returnCode = ADDR_OK;
155
156 if (GetFillSizeFieldsFlags() == TRUE)
157 {
158 if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_INPUT)) ||
159 (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_INFO_OUTPUT)))
160 {
161 returnCode = ADDR_PARAMSIZEMISMATCH;
162 }
163 }
164
165 // We suggest client do sanity check but a check here is also good
166 if (pIn->bpp > 128)
167 {
168 returnCode = ADDR_INVALIDPARAMS;
169 }
170
171 if ((pIn->tileMode == ADDR_TM_UNKNOWN) && (pIn->mipLevel > 0))
172 {
173 returnCode = ADDR_INVALIDPARAMS;
174 }
175
176 // Thick modes don't support multisample
177 if ((Thickness(pIn->tileMode) > 1) && (pIn->numSamples > 1))
178 {
179 returnCode = ADDR_INVALIDPARAMS;
180 }
181
182 if (returnCode == ADDR_OK)
183 {
184 // Get a local copy of input structure and only reference pIn for unadjusted values
185 ADDR_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
186 ADDR_TILEINFO tileInfoNull = {0};
187
188 if (UseTileInfo())
189 {
190 // If the original input has a valid ADDR_TILEINFO pointer then copy its contents.
191 // Otherwise the default 0's in tileInfoNull are used.
192 if (pIn->pTileInfo)
193 {
194 tileInfoNull = *pIn->pTileInfo;
195 }
196 localIn.pTileInfo = &tileInfoNull;
197 }
198
199 localIn.numSamples = (pIn->numSamples == 0) ? 1 : pIn->numSamples;
200
201 // Do mipmap check first
202 // If format is BCn, pre-pad dimension to power-of-two according to HWL
203 ComputeMipLevel(&localIn);
204
205 if (m_configFlags.checkLast2DLevel)
206 {
207 // Save this level's original height in pixels
208 pOut->height = pIn->height;
209 }
210
211 UINT_32 expandX = 1;
212 UINT_32 expandY = 1;
213 ElemMode elemMode;
214
215 // Save outputs that may not go through HWL
216 pOut->pixelBits = localIn.bpp;
217 pOut->numSamples = localIn.numSamples;
218 pOut->last2DLevel = FALSE;
219 pOut->tcCompatible = FALSE;
220
221 #if !ALT_TEST
222 if (localIn.numSamples > 1)
223 {
224 ADDR_ASSERT(localIn.mipLevel == 0);
225 }
226 #endif
227
228 if (localIn.format != ADDR_FMT_INVALID) // Set format to INVALID will skip this conversion
229 {
230 // Get compression/expansion factors and element mode
231 // (which indicates compression/expansion
232 localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
233 &elemMode,
234 &expandX,
235 &expandY);
236
237 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
238 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
239 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
240 // restrictions are different.
241 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
242 // but we use this flag to skip RestoreSurfaceInfo below
243
244 if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
245 {
246 ADDR_ASSERT(IsLinear(localIn.tileMode));
247 }
248
249 GetElemLib()->AdjustSurfaceInfo(elemMode,
250 expandX,
251 expandY,
252 &localIn.bpp,
253 &localIn.basePitch,
254 &localIn.width,
255 &localIn.height);
256
257 // Overwrite these parameters if we have a valid format
258 }
259 else if (localIn.bpp != 0)
260 {
261 localIn.width = (localIn.width != 0) ? localIn.width : 1;
262 localIn.height = (localIn.height != 0) ? localIn.height : 1;
263 }
264 else // Rule out some invalid parameters
265 {
266 ADDR_ASSERT_ALWAYS();
267
268 returnCode = ADDR_INVALIDPARAMS;
269 }
270
271 // Check mipmap after surface expansion
272 if (returnCode == ADDR_OK)
273 {
274 returnCode = PostComputeMipLevel(&localIn, pOut);
275 }
276
277 if (returnCode == ADDR_OK)
278 {
279 if (UseTileIndex(localIn.tileIndex))
280 {
281 // Make sure pTileInfo is not NULL
282 ADDR_ASSERT(localIn.pTileInfo);
283
284 UINT_32 numSamples = GetNumFragments(localIn.numSamples, localIn.numFrags);
285
286 INT_32 macroModeIndex = TileIndexNoMacroIndex;
287
288 if (localIn.tileIndex != TileIndexLinearGeneral)
289 {
290 // Try finding a macroModeIndex
291 macroModeIndex = HwlComputeMacroModeIndex(localIn.tileIndex,
292 localIn.flags,
293 localIn.bpp,
294 numSamples,
295 localIn.pTileInfo,
296 &localIn.tileMode,
297 &localIn.tileType);
298 }
299
300 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
301 if (macroModeIndex == TileIndexNoMacroIndex)
302 {
303 returnCode = HwlSetupTileCfg(localIn.bpp,
304 localIn.tileIndex, macroModeIndex,
305 localIn.pTileInfo,
306 &localIn.tileMode, &localIn.tileType);
307 }
308 // If macroModeIndex is invalid, then assert this is not macro tiled
309 else if (macroModeIndex == TileIndexInvalid)
310 {
311 ADDR_ASSERT(!IsMacroTiled(localIn.tileMode));
312 }
313
314 pOut->macroModeIndex = macroModeIndex;
315 }
316 }
317
318 if (returnCode == ADDR_OK)
319 {
320 localIn.flags.dccPipeWorkaround = localIn.flags.dccCompatible;
321
322 if (localIn.tileMode == ADDR_TM_UNKNOWN)
323 {
324 // HWL layer may override tile mode if necessary
325 HwlSelectTileMode(&localIn);
326 }
327 else
328 {
329 // HWL layer may override tile mode if necessary
330 HwlOverrideTileMode(&localIn);
331
332 // Optimize tile mode if possible
333 OptimizeTileMode(&localIn);
334 }
335 }
336
337 // Call main function to compute surface info
338 if (returnCode == ADDR_OK)
339 {
340 returnCode = HwlComputeSurfaceInfo(&localIn, pOut);
341 }
342
343 if (returnCode == ADDR_OK)
344 {
345 // Since bpp might be changed we just pass it through
346 pOut->bpp = localIn.bpp;
347
348 // Also original width/height/bpp
349 pOut->pixelPitch = pOut->pitch;
350 pOut->pixelHeight = pOut->height;
351
352 #if DEBUG
353 if (localIn.flags.display)
354 {
355 ADDR_ASSERT((pOut->pitchAlign % 32) == 0);
356 }
357 #endif //DEBUG
358
359 if (localIn.format != ADDR_FMT_INVALID)
360 {
361 //
362 // Note: For 96 bit surface, the pixelPitch returned might be an odd number, but it
363 // is okay to program texture pitch as HW's mip calculator would multiply 3 first,
364 // then do the appropriate paddings (linear alignment requirement and possible the
365 // nearest power-of-two for mipmaps), which results in the original pitch.
366 //
367 GetElemLib()->RestoreSurfaceInfo(elemMode,
368 expandX,
369 expandY,
370 &localIn.bpp,
371 &pOut->pixelPitch,
372 &pOut->pixelHeight);
373 }
374
375 if (localIn.flags.qbStereo)
376 {
377 if (pOut->pStereoInfo)
378 {
379 ComputeQbStereoInfo(pOut);
380 }
381 }
382
383 if (localIn.flags.volume) // For volume sliceSize equals to all z-slices
384 {
385 pOut->sliceSize = pOut->surfSize;
386 }
387 else // For array: sliceSize is likely to have slice-padding (the last one)
388 {
389 pOut->sliceSize = pOut->surfSize / pOut->depth;
390
391 // array or cubemap
392 if (pIn->numSlices > 1)
393 {
394 // If this is the last slice then add the padding size to this slice
395 if (pIn->slice == (pIn->numSlices - 1))
396 {
397 pOut->sliceSize += pOut->sliceSize * (pOut->depth - pIn->numSlices);
398 }
399 else if (m_configFlags.checkLast2DLevel)
400 {
401 // Reset last2DLevel flag if this is not the last array slice
402 pOut->last2DLevel = FALSE;
403 }
404 }
405 }
406
407 pOut->pitchTileMax = pOut->pitch / 8 - 1;
408 pOut->heightTileMax = pOut->height / 8 - 1;
409 pOut->sliceTileMax = pOut->pitch * pOut->height / 64 - 1;
410 }
411 }
412
413 ValidBaseAlignments(pOut->baseAlign);
414
415 return returnCode;
416 }
417
418 /**
419 ****************************************************************************************************
420 * Lib::ComputeSurfaceInfo
421 *
422 * @brief
423 * Interface function stub of AddrComputeSurfaceInfo.
424 *
425 * @return
426 * ADDR_E_RETURNCODE
427 ****************************************************************************************************
428 */
ComputeSurfaceAddrFromCoord(const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const429 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(
430 const ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
431 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
432 ) const
433 {
434 ADDR_E_RETURNCODE returnCode = ADDR_OK;
435
436 if (GetFillSizeFieldsFlags() == TRUE)
437 {
438 if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
439 (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
440 {
441 returnCode = ADDR_PARAMSIZEMISMATCH;
442 }
443 }
444
445 if (returnCode == ADDR_OK)
446 {
447 ADDR_TILEINFO tileInfoNull;
448 ADDR_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT input;
449
450 if (UseTileIndex(pIn->tileIndex))
451 {
452 input = *pIn;
453 // Use temp tile info for calcalation
454 input.pTileInfo = &tileInfoNull;
455
456 const ADDR_SURFACE_FLAGS flags = {{0}};
457 UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
458
459 // Try finding a macroModeIndex
460 INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
461 flags,
462 input.bpp,
463 numSamples,
464 input.pTileInfo,
465 &input.tileMode,
466 &input.tileType);
467
468 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
469 if (macroModeIndex == TileIndexNoMacroIndex)
470 {
471 returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex, macroModeIndex,
472 input.pTileInfo, &input.tileMode, &input.tileType);
473 }
474 // If macroModeIndex is invalid, then assert this is not macro tiled
475 else if (macroModeIndex == TileIndexInvalid)
476 {
477 ADDR_ASSERT(!IsMacroTiled(input.tileMode));
478 }
479
480 // Change the input structure
481 pIn = &input;
482 }
483
484 if (returnCode == ADDR_OK)
485 {
486 returnCode = HwlComputeSurfaceAddrFromCoord(pIn, pOut);
487
488 if (returnCode == ADDR_OK)
489 {
490 pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
491 }
492 }
493 }
494
495 return returnCode;
496 }
497
498 /**
499 ****************************************************************************************************
500 * Lib::ComputeSurfaceCoordFromAddr
501 *
502 * @brief
503 * Interface function stub of ComputeSurfaceCoordFromAddr.
504 *
505 * @return
506 * ADDR_E_RETURNCODE
507 ****************************************************************************************************
508 */
ComputeSurfaceCoordFromAddr(const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const509 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(
510 const ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
511 ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
512 ) const
513 {
514 ADDR_E_RETURNCODE returnCode = ADDR_OK;
515
516 if (GetFillSizeFieldsFlags() == TRUE)
517 {
518 if ((pIn->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
519 (pOut->size != sizeof(ADDR_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
520 {
521 returnCode = ADDR_PARAMSIZEMISMATCH;
522 }
523 }
524
525 if (returnCode == ADDR_OK)
526 {
527 ADDR_TILEINFO tileInfoNull;
528 ADDR_COMPUTE_SURFACE_COORDFROMADDR_INPUT input;
529
530 if (UseTileIndex(pIn->tileIndex))
531 {
532 input = *pIn;
533 // Use temp tile info for calcalation
534 input.pTileInfo = &tileInfoNull;
535
536 const ADDR_SURFACE_FLAGS flags = {{0}};
537 UINT_32 numSamples = GetNumFragments(pIn->numSamples, pIn->numFrags);
538
539 // Try finding a macroModeIndex
540 INT_32 macroModeIndex = HwlComputeMacroModeIndex(input.tileIndex,
541 flags,
542 input.bpp,
543 numSamples,
544 input.pTileInfo,
545 &input.tileMode,
546 &input.tileType);
547
548 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
549 if (macroModeIndex == TileIndexNoMacroIndex)
550 {
551 returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex, macroModeIndex,
552 input.pTileInfo, &input.tileMode, &input.tileType);
553 }
554 // If macroModeIndex is invalid, then assert this is not macro tiled
555 else if (macroModeIndex == TileIndexInvalid)
556 {
557 ADDR_ASSERT(!IsMacroTiled(input.tileMode));
558 }
559
560 // Change the input structure
561 pIn = &input;
562 }
563
564 if (returnCode == ADDR_OK)
565 {
566 returnCode = HwlComputeSurfaceCoordFromAddr(pIn, pOut);
567 }
568 }
569
570 return returnCode;
571 }
572
573 /**
574 ****************************************************************************************************
575 * Lib::ComputeSliceTileSwizzle
576 *
577 * @brief
578 * Interface function stub of ComputeSliceTileSwizzle.
579 *
580 * @return
581 * ADDR_E_RETURNCODE
582 ****************************************************************************************************
583 */
ComputeSliceTileSwizzle(const ADDR_COMPUTE_SLICESWIZZLE_INPUT * pIn,ADDR_COMPUTE_SLICESWIZZLE_OUTPUT * pOut) const584 ADDR_E_RETURNCODE Lib::ComputeSliceTileSwizzle(
585 const ADDR_COMPUTE_SLICESWIZZLE_INPUT* pIn, ///< [in] input structure
586 ADDR_COMPUTE_SLICESWIZZLE_OUTPUT* pOut ///< [out] output structure
587 ) const
588 {
589 ADDR_E_RETURNCODE returnCode = ADDR_OK;
590
591 if (GetFillSizeFieldsFlags() == TRUE)
592 {
593 if ((pIn->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_INPUT)) ||
594 (pOut->size != sizeof(ADDR_COMPUTE_SLICESWIZZLE_OUTPUT)))
595 {
596 returnCode = ADDR_PARAMSIZEMISMATCH;
597 }
598 }
599
600 if (returnCode == ADDR_OK)
601 {
602 ADDR_TILEINFO tileInfoNull;
603 ADDR_COMPUTE_SLICESWIZZLE_INPUT input;
604
605 if (UseTileIndex(pIn->tileIndex))
606 {
607 input = *pIn;
608 // Use temp tile info for calcalation
609 input.pTileInfo = &tileInfoNull;
610
611 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex,
612 input.pTileInfo, &input.tileMode);
613 // Change the input structure
614 pIn = &input;
615 }
616
617 if (returnCode == ADDR_OK)
618 {
619 returnCode = HwlComputeSliceTileSwizzle(pIn, pOut);
620 }
621 }
622
623 return returnCode;
624 }
625
626 /**
627 ****************************************************************************************************
628 * Lib::ExtractBankPipeSwizzle
629 *
630 * @brief
631 * Interface function stub of AddrExtractBankPipeSwizzle.
632 *
633 * @return
634 * ADDR_E_RETURNCODE
635 ****************************************************************************************************
636 */
ExtractBankPipeSwizzle(const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT * pIn,ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT * pOut) const637 ADDR_E_RETURNCODE Lib::ExtractBankPipeSwizzle(
638 const ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
639 ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
640 ) const
641 {
642 ADDR_E_RETURNCODE returnCode = ADDR_OK;
643
644 if (GetFillSizeFieldsFlags() == TRUE)
645 {
646 if ((pIn->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT)) ||
647 (pOut->size != sizeof(ADDR_EXTRACT_BANKPIPE_SWIZZLE_OUTPUT)))
648 {
649 returnCode = ADDR_PARAMSIZEMISMATCH;
650 }
651 }
652
653 if (returnCode == ADDR_OK)
654 {
655 ADDR_TILEINFO tileInfoNull;
656 ADDR_EXTRACT_BANKPIPE_SWIZZLE_INPUT input;
657
658 if (UseTileIndex(pIn->tileIndex))
659 {
660 input = *pIn;
661 // Use temp tile info for calcalation
662 input.pTileInfo = &tileInfoNull;
663
664 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
665 // Change the input structure
666 pIn = &input;
667 }
668
669 if (returnCode == ADDR_OK)
670 {
671 returnCode = HwlExtractBankPipeSwizzle(pIn, pOut);
672 }
673 }
674
675 return returnCode;
676 }
677
678 /**
679 ****************************************************************************************************
680 * Lib::CombineBankPipeSwizzle
681 *
682 * @brief
683 * Interface function stub of AddrCombineBankPipeSwizzle.
684 *
685 * @return
686 * ADDR_E_RETURNCODE
687 ****************************************************************************************************
688 */
CombineBankPipeSwizzle(const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT * pIn,ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT * pOut) const689 ADDR_E_RETURNCODE Lib::CombineBankPipeSwizzle(
690 const ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT* pIn, ///< [in] input structure
691 ADDR_COMBINE_BANKPIPE_SWIZZLE_OUTPUT* pOut ///< [out] output structure
692 ) const
693 {
694 ADDR_E_RETURNCODE returnCode = ADDR_OK;
695
696 if (GetFillSizeFieldsFlags() == TRUE)
697 {
698 if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
699 (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
700 {
701 returnCode = ADDR_PARAMSIZEMISMATCH;
702 }
703 }
704
705 if (returnCode == ADDR_OK)
706 {
707 ADDR_TILEINFO tileInfoNull;
708 ADDR_COMBINE_BANKPIPE_SWIZZLE_INPUT input;
709
710 if (UseTileIndex(pIn->tileIndex))
711 {
712 input = *pIn;
713 // Use temp tile info for calcalation
714 input.pTileInfo = &tileInfoNull;
715
716 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
717 // Change the input structure
718 pIn = &input;
719 }
720
721 if (returnCode == ADDR_OK)
722 {
723 returnCode = HwlCombineBankPipeSwizzle(pIn->bankSwizzle,
724 pIn->pipeSwizzle,
725 pIn->pTileInfo,
726 pIn->baseAddr,
727 &pOut->tileSwizzle);
728 }
729 }
730
731 return returnCode;
732 }
733
734 /**
735 ****************************************************************************************************
736 * Lib::ComputeBaseSwizzle
737 *
738 * @brief
739 * Interface function stub of AddrCompueBaseSwizzle.
740 * @return
741 * ADDR_E_RETURNCODE
742 ****************************************************************************************************
743 */
ComputeBaseSwizzle(const ADDR_COMPUTE_BASE_SWIZZLE_INPUT * pIn,ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT * pOut) const744 ADDR_E_RETURNCODE Lib::ComputeBaseSwizzle(
745 const ADDR_COMPUTE_BASE_SWIZZLE_INPUT* pIn,
746 ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT* pOut) const
747 {
748 ADDR_E_RETURNCODE returnCode = ADDR_OK;
749
750 if (GetFillSizeFieldsFlags() == TRUE)
751 {
752 if ((pIn->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_INPUT)) ||
753 (pOut->size != sizeof(ADDR_COMPUTE_BASE_SWIZZLE_OUTPUT)))
754 {
755 returnCode = ADDR_PARAMSIZEMISMATCH;
756 }
757 }
758
759 if (returnCode == ADDR_OK)
760 {
761 ADDR_TILEINFO tileInfoNull;
762 ADDR_COMPUTE_BASE_SWIZZLE_INPUT input;
763
764 if (UseTileIndex(pIn->tileIndex))
765 {
766 input = *pIn;
767 // Use temp tile info for calcalation
768 input.pTileInfo = &tileInfoNull;
769
770 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
771 // Change the input structure
772 pIn = &input;
773 }
774
775 if (returnCode == ADDR_OK)
776 {
777 if (IsMacroTiled(pIn->tileMode))
778 {
779 returnCode = HwlComputeBaseSwizzle(pIn, pOut);
780 }
781 else
782 {
783 pOut->tileSwizzle = 0;
784 }
785 }
786 }
787
788 return returnCode;
789 }
790
791 /**
792 ****************************************************************************************************
793 * Lib::ComputeFmaskInfo
794 *
795 * @brief
796 * Interface function stub of ComputeFmaskInfo.
797 *
798 * @return
799 * ADDR_E_RETURNCODE
800 ****************************************************************************************************
801 */
ComputeFmaskInfo(const ADDR_COMPUTE_FMASK_INFO_INPUT * pIn,ADDR_COMPUTE_FMASK_INFO_OUTPUT * pOut)802 ADDR_E_RETURNCODE Lib::ComputeFmaskInfo(
803 const ADDR_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
804 ADDR_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
805 )
806 {
807 ADDR_E_RETURNCODE returnCode = ADDR_OK;
808
809 if (GetFillSizeFieldsFlags() == TRUE)
810 {
811 if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_INFO_INPUT)) ||
812 (pOut->size != sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT)))
813 {
814 returnCode = ADDR_PARAMSIZEMISMATCH;
815 }
816 }
817
818 // No thick MSAA
819 if (Thickness(pIn->tileMode) > 1)
820 {
821 returnCode = ADDR_INVALIDPARAMS;
822 }
823
824 if (returnCode == ADDR_OK)
825 {
826 ADDR_TILEINFO tileInfoNull;
827 ADDR_COMPUTE_FMASK_INFO_INPUT input;
828
829 if (UseTileIndex(pIn->tileIndex))
830 {
831 input = *pIn;
832
833 if (pOut->pTileInfo)
834 {
835 // Use temp tile info for calcalation
836 input.pTileInfo = pOut->pTileInfo;
837 }
838 else
839 {
840 input.pTileInfo = &tileInfoNull;
841 }
842
843 ADDR_SURFACE_FLAGS flags = {{0}};
844 flags.fmask = 1;
845
846 // Try finding a macroModeIndex
847 INT_32 macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex,
848 flags,
849 HwlComputeFmaskBits(pIn, NULL),
850 pIn->numSamples,
851 input.pTileInfo,
852 &input.tileMode);
853
854 // If macroModeIndex is not needed, then call HwlSetupTileCfg to get tile info
855 if (macroModeIndex == TileIndexNoMacroIndex)
856 {
857 returnCode = HwlSetupTileCfg(0, input.tileIndex, macroModeIndex,
858 input.pTileInfo, &input.tileMode);
859 }
860
861 ADDR_ASSERT(macroModeIndex != TileIndexInvalid);
862
863 // Change the input structure
864 pIn = &input;
865 }
866
867 if (returnCode == ADDR_OK)
868 {
869 if (pIn->numSamples > 1)
870 {
871 returnCode = HwlComputeFmaskInfo(pIn, pOut);
872 }
873 else
874 {
875 memset(pOut, 0, sizeof(ADDR_COMPUTE_FMASK_INFO_OUTPUT));
876
877 returnCode = ADDR_INVALIDPARAMS;
878 }
879 }
880 }
881
882 ValidBaseAlignments(pOut->baseAlign);
883
884 return returnCode;
885 }
886
887 /**
888 ****************************************************************************************************
889 * Lib::ComputeFmaskAddrFromCoord
890 *
891 * @brief
892 * Interface function stub of ComputeFmaskAddrFromCoord.
893 *
894 * @return
895 * ADDR_E_RETURNCODE
896 ****************************************************************************************************
897 */
ComputeFmaskAddrFromCoord(const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT * pOut) const898 ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(
899 const ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
900 ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
901 ) const
902 {
903 ADDR_E_RETURNCODE returnCode = ADDR_OK;
904
905 if (GetFillSizeFieldsFlags() == TRUE)
906 {
907 if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_INPUT)) ||
908 (pOut->size != sizeof(ADDR_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT)))
909 {
910 returnCode = ADDR_PARAMSIZEMISMATCH;
911 }
912 }
913
914 if (returnCode == ADDR_OK)
915 {
916 ADDR_ASSERT(pIn->numSamples > 1);
917
918 if (pIn->numSamples > 1)
919 {
920 returnCode = HwlComputeFmaskAddrFromCoord(pIn, pOut);
921 }
922 else
923 {
924 returnCode = ADDR_INVALIDPARAMS;
925 }
926 }
927
928 return returnCode;
929 }
930
931 /**
932 ****************************************************************************************************
933 * Lib::ComputeFmaskCoordFromAddr
934 *
935 * @brief
936 * Interface function stub of ComputeFmaskAddrFromCoord.
937 *
938 * @return
939 * ADDR_E_RETURNCODE
940 ****************************************************************************************************
941 */
ComputeFmaskCoordFromAddr(const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT * pOut) const942 ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(
943 const ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
944 ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
945 ) const
946 {
947 ADDR_E_RETURNCODE returnCode = ADDR_OK;
948
949 if (GetFillSizeFieldsFlags() == TRUE)
950 {
951 if ((pIn->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_INPUT)) ||
952 (pOut->size != sizeof(ADDR_COMPUTE_FMASK_COORDFROMADDR_OUTPUT)))
953 {
954 returnCode = ADDR_PARAMSIZEMISMATCH;
955 }
956 }
957
958 if (returnCode == ADDR_OK)
959 {
960 ADDR_ASSERT(pIn->numSamples > 1);
961
962 if (pIn->numSamples > 1)
963 {
964 returnCode = HwlComputeFmaskCoordFromAddr(pIn, pOut);
965 }
966 else
967 {
968 returnCode = ADDR_INVALIDPARAMS;
969 }
970 }
971
972 return returnCode;
973 }
974
975 /**
976 ****************************************************************************************************
977 * Lib::ConvertTileInfoToHW
978 *
979 * @brief
980 * Convert tile info from real value to HW register value in HW layer
981 *
982 * @return
983 * ADDR_E_RETURNCODE
984 ****************************************************************************************************
985 */
ConvertTileInfoToHW(const ADDR_CONVERT_TILEINFOTOHW_INPUT * pIn,ADDR_CONVERT_TILEINFOTOHW_OUTPUT * pOut) const986 ADDR_E_RETURNCODE Lib::ConvertTileInfoToHW(
987 const ADDR_CONVERT_TILEINFOTOHW_INPUT* pIn, ///< [in] input structure
988 ADDR_CONVERT_TILEINFOTOHW_OUTPUT* pOut ///< [out] output structure
989 ) const
990 {
991 ADDR_E_RETURNCODE returnCode = ADDR_OK;
992
993 if (GetFillSizeFieldsFlags() == TRUE)
994 {
995 if ((pIn->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_INPUT)) ||
996 (pOut->size != sizeof(ADDR_CONVERT_TILEINFOTOHW_OUTPUT)))
997 {
998 returnCode = ADDR_PARAMSIZEMISMATCH;
999 }
1000 }
1001
1002 if (returnCode == ADDR_OK)
1003 {
1004 ADDR_TILEINFO tileInfoNull;
1005 ADDR_CONVERT_TILEINFOTOHW_INPUT input;
1006 // if pIn->reverse is TRUE, indices are ignored
1007 if (pIn->reverse == FALSE && UseTileIndex(pIn->tileIndex))
1008 {
1009 input = *pIn;
1010 input.pTileInfo = &tileInfoNull;
1011
1012 returnCode = HwlSetupTileCfg(input.bpp, input.tileIndex,
1013 input.macroModeIndex, input.pTileInfo);
1014
1015 pIn = &input;
1016 }
1017
1018 if (returnCode == ADDR_OK)
1019 {
1020 returnCode = HwlConvertTileInfoToHW(pIn, pOut);
1021 }
1022 }
1023
1024 return returnCode;
1025 }
1026
1027 /**
1028 ****************************************************************************************************
1029 * Lib::ConvertTileIndex
1030 *
1031 * @brief
1032 * Convert tile index to tile mode/type/info
1033 *
1034 * @return
1035 * ADDR_E_RETURNCODE
1036 ****************************************************************************************************
1037 */
ConvertTileIndex(const ADDR_CONVERT_TILEINDEX_INPUT * pIn,ADDR_CONVERT_TILEINDEX_OUTPUT * pOut) const1038 ADDR_E_RETURNCODE Lib::ConvertTileIndex(
1039 const ADDR_CONVERT_TILEINDEX_INPUT* pIn, ///< [in] input structure
1040 ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure
1041 ) const
1042 {
1043 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1044
1045 if (GetFillSizeFieldsFlags() == TRUE)
1046 {
1047 if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX_INPUT)) ||
1048 (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
1049 {
1050 returnCode = ADDR_PARAMSIZEMISMATCH;
1051 }
1052 }
1053
1054 if (returnCode == ADDR_OK)
1055 {
1056
1057 returnCode = HwlSetupTileCfg(pIn->bpp, pIn->tileIndex, pIn->macroModeIndex,
1058 pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
1059
1060 if (returnCode == ADDR_OK && pIn->tileInfoHw)
1061 {
1062 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
1063 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
1064
1065 hwInput.pTileInfo = pOut->pTileInfo;
1066 hwInput.tileIndex = -1;
1067 hwOutput.pTileInfo = pOut->pTileInfo;
1068
1069 returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
1070 }
1071 }
1072
1073 return returnCode;
1074 }
1075
1076 /**
1077 ****************************************************************************************************
1078 * Lib::GetMacroModeIndex
1079 *
1080 * @brief
1081 * Get macro mode index based on input info
1082 *
1083 * @return
1084 * ADDR_E_RETURNCODE
1085 ****************************************************************************************************
1086 */
GetMacroModeIndex(const ADDR_GET_MACROMODEINDEX_INPUT * pIn,ADDR_GET_MACROMODEINDEX_OUTPUT * pOut) const1087 ADDR_E_RETURNCODE Lib::GetMacroModeIndex(
1088 const ADDR_GET_MACROMODEINDEX_INPUT* pIn, ///< [in] input structure
1089 ADDR_GET_MACROMODEINDEX_OUTPUT* pOut ///< [out] output structure
1090 ) const
1091 {
1092 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1093
1094 if (GetFillSizeFieldsFlags())
1095 {
1096 if ((pIn->size != sizeof(ADDR_GET_MACROMODEINDEX_INPUT)) ||
1097 (pOut->size != sizeof(ADDR_GET_MACROMODEINDEX_OUTPUT)))
1098 {
1099 returnCode = ADDR_PARAMSIZEMISMATCH;
1100 }
1101 }
1102
1103 if (returnCode == ADDR_OK)
1104 {
1105 ADDR_TILEINFO tileInfo = {0};
1106 pOut->macroModeIndex = HwlComputeMacroModeIndex(pIn->tileIndex, pIn->flags, pIn->bpp,
1107 pIn->numFrags, &tileInfo);
1108 }
1109
1110 return returnCode;
1111 }
1112
1113 /**
1114 ****************************************************************************************************
1115 * Lib::ConvertTileIndex1
1116 *
1117 * @brief
1118 * Convert tile index to tile mode/type/info
1119 *
1120 * @return
1121 * ADDR_E_RETURNCODE
1122 ****************************************************************************************************
1123 */
ConvertTileIndex1(const ADDR_CONVERT_TILEINDEX1_INPUT * pIn,ADDR_CONVERT_TILEINDEX_OUTPUT * pOut) const1124 ADDR_E_RETURNCODE Lib::ConvertTileIndex1(
1125 const ADDR_CONVERT_TILEINDEX1_INPUT* pIn, ///< [in] input structure
1126 ADDR_CONVERT_TILEINDEX_OUTPUT* pOut ///< [out] output structure
1127 ) const
1128 {
1129 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1130
1131 if (GetFillSizeFieldsFlags() == TRUE)
1132 {
1133 if ((pIn->size != sizeof(ADDR_CONVERT_TILEINDEX1_INPUT)) ||
1134 (pOut->size != sizeof(ADDR_CONVERT_TILEINDEX_OUTPUT)))
1135 {
1136 returnCode = ADDR_PARAMSIZEMISMATCH;
1137 }
1138 }
1139
1140 if (returnCode == ADDR_OK)
1141 {
1142 ADDR_SURFACE_FLAGS flags = {{0}};
1143
1144 HwlComputeMacroModeIndex(pIn->tileIndex, flags, pIn->bpp, pIn->numSamples,
1145 pOut->pTileInfo, &pOut->tileMode, &pOut->tileType);
1146
1147 if (pIn->tileInfoHw)
1148 {
1149 ADDR_CONVERT_TILEINFOTOHW_INPUT hwInput = {0};
1150 ADDR_CONVERT_TILEINFOTOHW_OUTPUT hwOutput = {0};
1151
1152 hwInput.pTileInfo = pOut->pTileInfo;
1153 hwInput.tileIndex = -1;
1154 hwOutput.pTileInfo = pOut->pTileInfo;
1155
1156 returnCode = HwlConvertTileInfoToHW(&hwInput, &hwOutput);
1157 }
1158 }
1159
1160 return returnCode;
1161 }
1162
1163 /**
1164 ****************************************************************************************************
1165 * Lib::GetTileIndex
1166 *
1167 * @brief
1168 * Get tile index from tile mode/type/info
1169 *
1170 * @return
1171 * ADDR_E_RETURNCODE
1172 ****************************************************************************************************
1173 */
GetTileIndex(const ADDR_GET_TILEINDEX_INPUT * pIn,ADDR_GET_TILEINDEX_OUTPUT * pOut) const1174 ADDR_E_RETURNCODE Lib::GetTileIndex(
1175 const ADDR_GET_TILEINDEX_INPUT* pIn, ///< [in] input structure
1176 ADDR_GET_TILEINDEX_OUTPUT* pOut ///< [out] output structure
1177 ) const
1178 {
1179 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1180
1181 if (GetFillSizeFieldsFlags() == TRUE)
1182 {
1183 if ((pIn->size != sizeof(ADDR_GET_TILEINDEX_INPUT)) ||
1184 (pOut->size != sizeof(ADDR_GET_TILEINDEX_OUTPUT)))
1185 {
1186 returnCode = ADDR_PARAMSIZEMISMATCH;
1187 }
1188 }
1189
1190 if (returnCode == ADDR_OK)
1191 {
1192 returnCode = HwlGetTileIndex(pIn, pOut);
1193 }
1194
1195 return returnCode;
1196 }
1197
1198 /**
1199 ****************************************************************************************************
1200 * Lib::Thickness
1201 *
1202 * @brief
1203 * Get tile mode thickness
1204 *
1205 * @return
1206 * Tile mode thickness
1207 ****************************************************************************************************
1208 */
Thickness(AddrTileMode tileMode)1209 UINT_32 Lib::Thickness(
1210 AddrTileMode tileMode) ///< [in] tile mode
1211 {
1212 return ModeFlags[tileMode].thickness;
1213 }
1214
1215
1216
1217 ////////////////////////////////////////////////////////////////////////////////////////////////////
1218 // CMASK/HTILE
1219 ////////////////////////////////////////////////////////////////////////////////////////////////////
1220
1221 /**
1222 ****************************************************************************************************
1223 * Lib::ComputeHtileInfo
1224 *
1225 * @brief
1226 * Interface function stub of AddrComputeHtilenfo
1227 *
1228 * @return
1229 * ADDR_E_RETURNCODE
1230 ****************************************************************************************************
1231 */
ComputeHtileInfo(const ADDR_COMPUTE_HTILE_INFO_INPUT * pIn,ADDR_COMPUTE_HTILE_INFO_OUTPUT * pOut) const1232 ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
1233 const ADDR_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure
1234 ADDR_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure
1235 ) const
1236 {
1237 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1238
1239 BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE;
1240 BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1241
1242 if (GetFillSizeFieldsFlags() == TRUE)
1243 {
1244 if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_INFO_INPUT)) ||
1245 (pOut->size != sizeof(ADDR_COMPUTE_HTILE_INFO_OUTPUT)))
1246 {
1247 returnCode = ADDR_PARAMSIZEMISMATCH;
1248 }
1249 }
1250
1251 if (returnCode == ADDR_OK)
1252 {
1253 ADDR_TILEINFO tileInfoNull;
1254 ADDR_COMPUTE_HTILE_INFO_INPUT input;
1255
1256 if (UseTileIndex(pIn->tileIndex))
1257 {
1258 input = *pIn;
1259 // Use temp tile info for calcalation
1260 input.pTileInfo = &tileInfoNull;
1261
1262 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1263
1264 // Change the input structure
1265 pIn = &input;
1266 }
1267
1268 if (returnCode == ADDR_OK)
1269 {
1270 if (pIn->flags.tcCompatible)
1271 {
1272 const UINT_32 sliceSize = pIn->pitch * pIn->height * 4 / (8 * 8);
1273 const UINT_32 align = HwlGetPipes(pIn->pTileInfo) * pIn->pTileInfo->banks * m_pipeInterleaveBytes;
1274
1275 if (pIn->numSlices > 1)
1276 {
1277 const UINT_32 surfBytes = (sliceSize * pIn->numSlices);
1278
1279 pOut->sliceSize = sliceSize;
1280 pOut->htileBytes = pIn->flags.skipTcCompatSizeAlign ?
1281 surfBytes : PowTwoAlign(surfBytes, align);
1282 pOut->sliceInterleaved = ((sliceSize % align) != 0) ? TRUE : FALSE;
1283 }
1284 else
1285 {
1286 pOut->sliceSize = pIn->flags.skipTcCompatSizeAlign ?
1287 sliceSize : PowTwoAlign(sliceSize, align);
1288 pOut->htileBytes = pOut->sliceSize;
1289 pOut->sliceInterleaved = FALSE;
1290 }
1291
1292 pOut->nextMipLevelCompressible = ((sliceSize % align) == 0) ? TRUE : FALSE;
1293
1294 pOut->pitch = pIn->pitch;
1295 pOut->height = pIn->height;
1296 pOut->baseAlign = align;
1297 pOut->macroWidth = 0;
1298 pOut->macroHeight = 0;
1299 pOut->bpp = 32;
1300 }
1301 else
1302 {
1303 pOut->bpp = ComputeHtileInfo(pIn->flags,
1304 pIn->pitch,
1305 pIn->height,
1306 pIn->numSlices,
1307 pIn->isLinear,
1308 isWidth8,
1309 isHeight8,
1310 pIn->pTileInfo,
1311 &pOut->pitch,
1312 &pOut->height,
1313 &pOut->htileBytes,
1314 &pOut->macroWidth,
1315 &pOut->macroHeight,
1316 &pOut->sliceSize,
1317 &pOut->baseAlign);
1318 }
1319 }
1320 }
1321
1322 ValidMetaBaseAlignments(pOut->baseAlign);
1323
1324 return returnCode;
1325 }
1326
1327 /**
1328 ****************************************************************************************************
1329 * Lib::ComputeCmaskInfo
1330 *
1331 * @brief
1332 * Interface function stub of AddrComputeCmaskInfo
1333 *
1334 * @return
1335 * ADDR_E_RETURNCODE
1336 ****************************************************************************************************
1337 */
ComputeCmaskInfo(const ADDR_COMPUTE_CMASK_INFO_INPUT * pIn,ADDR_COMPUTE_CMASK_INFO_OUTPUT * pOut) const1338 ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
1339 const ADDR_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure
1340 ADDR_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure
1341 ) const
1342 {
1343 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1344
1345 if (GetFillSizeFieldsFlags() == TRUE)
1346 {
1347 if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_INFO_INPUT)) ||
1348 (pOut->size != sizeof(ADDR_COMPUTE_CMASK_INFO_OUTPUT)))
1349 {
1350 returnCode = ADDR_PARAMSIZEMISMATCH;
1351 }
1352 }
1353
1354 if (returnCode == ADDR_OK)
1355 {
1356 ADDR_TILEINFO tileInfoNull;
1357 ADDR_COMPUTE_CMASK_INFO_INPUT input;
1358
1359 if (UseTileIndex(pIn->tileIndex))
1360 {
1361 input = *pIn;
1362 // Use temp tile info for calcalation
1363 input.pTileInfo = &tileInfoNull;
1364
1365 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1366
1367 // Change the input structure
1368 pIn = &input;
1369 }
1370
1371 if (returnCode == ADDR_OK)
1372 {
1373 returnCode = ComputeCmaskInfo(pIn->flags,
1374 pIn->pitch,
1375 pIn->height,
1376 pIn->numSlices,
1377 pIn->isLinear,
1378 pIn->pTileInfo,
1379 &pOut->pitch,
1380 &pOut->height,
1381 &pOut->cmaskBytes,
1382 &pOut->macroWidth,
1383 &pOut->macroHeight,
1384 &pOut->sliceSize,
1385 &pOut->baseAlign,
1386 &pOut->blockMax);
1387 }
1388 }
1389
1390 ValidMetaBaseAlignments(pOut->baseAlign);
1391
1392 return returnCode;
1393 }
1394
1395 /**
1396 ****************************************************************************************************
1397 * Lib::ComputeDccInfo
1398 *
1399 * @brief
1400 * Interface function to compute DCC key info
1401 *
1402 * @return
1403 * return code of HwlComputeDccInfo
1404 ****************************************************************************************************
1405 */
ComputeDccInfo(const ADDR_COMPUTE_DCCINFO_INPUT * pIn,ADDR_COMPUTE_DCCINFO_OUTPUT * pOut) const1406 ADDR_E_RETURNCODE Lib::ComputeDccInfo(
1407 const ADDR_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure
1408 ADDR_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure
1409 ) const
1410 {
1411 ADDR_E_RETURNCODE ret = ADDR_OK;
1412
1413 if (GetFillSizeFieldsFlags() == TRUE)
1414 {
1415 if ((pIn->size != sizeof(ADDR_COMPUTE_DCCINFO_INPUT)) ||
1416 (pOut->size != sizeof(ADDR_COMPUTE_DCCINFO_OUTPUT)))
1417 {
1418 ret = ADDR_PARAMSIZEMISMATCH;
1419 }
1420 }
1421
1422 if (ret == ADDR_OK)
1423 {
1424 ADDR_COMPUTE_DCCINFO_INPUT input;
1425
1426 if (UseTileIndex(pIn->tileIndex))
1427 {
1428 input = *pIn;
1429
1430 ret = HwlSetupTileCfg(input.bpp, input.tileIndex, input.macroModeIndex,
1431 &input.tileInfo, &input.tileMode);
1432
1433 pIn = &input;
1434 }
1435
1436 if (ret == ADDR_OK)
1437 {
1438 ret = HwlComputeDccInfo(pIn, pOut);
1439
1440 ValidMetaBaseAlignments(pOut->dccRamBaseAlign);
1441 }
1442 }
1443
1444 return ret;
1445 }
1446
1447 /**
1448 ****************************************************************************************************
1449 * Lib::ComputeHtileAddrFromCoord
1450 *
1451 * @brief
1452 * Interface function stub of AddrComputeHtileAddrFromCoord
1453 *
1454 * @return
1455 * ADDR_E_RETURNCODE
1456 ****************************************************************************************************
1457 */
ComputeHtileAddrFromCoord(const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT * pOut) const1458 ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(
1459 const ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1460 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1461 ) const
1462 {
1463 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1464
1465 BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE;
1466 BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1467
1468 if (GetFillSizeFieldsFlags() == TRUE)
1469 {
1470 if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
1471 (pOut->size != sizeof(ADDR_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT)))
1472 {
1473 returnCode = ADDR_PARAMSIZEMISMATCH;
1474 }
1475 }
1476
1477 if (returnCode == ADDR_OK)
1478 {
1479 ADDR_TILEINFO tileInfoNull;
1480 ADDR_COMPUTE_HTILE_ADDRFROMCOORD_INPUT input;
1481
1482 if (UseTileIndex(pIn->tileIndex))
1483 {
1484 input = *pIn;
1485 // Use temp tile info for calcalation
1486 input.pTileInfo = &tileInfoNull;
1487
1488 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1489
1490 // Change the input structure
1491 pIn = &input;
1492 }
1493
1494 if (returnCode == ADDR_OK)
1495 {
1496 if (pIn->flags.tcCompatible)
1497 {
1498 HwlComputeHtileAddrFromCoord(pIn, pOut);
1499 }
1500 else
1501 {
1502 pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
1503 pIn->height,
1504 pIn->x,
1505 pIn->y,
1506 pIn->slice,
1507 pIn->numSlices,
1508 1,
1509 pIn->isLinear,
1510 isWidth8,
1511 isHeight8,
1512 pIn->pTileInfo,
1513 &pOut->bitPosition);
1514 }
1515 }
1516 }
1517
1518 return returnCode;
1519
1520 }
1521
1522 /**
1523 ****************************************************************************************************
1524 * Lib::ComputeHtileCoordFromAddr
1525 *
1526 * @brief
1527 * Interface function stub of AddrComputeHtileCoordFromAddr
1528 *
1529 * @return
1530 * ADDR_E_RETURNCODE
1531 ****************************************************************************************************
1532 */
ComputeHtileCoordFromAddr(const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT * pOut) const1533 ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(
1534 const ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1535 ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1536 ) const
1537 {
1538 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1539
1540 BOOL_32 isWidth8 = (pIn->blockWidth == 8) ? TRUE : FALSE;
1541 BOOL_32 isHeight8 = (pIn->blockHeight == 8) ? TRUE : FALSE;
1542
1543 if (GetFillSizeFieldsFlags() == TRUE)
1544 {
1545 if ((pIn->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
1546 (pOut->size != sizeof(ADDR_COMPUTE_HTILE_COORDFROMADDR_OUTPUT)))
1547 {
1548 returnCode = ADDR_PARAMSIZEMISMATCH;
1549 }
1550 }
1551
1552 if (returnCode == ADDR_OK)
1553 {
1554 ADDR_TILEINFO tileInfoNull;
1555 ADDR_COMPUTE_HTILE_COORDFROMADDR_INPUT input;
1556
1557 if (UseTileIndex(pIn->tileIndex))
1558 {
1559 input = *pIn;
1560 // Use temp tile info for calcalation
1561 input.pTileInfo = &tileInfoNull;
1562
1563 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1564
1565 // Change the input structure
1566 pIn = &input;
1567 }
1568
1569 if (returnCode == ADDR_OK)
1570 {
1571 HwlComputeXmaskCoordFromAddr(pIn->addr,
1572 pIn->bitPosition,
1573 pIn->pitch,
1574 pIn->height,
1575 pIn->numSlices,
1576 1,
1577 pIn->isLinear,
1578 isWidth8,
1579 isHeight8,
1580 pIn->pTileInfo,
1581 &pOut->x,
1582 &pOut->y,
1583 &pOut->slice);
1584 }
1585 }
1586
1587 return returnCode;
1588 }
1589
1590 /**
1591 ****************************************************************************************************
1592 * Lib::ComputeCmaskAddrFromCoord
1593 *
1594 * @brief
1595 * Interface function stub of AddrComputeCmaskAddrFromCoord
1596 *
1597 * @return
1598 * ADDR_E_RETURNCODE
1599 ****************************************************************************************************
1600 */
ComputeCmaskAddrFromCoord(const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT * pIn,ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT * pOut) const1601 ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(
1602 const ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1603 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1604 ) const
1605 {
1606 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1607
1608 if (GetFillSizeFieldsFlags() == TRUE)
1609 {
1610 if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
1611 (pOut->size != sizeof(ADDR_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT)))
1612 {
1613 returnCode = ADDR_PARAMSIZEMISMATCH;
1614 }
1615 }
1616
1617 if (returnCode == ADDR_OK)
1618 {
1619 ADDR_TILEINFO tileInfoNull;
1620 ADDR_COMPUTE_CMASK_ADDRFROMCOORD_INPUT input;
1621
1622 if (UseTileIndex(pIn->tileIndex))
1623 {
1624 input = *pIn;
1625 // Use temp tile info for calcalation
1626 input.pTileInfo = &tileInfoNull;
1627
1628 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1629
1630 // Change the input structure
1631 pIn = &input;
1632 }
1633
1634 if (returnCode == ADDR_OK)
1635 {
1636 if (pIn->flags.tcCompatible == TRUE)
1637 {
1638 returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
1639 }
1640 else
1641 {
1642 pOut->addr = HwlComputeXmaskAddrFromCoord(pIn->pitch,
1643 pIn->height,
1644 pIn->x,
1645 pIn->y,
1646 pIn->slice,
1647 pIn->numSlices,
1648 2,
1649 pIn->isLinear,
1650 FALSE, //this is cmask, isWidth8 is not needed
1651 FALSE, //this is cmask, isHeight8 is not needed
1652 pIn->pTileInfo,
1653 &pOut->bitPosition);
1654 }
1655
1656 }
1657 }
1658
1659 return returnCode;
1660 }
1661
1662 /**
1663 ****************************************************************************************************
1664 * Lib::ComputeCmaskCoordFromAddr
1665 *
1666 * @brief
1667 * Interface function stub of AddrComputeCmaskCoordFromAddr
1668 *
1669 * @return
1670 * ADDR_E_RETURNCODE
1671 ****************************************************************************************************
1672 */
ComputeCmaskCoordFromAddr(const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT * pIn,ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT * pOut) const1673 ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(
1674 const ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1675 ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1676 ) const
1677 {
1678 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1679
1680 if (GetFillSizeFieldsFlags() == TRUE)
1681 {
1682 if ((pIn->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT)) ||
1683 (pOut->size != sizeof(ADDR_COMPUTE_CMASK_COORDFROMADDR_OUTPUT)))
1684 {
1685 returnCode = ADDR_PARAMSIZEMISMATCH;
1686 }
1687 }
1688
1689 if (returnCode == ADDR_OK)
1690 {
1691 ADDR_TILEINFO tileInfoNull;
1692 ADDR_COMPUTE_CMASK_COORDFROMADDR_INPUT input;
1693
1694 if (UseTileIndex(pIn->tileIndex))
1695 {
1696 input = *pIn;
1697 // Use temp tile info for calcalation
1698 input.pTileInfo = &tileInfoNull;
1699
1700 returnCode = HwlSetupTileCfg(0, input.tileIndex, input.macroModeIndex, input.pTileInfo);
1701
1702 // Change the input structure
1703 pIn = &input;
1704 }
1705
1706 if (returnCode == ADDR_OK)
1707 {
1708 HwlComputeXmaskCoordFromAddr(pIn->addr,
1709 pIn->bitPosition,
1710 pIn->pitch,
1711 pIn->height,
1712 pIn->numSlices,
1713 2,
1714 pIn->isLinear,
1715 FALSE,
1716 FALSE,
1717 pIn->pTileInfo,
1718 &pOut->x,
1719 &pOut->y,
1720 &pOut->slice);
1721 }
1722 }
1723
1724 return returnCode;
1725 }
1726
1727 /**
1728 ****************************************************************************************************
1729 * Lib::ComputeTileDataWidthAndHeight
1730 *
1731 * @brief
1732 * Compute the squared cache shape for per-tile data (CMASK and HTILE)
1733 *
1734 * @return
1735 * N/A
1736 *
1737 * @note
1738 * MacroWidth and macroHeight are measured in pixels
1739 ****************************************************************************************************
1740 */
ComputeTileDataWidthAndHeight(UINT_32 bpp,UINT_32 cacheBits,ADDR_TILEINFO * pTileInfo,UINT_32 * pMacroWidth,UINT_32 * pMacroHeight) const1741 VOID Lib::ComputeTileDataWidthAndHeight(
1742 UINT_32 bpp, ///< [in] bits per pixel
1743 UINT_32 cacheBits, ///< [in] bits of cache
1744 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
1745 UINT_32* pMacroWidth, ///< [out] macro tile width
1746 UINT_32* pMacroHeight ///< [out] macro tile height
1747 ) const
1748 {
1749 UINT_32 height = 1;
1750 UINT_32 width = cacheBits / bpp;
1751 UINT_32 pipes = HwlGetPipes(pTileInfo);
1752
1753 // Double height until the macro-tile is close to square
1754 // Height can only be doubled if width is even
1755
1756 while ((width > height * 2 * pipes) && !(width & 1))
1757 {
1758 width /= 2;
1759 height *= 2;
1760 }
1761
1762 *pMacroWidth = 8 * width;
1763 *pMacroHeight = 8 * height * pipes;
1764
1765 // Note: The above iterative comptuation is equivalent to the following
1766 //
1767 //int log2_height = ((log2(cacheBits)-log2(bpp)-log2(pipes))/2);
1768 //int macroHeight = pow2( 3+log2(pipes)+log2_height );
1769 }
1770
1771 /**
1772 ****************************************************************************************************
1773 * Lib::HwlComputeTileDataWidthAndHeightLinear
1774 *
1775 * @brief
1776 * Compute the squared cache shape for per-tile data (CMASK and HTILE) for linear layout
1777 *
1778 * @return
1779 * N/A
1780 *
1781 * @note
1782 * MacroWidth and macroHeight are measured in pixels
1783 ****************************************************************************************************
1784 */
HwlComputeTileDataWidthAndHeightLinear(UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_32 bpp,ADDR_TILEINFO * pTileInfo) const1785 VOID Lib::HwlComputeTileDataWidthAndHeightLinear(
1786 UINT_32* pMacroWidth, ///< [out] macro tile width
1787 UINT_32* pMacroHeight, ///< [out] macro tile height
1788 UINT_32 bpp, ///< [in] bits per pixel
1789 ADDR_TILEINFO* pTileInfo ///< [in] tile info
1790 ) const
1791 {
1792 ADDR_ASSERT(bpp != 4); // Cmask does not support linear layout prior to SI
1793 *pMacroWidth = 8 * 512 / bpp; // Align width to 512-bit memory accesses
1794 *pMacroHeight = 8 * m_pipes; // Align height to number of pipes
1795 }
1796
1797 /**
1798 ****************************************************************************************************
1799 * Lib::ComputeHtileInfo
1800 *
1801 * @brief
1802 * Compute htile pitch,width, bytes per 2D slice
1803 *
1804 * @return
1805 * Htile bpp i.e. How many bits for an 8x8 tile
1806 * Also returns by output parameters:
1807 * *Htile pitch, height, total size in bytes, macro-tile dimensions and slice size*
1808 ****************************************************************************************************
1809 */
ComputeHtileInfo(ADDR_HTILE_FLAGS flags,UINT_32 pitchIn,UINT_32 heightIn,UINT_32 numSlices,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pPitchOut,UINT_32 * pHeightOut,UINT_64 * pHtileBytes,UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_64 * pSliceSize,UINT_32 * pBaseAlign) const1810 UINT_32 Lib::ComputeHtileInfo(
1811 ADDR_HTILE_FLAGS flags, ///< [in] htile flags
1812 UINT_32 pitchIn, ///< [in] pitch input
1813 UINT_32 heightIn, ///< [in] height input
1814 UINT_32 numSlices, ///< [in] number of slices
1815 BOOL_32 isLinear, ///< [in] if it is linear mode
1816 BOOL_32 isWidth8, ///< [in] if htile block width is 8
1817 BOOL_32 isHeight8, ///< [in] if htile block height is 8
1818 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
1819 UINT_32* pPitchOut, ///< [out] pitch output
1820 UINT_32* pHeightOut, ///< [out] height output
1821 UINT_64* pHtileBytes, ///< [out] bytes per 2D slice
1822 UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels
1823 UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels
1824 UINT_64* pSliceSize, ///< [out] slice size in bytes
1825 UINT_32* pBaseAlign ///< [out] base alignment
1826 ) const
1827 {
1828
1829 UINT_32 macroWidth;
1830 UINT_32 macroHeight;
1831 UINT_32 baseAlign;
1832 UINT_64 surfBytes;
1833 UINT_64 sliceBytes;
1834
1835 numSlices = Max(1u, numSlices);
1836
1837 const UINT_32 bpp = HwlComputeHtileBpp(isWidth8, isHeight8);
1838 const UINT_32 cacheBits = HtileCacheBits;
1839
1840 if (isLinear)
1841 {
1842 HwlComputeTileDataWidthAndHeightLinear(¯oWidth,
1843 ¯oHeight,
1844 bpp,
1845 pTileInfo);
1846 }
1847 else
1848 {
1849 ComputeTileDataWidthAndHeight(bpp,
1850 cacheBits,
1851 pTileInfo,
1852 ¯oWidth,
1853 ¯oHeight);
1854 }
1855
1856 *pPitchOut = PowTwoAlign(pitchIn, macroWidth);
1857 *pHeightOut = PowTwoAlign(heightIn, macroHeight);
1858
1859 baseAlign = HwlComputeHtileBaseAlign(flags.tcCompatible, isLinear, pTileInfo);
1860
1861 surfBytes = HwlComputeHtileBytes(*pPitchOut,
1862 *pHeightOut,
1863 bpp,
1864 isLinear,
1865 numSlices,
1866 &sliceBytes,
1867 baseAlign);
1868
1869 *pHtileBytes = surfBytes;
1870
1871 //
1872 // Use SafeAssign since they are optional
1873 //
1874 SafeAssign(pMacroWidth, macroWidth);
1875
1876 SafeAssign(pMacroHeight, macroHeight);
1877
1878 SafeAssign(pSliceSize, sliceBytes);
1879
1880 SafeAssign(pBaseAlign, baseAlign);
1881
1882 return bpp;
1883 }
1884
1885 /**
1886 ****************************************************************************************************
1887 * Lib::ComputeCmaskBaseAlign
1888 *
1889 * @brief
1890 * Compute cmask base alignment
1891 *
1892 * @return
1893 * Cmask base alignment
1894 ****************************************************************************************************
1895 */
ComputeCmaskBaseAlign(ADDR_CMASK_FLAGS flags,ADDR_TILEINFO * pTileInfo) const1896 UINT_32 Lib::ComputeCmaskBaseAlign(
1897 ADDR_CMASK_FLAGS flags, ///< [in] Cmask flags
1898 ADDR_TILEINFO* pTileInfo ///< [in] Tile info
1899 ) const
1900 {
1901 UINT_32 baseAlign = m_pipeInterleaveBytes * HwlGetPipes(pTileInfo);
1902
1903 if (flags.tcCompatible)
1904 {
1905 ADDR_ASSERT(pTileInfo != NULL);
1906 if (pTileInfo)
1907 {
1908 baseAlign *= pTileInfo->banks;
1909 }
1910 }
1911
1912 return baseAlign;
1913 }
1914
1915 /**
1916 ****************************************************************************************************
1917 * Lib::ComputeCmaskBytes
1918 *
1919 * @brief
1920 * Compute cmask size in bytes
1921 *
1922 * @return
1923 * Cmask size in bytes
1924 ****************************************************************************************************
1925 */
ComputeCmaskBytes(UINT_32 pitch,UINT_32 height,UINT_32 numSlices) const1926 UINT_64 Lib::ComputeCmaskBytes(
1927 UINT_32 pitch, ///< [in] pitch
1928 UINT_32 height, ///< [in] height
1929 UINT_32 numSlices ///< [in] number of slices
1930 ) const
1931 {
1932 return BITS_TO_BYTES(static_cast<UINT_64>(pitch) * height * numSlices * CmaskElemBits) /
1933 MicroTilePixels;
1934 }
1935
1936 /**
1937 ****************************************************************************************************
1938 * Lib::ComputeCmaskInfo
1939 *
1940 * @brief
1941 * Compute cmask pitch,width, bytes per 2D slice
1942 *
1943 * @return
1944 * BlockMax. Also by output parameters: Cmask pitch,height, total size in bytes,
1945 * macro-tile dimensions
1946 ****************************************************************************************************
1947 */
ComputeCmaskInfo(ADDR_CMASK_FLAGS flags,UINT_32 pitchIn,UINT_32 heightIn,UINT_32 numSlices,BOOL_32 isLinear,ADDR_TILEINFO * pTileInfo,UINT_32 * pPitchOut,UINT_32 * pHeightOut,UINT_64 * pCmaskBytes,UINT_32 * pMacroWidth,UINT_32 * pMacroHeight,UINT_64 * pSliceSize,UINT_32 * pBaseAlign,UINT_32 * pBlockMax) const1948 ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
1949 ADDR_CMASK_FLAGS flags, ///< [in] cmask flags
1950 UINT_32 pitchIn, ///< [in] pitch input
1951 UINT_32 heightIn, ///< [in] height input
1952 UINT_32 numSlices, ///< [in] number of slices
1953 BOOL_32 isLinear, ///< [in] is linear mode
1954 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
1955 UINT_32* pPitchOut, ///< [out] pitch output
1956 UINT_32* pHeightOut, ///< [out] height output
1957 UINT_64* pCmaskBytes, ///< [out] bytes per 2D slice
1958 UINT_32* pMacroWidth, ///< [out] macro-tile width in pixels
1959 UINT_32* pMacroHeight, ///< [out] macro-tile width in pixels
1960 UINT_64* pSliceSize, ///< [out] slice size in bytes
1961 UINT_32* pBaseAlign, ///< [out] base alignment
1962 UINT_32* pBlockMax ///< [out] block max == slice / 128 / 128 - 1
1963 ) const
1964 {
1965 UINT_32 macroWidth;
1966 UINT_32 macroHeight;
1967 UINT_32 baseAlign;
1968 UINT_64 surfBytes;
1969 UINT_64 sliceBytes;
1970
1971 numSlices = Max(1u, numSlices);
1972
1973 const UINT_32 bpp = CmaskElemBits;
1974 const UINT_32 cacheBits = CmaskCacheBits;
1975
1976 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1977
1978 if (isLinear)
1979 {
1980 HwlComputeTileDataWidthAndHeightLinear(¯oWidth,
1981 ¯oHeight,
1982 bpp,
1983 pTileInfo);
1984 }
1985 else
1986 {
1987 ComputeTileDataWidthAndHeight(bpp,
1988 cacheBits,
1989 pTileInfo,
1990 ¯oWidth,
1991 ¯oHeight);
1992 }
1993
1994 *pPitchOut = (pitchIn + macroWidth - 1) & ~(macroWidth - 1);
1995 *pHeightOut = (heightIn + macroHeight - 1) & ~(macroHeight - 1);
1996
1997
1998 sliceBytes = ComputeCmaskBytes(*pPitchOut,
1999 *pHeightOut,
2000 1);
2001
2002 baseAlign = ComputeCmaskBaseAlign(flags, pTileInfo);
2003
2004 while (sliceBytes % baseAlign)
2005 {
2006 *pHeightOut += macroHeight;
2007
2008 sliceBytes = ComputeCmaskBytes(*pPitchOut,
2009 *pHeightOut,
2010 1);
2011 }
2012
2013 surfBytes = sliceBytes * numSlices;
2014
2015 *pCmaskBytes = surfBytes;
2016
2017 //
2018 // Use SafeAssign since they are optional
2019 //
2020 SafeAssign(pMacroWidth, macroWidth);
2021
2022 SafeAssign(pMacroHeight, macroHeight);
2023
2024 SafeAssign(pBaseAlign, baseAlign);
2025
2026 SafeAssign(pSliceSize, sliceBytes);
2027
2028 UINT_32 slice = (*pPitchOut) * (*pHeightOut);
2029 UINT_32 blockMax = slice / 128 / 128 - 1;
2030
2031 #if DEBUG
2032 if (slice % (64*256) != 0)
2033 {
2034 ADDR_ASSERT_ALWAYS();
2035 }
2036 #endif //DEBUG
2037
2038 UINT_32 maxBlockMax = HwlGetMaxCmaskBlockMax();
2039
2040 if (blockMax > maxBlockMax)
2041 {
2042 blockMax = maxBlockMax;
2043 returnCode = ADDR_INVALIDPARAMS;
2044 }
2045
2046 SafeAssign(pBlockMax, blockMax);
2047
2048 return returnCode;
2049 }
2050
2051 /**
2052 ****************************************************************************************************
2053 * Lib::ComputeXmaskCoordYFromPipe
2054 *
2055 * @brief
2056 * Compute the Y coord from pipe number for cmask/htile
2057 *
2058 * @return
2059 * Y coordinate
2060 *
2061 ****************************************************************************************************
2062 */
ComputeXmaskCoordYFromPipe(UINT_32 pipe,UINT_32 x) const2063 UINT_32 Lib::ComputeXmaskCoordYFromPipe(
2064 UINT_32 pipe, ///< [in] pipe number
2065 UINT_32 x ///< [in] x coordinate
2066 ) const
2067 {
2068 UINT_32 pipeBit0;
2069 UINT_32 pipeBit1;
2070 UINT_32 xBit0;
2071 UINT_32 xBit1;
2072 UINT_32 yBit0;
2073 UINT_32 yBit1;
2074
2075 UINT_32 y = 0;
2076
2077 UINT_32 numPipes = m_pipes; // SI has its implementation
2078 //
2079 // Convert pipe + x to y coordinate.
2080 //
2081 switch (numPipes)
2082 {
2083 case 1:
2084 //
2085 // 1 pipe
2086 //
2087 // p0 = 0
2088 //
2089 y = 0;
2090 break;
2091 case 2:
2092 //
2093 // 2 pipes
2094 //
2095 // p0 = x0 ^ y0
2096 //
2097 // y0 = p0 ^ x0
2098 //
2099 pipeBit0 = pipe & 0x1;
2100
2101 xBit0 = x & 0x1;
2102
2103 yBit0 = pipeBit0 ^ xBit0;
2104
2105 y = yBit0;
2106 break;
2107 case 4:
2108 //
2109 // 4 pipes
2110 //
2111 // p0 = x1 ^ y0
2112 // p1 = x0 ^ y1
2113 //
2114 // y0 = p0 ^ x1
2115 // y1 = p1 ^ x0
2116 //
2117 pipeBit0 = pipe & 0x1;
2118 pipeBit1 = (pipe & 0x2) >> 1;
2119
2120 xBit0 = x & 0x1;
2121 xBit1 = (x & 0x2) >> 1;
2122
2123 yBit0 = pipeBit0 ^ xBit1;
2124 yBit1 = pipeBit1 ^ xBit0;
2125
2126 y = (yBit0 |
2127 (yBit1 << 1));
2128 break;
2129 case 8:
2130 //
2131 // 8 pipes
2132 //
2133 // r600 and r800 have different method
2134 //
2135 y = HwlComputeXmaskCoordYFrom8Pipe(pipe, x);
2136 break;
2137 default:
2138 break;
2139 }
2140 return y;
2141 }
2142
2143 /**
2144 ****************************************************************************************************
2145 * Lib::HwlComputeXmaskCoordFromAddr
2146 *
2147 * @brief
2148 * Compute the coord from an address of a cmask/htile
2149 *
2150 * @return
2151 * N/A
2152 *
2153 * @note
2154 * This method is reused by htile, so rename to Xmask
2155 ****************************************************************************************************
2156 */
HwlComputeXmaskCoordFromAddr(UINT_64 addr,UINT_32 bitPosition,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 factor,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice) const2157 VOID Lib::HwlComputeXmaskCoordFromAddr(
2158 UINT_64 addr, ///< [in] address
2159 UINT_32 bitPosition, ///< [in] bitPosition in a byte
2160 UINT_32 pitch, ///< [in] pitch
2161 UINT_32 height, ///< [in] height
2162 UINT_32 numSlices, ///< [in] number of slices
2163 UINT_32 factor, ///< [in] factor that indicates cmask or htile
2164 BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout
2165 BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2166 BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2167 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
2168 UINT_32* pX, ///< [out] x coord
2169 UINT_32* pY, ///< [out] y coord
2170 UINT_32* pSlice ///< [out] slice index
2171 ) const
2172 {
2173 UINT_32 pipe;
2174 UINT_32 numPipes;
2175 UINT_32 numGroupBits;
2176 UINT_32 numPipeBits;
2177 UINT_32 macroTilePitch;
2178 UINT_32 macroTileHeight;
2179
2180 UINT_64 bitAddr;
2181
2182 UINT_32 microTileCoordY;
2183
2184 UINT_32 elemBits;
2185
2186 UINT_32 pitchAligned = pitch;
2187 UINT_32 heightAligned = height;
2188 UINT_64 totalBytes;
2189
2190 UINT_64 elemOffset;
2191
2192 UINT_64 macroIndex;
2193 UINT_32 microIndex;
2194
2195 UINT_64 macroNumber;
2196 UINT_32 microNumber;
2197
2198 UINT_32 macroX;
2199 UINT_32 macroY;
2200 UINT_32 macroZ;
2201
2202 UINT_32 microX;
2203 UINT_32 microY;
2204
2205 UINT_32 tilesPerMacro;
2206 UINT_32 macrosPerPitch;
2207 UINT_32 macrosPerSlice;
2208
2209 //
2210 // Extract pipe.
2211 //
2212 numPipes = HwlGetPipes(pTileInfo);
2213 pipe = ComputePipeFromAddr(addr, numPipes);
2214
2215 //
2216 // Compute the number of group and pipe bits.
2217 //
2218 numGroupBits = Log2(m_pipeInterleaveBytes);
2219 numPipeBits = Log2(numPipes);
2220
2221 UINT_32 groupBits = 8 * m_pipeInterleaveBytes;
2222 UINT_32 pipes = numPipes;
2223
2224
2225 //
2226 // Compute the micro tile size, in bits. And macro tile pitch and height.
2227 //
2228 if (factor == 2) //CMASK
2229 {
2230 ADDR_CMASK_FLAGS flags = {{0}};
2231
2232 elemBits = CmaskElemBits;
2233
2234 ComputeCmaskInfo(flags,
2235 pitch,
2236 height,
2237 numSlices,
2238 isLinear,
2239 pTileInfo,
2240 &pitchAligned,
2241 &heightAligned,
2242 &totalBytes,
2243 ¯oTilePitch,
2244 ¯oTileHeight);
2245 }
2246 else //HTILE
2247 {
2248 ADDR_HTILE_FLAGS flags = {{0}};
2249
2250 if (factor != 1)
2251 {
2252 factor = 1;
2253 }
2254
2255 elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
2256
2257 ComputeHtileInfo(flags,
2258 pitch,
2259 height,
2260 numSlices,
2261 isLinear,
2262 isWidth8,
2263 isHeight8,
2264 pTileInfo,
2265 &pitchAligned,
2266 &heightAligned,
2267 &totalBytes,
2268 ¯oTilePitch,
2269 ¯oTileHeight);
2270 }
2271
2272 // Should use aligned dims
2273 //
2274 pitch = pitchAligned;
2275 height = heightAligned;
2276
2277
2278 //
2279 // Convert byte address to bit address.
2280 //
2281 bitAddr = BYTES_TO_BITS(addr) + bitPosition;
2282
2283
2284 //
2285 // Remove pipe bits from address.
2286 //
2287
2288 bitAddr = (bitAddr % groupBits) + ((bitAddr/groupBits/pipes)*groupBits);
2289
2290
2291 elemOffset = bitAddr / elemBits;
2292
2293 tilesPerMacro = (macroTilePitch/factor) * macroTileHeight / MicroTilePixels >> numPipeBits;
2294
2295 macrosPerPitch = pitch / (macroTilePitch/factor);
2296 macrosPerSlice = macrosPerPitch * height / macroTileHeight;
2297
2298 macroIndex = elemOffset / factor / tilesPerMacro;
2299 microIndex = static_cast<UINT_32>(elemOffset % (tilesPerMacro * factor));
2300
2301 macroNumber = macroIndex * factor + microIndex % factor;
2302 microNumber = microIndex / factor;
2303
2304 macroX = static_cast<UINT_32>((macroNumber % macrosPerPitch));
2305 macroY = static_cast<UINT_32>((macroNumber % macrosPerSlice) / macrosPerPitch);
2306 macroZ = static_cast<UINT_32>((macroNumber / macrosPerSlice));
2307
2308
2309 microX = microNumber % (macroTilePitch / factor / MicroTileWidth);
2310 microY = (microNumber / (macroTilePitch / factor / MicroTileHeight));
2311
2312 *pX = macroX * (macroTilePitch/factor) + microX * MicroTileWidth;
2313 *pY = macroY * macroTileHeight + (microY * MicroTileHeight << numPipeBits);
2314 *pSlice = macroZ;
2315
2316 microTileCoordY = ComputeXmaskCoordYFromPipe(pipe,
2317 *pX/MicroTileWidth);
2318
2319
2320 //
2321 // Assemble final coordinates.
2322 //
2323 *pY += microTileCoordY * MicroTileHeight;
2324
2325 }
2326
2327 /**
2328 ****************************************************************************************************
2329 * Lib::HwlComputeXmaskAddrFromCoord
2330 *
2331 * @brief
2332 * Compute the address from an address of cmask (prior to si)
2333 *
2334 * @return
2335 * Address in bytes
2336 *
2337 ****************************************************************************************************
2338 */
HwlComputeXmaskAddrFromCoord(UINT_32 pitch,UINT_32 height,UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 numSlices,UINT_32 factor,BOOL_32 isLinear,BOOL_32 isWidth8,BOOL_32 isHeight8,ADDR_TILEINFO * pTileInfo,UINT_32 * pBitPosition) const2339 UINT_64 Lib::HwlComputeXmaskAddrFromCoord(
2340 UINT_32 pitch, ///< [in] pitch
2341 UINT_32 height, ///< [in] height
2342 UINT_32 x, ///< [in] x coord
2343 UINT_32 y, ///< [in] y coord
2344 UINT_32 slice, ///< [in] slice/depth index
2345 UINT_32 numSlices, ///< [in] number of slices
2346 UINT_32 factor, ///< [in] factor that indicates cmask(2) or htile(1)
2347 BOOL_32 isLinear, ///< [in] linear or tiled HTILE layout
2348 BOOL_32 isWidth8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2349 BOOL_32 isHeight8, ///< [in] TRUE if width is 8, FALSE means 4. It's register value
2350 ADDR_TILEINFO* pTileInfo, ///< [in] Tile info
2351 UINT_32* pBitPosition ///< [out] bit position inside a byte
2352 ) const
2353 {
2354 UINT_64 addr;
2355 UINT_32 numGroupBits;
2356 UINT_32 numPipeBits;
2357 UINT_32 newPitch = 0;
2358 UINT_32 newHeight = 0;
2359 UINT_64 sliceBytes = 0;
2360 UINT_64 totalBytes = 0;
2361 UINT_64 sliceOffset;
2362 UINT_32 pipe;
2363 UINT_32 macroTileWidth;
2364 UINT_32 macroTileHeight;
2365 UINT_32 macroTilesPerRow;
2366 UINT_32 macroTileBytes;
2367 UINT_32 macroTileIndexX;
2368 UINT_32 macroTileIndexY;
2369 UINT_64 macroTileOffset;
2370 UINT_32 pixelBytesPerRow;
2371 UINT_32 pixelOffsetX;
2372 UINT_32 pixelOffsetY;
2373 UINT_32 pixelOffset;
2374 UINT_64 totalOffset;
2375 UINT_64 offsetLo;
2376 UINT_64 offsetHi;
2377 UINT_64 groupMask;
2378
2379
2380 UINT_32 elemBits = 0;
2381
2382 UINT_32 numPipes = m_pipes; // This function is accessed prior to si only
2383
2384 if (factor == 2) //CMASK
2385 {
2386 elemBits = CmaskElemBits;
2387
2388 // For asics before SI, cmask is always tiled
2389 isLinear = FALSE;
2390 }
2391 else //HTILE
2392 {
2393 if (factor != 1) // Fix compile warning
2394 {
2395 factor = 1;
2396 }
2397
2398 elemBits = HwlComputeHtileBpp(isWidth8, isHeight8);
2399 }
2400
2401 //
2402 // Compute the number of group bits and pipe bits.
2403 //
2404 numGroupBits = Log2(m_pipeInterleaveBytes);
2405 numPipeBits = Log2(numPipes);
2406
2407 //
2408 // Compute macro tile dimensions.
2409 //
2410 if (factor == 2) // CMASK
2411 {
2412 ADDR_CMASK_FLAGS flags = {{0}};
2413
2414 ComputeCmaskInfo(flags,
2415 pitch,
2416 height,
2417 numSlices,
2418 isLinear,
2419 pTileInfo,
2420 &newPitch,
2421 &newHeight,
2422 &totalBytes,
2423 ¯oTileWidth,
2424 ¯oTileHeight);
2425
2426 sliceBytes = totalBytes / numSlices;
2427 }
2428 else // HTILE
2429 {
2430 ADDR_HTILE_FLAGS flags = {{0}};
2431
2432 ComputeHtileInfo(flags,
2433 pitch,
2434 height,
2435 numSlices,
2436 isLinear,
2437 isWidth8,
2438 isHeight8,
2439 pTileInfo,
2440 &newPitch,
2441 &newHeight,
2442 &totalBytes,
2443 ¯oTileWidth,
2444 ¯oTileHeight,
2445 &sliceBytes);
2446 }
2447
2448 sliceOffset = slice * sliceBytes;
2449
2450 //
2451 // Get the pipe. Note that neither slice rotation nor pipe swizzling apply for CMASK.
2452 //
2453 pipe = ComputePipeFromCoord(x,
2454 y,
2455 0,
2456 ADDR_TM_2D_TILED_THIN1,
2457 0,
2458 FALSE,
2459 pTileInfo);
2460
2461 //
2462 // Compute the number of macro tiles per row.
2463 //
2464 macroTilesPerRow = newPitch / macroTileWidth;
2465
2466 //
2467 // Compute the number of bytes per macro tile.
2468 //
2469 macroTileBytes = BITS_TO_BYTES((macroTileWidth * macroTileHeight * elemBits) / MicroTilePixels);
2470
2471 //
2472 // Compute the offset to the macro tile containing the specified coordinate.
2473 //
2474 macroTileIndexX = x / macroTileWidth;
2475 macroTileIndexY = y / macroTileHeight;
2476 macroTileOffset = ((macroTileIndexY * macroTilesPerRow) + macroTileIndexX) * macroTileBytes;
2477
2478 //
2479 // Compute the pixel offset within the macro tile.
2480 //
2481 pixelBytesPerRow = BITS_TO_BYTES(macroTileWidth * elemBits) / MicroTileWidth;
2482
2483 //
2484 // The nibbles are interleaved (see below), so the part of the offset relative to the x
2485 // coordinate repeats halfway across the row. (Not for HTILE)
2486 //
2487 if (factor == 2)
2488 {
2489 pixelOffsetX = (x % (macroTileWidth / 2)) / MicroTileWidth;
2490 }
2491 else
2492 {
2493 pixelOffsetX = (x % (macroTileWidth)) / MicroTileWidth * BITS_TO_BYTES(elemBits);
2494 }
2495
2496 //
2497 // Compute the y offset within the macro tile.
2498 //
2499 pixelOffsetY = (((y % macroTileHeight) / MicroTileHeight) / numPipes) * pixelBytesPerRow;
2500
2501 pixelOffset = pixelOffsetX + pixelOffsetY;
2502
2503 //
2504 // Combine the slice offset and macro tile offset with the pixel offset, accounting for the
2505 // pipe bits in the middle of the address.
2506 //
2507 totalOffset = ((sliceOffset + macroTileOffset) >> numPipeBits) + pixelOffset;
2508
2509 //
2510 // Split the offset to put some bits below the pipe bits and some above.
2511 //
2512 groupMask = (1 << numGroupBits) - 1;
2513 offsetLo = totalOffset & groupMask;
2514 offsetHi = (totalOffset & ~groupMask) << numPipeBits;
2515
2516 //
2517 // Assemble the address from its components.
2518 //
2519 addr = offsetLo;
2520 addr |= offsetHi;
2521 // This is to remove warning with /analyze option
2522 UINT_32 pipeBits = pipe << numGroupBits;
2523 addr |= pipeBits;
2524
2525 //
2526 // Compute the bit position. The lower nibble is used when the x coordinate within the macro
2527 // tile is less than half of the macro tile width, and the upper nibble is used when the x
2528 // coordinate within the macro tile is greater than or equal to half the macro tile width.
2529 //
2530 *pBitPosition = ((x % macroTileWidth) < (macroTileWidth / factor)) ? 0 : 4;
2531
2532 return addr;
2533 }
2534
2535 ////////////////////////////////////////////////////////////////////////////////////////////////////
2536 // Surface Addressing Shared
2537 ////////////////////////////////////////////////////////////////////////////////////////////////////
2538
2539 /**
2540 ****************************************************************************************************
2541 * Lib::ComputeSurfaceAddrFromCoordLinear
2542 *
2543 * @brief
2544 * Compute address from coord for linear surface
2545 *
2546 * @return
2547 * Address in bytes
2548 *
2549 ****************************************************************************************************
2550 */
ComputeSurfaceAddrFromCoordLinear(UINT_32 x,UINT_32 y,UINT_32 slice,UINT_32 sample,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 * pBitPosition) const2551 UINT_64 Lib::ComputeSurfaceAddrFromCoordLinear(
2552 UINT_32 x, ///< [in] x coord
2553 UINT_32 y, ///< [in] y coord
2554 UINT_32 slice, ///< [in] slice/depth index
2555 UINT_32 sample, ///< [in] sample index
2556 UINT_32 bpp, ///< [in] bits per pixel
2557 UINT_32 pitch, ///< [in] pitch
2558 UINT_32 height, ///< [in] height
2559 UINT_32 numSlices, ///< [in] number of slices
2560 UINT_32* pBitPosition ///< [out] bit position inside a byte
2561 ) const
2562 {
2563 const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
2564
2565 UINT_64 sliceOffset = (slice + sample * numSlices)* sliceSize;
2566 UINT_64 rowOffset = static_cast<UINT_64>(y) * pitch;
2567 UINT_64 pixOffset = x;
2568
2569 UINT_64 addr = (sliceOffset + rowOffset + pixOffset) * bpp;
2570
2571 *pBitPosition = static_cast<UINT_32>(addr % 8);
2572 addr /= 8;
2573
2574 return addr;
2575 }
2576
2577 /**
2578 ****************************************************************************************************
2579 * Lib::ComputeSurfaceCoordFromAddrLinear
2580 *
2581 * @brief
2582 * Compute the coord from an address of a linear surface
2583 *
2584 * @return
2585 * N/A
2586 ****************************************************************************************************
2587 */
ComputeSurfaceCoordFromAddrLinear(UINT_64 addr,UINT_32 bitPosition,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSlices,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice,UINT_32 * pSample) const2588 VOID Lib::ComputeSurfaceCoordFromAddrLinear(
2589 UINT_64 addr, ///< [in] address
2590 UINT_32 bitPosition, ///< [in] bitPosition in a byte
2591 UINT_32 bpp, ///< [in] bits per pixel
2592 UINT_32 pitch, ///< [in] pitch
2593 UINT_32 height, ///< [in] height
2594 UINT_32 numSlices, ///< [in] number of slices
2595 UINT_32* pX, ///< [out] x coord
2596 UINT_32* pY, ///< [out] y coord
2597 UINT_32* pSlice, ///< [out] slice/depth index
2598 UINT_32* pSample ///< [out] sample index
2599 ) const
2600 {
2601 const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height;
2602 const UINT_64 linearOffset = (BYTES_TO_BITS(addr) + bitPosition) / bpp;
2603
2604 *pX = static_cast<UINT_32>((linearOffset % sliceSize) % pitch);
2605 *pY = static_cast<UINT_32>((linearOffset % sliceSize) / pitch % height);
2606 *pSlice = static_cast<UINT_32>((linearOffset / sliceSize) % numSlices);
2607 *pSample = static_cast<UINT_32>((linearOffset / sliceSize) / numSlices);
2608 }
2609
2610 /**
2611 ****************************************************************************************************
2612 * Lib::ComputeSurfaceCoordFromAddrMicroTiled
2613 *
2614 * @brief
2615 * Compute the coord from an address of a micro tiled surface
2616 *
2617 * @return
2618 * N/A
2619 ****************************************************************************************************
2620 */
ComputeSurfaceCoordFromAddrMicroTiled(UINT_64 addr,UINT_32 bitPosition,UINT_32 bpp,UINT_32 pitch,UINT_32 height,UINT_32 numSamples,AddrTileMode tileMode,UINT_32 tileBase,UINT_32 compBits,UINT_32 * pX,UINT_32 * pY,UINT_32 * pSlice,UINT_32 * pSample,AddrTileType microTileType,BOOL_32 isDepthSampleOrder) const2621 VOID Lib::ComputeSurfaceCoordFromAddrMicroTiled(
2622 UINT_64 addr, ///< [in] address
2623 UINT_32 bitPosition, ///< [in] bitPosition in a byte
2624 UINT_32 bpp, ///< [in] bits per pixel
2625 UINT_32 pitch, ///< [in] pitch
2626 UINT_32 height, ///< [in] height
2627 UINT_32 numSamples, ///< [in] number of samples
2628 AddrTileMode tileMode, ///< [in] tile mode
2629 UINT_32 tileBase, ///< [in] base offset within a tile
2630 UINT_32 compBits, ///< [in] component bits actually needed(for planar surface)
2631 UINT_32* pX, ///< [out] x coord
2632 UINT_32* pY, ///< [out] y coord
2633 UINT_32* pSlice, ///< [out] slice/depth index
2634 UINT_32* pSample, ///< [out] sample index,
2635 AddrTileType microTileType, ///< [in] micro tiling order
2636 BOOL_32 isDepthSampleOrder ///< [in] TRUE if in depth sample order
2637 ) const
2638 {
2639 UINT_64 bitAddr;
2640 UINT_32 microTileThickness;
2641 UINT_32 microTileBits;
2642 UINT_64 sliceBits;
2643 UINT_64 rowBits;
2644 UINT_32 sliceIndex;
2645 UINT_32 microTileCoordX;
2646 UINT_32 microTileCoordY;
2647 UINT_32 pixelOffset;
2648 UINT_32 pixelCoordX = 0;
2649 UINT_32 pixelCoordY = 0;
2650 UINT_32 pixelCoordZ = 0;
2651 UINT_32 pixelCoordS = 0;
2652
2653 //
2654 // Convert byte address to bit address.
2655 //
2656 bitAddr = BYTES_TO_BITS(addr) + bitPosition;
2657
2658 //
2659 // Compute the micro tile size, in bits.
2660 //
2661 switch (tileMode)
2662 {
2663 case ADDR_TM_1D_TILED_THICK:
2664 microTileThickness = ThickTileThickness;
2665 break;
2666 default:
2667 microTileThickness = 1;
2668 break;
2669 }
2670
2671 microTileBits = MicroTilePixels * microTileThickness * bpp * numSamples;
2672
2673 //
2674 // Compute number of bits per slice and number of bits per row of micro tiles.
2675 //
2676 sliceBits = static_cast<UINT_64>(pitch) * height * microTileThickness * bpp * numSamples;
2677
2678 rowBits = (pitch / MicroTileWidth) * microTileBits;
2679
2680 //
2681 // Extract the slice index.
2682 //
2683 sliceIndex = static_cast<UINT_32>(bitAddr / sliceBits);
2684 bitAddr -= sliceIndex * sliceBits;
2685
2686 //
2687 // Extract the y coordinate of the micro tile.
2688 //
2689 microTileCoordY = static_cast<UINT_32>(bitAddr / rowBits) * MicroTileHeight;
2690 bitAddr -= (microTileCoordY / MicroTileHeight) * rowBits;
2691
2692 //
2693 // Extract the x coordinate of the micro tile.
2694 //
2695 microTileCoordX = static_cast<UINT_32>(bitAddr / microTileBits) * MicroTileWidth;
2696
2697 //
2698 // Compute the pixel offset within the micro tile.
2699 //
2700 pixelOffset = static_cast<UINT_32>(bitAddr % microTileBits);
2701
2702 //
2703 // Extract pixel coordinates from the offset.
2704 //
2705 HwlComputePixelCoordFromOffset(pixelOffset,
2706 bpp,
2707 numSamples,
2708 tileMode,
2709 tileBase,
2710 compBits,
2711 &pixelCoordX,
2712 &pixelCoordY,
2713 &pixelCoordZ,
2714 &pixelCoordS,
2715 microTileType,
2716 isDepthSampleOrder);
2717
2718 //
2719 // Assemble final coordinates.
2720 //
2721 *pX = microTileCoordX + pixelCoordX;
2722 *pY = microTileCoordY + pixelCoordY;
2723 *pSlice = (sliceIndex * microTileThickness) + pixelCoordZ;
2724 *pSample = pixelCoordS;
2725
2726 if (microTileThickness > 1)
2727 {
2728 *pSample = 0;
2729 }
2730 }
2731
2732 /**
2733 ****************************************************************************************************
2734 * Lib::ComputePipeFromAddr
2735 *
2736 * @brief
2737 * Compute the pipe number from an address
2738 *
2739 * @return
2740 * Pipe number
2741 *
2742 ****************************************************************************************************
2743 */
ComputePipeFromAddr(UINT_64 addr,UINT_32 numPipes) const2744 UINT_32 Lib::ComputePipeFromAddr(
2745 UINT_64 addr, ///< [in] address
2746 UINT_32 numPipes ///< [in] number of banks
2747 ) const
2748 {
2749 UINT_32 pipe;
2750
2751 UINT_32 groupBytes = m_pipeInterleaveBytes; //just different terms
2752
2753 // R600
2754 // The LSBs of the address are arranged as follows:
2755 // bank | pipe | group
2756 //
2757 // To get the pipe number, shift off the group bits and mask the pipe bits.
2758 //
2759
2760 // R800
2761 // The LSBs of the address are arranged as follows:
2762 // bank | bankInterleave | pipe | pipeInterleave
2763 //
2764 // To get the pipe number, shift off the pipe interleave bits and mask the pipe bits.
2765 //
2766
2767 pipe = static_cast<UINT_32>(addr >> Log2(groupBytes)) & (numPipes - 1);
2768
2769 return pipe;
2770 }
2771
2772 /**
2773 ****************************************************************************************************
2774 * Lib::ComputeMicroTileEquation
2775 *
2776 * @brief
2777 * Compute micro tile equation
2778 *
2779 * @return
2780 * If equation can be computed
2781 *
2782 ****************************************************************************************************
2783 */
ComputeMicroTileEquation(UINT_32 log2BytesPP,AddrTileMode tileMode,AddrTileType microTileType,ADDR_EQUATION * pEquation) const2784 ADDR_E_RETURNCODE Lib::ComputeMicroTileEquation(
2785 UINT_32 log2BytesPP, ///< [in] log2 of bytes per pixel
2786 AddrTileMode tileMode, ///< [in] tile mode
2787 AddrTileType microTileType, ///< [in] pixel order in display/non-display mode
2788 ADDR_EQUATION* pEquation ///< [out] equation
2789 ) const
2790 {
2791 ADDR_E_RETURNCODE retCode = ADDR_OK;
2792
2793 for (UINT_32 i = 0; i < log2BytesPP; i++)
2794 {
2795 pEquation->addr[i].valid = 1;
2796 pEquation->addr[i].channel = 0;
2797 pEquation->addr[i].index = i;
2798 }
2799
2800 ADDR_CHANNEL_SETTING* pixelBit = &pEquation->addr[log2BytesPP];
2801
2802 ADDR_CHANNEL_SETTING x0 = InitChannel(1, 0, log2BytesPP + 0);
2803 ADDR_CHANNEL_SETTING x1 = InitChannel(1, 0, log2BytesPP + 1);
2804 ADDR_CHANNEL_SETTING x2 = InitChannel(1, 0, log2BytesPP + 2);
2805 ADDR_CHANNEL_SETTING y0 = InitChannel(1, 1, 0);
2806 ADDR_CHANNEL_SETTING y1 = InitChannel(1, 1, 1);
2807 ADDR_CHANNEL_SETTING y2 = InitChannel(1, 1, 2);
2808 ADDR_CHANNEL_SETTING z0 = InitChannel(1, 2, 0);
2809 ADDR_CHANNEL_SETTING z1 = InitChannel(1, 2, 1);
2810 ADDR_CHANNEL_SETTING z2 = InitChannel(1, 2, 2);
2811
2812 UINT_32 thickness = Thickness(tileMode);
2813 UINT_32 bpp = 1 << (log2BytesPP + 3);
2814
2815 if (microTileType != ADDR_THICK)
2816 {
2817 if (microTileType == ADDR_DISPLAYABLE)
2818 {
2819 switch (bpp)
2820 {
2821 case 8:
2822 pixelBit[0] = x0;
2823 pixelBit[1] = x1;
2824 pixelBit[2] = x2;
2825 pixelBit[3] = y1;
2826 pixelBit[4] = y0;
2827 pixelBit[5] = y2;
2828 break;
2829 case 16:
2830 pixelBit[0] = x0;
2831 pixelBit[1] = x1;
2832 pixelBit[2] = x2;
2833 pixelBit[3] = y0;
2834 pixelBit[4] = y1;
2835 pixelBit[5] = y2;
2836 break;
2837 case 32:
2838 pixelBit[0] = x0;
2839 pixelBit[1] = x1;
2840 pixelBit[2] = y0;
2841 pixelBit[3] = x2;
2842 pixelBit[4] = y1;
2843 pixelBit[5] = y2;
2844 break;
2845 case 64:
2846 pixelBit[0] = x0;
2847 pixelBit[1] = y0;
2848 pixelBit[2] = x1;
2849 pixelBit[3] = x2;
2850 pixelBit[4] = y1;
2851 pixelBit[5] = y2;
2852 break;
2853 case 128:
2854 pixelBit[0] = y0;
2855 pixelBit[1] = x0;
2856 pixelBit[2] = x1;
2857 pixelBit[3] = x2;
2858 pixelBit[4] = y1;
2859 pixelBit[5] = y2;
2860 break;
2861 default:
2862 ADDR_ASSERT_ALWAYS();
2863 break;
2864 }
2865 }
2866 else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
2867 {
2868 pixelBit[0] = x0;
2869 pixelBit[1] = y0;
2870 pixelBit[2] = x1;
2871 pixelBit[3] = y1;
2872 pixelBit[4] = x2;
2873 pixelBit[5] = y2;
2874 }
2875 else if (microTileType == ADDR_ROTATED)
2876 {
2877 ADDR_ASSERT(thickness == 1);
2878
2879 switch (bpp)
2880 {
2881 case 8:
2882 pixelBit[0] = y0;
2883 pixelBit[1] = y1;
2884 pixelBit[2] = y2;
2885 pixelBit[3] = x1;
2886 pixelBit[4] = x0;
2887 pixelBit[5] = x2;
2888 break;
2889 case 16:
2890 pixelBit[0] = y0;
2891 pixelBit[1] = y1;
2892 pixelBit[2] = y2;
2893 pixelBit[3] = x0;
2894 pixelBit[4] = x1;
2895 pixelBit[5] = x2;
2896 break;
2897 case 32:
2898 pixelBit[0] = y0;
2899 pixelBit[1] = y1;
2900 pixelBit[2] = x0;
2901 pixelBit[3] = y2;
2902 pixelBit[4] = x1;
2903 pixelBit[5] = x2;
2904 break;
2905 case 64:
2906 pixelBit[0] = y0;
2907 pixelBit[1] = x0;
2908 pixelBit[2] = y1;
2909 pixelBit[3] = x1;
2910 pixelBit[4] = x2;
2911 pixelBit[5] = y2;
2912 break;
2913 default:
2914 retCode = ADDR_NOTSUPPORTED;
2915 break;
2916 }
2917 }
2918
2919 if (thickness > 1)
2920 {
2921 pixelBit[6] = z0;
2922 pixelBit[7] = z1;
2923 pEquation->numBits = 8 + log2BytesPP;
2924 }
2925 else
2926 {
2927 pEquation->numBits = 6 + log2BytesPP;
2928 }
2929 }
2930 else // ADDR_THICK
2931 {
2932 ADDR_ASSERT(thickness > 1);
2933
2934 switch (bpp)
2935 {
2936 case 8:
2937 case 16:
2938 pixelBit[0] = x0;
2939 pixelBit[1] = y0;
2940 pixelBit[2] = x1;
2941 pixelBit[3] = y1;
2942 pixelBit[4] = z0;
2943 pixelBit[5] = z1;
2944 break;
2945 case 32:
2946 pixelBit[0] = x0;
2947 pixelBit[1] = y0;
2948 pixelBit[2] = x1;
2949 pixelBit[3] = z0;
2950 pixelBit[4] = y1;
2951 pixelBit[5] = z1;
2952 break;
2953 case 64:
2954 case 128:
2955 pixelBit[0] = x0;
2956 pixelBit[1] = y0;
2957 pixelBit[2] = z0;
2958 pixelBit[3] = x1;
2959 pixelBit[4] = y1;
2960 pixelBit[5] = z1;
2961 break;
2962 default:
2963 ADDR_ASSERT_ALWAYS();
2964 break;
2965 }
2966
2967 pixelBit[6] = x2;
2968 pixelBit[7] = y2;
2969 pEquation->numBits = 8 + log2BytesPP;
2970 }
2971
2972 if (thickness == 8)
2973 {
2974 pixelBit[8] = z2;
2975 pEquation->numBits = 9 + log2BytesPP;
2976 }
2977
2978 // stackedDepthSlices is used for addressing mode that a tile block contains multiple slices,
2979 // which is not supported by our address lib
2980 pEquation->stackedDepthSlices = FALSE;
2981 pEquation->numBitComponents = 1;
2982
2983 return retCode;
2984 }
2985
2986 /**
2987 ****************************************************************************************************
2988 * Lib::ComputePixelIndexWithinMicroTile
2989 *
2990 * @brief
2991 * Compute the pixel index inside a micro tile of surface
2992 *
2993 * @return
2994 * Pixel index
2995 *
2996 ****************************************************************************************************
2997 */
ComputePixelIndexWithinMicroTile(UINT_32 x,UINT_32 y,UINT_32 z,UINT_32 bpp,AddrTileMode tileMode,AddrTileType microTileType) const2998 UINT_32 Lib::ComputePixelIndexWithinMicroTile(
2999 UINT_32 x, ///< [in] x coord
3000 UINT_32 y, ///< [in] y coord
3001 UINT_32 z, ///< [in] slice/depth index
3002 UINT_32 bpp, ///< [in] bits per pixel
3003 AddrTileMode tileMode, ///< [in] tile mode
3004 AddrTileType microTileType ///< [in] pixel order in display/non-display mode
3005 ) const
3006 {
3007 UINT_32 pixelBit0 = 0;
3008 UINT_32 pixelBit1 = 0;
3009 UINT_32 pixelBit2 = 0;
3010 UINT_32 pixelBit3 = 0;
3011 UINT_32 pixelBit4 = 0;
3012 UINT_32 pixelBit5 = 0;
3013 UINT_32 pixelBit6 = 0;
3014 UINT_32 pixelBit7 = 0;
3015 UINT_32 pixelBit8 = 0;
3016 UINT_32 pixelNumber;
3017
3018 UINT_32 x0 = _BIT(x, 0);
3019 UINT_32 x1 = _BIT(x, 1);
3020 UINT_32 x2 = _BIT(x, 2);
3021 UINT_32 y0 = _BIT(y, 0);
3022 UINT_32 y1 = _BIT(y, 1);
3023 UINT_32 y2 = _BIT(y, 2);
3024 UINT_32 z0 = _BIT(z, 0);
3025 UINT_32 z1 = _BIT(z, 1);
3026 UINT_32 z2 = _BIT(z, 2);
3027
3028 UINT_32 thickness = Thickness(tileMode);
3029
3030 // Compute the pixel number within the micro tile.
3031
3032 if (microTileType != ADDR_THICK)
3033 {
3034 if (microTileType == ADDR_DISPLAYABLE)
3035 {
3036 switch (bpp)
3037 {
3038 case 8:
3039 pixelBit0 = x0;
3040 pixelBit1 = x1;
3041 pixelBit2 = x2;
3042 pixelBit3 = y1;
3043 pixelBit4 = y0;
3044 pixelBit5 = y2;
3045 break;
3046 case 16:
3047 pixelBit0 = x0;
3048 pixelBit1 = x1;
3049 pixelBit2 = x2;
3050 pixelBit3 = y0;
3051 pixelBit4 = y1;
3052 pixelBit5 = y2;
3053 break;
3054 case 32:
3055 pixelBit0 = x0;
3056 pixelBit1 = x1;
3057 pixelBit2 = y0;
3058 pixelBit3 = x2;
3059 pixelBit4 = y1;
3060 pixelBit5 = y2;
3061 break;
3062 case 64:
3063 pixelBit0 = x0;
3064 pixelBit1 = y0;
3065 pixelBit2 = x1;
3066 pixelBit3 = x2;
3067 pixelBit4 = y1;
3068 pixelBit5 = y2;
3069 break;
3070 case 128:
3071 pixelBit0 = y0;
3072 pixelBit1 = x0;
3073 pixelBit2 = x1;
3074 pixelBit3 = x2;
3075 pixelBit4 = y1;
3076 pixelBit5 = y2;
3077 break;
3078 default:
3079 ADDR_ASSERT_ALWAYS();
3080 break;
3081 }
3082 }
3083 else if (microTileType == ADDR_NON_DISPLAYABLE || microTileType == ADDR_DEPTH_SAMPLE_ORDER)
3084 {
3085 pixelBit0 = x0;
3086 pixelBit1 = y0;
3087 pixelBit2 = x1;
3088 pixelBit3 = y1;
3089 pixelBit4 = x2;
3090 pixelBit5 = y2;
3091 }
3092 else if (microTileType == ADDR_ROTATED)
3093 {
3094 ADDR_ASSERT(thickness == 1);
3095
3096 switch (bpp)
3097 {
3098 case 8:
3099 pixelBit0 = y0;
3100 pixelBit1 = y1;
3101 pixelBit2 = y2;
3102 pixelBit3 = x1;
3103 pixelBit4 = x0;
3104 pixelBit5 = x2;
3105 break;
3106 case 16:
3107 pixelBit0 = y0;
3108 pixelBit1 = y1;
3109 pixelBit2 = y2;
3110 pixelBit3 = x0;
3111 pixelBit4 = x1;
3112 pixelBit5 = x2;
3113 break;
3114 case 32:
3115 pixelBit0 = y0;
3116 pixelBit1 = y1;
3117 pixelBit2 = x0;
3118 pixelBit3 = y2;
3119 pixelBit4 = x1;
3120 pixelBit5 = x2;
3121 break;
3122 case 64:
3123 pixelBit0 = y0;
3124 pixelBit1 = x0;
3125 pixelBit2 = y1;
3126 pixelBit3 = x1;
3127 pixelBit4 = x2;
3128 pixelBit5 = y2;
3129 break;
3130 default:
3131 ADDR_ASSERT_ALWAYS();
3132 break;
3133 }
3134 }
3135
3136 if (thickness > 1)
3137 {
3138 pixelBit6 = z0;
3139 pixelBit7 = z1;
3140 }
3141 }
3142 else // ADDR_THICK
3143 {
3144 ADDR_ASSERT(thickness > 1);
3145
3146 switch (bpp)
3147 {
3148 case 8:
3149 case 16:
3150 pixelBit0 = x0;
3151 pixelBit1 = y0;
3152 pixelBit2 = x1;
3153 pixelBit3 = y1;
3154 pixelBit4 = z0;
3155 pixelBit5 = z1;
3156 break;
3157 case 32:
3158 pixelBit0 = x0;
3159 pixelBit1 = y0;
3160 pixelBit2 = x1;
3161 pixelBit3 = z0;
3162 pixelBit4 = y1;
3163 pixelBit5 = z1;
3164 break;
3165 case 64:
3166 case 128:
3167 pixelBit0 = x0;
3168 pixelBit1 = y0;
3169 pixelBit2 = z0;
3170 pixelBit3 = x1;
3171 pixelBit4 = y1;
3172 pixelBit5 = z1;
3173 break;
3174 default:
3175 ADDR_ASSERT_ALWAYS();
3176 break;
3177 }
3178
3179 pixelBit6 = x2;
3180 pixelBit7 = y2;
3181 }
3182
3183 if (thickness == 8)
3184 {
3185 pixelBit8 = z2;
3186 }
3187
3188 pixelNumber = ((pixelBit0 ) |
3189 (pixelBit1 << 1) |
3190 (pixelBit2 << 2) |
3191 (pixelBit3 << 3) |
3192 (pixelBit4 << 4) |
3193 (pixelBit5 << 5) |
3194 (pixelBit6 << 6) |
3195 (pixelBit7 << 7) |
3196 (pixelBit8 << 8));
3197
3198 return pixelNumber;
3199 }
3200
3201 /**
3202 ****************************************************************************************************
3203 * Lib::AdjustPitchAlignment
3204 *
3205 * @brief
3206 * Adjusts pitch alignment for flipping surface
3207 *
3208 * @return
3209 * N/A
3210 *
3211 ****************************************************************************************************
3212 */
AdjustPitchAlignment(ADDR_SURFACE_FLAGS flags,UINT_32 * pPitchAlign) const3213 VOID Lib::AdjustPitchAlignment(
3214 ADDR_SURFACE_FLAGS flags, ///< [in] Surface flags
3215 UINT_32* pPitchAlign ///< [out] Pointer to pitch alignment
3216 ) const
3217 {
3218 // Display engine hardwires lower 5 bit of GRPH_PITCH to ZERO which means 32 pixel alignment
3219 // Maybe it will be fixed in future but let's make it general for now.
3220 if (flags.display || flags.overlay)
3221 {
3222 *pPitchAlign = PowTwoAlign(*pPitchAlign, 32);
3223
3224 if(flags.display)
3225 {
3226 *pPitchAlign = Max(m_minPitchAlignPixels, *pPitchAlign);
3227 }
3228 }
3229 }
3230
3231 /**
3232 ****************************************************************************************************
3233 * Lib::PadDimensions
3234 *
3235 * @brief
3236 * Helper function to pad dimensions
3237 *
3238 * @return
3239 * N/A
3240 *
3241 ****************************************************************************************************
3242 */
PadDimensions(AddrTileMode tileMode,UINT_32 bpp,ADDR_SURFACE_FLAGS flags,UINT_32 numSamples,ADDR_TILEINFO * pTileInfo,UINT_32 padDims,UINT_32 mipLevel,UINT_32 * pPitch,UINT_32 * pPitchAlign,UINT_32 * pHeight,UINT_32 heightAlign,UINT_32 * pSlices,UINT_32 sliceAlign) const3243 VOID Lib::PadDimensions(
3244 AddrTileMode tileMode, ///< [in] tile mode
3245 UINT_32 bpp, ///< [in] bits per pixel
3246 ADDR_SURFACE_FLAGS flags, ///< [in] surface flags
3247 UINT_32 numSamples, ///< [in] number of samples
3248 ADDR_TILEINFO* pTileInfo, ///< [in,out] bank structure.
3249 UINT_32 padDims, ///< [in] Dimensions to pad valid value 1,2,3
3250 UINT_32 mipLevel, ///< [in] MipLevel
3251 UINT_32* pPitch, ///< [in,out] pitch in pixels
3252 UINT_32* pPitchAlign, ///< [in,out] pitch align could be changed in HwlPadDimensions
3253 UINT_32* pHeight, ///< [in,out] height in pixels
3254 UINT_32 heightAlign, ///< [in] height alignment
3255 UINT_32* pSlices, ///< [in,out] number of slices
3256 UINT_32 sliceAlign ///< [in] number of slice alignment
3257 ) const
3258 {
3259 UINT_32 pitchAlign = *pPitchAlign;
3260 UINT_32 thickness = Thickness(tileMode);
3261
3262 ADDR_ASSERT(padDims <= 3);
3263
3264 //
3265 // Override padding for mip levels
3266 //
3267 if (mipLevel > 0)
3268 {
3269 if (flags.cube)
3270 {
3271 // for cubemap, we only pad when client call with 6 faces as an identity
3272 if (*pSlices > 1)
3273 {
3274 padDims = 3; // we should pad cubemap sub levels when we treat it as 3d texture
3275 }
3276 else
3277 {
3278 padDims = 2;
3279 }
3280 }
3281 }
3282
3283 // Any possibilities that padDims is 0?
3284 if (padDims == 0)
3285 {
3286 padDims = 3;
3287 }
3288
3289 if (IsPow2(pitchAlign))
3290 {
3291 *pPitch = PowTwoAlign((*pPitch), pitchAlign);
3292 }
3293 else // add this code to pass unit test, r600 linear mode is not align bpp to pow2 for linear
3294 {
3295 *pPitch += pitchAlign - 1;
3296 *pPitch /= pitchAlign;
3297 *pPitch *= pitchAlign;
3298 }
3299
3300 if (padDims > 1)
3301 {
3302 if (IsPow2(heightAlign))
3303 {
3304 *pHeight = PowTwoAlign((*pHeight), heightAlign);
3305 }
3306 else
3307 {
3308 *pHeight += heightAlign - 1;
3309 *pHeight /= heightAlign;
3310 *pHeight *= heightAlign;
3311 }
3312 }
3313
3314 if (padDims > 2 || thickness > 1)
3315 {
3316 // for cubemap single face, we do not pad slices.
3317 // if we pad it, the slice number should be set to 6 and current mip level > 1
3318 if (flags.cube && (!m_configFlags.noCubeMipSlicesPad || flags.cubeAsArray))
3319 {
3320 *pSlices = NextPow2(*pSlices);
3321 }
3322
3323 // normal 3D texture or arrays or cubemap has a thick mode? (Just pass unit test)
3324 if (thickness > 1)
3325 {
3326 *pSlices = PowTwoAlign((*pSlices), sliceAlign);
3327 }
3328
3329 }
3330
3331 HwlPadDimensions(tileMode,
3332 bpp,
3333 flags,
3334 numSamples,
3335 pTileInfo,
3336 mipLevel,
3337 pPitch,
3338 pPitchAlign,
3339 *pHeight,
3340 heightAlign);
3341 }
3342
3343
3344 /**
3345 ****************************************************************************************************
3346 * Lib::HwlPreHandleBaseLvl3xPitch
3347 *
3348 * @brief
3349 * Pre-handler of 3x pitch (96 bit) adjustment
3350 *
3351 * @return
3352 * Expected pitch
3353 ****************************************************************************************************
3354 */
HwlPreHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const3355 UINT_32 Lib::HwlPreHandleBaseLvl3xPitch(
3356 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
3357 UINT_32 expPitch ///< [in] pitch
3358 ) const
3359 {
3360 ADDR_ASSERT(pIn->width == expPitch);
3361 //
3362 // If pitch is pre-multiplied by 3, we retrieve original one here to get correct miplevel size
3363 //
3364 if (ElemLib::IsExpand3x(pIn->format) &&
3365 pIn->mipLevel == 0 &&
3366 pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
3367 {
3368 expPitch /= 3;
3369 expPitch = NextPow2(expPitch);
3370 }
3371
3372 return expPitch;
3373 }
3374
3375 /**
3376 ****************************************************************************************************
3377 * Lib::HwlPostHandleBaseLvl3xPitch
3378 *
3379 * @brief
3380 * Post-handler of 3x pitch adjustment
3381 *
3382 * @return
3383 * Expected pitch
3384 ****************************************************************************************************
3385 */
HwlPostHandleBaseLvl3xPitch(const ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 expPitch) const3386 UINT_32 Lib::HwlPostHandleBaseLvl3xPitch(
3387 const ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input
3388 UINT_32 expPitch ///< [in] pitch
3389 ) const
3390 {
3391 //
3392 // 96 bits surface of sub levels require element pitch of 32 bits instead
3393 // So we just return pitch in 32 bit pixels without timing 3
3394 //
3395 if (ElemLib::IsExpand3x(pIn->format) &&
3396 pIn->mipLevel == 0 &&
3397 pIn->tileMode == ADDR_TM_LINEAR_ALIGNED)
3398 {
3399 expPitch *= 3;
3400 }
3401
3402 return expPitch;
3403 }
3404
3405
3406 /**
3407 ****************************************************************************************************
3408 * Lib::IsMacroTiled
3409 *
3410 * @brief
3411 * Check if the tile mode is macro tiled
3412 *
3413 * @return
3414 * TRUE if it is macro tiled (2D/2B/3D/3B)
3415 ****************************************************************************************************
3416 */
IsMacroTiled(AddrTileMode tileMode)3417 BOOL_32 Lib::IsMacroTiled(
3418 AddrTileMode tileMode) ///< [in] tile mode
3419 {
3420 return ModeFlags[tileMode].isMacro;
3421 }
3422
3423 /**
3424 ****************************************************************************************************
3425 * Lib::IsMacro3dTiled
3426 *
3427 * @brief
3428 * Check if the tile mode is 3D macro tiled
3429 *
3430 * @return
3431 * TRUE if it is 3D macro tiled
3432 ****************************************************************************************************
3433 */
IsMacro3dTiled(AddrTileMode tileMode)3434 BOOL_32 Lib::IsMacro3dTiled(
3435 AddrTileMode tileMode) ///< [in] tile mode
3436 {
3437 return ModeFlags[tileMode].isMacro3d;
3438 }
3439
3440 /**
3441 ****************************************************************************************************
3442 * Lib::IsMicroTiled
3443 *
3444 * @brief
3445 * Check if the tile mode is micro tiled
3446 *
3447 * @return
3448 * TRUE if micro tiled
3449 ****************************************************************************************************
3450 */
IsMicroTiled(AddrTileMode tileMode)3451 BOOL_32 Lib::IsMicroTiled(
3452 AddrTileMode tileMode) ///< [in] tile mode
3453 {
3454 return ModeFlags[tileMode].isMicro;
3455 }
3456
3457 /**
3458 ****************************************************************************************************
3459 * Lib::IsLinear
3460 *
3461 * @brief
3462 * Check if the tile mode is linear
3463 *
3464 * @return
3465 * TRUE if linear
3466 ****************************************************************************************************
3467 */
IsLinear(AddrTileMode tileMode)3468 BOOL_32 Lib::IsLinear(
3469 AddrTileMode tileMode) ///< [in] tile mode
3470 {
3471 return ModeFlags[tileMode].isLinear;
3472 }
3473
3474 /**
3475 ****************************************************************************************************
3476 * Lib::IsPrtNoRotationTileMode
3477 *
3478 * @brief
3479 * Return TRUE if it is prt tile without rotation
3480 * @note
3481 * This function just used by CI
3482 ****************************************************************************************************
3483 */
IsPrtNoRotationTileMode(AddrTileMode tileMode)3484 BOOL_32 Lib::IsPrtNoRotationTileMode(
3485 AddrTileMode tileMode)
3486 {
3487 return ModeFlags[tileMode].isPrtNoRotation;
3488 }
3489
3490 /**
3491 ****************************************************************************************************
3492 * Lib::IsPrtTileMode
3493 *
3494 * @brief
3495 * Return TRUE if it is prt tile
3496 * @note
3497 * This function just used by CI
3498 ****************************************************************************************************
3499 */
IsPrtTileMode(AddrTileMode tileMode)3500 BOOL_32 Lib::IsPrtTileMode(
3501 AddrTileMode tileMode)
3502 {
3503 return ModeFlags[tileMode].isPrt;
3504 }
3505
3506 /**
3507 ****************************************************************************************************
3508 * Lib::ComputeMipLevel
3509 *
3510 * @brief
3511 * Compute mipmap level width/height/slices
3512 * @return
3513 * N/A
3514 ****************************************************************************************************
3515 */
ComputeMipLevel(ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn) const3516 VOID Lib::ComputeMipLevel(
3517 ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in,out] Input structure
3518 ) const
3519 {
3520 // Check if HWL has handled
3521 BOOL_32 hwlHandled = FALSE;
3522
3523 if (ElemLib::IsBlockCompressed(pIn->format))
3524 {
3525 if (pIn->mipLevel == 0)
3526 {
3527 // DXTn's level 0 must be multiple of 4
3528 // But there are exceptions:
3529 // 1. Internal surface creation in hostblt/vsblt/etc...
3530 // 2. Runtime doesn't reject ATI1/ATI2 whose width/height are not multiple of 4
3531 pIn->width = PowTwoAlign(pIn->width, 4);
3532 pIn->height = PowTwoAlign(pIn->height, 4);
3533 }
3534 }
3535
3536 hwlHandled = HwlComputeMipLevel(pIn);
3537 }
3538
3539 /**
3540 ****************************************************************************************************
3541 * Lib::DegradeTo1D
3542 *
3543 * @brief
3544 * Check if surface can be degraded to 1D
3545 * @return
3546 * TRUE if degraded
3547 ****************************************************************************************************
3548 */
DegradeTo1D(UINT_32 width,UINT_32 height,UINT_32 macroTilePitchAlign,UINT_32 macroTileHeightAlign)3549 BOOL_32 Lib::DegradeTo1D(
3550 UINT_32 width, ///< surface width
3551 UINT_32 height, ///< surface height
3552 UINT_32 macroTilePitchAlign, ///< macro tile pitch align
3553 UINT_32 macroTileHeightAlign ///< macro tile height align
3554 )
3555 {
3556 BOOL_32 degrade = ((width < macroTilePitchAlign) || (height < macroTileHeightAlign));
3557
3558 // Check whether 2D tiling still has too much footprint
3559 if (degrade == FALSE)
3560 {
3561 // Only check width and height as slices are aligned to thickness
3562 UINT_64 unalignedSize = width * height;
3563
3564 UINT_32 alignedPitch = PowTwoAlign(width, macroTilePitchAlign);
3565 UINT_32 alignedHeight = PowTwoAlign(height, macroTileHeightAlign);
3566 UINT_64 alignedSize = alignedPitch * alignedHeight;
3567
3568 // alignedSize > 1.5 * unalignedSize
3569 if (2 * alignedSize > 3 * unalignedSize)
3570 {
3571 degrade = TRUE;
3572 }
3573 }
3574
3575 return degrade;
3576 }
3577
3578 /**
3579 ****************************************************************************************************
3580 * Lib::OptimizeTileMode
3581 *
3582 * @brief
3583 * Check if base level's tile mode can be optimized (degraded)
3584 * @return
3585 * N/A
3586 ****************************************************************************************************
3587 */
OptimizeTileMode(ADDR_COMPUTE_SURFACE_INFO_INPUT * pInOut) const3588 VOID Lib::OptimizeTileMode(
3589 ADDR_COMPUTE_SURFACE_INFO_INPUT* pInOut ///< [in, out] structure for surface info
3590 ) const
3591 {
3592 AddrTileMode tileMode = pInOut->tileMode;
3593
3594 BOOL_32 doOpt = (pInOut->flags.opt4Space == TRUE) ||
3595 (pInOut->flags.minimizeAlignment == TRUE) ||
3596 (pInOut->maxBaseAlign != 0);
3597
3598 BOOL_32 convertToPrt = FALSE;
3599
3600 // Optimization can only be done on level 0 and samples <= 1
3601 if ((doOpt == TRUE) &&
3602 (pInOut->mipLevel == 0) &&
3603 (IsPrtTileMode(tileMode) == FALSE) &&
3604 (pInOut->flags.prt == FALSE))
3605 {
3606 UINT_32 width = pInOut->width;
3607 UINT_32 height = pInOut->height;
3608 UINT_32 thickness = Thickness(tileMode);
3609 BOOL_32 macroTiledOK = TRUE;
3610 UINT_32 macroWidthAlign = 0;
3611 UINT_32 macroHeightAlign = 0;
3612 UINT_32 macroSizeAlign = 0;
3613
3614 if (IsMacroTiled(tileMode))
3615 {
3616 macroTiledOK = HwlGetAlignmentInfoMacroTiled(pInOut,
3617 ¯oWidthAlign,
3618 ¯oHeightAlign,
3619 ¯oSizeAlign);
3620 }
3621
3622 if (macroTiledOK)
3623 {
3624 if ((pInOut->flags.display == FALSE) &&
3625 (pInOut->flags.opt4Space == TRUE) &&
3626 (pInOut->numSamples <= 1))
3627 {
3628 // Check if linear mode is optimal
3629 if ((pInOut->height == 1) &&
3630 (IsLinear(tileMode) == FALSE) &&
3631 (ElemLib::IsBlockCompressed(pInOut->format) == FALSE) &&
3632 (pInOut->flags.depth == FALSE) &&
3633 (pInOut->flags.stencil == FALSE) &&
3634 (m_configFlags.disableLinearOpt == FALSE) &&
3635 (pInOut->flags.disableLinearOpt == FALSE))
3636 {
3637 tileMode = ADDR_TM_LINEAR_ALIGNED;
3638 }
3639 else if (IsMacroTiled(tileMode) && (pInOut->flags.tcCompatible == FALSE))
3640 {
3641 if (DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
3642 {
3643 tileMode = (thickness == 1) ?
3644 ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
3645 }
3646 else if ((thickness > 1) && (pInOut->flags.disallowLargeThickDegrade == 0))
3647 {
3648 // As in the following HwlComputeSurfaceInfo, thick modes may be degraded to
3649 // thinner modes, we should re-evaluate whether the corresponding
3650 // thinner modes should be degraded. If so, we choose 1D thick mode instead.
3651 tileMode = DegradeLargeThickTile(pInOut->tileMode, pInOut->bpp);
3652
3653 if (tileMode != pInOut->tileMode)
3654 {
3655 // Get thickness again after large thick degrade
3656 thickness = Thickness(tileMode);
3657
3658 ADDR_COMPUTE_SURFACE_INFO_INPUT input = *pInOut;
3659 input.tileMode = tileMode;
3660
3661 macroTiledOK = HwlGetAlignmentInfoMacroTiled(&input,
3662 ¯oWidthAlign,
3663 ¯oHeightAlign,
3664 ¯oSizeAlign);
3665
3666 if (macroTiledOK &&
3667 DegradeTo1D(width, height, macroWidthAlign, macroHeightAlign))
3668 {
3669 tileMode = ADDR_TM_1D_TILED_THICK;
3670 }
3671 }
3672 }
3673 }
3674 }
3675
3676 if (macroTiledOK)
3677 {
3678 if ((pInOut->flags.minimizeAlignment == TRUE) &&
3679 (pInOut->numSamples <= 1) &&
3680 (IsMacroTiled(tileMode) == TRUE))
3681 {
3682 UINT_32 macroSize = PowTwoAlign(width, macroWidthAlign) *
3683 PowTwoAlign(height, macroHeightAlign);
3684 UINT_32 microSize = PowTwoAlign(width, MicroTileWidth) *
3685 PowTwoAlign(height, MicroTileHeight);
3686
3687 if (macroSize > microSize)
3688 {
3689 tileMode = (thickness == 1) ?
3690 ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
3691 }
3692 }
3693
3694 if ((pInOut->maxBaseAlign != 0) &&
3695 (IsMacroTiled(tileMode) == TRUE))
3696 {
3697 if (macroSizeAlign > pInOut->maxBaseAlign)
3698 {
3699 if (pInOut->numSamples > 1)
3700 {
3701 ADDR_ASSERT(pInOut->maxBaseAlign >= Block64K);
3702
3703 convertToPrt = TRUE;
3704 }
3705 else if (pInOut->maxBaseAlign < Block64K)
3706 {
3707 tileMode = (thickness == 1) ?
3708 ADDR_TM_1D_TILED_THIN1 : ADDR_TM_1D_TILED_THICK;
3709 }
3710 else
3711 {
3712 convertToPrt = TRUE;
3713 }
3714 }
3715 }
3716 }
3717 }
3718 }
3719
3720 if (convertToPrt)
3721 {
3722 if ((pInOut->flags.matchStencilTileCfg == TRUE) && (pInOut->numSamples <= 1))
3723 {
3724 pInOut->tileMode = ADDR_TM_1D_TILED_THIN1;
3725 }
3726 else
3727 {
3728 HwlSetPrtTileMode(pInOut);
3729 }
3730 }
3731 else if (tileMode != pInOut->tileMode)
3732 {
3733 pInOut->tileMode = tileMode;
3734 }
3735
3736 HwlOptimizeTileMode(pInOut);
3737 }
3738
3739 /**
3740 ****************************************************************************************************
3741 * Lib::DegradeLargeThickTile
3742 *
3743 * @brief
3744 * Check if the thickness needs to be reduced if a tile is too large
3745 * @return
3746 * The degraded tile mode (unchanged if not degraded)
3747 ****************************************************************************************************
3748 */
DegradeLargeThickTile(AddrTileMode tileMode,UINT_32 bpp) const3749 AddrTileMode Lib::DegradeLargeThickTile(
3750 AddrTileMode tileMode,
3751 UINT_32 bpp) const
3752 {
3753 // Override tilemode
3754 // When tile_width (8) * tile_height (8) * thickness * element_bytes is > row_size,
3755 // it is better to just use THIN mode in this case
3756 UINT_32 thickness = Thickness(tileMode);
3757
3758 if (thickness > 1 && m_configFlags.allowLargeThickTile == 0)
3759 {
3760 UINT_32 tileSize = MicroTilePixels * thickness * (bpp >> 3);
3761
3762 if (tileSize > m_rowSize)
3763 {
3764 switch (tileMode)
3765 {
3766 case ADDR_TM_2D_TILED_XTHICK:
3767 if ((tileSize >> 1) <= m_rowSize)
3768 {
3769 tileMode = ADDR_TM_2D_TILED_THICK;
3770 break;
3771 }
3772 // else fall through
3773 case ADDR_TM_2D_TILED_THICK:
3774 tileMode = ADDR_TM_2D_TILED_THIN1;
3775 break;
3776
3777 case ADDR_TM_3D_TILED_XTHICK:
3778 if ((tileSize >> 1) <= m_rowSize)
3779 {
3780 tileMode = ADDR_TM_3D_TILED_THICK;
3781 break;
3782 }
3783 // else fall through
3784 case ADDR_TM_3D_TILED_THICK:
3785 tileMode = ADDR_TM_3D_TILED_THIN1;
3786 break;
3787
3788 case ADDR_TM_PRT_TILED_THICK:
3789 tileMode = ADDR_TM_PRT_TILED_THIN1;
3790 break;
3791
3792 case ADDR_TM_PRT_2D_TILED_THICK:
3793 tileMode = ADDR_TM_PRT_2D_TILED_THIN1;
3794 break;
3795
3796 case ADDR_TM_PRT_3D_TILED_THICK:
3797 tileMode = ADDR_TM_PRT_3D_TILED_THIN1;
3798 break;
3799
3800 default:
3801 break;
3802 }
3803 }
3804 }
3805
3806 return tileMode;
3807 }
3808
3809 /**
3810 ****************************************************************************************************
3811 * Lib::PostComputeMipLevel
3812 * @brief
3813 * Compute MipLevel info (including level 0) after surface adjustment
3814 * @return
3815 * ADDR_E_RETURNCODE
3816 ****************************************************************************************************
3817 */
PostComputeMipLevel(ADDR_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const3818 ADDR_E_RETURNCODE Lib::PostComputeMipLevel(
3819 ADDR_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in,out] Input structure
3820 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] Output structure
3821 ) const
3822 {
3823 // Mipmap including level 0 must be pow2 padded since either SI hw expects so or it is
3824 // required by CFX for Hw Compatibility between NI and SI. Otherwise it is only needed for
3825 // mipLevel > 0. Any h/w has different requirement should implement its own virtual function
3826
3827 if (pIn->flags.pow2Pad)
3828 {
3829 pIn->width = NextPow2(pIn->width);
3830 pIn->height = NextPow2(pIn->height);
3831 pIn->numSlices = NextPow2(pIn->numSlices);
3832 }
3833 else if (pIn->mipLevel > 0)
3834 {
3835 pIn->width = NextPow2(pIn->width);
3836 pIn->height = NextPow2(pIn->height);
3837
3838 if (!pIn->flags.cube)
3839 {
3840 pIn->numSlices = NextPow2(pIn->numSlices);
3841 }
3842
3843 // for cubemap, we keep its value at first
3844 }
3845
3846 return ADDR_OK;
3847 }
3848
3849 /**
3850 ****************************************************************************************************
3851 * Lib::HwlSetupTileCfg
3852 *
3853 * @brief
3854 * Map tile index to tile setting.
3855 * @return
3856 * ADDR_E_RETURNCODE
3857 ****************************************************************************************************
3858 */
HwlSetupTileCfg(UINT_32 bpp,INT_32 index,INT_32 macroModeIndex,ADDR_TILEINFO * pInfo,AddrTileMode * pMode,AddrTileType * pType) const3859 ADDR_E_RETURNCODE Lib::HwlSetupTileCfg(
3860 UINT_32 bpp, ///< Bits per pixel
3861 INT_32 index, ///< [in] Tile index
3862 INT_32 macroModeIndex, ///< [in] Index in macro tile mode table(CI)
3863 ADDR_TILEINFO* pInfo, ///< [out] Tile Info
3864 AddrTileMode* pMode, ///< [out] Tile mode
3865 AddrTileType* pType ///< [out] Tile type
3866 ) const
3867 {
3868 return ADDR_NOTSUPPORTED;
3869 }
3870
3871 /**
3872 ****************************************************************************************************
3873 * Lib::HwlGetPipes
3874 *
3875 * @brief
3876 * Get number pipes
3877 * @return
3878 * num pipes
3879 ****************************************************************************************************
3880 */
HwlGetPipes(const ADDR_TILEINFO * pTileInfo) const3881 UINT_32 Lib::HwlGetPipes(
3882 const ADDR_TILEINFO* pTileInfo ///< [in] Tile info
3883 ) const
3884 {
3885 //pTileInfo can be NULL when asic is 6xx and 8xx.
3886 return m_pipes;
3887 }
3888
3889 /**
3890 ****************************************************************************************************
3891 * Lib::ComputeQbStereoInfo
3892 *
3893 * @brief
3894 * Get quad buffer stereo information
3895 * @return
3896 * N/A
3897 ****************************************************************************************************
3898 */
ComputeQbStereoInfo(ADDR_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const3899 VOID Lib::ComputeQbStereoInfo(
3900 ADDR_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] updated pOut+pStereoInfo
3901 ) const
3902 {
3903 ADDR_ASSERT(pOut->bpp >= 8);
3904 ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
3905
3906 // Save original height
3907 pOut->pStereoInfo->eyeHeight = pOut->height;
3908
3909 // Right offset
3910 pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
3911
3912 pOut->pStereoInfo->rightSwizzle = HwlComputeQbStereoRightSwizzle(pOut);
3913 // Double height
3914 pOut->height <<= 1;
3915 pOut->pixelHeight <<= 1;
3916
3917 // Double size
3918 pOut->surfSize <<= 1;
3919
3920 // Right start address meets the base align since it is guaranteed by AddrLib1
3921
3922 // 1D surface on SI may break this rule, but we can force it to meet by checking .qbStereo.
3923 }
3924
3925
3926 /**
3927 ****************************************************************************************************
3928 * Lib::ComputePrtInfo
3929 *
3930 * @brief
3931 * Compute prt surface related info
3932 *
3933 * @return
3934 * ADDR_E_RETURNCODE
3935 ****************************************************************************************************
3936 */
ComputePrtInfo(const ADDR_PRT_INFO_INPUT * pIn,ADDR_PRT_INFO_OUTPUT * pOut) const3937 ADDR_E_RETURNCODE Lib::ComputePrtInfo(
3938 const ADDR_PRT_INFO_INPUT* pIn,
3939 ADDR_PRT_INFO_OUTPUT* pOut) const
3940 {
3941 ADDR_ASSERT(pOut != NULL);
3942
3943 ADDR_E_RETURNCODE returnCode = ADDR_OK;
3944
3945 UINT_32 expandX = 1;
3946 UINT_32 expandY = 1;
3947 ElemMode elemMode;
3948
3949 UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
3950 &elemMode,
3951 &expandX,
3952 &expandY);
3953
3954 if (bpp <8 || bpp == 24 || bpp == 48 || bpp == 96)
3955 {
3956 returnCode = ADDR_INVALIDPARAMS;
3957 }
3958
3959 UINT_32 numFrags = pIn->numFrags;
3960 ADDR_ASSERT(numFrags <= 8);
3961
3962 UINT_32 tileWidth = 0;
3963 UINT_32 tileHeight = 0;
3964 if (returnCode == ADDR_OK)
3965 {
3966 // 3D texture without depth or 2d texture
3967 if (pIn->baseMipDepth > 1 || pIn->baseMipHeight > 1)
3968 {
3969 if (bpp == 8)
3970 {
3971 tileWidth = 256;
3972 tileHeight = 256;
3973 }
3974 else if (bpp == 16)
3975 {
3976 tileWidth = 256;
3977 tileHeight = 128;
3978 }
3979 else if (bpp == 32)
3980 {
3981 tileWidth = 128;
3982 tileHeight = 128;
3983 }
3984 else if (bpp == 64)
3985 {
3986 // assume it is BC1/4
3987 tileWidth = 512;
3988 tileHeight = 256;
3989
3990 if (elemMode == ADDR_UNCOMPRESSED)
3991 {
3992 tileWidth = 128;
3993 tileHeight = 64;
3994 }
3995 }
3996 else if (bpp == 128)
3997 {
3998 // assume it is BC2/3/5/6H/7
3999 tileWidth = 256;
4000 tileHeight = 256;
4001
4002 if (elemMode == ADDR_UNCOMPRESSED)
4003 {
4004 tileWidth = 64;
4005 tileHeight = 64;
4006 }
4007 }
4008
4009 if (numFrags == 2)
4010 {
4011 tileWidth = tileWidth / 2;
4012 }
4013 else if (numFrags == 4)
4014 {
4015 tileWidth = tileWidth / 2;
4016 tileHeight = tileHeight / 2;
4017 }
4018 else if (numFrags == 8)
4019 {
4020 tileWidth = tileWidth / 4;
4021 tileHeight = tileHeight / 2;
4022 }
4023 }
4024 else // 1d
4025 {
4026 tileHeight = 1;
4027 if (bpp == 8)
4028 {
4029 tileWidth = 65536;
4030 }
4031 else if (bpp == 16)
4032 {
4033 tileWidth = 32768;
4034 }
4035 else if (bpp == 32)
4036 {
4037 tileWidth = 16384;
4038 }
4039 else if (bpp == 64)
4040 {
4041 tileWidth = 8192;
4042 }
4043 else if (bpp == 128)
4044 {
4045 tileWidth = 4096;
4046 }
4047 }
4048 }
4049
4050 pOut->prtTileWidth = tileWidth;
4051 pOut->prtTileHeight = tileHeight;
4052
4053 return returnCode;
4054 }
4055
4056 } // V1
4057 } // Addr
4058