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