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