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