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