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