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