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