amd/addrlib: update Mesa's copy of addrlib
[mesa.git] / src / amd / addrlib / src / core / addrlib2.cpp
1 /*
2 * Copyright © 2007-2018 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 */
26
27 /**
28 ************************************************************************************************************************
29 * @file addrlib2.cpp
30 * @brief Contains the implementation for the AddrLib2 base class.
31 ************************************************************************************************************************
32 */
33
34 #include "addrinterface.h"
35 #include "addrlib2.h"
36 #include "addrcommon.h"
37
38 namespace Addr
39 {
40 namespace V2
41 {
42
43 ////////////////////////////////////////////////////////////////////////////////////////////////////
44 // Static Const Member
45 ////////////////////////////////////////////////////////////////////////////////////////////////////
46
47 const Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
48
49 const Dim3d Lib::Block1K_3d[] = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};
50
51 ////////////////////////////////////////////////////////////////////////////////////////////////////
52 // Constructor/Destructor
53 ////////////////////////////////////////////////////////////////////////////////////////////////////
54
55 /**
56 ************************************************************************************************************************
57 * Lib::Lib
58 *
59 * @brief
60 * Constructor for the Addr::V2::Lib class
61 *
62 ************************************************************************************************************************
63 */
64 Lib::Lib()
65 :
66 Addr::Lib()
67 {
68 }
69
70 /**
71 ************************************************************************************************************************
72 * Lib::Lib
73 *
74 * @brief
75 * Constructor for the AddrLib2 class with hClient as parameter
76 *
77 ************************************************************************************************************************
78 */
79 Lib::Lib(const Client* pClient)
80 :
81 Addr::Lib(pClient)
82 {
83 }
84
85 /**
86 ************************************************************************************************************************
87 * Lib::~Lib
88 *
89 * @brief
90 * Destructor for the AddrLib2 class
91 *
92 ************************************************************************************************************************
93 */
94 Lib::~Lib()
95 {
96 }
97
98 /**
99 ************************************************************************************************************************
100 * Lib::GetLib
101 *
102 * @brief
103 * Get Addr::V2::Lib pointer
104 *
105 * @return
106 * An Addr::V2::Lib class pointer
107 ************************************************************************************************************************
108 */
109 Lib* Lib::GetLib(
110 ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE
111 {
112 Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);
113 if ((pAddrLib != NULL) &&
114 (pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI))
115 {
116 // only valid and GFX9+ ASIC can use AddrLib2 function.
117 ADDR_ASSERT_ALWAYS();
118 hLib = NULL;
119 }
120 return static_cast<Lib*>(hLib);
121 }
122
123 ////////////////////////////////////////////////////////////////////////////////////////////////////
124 // Surface Methods
125 ////////////////////////////////////////////////////////////////////////////////////////////////////
126
127 /**
128 ************************************************************************************************************************
129 * Lib::ComputeSurfaceInfo
130 *
131 * @brief
132 * Interface function stub of AddrComputeSurfaceInfo.
133 *
134 * @return
135 * ADDR_E_RETURNCODE
136 ************************************************************************************************************************
137 */
138 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
139 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
140 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
141 ) const
142 {
143 ADDR_E_RETURNCODE returnCode = ADDR_OK;
144
145 if (GetFillSizeFieldsFlags() == TRUE)
146 {
147 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) ||
148 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT)))
149 {
150 returnCode = ADDR_PARAMSIZEMISMATCH;
151 }
152 }
153
154 // Adjust coming parameters.
155 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
156 localIn.width = Max(pIn->width, 1u);
157 localIn.height = Max(pIn->height, 1u);
158 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
159 localIn.numSlices = Max(pIn->numSlices, 1u);
160 localIn.numSamples = Max(pIn->numSamples, 1u);
161 localIn.numFrags = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags;
162
163 UINT_32 expandX = 1;
164 UINT_32 expandY = 1;
165 ElemMode elemMode = ADDR_UNCOMPRESSED;
166
167 if (returnCode == ADDR_OK)
168 {
169 // Set format to INVALID will skip this conversion
170 if (localIn.format != ADDR_FMT_INVALID)
171 {
172 // Get compression/expansion factors and element mode which indicates compression/expansion
173 localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
174 &elemMode,
175 &expandX,
176 &expandY);
177
178 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
179 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
180 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
181 // restrictions are different.
182 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
183 // but we use this flag to skip RestoreSurfaceInfo below
184
185 if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
186 {
187 ADDR_ASSERT(IsLinear(localIn.swizzleMode));
188 }
189
190 UINT_32 basePitch = 0;
191 GetElemLib()->AdjustSurfaceInfo(elemMode,
192 expandX,
193 expandY,
194 &localIn.bpp,
195 &basePitch,
196 &localIn.width,
197 &localIn.height);
198
199 // Overwrite these parameters if we have a valid format
200 }
201
202 if (localIn.bpp != 0)
203 {
204 localIn.width = Max(localIn.width, 1u);
205 localIn.height = Max(localIn.height, 1u);
206 }
207 else // Rule out some invalid parameters
208 {
209 ADDR_ASSERT_ALWAYS();
210
211 returnCode = ADDR_INVALIDPARAMS;
212 }
213 }
214
215 if (returnCode == ADDR_OK)
216 {
217 returnCode = ComputeSurfaceInfoSanityCheck(&localIn);
218 }
219
220 if (returnCode == ADDR_OK)
221 {
222 VerifyMipLevelInfo(pIn);
223
224 if (IsLinear(pIn->swizzleMode))
225 {
226 // linear mode
227 returnCode = ComputeSurfaceInfoLinear(&localIn, pOut);
228 }
229 else
230 {
231 // tiled mode
232 returnCode = ComputeSurfaceInfoTiled(&localIn, pOut);
233 }
234
235 if (returnCode == ADDR_OK)
236 {
237 pOut->bpp = localIn.bpp;
238 pOut->pixelPitch = pOut->pitch;
239 pOut->pixelHeight = pOut->height;
240 pOut->pixelMipChainPitch = pOut->mipChainPitch;
241 pOut->pixelMipChainHeight = pOut->mipChainHeight;
242 pOut->pixelBits = localIn.bpp;
243
244 if (localIn.format != ADDR_FMT_INVALID)
245 {
246 UINT_32 pixelBits = pOut->pixelBits;
247
248 GetElemLib()->RestoreSurfaceInfo(elemMode,
249 expandX,
250 expandY,
251 &pOut->pixelBits,
252 &pOut->pixelPitch,
253 &pOut->pixelHeight);
254
255 GetElemLib()->RestoreSurfaceInfo(elemMode,
256 expandX,
257 expandY,
258 &pixelBits,
259 &pOut->pixelMipChainPitch,
260 &pOut->pixelMipChainHeight);
261
262 if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL))
263 {
264 for (UINT_32 i = 0; i < localIn.numMipLevels; i++)
265 {
266 pOut->pMipInfo[i].pixelPitch = pOut->pMipInfo[i].pitch;
267 pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height;
268
269 GetElemLib()->RestoreSurfaceInfo(elemMode,
270 expandX,
271 expandY,
272 &pixelBits,
273 &pOut->pMipInfo[i].pixelPitch,
274 &pOut->pMipInfo[i].pixelHeight);
275 }
276 }
277 }
278
279 if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0))
280 {
281 pOut->equationIndex = GetEquationIndex(&localIn, pOut);
282 }
283
284 if (localIn.flags.qbStereo)
285 {
286 if (pOut->pStereoInfo != NULL)
287 {
288 ComputeQbStereoInfo(pOut);
289 }
290 }
291 }
292 }
293
294 ADDR_ASSERT(pOut->surfSize != 0);
295
296 ValidBaseAlignments(pOut->baseAlign);
297
298 return returnCode;
299 }
300
301 /**
302 ************************************************************************************************************************
303 * Lib::ComputeSurfaceInfo
304 *
305 * @brief
306 * Interface function stub of AddrComputeSurfaceInfo.
307 *
308 * @return
309 * ADDR_E_RETURNCODE
310 ************************************************************************************************************************
311 */
312 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(
313 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
314 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
315 ) const
316 {
317 ADDR_E_RETURNCODE returnCode = ADDR_OK;
318
319 if (GetFillSizeFieldsFlags() == TRUE)
320 {
321 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
322 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
323 {
324 returnCode = ADDR_PARAMSIZEMISMATCH;
325 }
326 }
327
328 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn;
329 localIn.unalignedWidth = Max(pIn->unalignedWidth, 1u);
330 localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u);
331 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
332 localIn.numSlices = Max(pIn->numSlices, 1u);
333 localIn.numSamples = Max(pIn->numSamples, 1u);
334 localIn.numFrags = Max(pIn->numFrags, 1u);
335
336 if ((localIn.bpp < 8) ||
337 (localIn.bpp > 128) ||
338 ((localIn.bpp % 8) != 0) ||
339 (localIn.sample >= localIn.numSamples) ||
340 (localIn.slice >= localIn.numSlices) ||
341 (localIn.mipId >= localIn.numMipLevels) ||
342 (IsTex3d(localIn.resourceType) &&
343 (Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE)))
344 {
345 returnCode = ADDR_INVALIDPARAMS;
346 }
347
348 if (returnCode == ADDR_OK)
349 {
350 if (IsLinear(localIn.swizzleMode))
351 {
352 returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut);
353 }
354 else
355 {
356 returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut);
357 }
358
359 if (returnCode == ADDR_OK)
360 {
361 pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
362 }
363 }
364
365 return returnCode;
366 }
367
368 /**
369 ************************************************************************************************************************
370 * Lib::ComputeSurfaceCoordFromAddr
371 *
372 * @brief
373 * Interface function stub of ComputeSurfaceCoordFromAddr.
374 *
375 * @return
376 * ADDR_E_RETURNCODE
377 ************************************************************************************************************************
378 */
379 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(
380 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
381 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
382 ) const
383 {
384 ADDR_E_RETURNCODE returnCode = ADDR_OK;
385
386 if (GetFillSizeFieldsFlags() == TRUE)
387 {
388 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
389 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
390 {
391 returnCode = ADDR_PARAMSIZEMISMATCH;
392 }
393 }
394
395 if ((pIn->bpp < 8) ||
396 (pIn->bpp > 128) ||
397 ((pIn->bpp % 8) != 0) ||
398 (pIn->bitPosition >= 8))
399 {
400 returnCode = ADDR_INVALIDPARAMS;
401 }
402
403 if (returnCode == ADDR_OK)
404 {
405 if (IsLinear(pIn->swizzleMode))
406 {
407 returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut);
408 }
409 else
410 {
411 returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut);
412 }
413 }
414
415 return returnCode;
416 }
417
418 ////////////////////////////////////////////////////////////////////////////////////////////////////
419 // CMASK/HTILE
420 ////////////////////////////////////////////////////////////////////////////////////////////////////
421
422 /**
423 ************************************************************************************************************************
424 * Lib::ComputeHtileInfo
425 *
426 * @brief
427 * Interface function stub of AddrComputeHtilenfo
428 *
429 * @return
430 * ADDR_E_RETURNCODE
431 ************************************************************************************************************************
432 */
433 ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
434 const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure
435 ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure
436 ) const
437 {
438 ADDR_E_RETURNCODE returnCode;
439
440 if ((GetFillSizeFieldsFlags() == TRUE) &&
441 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) ||
442 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT))))
443 {
444 returnCode = ADDR_INVALIDPARAMS;
445 }
446 else
447 {
448 returnCode = HwlComputeHtileInfo(pIn, pOut);
449
450 ValidMetaBaseAlignments(pOut->baseAlign);
451 }
452
453 return returnCode;
454 }
455
456 /**
457 ************************************************************************************************************************
458 * Lib::ComputeHtileAddrFromCoord
459 *
460 * @brief
461 * Interface function stub of AddrComputeHtileAddrFromCoord
462 *
463 * @return
464 * ADDR_E_RETURNCODE
465 ************************************************************************************************************************
466 */
467 ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(
468 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
469 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
470 {
471 ADDR_E_RETURNCODE returnCode;
472
473 if ((GetFillSizeFieldsFlags() == TRUE) &&
474 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
475 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))))
476 {
477 returnCode = ADDR_INVALIDPARAMS;
478 }
479 else
480 {
481 returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut);
482 }
483
484 return returnCode;
485 }
486
487 /**
488 ************************************************************************************************************************
489 * Lib::ComputeHtileCoordFromAddr
490 *
491 * @brief
492 * Interface function stub of AddrComputeHtileCoordFromAddr
493 *
494 * @return
495 * ADDR_E_RETURNCODE
496 ************************************************************************************************************************
497 */
498 ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(
499 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
500 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) ///< [out] output structure
501 {
502 ADDR_E_RETURNCODE returnCode;
503
504 if ((GetFillSizeFieldsFlags() == TRUE) &&
505 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
506 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))))
507 {
508 returnCode = ADDR_INVALIDPARAMS;
509 }
510 else
511 {
512 returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut);
513 }
514
515 return returnCode;
516 }
517
518 /**
519 ************************************************************************************************************************
520 * Lib::ComputeCmaskInfo
521 *
522 * @brief
523 * Interface function stub of AddrComputeCmaskInfo
524 *
525 * @return
526 * ADDR_E_RETURNCODE
527 ************************************************************************************************************************
528 */
529 ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
530 const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure
531 ADDR2_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure
532 ) const
533 {
534 ADDR_E_RETURNCODE returnCode;
535
536 if ((GetFillSizeFieldsFlags() == TRUE) &&
537 ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) ||
538 (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT))))
539 {
540 returnCode = ADDR_INVALIDPARAMS;
541 }
542 else if (pIn->cMaskFlags.linear)
543 {
544 returnCode = ADDR_INVALIDPARAMS;
545 }
546 else
547 {
548 returnCode = HwlComputeCmaskInfo(pIn, pOut);
549
550 ValidMetaBaseAlignments(pOut->baseAlign);
551 }
552
553 return returnCode;
554 }
555
556 /**
557 ************************************************************************************************************************
558 * Lib::ComputeCmaskAddrFromCoord
559 *
560 * @brief
561 * Interface function stub of AddrComputeCmaskAddrFromCoord
562 *
563 * @return
564 * ADDR_E_RETURNCODE
565 ************************************************************************************************************************
566 */
567 ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(
568 const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
569 ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
570 {
571 ADDR_E_RETURNCODE returnCode;
572
573 if ((GetFillSizeFieldsFlags() == TRUE) &&
574 ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
575 (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))))
576 {
577 returnCode = ADDR_INVALIDPARAMS;
578 }
579 else
580 {
581 returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
582 }
583
584 return returnCode;
585 }
586
587 /**
588 ************************************************************************************************************************
589 * Lib::ComputeCmaskCoordFromAddr
590 *
591 * @brief
592 * Interface function stub of AddrComputeCmaskCoordFromAddr
593 *
594 * @return
595 * ADDR_E_RETURNCODE
596 ************************************************************************************************************************
597 */
598 ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(
599 const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
600 ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
601 ) const
602 {
603 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
604
605 ADDR_NOT_IMPLEMENTED();
606
607 return returnCode;
608 }
609
610 /**
611 ************************************************************************************************************************
612 * Lib::ComputeFmaskInfo
613 *
614 * @brief
615 * Interface function stub of ComputeFmaskInfo.
616 *
617 * @return
618 * ADDR_E_RETURNCODE
619 ************************************************************************************************************************
620 */
621 ADDR_E_RETURNCODE Lib::ComputeFmaskInfo(
622 const ADDR2_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
623 ADDR2_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
624 )
625 {
626 ADDR_E_RETURNCODE returnCode;
627
628 BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) &&
629 ((pIn->numSamples > 0) || (pIn->numFrags > 0));
630
631 if (GetFillSizeFieldsFlags())
632 {
633 if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) ||
634 (pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT)))
635 {
636 valid = FALSE;
637 }
638 }
639
640 if (valid == FALSE)
641 {
642 returnCode = ADDR_INVALIDPARAMS;
643 }
644 else
645 {
646 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
647 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
648
649 localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);
650 localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);
651
652 localIn.swizzleMode = pIn->swizzleMode;
653 localIn.numSlices = Max(pIn->numSlices, 1u);
654 localIn.width = Max(pIn->unalignedWidth, 1u);
655 localIn.height = Max(pIn->unalignedHeight, 1u);
656 localIn.bpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags);
657 localIn.flags.fmask = 1;
658 localIn.numFrags = 1;
659 localIn.numSamples = 1;
660 localIn.resourceType = ADDR_RSRC_TEX_2D;
661
662 if (localIn.bpp == 8)
663 {
664 localIn.format = ADDR_FMT_8;
665 }
666 else if (localIn.bpp == 16)
667 {
668 localIn.format = ADDR_FMT_16;
669 }
670 else if (localIn.bpp == 32)
671 {
672 localIn.format = ADDR_FMT_32;
673 }
674 else
675 {
676 localIn.format = ADDR_FMT_32_32;
677 }
678
679 returnCode = ComputeSurfaceInfo(&localIn, &localOut);
680
681 if (returnCode == ADDR_OK)
682 {
683 pOut->pitch = localOut.pitch;
684 pOut->height = localOut.height;
685 pOut->baseAlign = localOut.baseAlign;
686 pOut->numSlices = localOut.numSlices;
687 pOut->fmaskBytes = static_cast<UINT_32>(localOut.surfSize);
688 pOut->sliceSize = static_cast<UINT_32>(localOut.sliceSize);
689 pOut->bpp = localIn.bpp;
690 pOut->numSamples = 1;
691 }
692 }
693
694 ValidBaseAlignments(pOut->baseAlign);
695
696 return returnCode;
697 }
698
699 /**
700 ************************************************************************************************************************
701 * Lib::ComputeFmaskAddrFromCoord
702 *
703 * @brief
704 * Interface function stub of ComputeFmaskAddrFromCoord.
705 *
706 * @return
707 * ADDR_E_RETURNCODE
708 ************************************************************************************************************************
709 */
710 ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(
711 const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
712 ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
713 ) const
714 {
715 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
716
717 ADDR_NOT_IMPLEMENTED();
718
719 return returnCode;
720 }
721
722 /**
723 ************************************************************************************************************************
724 * Lib::ComputeFmaskCoordFromAddr
725 *
726 * @brief
727 * Interface function stub of ComputeFmaskAddrFromCoord.
728 *
729 * @return
730 * ADDR_E_RETURNCODE
731 ************************************************************************************************************************
732 */
733 ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(
734 const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
735 ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
736 ) const
737 {
738 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
739
740 ADDR_NOT_IMPLEMENTED();
741
742 return returnCode;
743 }
744
745 /**
746 ************************************************************************************************************************
747 * Lib::ComputeDccInfo
748 *
749 * @brief
750 * Interface function to compute DCC key info
751 *
752 * @return
753 * return code of HwlComputeDccInfo
754 ************************************************************************************************************************
755 */
756 ADDR_E_RETURNCODE Lib::ComputeDccInfo(
757 const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure
758 ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure
759 ) const
760 {
761 ADDR_E_RETURNCODE returnCode;
762
763 if ((GetFillSizeFieldsFlags() == TRUE) &&
764 ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) ||
765 (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT))))
766 {
767 returnCode = ADDR_INVALIDPARAMS;
768 }
769 else
770 {
771 returnCode = HwlComputeDccInfo(pIn, pOut);
772
773 ValidMetaBaseAlignments(pOut->dccRamBaseAlign);
774 }
775
776 return returnCode;
777 }
778
779 /**
780 ************************************************************************************************************************
781 * Lib::ComputeDccAddrFromCoord
782 *
783 * @brief
784 * Interface function stub of ComputeDccAddrFromCoord
785 *
786 * @return
787 * ADDR_E_RETURNCODE
788 ************************************************************************************************************************
789 */
790 ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord(
791 const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
792 ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
793 {
794 ADDR_E_RETURNCODE returnCode;
795
796 if ((GetFillSizeFieldsFlags() == TRUE) &&
797 ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) ||
798 (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT))))
799 {
800 returnCode = ADDR_INVALIDPARAMS;
801 }
802 else
803 {
804 returnCode = HwlComputeDccAddrFromCoord(pIn, pOut);
805 }
806
807 return returnCode;
808 }
809
810 /**
811 ************************************************************************************************************************
812 * Lib::ComputePipeBankXor
813 *
814 * @brief
815 * Interface function stub of Addr2ComputePipeBankXor.
816 *
817 * @return
818 * ADDR_E_RETURNCODE
819 ************************************************************************************************************************
820 */
821 ADDR_E_RETURNCODE Lib::ComputePipeBankXor(
822 const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,
823 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut)
824 {
825 ADDR_E_RETURNCODE returnCode;
826
827 if ((GetFillSizeFieldsFlags() == TRUE) &&
828 ((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) ||
829 (pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT))))
830 {
831 returnCode = ADDR_INVALIDPARAMS;
832 }
833 else
834 {
835 returnCode = HwlComputePipeBankXor(pIn, pOut);
836 }
837
838 return returnCode;
839 }
840
841 /**
842 ************************************************************************************************************************
843 * Lib::ComputeSlicePipeBankXor
844 *
845 * @brief
846 * Interface function stub of Addr2ComputeSlicePipeBankXor.
847 *
848 * @return
849 * ADDR_E_RETURNCODE
850 ************************************************************************************************************************
851 */
852 ADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor(
853 const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,
854 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut)
855 {
856 ADDR_E_RETURNCODE returnCode;
857
858 if ((GetFillSizeFieldsFlags() == TRUE) &&
859 ((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) ||
860 (pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT))))
861 {
862 returnCode = ADDR_INVALIDPARAMS;
863 }
864 else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) ||
865 (IsNonPrtXor(pIn->swizzleMode) == FALSE) ||
866 (pIn->numSamples > 1))
867 {
868 returnCode = ADDR_NOTSUPPORTED;
869 }
870 else
871 {
872 returnCode = HwlComputeSlicePipeBankXor(pIn, pOut);
873 }
874
875 return returnCode;
876 }
877
878 /**
879 ************************************************************************************************************************
880 * Lib::ComputeSubResourceOffsetForSwizzlePattern
881 *
882 * @brief
883 * Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern.
884 *
885 * @return
886 * ADDR_E_RETURNCODE
887 ************************************************************************************************************************
888 */
889 ADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern(
890 const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,
891 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut)
892 {
893 ADDR_E_RETURNCODE returnCode;
894
895 if ((GetFillSizeFieldsFlags() == TRUE) &&
896 ((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) ||
897 (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT))))
898 {
899 returnCode = ADDR_INVALIDPARAMS;
900 }
901 else
902 {
903 returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);
904 }
905
906 return returnCode;
907 }
908
909 /**
910 ************************************************************************************************************************
911 * Lib::ExtractPipeBankXor
912 *
913 * @brief
914 * Internal function to extract bank and pipe xor bits from combined xor bits.
915 *
916 * @return
917 * ADDR_E_RETURNCODE
918 ************************************************************************************************************************
919 */
920 ADDR_E_RETURNCODE Lib::ExtractPipeBankXor(
921 UINT_32 pipeBankXor,
922 UINT_32 bankBits,
923 UINT_32 pipeBits,
924 UINT_32* pBankX,
925 UINT_32* pPipeX)
926 {
927 ADDR_E_RETURNCODE returnCode;
928
929 if (pipeBankXor < (1u << (pipeBits + bankBits)))
930 {
931 *pPipeX = pipeBankXor % (1 << pipeBits);
932 *pBankX = pipeBankXor >> pipeBits;
933 returnCode = ADDR_OK;
934 }
935 else
936 {
937 ADDR_ASSERT_ALWAYS();
938 returnCode = ADDR_INVALIDPARAMS;
939 }
940
941 return returnCode;
942 }
943
944 /**
945 ************************************************************************************************************************
946 * Lib::ComputeSurfaceInfoSanityCheck
947 *
948 * @brief
949 * Internal function to do basic sanity check before compute surface info
950 *
951 * @return
952 * ADDR_E_RETURNCODE
953 ************************************************************************************************************************
954 */
955 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck(
956 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure
957 ) const
958 {
959 ADDR_E_RETURNCODE returnCode;
960
961 if ((GetFillSizeFieldsFlags() == TRUE) &&
962 (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)))
963 {
964 returnCode = ADDR_INVALIDPARAMS;
965 }
966 else
967 {
968 returnCode = HwlComputeSurfaceInfoSanityCheck(pIn);
969 }
970
971 return returnCode;
972 }
973
974 /**
975 ************************************************************************************************************************
976 * Lib::ApplyCustomizedPitchHeight
977 *
978 * @brief
979 * Helper function to override hw required row pitch/slice pitch by customrized one
980 *
981 * @return
982 * ADDR_E_RETURNCODE
983 ************************************************************************************************************************
984 */
985 ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight(
986 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
987 UINT_32 elementBytes, ///< [in] element bytes per element
988 UINT_32 pitchAlignInElement, ///< [in] pitch alignment in element
989 UINT_32* pPitch, ///< [in/out] pitch
990 UINT_32* pHeight ///< [in/out] height
991 ) const
992 {
993 ADDR_E_RETURNCODE returnCode = ADDR_OK;
994
995 if (pIn->numMipLevels <= 1)
996 {
997 if (pIn->pitchInElement > 0)
998 {
999 if ((pIn->pitchInElement % pitchAlignInElement) != 0)
1000 {
1001 returnCode = ADDR_INVALIDPARAMS;
1002 }
1003 else if (pIn->pitchInElement < (*pPitch))
1004 {
1005 returnCode = ADDR_INVALIDPARAMS;
1006 }
1007 else
1008 {
1009 *pPitch = pIn->pitchInElement;
1010 }
1011 }
1012
1013 if (returnCode == ADDR_OK)
1014 {
1015 if (pIn->sliceAlign > 0)
1016 {
1017 UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch);
1018
1019 if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign)
1020 {
1021 returnCode = ADDR_INVALIDPARAMS;
1022 }
1023 else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight))
1024 {
1025 returnCode = ADDR_INVALIDPARAMS;
1026 }
1027 else
1028 {
1029 *pHeight = customizedHeight;
1030 }
1031 }
1032 }
1033 }
1034
1035 return returnCode;
1036 }
1037
1038 /**
1039 ************************************************************************************************************************
1040 * Lib::ComputeSurfaceInfoLinear
1041 *
1042 * @brief
1043 * Internal function to calculate alignment for linear swizzle surface
1044 *
1045 * @return
1046 * ADDR_E_RETURNCODE
1047 ************************************************************************************************************************
1048 */
1049 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear(
1050 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1051 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
1052 ) const
1053 {
1054 return HwlComputeSurfaceInfoLinear(pIn, pOut);
1055 }
1056
1057 /**
1058 ************************************************************************************************************************
1059 * Lib::ComputeSurfaceInfoTiled
1060 *
1061 * @brief
1062 * Internal function to calculate alignment for tiled swizzle surface
1063 *
1064 * @return
1065 * ADDR_E_RETURNCODE
1066 ************************************************************************************************************************
1067 */
1068 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled(
1069 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1070 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
1071 ) const
1072 {
1073 return HwlComputeSurfaceInfoTiled(pIn, pOut);
1074 }
1075
1076 /**
1077 ************************************************************************************************************************
1078 * Lib::ComputeSurfaceAddrFromCoordLinear
1079 *
1080 * @brief
1081 * Internal function to calculate address from coord for linear swizzle surface
1082 *
1083 * @return
1084 * ADDR_E_RETURNCODE
1085 ************************************************************************************************************************
1086 */
1087 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(
1088 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1089 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1090 ) const
1091 {
1092 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1093 BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0);
1094
1095 if (valid)
1096 {
1097 if (IsTex1d(pIn->resourceType))
1098 {
1099 valid = (pIn->y == 0);
1100 }
1101 }
1102
1103 if (valid)
1104 {
1105 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
1106 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1107 ADDR2_MIP_INFO mipInfo[MaxMipLevels];
1108
1109 localIn.bpp = pIn->bpp;
1110 localIn.flags = pIn->flags;
1111 localIn.width = Max(pIn->unalignedWidth, 1u);
1112 localIn.height = Max(pIn->unalignedHeight, 1u);
1113 localIn.numSlices = Max(pIn->numSlices, 1u);
1114 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1115 localIn.resourceType = pIn->resourceType;
1116
1117 if (localIn.numMipLevels <= 1)
1118 {
1119 localIn.pitchInElement = pIn->pitchInElement;
1120 }
1121
1122 localOut.pMipInfo = mipInfo;
1123
1124 returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1125
1126 if (returnCode == ADDR_OK)
1127 {
1128 pOut->addr = (localOut.sliceSize * pIn->slice) +
1129 mipInfo[pIn->mipId].offset +
1130 (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3);
1131 pOut->bitPosition = 0;
1132 }
1133 else
1134 {
1135 valid = FALSE;
1136 }
1137 }
1138
1139 if (valid == FALSE)
1140 {
1141 returnCode = ADDR_INVALIDPARAMS;
1142 }
1143
1144 return returnCode;
1145 }
1146
1147 /**
1148 ************************************************************************************************************************
1149 * Lib::ComputeSurfaceAddrFromCoordTiled
1150 *
1151 * @brief
1152 * Internal function to calculate address from coord for tiled swizzle surface
1153 *
1154 * @return
1155 * ADDR_E_RETURNCODE
1156 ************************************************************************************************************************
1157 */
1158 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled(
1159 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1160 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1161 ) const
1162 {
1163 return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut);
1164 }
1165
1166 /**
1167 ************************************************************************************************************************
1168 * Lib::ComputeSurfaceCoordFromAddrLinear
1169 *
1170 * @brief
1171 * Internal function to calculate coord from address for linear swizzle surface
1172 *
1173 * @return
1174 * ADDR_E_RETURNCODE
1175 ************************************************************************************************************************
1176 */
1177 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear(
1178 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1179 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1180 ) const
1181 {
1182 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1183
1184 BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1);
1185
1186 if (valid)
1187 {
1188 if (IsTex1d(pIn->resourceType))
1189 {
1190 valid = (pIn->unalignedHeight == 1);
1191 }
1192 }
1193
1194 if (valid)
1195 {
1196 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
1197 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1198 localIn.bpp = pIn->bpp;
1199 localIn.flags = pIn->flags;
1200 localIn.width = Max(pIn->unalignedWidth, 1u);
1201 localIn.height = Max(pIn->unalignedHeight, 1u);
1202 localIn.numSlices = Max(pIn->numSlices, 1u);
1203 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1204 localIn.resourceType = pIn->resourceType;
1205 if (localIn.numMipLevels <= 1)
1206 {
1207 localIn.pitchInElement = pIn->pitchInElement;
1208 }
1209 returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1210
1211 if (returnCode == ADDR_OK)
1212 {
1213 pOut->slice = static_cast<UINT_32>(pIn->addr / localOut.sliceSize);
1214 pOut->sample = 0;
1215
1216 UINT_32 offsetInSlice = static_cast<UINT_32>(pIn->addr % localOut.sliceSize);
1217 UINT_32 elementBytes = pIn->bpp >> 3;
1218 UINT_32 mipOffsetInSlice = 0;
1219 UINT_32 mipSize = 0;
1220 UINT_32 mipId = 0;
1221 for (; mipId < pIn->numMipLevels ; mipId++)
1222 {
1223 if (IsTex1d(pIn->resourceType))
1224 {
1225 mipSize = localOut.pitch * elementBytes;
1226 }
1227 else
1228 {
1229 UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId;
1230 mipSize = currentMipHeight * localOut.pitch * elementBytes;
1231 }
1232
1233 if (mipSize == 0)
1234 {
1235 valid = FALSE;
1236 break;
1237 }
1238 else if ((mipSize + mipOffsetInSlice) > offsetInSlice)
1239 {
1240 break;
1241 }
1242 else
1243 {
1244 mipOffsetInSlice += mipSize;
1245 if ((mipId == (pIn->numMipLevels - 1)) ||
1246 (mipOffsetInSlice >= localOut.sliceSize))
1247 {
1248 valid = FALSE;
1249 }
1250 }
1251 }
1252
1253 if (valid)
1254 {
1255 pOut->mipId = mipId;
1256
1257 UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes;
1258 if (IsTex1d(pIn->resourceType))
1259 {
1260 if (elemOffsetInMip < localOut.pitch)
1261 {
1262 pOut->x = elemOffsetInMip;
1263 pOut->y = 0;
1264 }
1265 else
1266 {
1267 valid = FALSE;
1268 }
1269 }
1270 else
1271 {
1272 pOut->y = elemOffsetInMip / localOut.pitch;
1273 pOut->x = elemOffsetInMip % localOut.pitch;
1274 }
1275
1276 if ((pOut->slice >= pIn->numSlices) ||
1277 (pOut->mipId >= pIn->numMipLevels) ||
1278 (pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u)) ||
1279 (pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) ||
1280 (IsTex3d(pIn->resourceType) &&
1281 (FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices,
1282 pOut->mipId,
1283 pOut->slice))))
1284 {
1285 valid = FALSE;
1286 }
1287 }
1288 }
1289 else
1290 {
1291 valid = FALSE;
1292 }
1293 }
1294
1295 if (valid == FALSE)
1296 {
1297 returnCode = ADDR_INVALIDPARAMS;
1298 }
1299
1300 return returnCode;
1301 }
1302
1303 /**
1304 ************************************************************************************************************************
1305 * Lib::ComputeSurfaceCoordFromAddrTiled
1306 *
1307 * @brief
1308 * Internal function to calculate coord from address for tiled swizzle surface
1309 *
1310 * @return
1311 * ADDR_E_RETURNCODE
1312 ************************************************************************************************************************
1313 */
1314 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled(
1315 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1316 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1317 ) const
1318 {
1319 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
1320
1321 ADDR_NOT_IMPLEMENTED();
1322
1323 return returnCode;
1324 }
1325
1326 /**
1327 ************************************************************************************************************************
1328 * Lib::ComputeBlockDimensionForSurf
1329 *
1330 * @brief
1331 * Internal function to get block width/height/depth in element from surface input params.
1332 *
1333 * @return
1334 * ADDR_E_RETURNCODE
1335 ************************************************************************************************************************
1336 */
1337 ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf(
1338 UINT_32* pWidth,
1339 UINT_32* pHeight,
1340 UINT_32* pDepth,
1341 UINT_32 bpp,
1342 UINT_32 numSamples,
1343 AddrResourceType resourceType,
1344 AddrSwizzleMode swizzleMode) const
1345 {
1346 ADDR_E_RETURNCODE returnCode = ComputeBlockDimension(pWidth,
1347 pHeight,
1348 pDepth,
1349 bpp,
1350 resourceType,
1351 swizzleMode);
1352
1353 if ((returnCode == ADDR_OK) && (numSamples > 1) && IsThin(resourceType, swizzleMode))
1354 {
1355 const UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode);
1356 const UINT_32 log2sample = Log2(numSamples);
1357 const UINT_32 q = log2sample >> 1;
1358 const UINT_32 r = log2sample & 1;
1359
1360 if (log2blkSize & 1)
1361 {
1362 *pWidth >>= q;
1363 *pHeight >>= (q + r);
1364 }
1365 else
1366 {
1367 *pWidth >>= (q + r);
1368 *pHeight >>= q;
1369 }
1370 }
1371
1372 return returnCode;
1373 }
1374
1375 /**
1376 ************************************************************************************************************************
1377 * Lib::ComputeBlockDimension
1378 *
1379 * @brief
1380 * Internal function to get block width/height/depth in element without considering MSAA case
1381 *
1382 * @return
1383 * ADDR_E_RETURNCODE
1384 ************************************************************************************************************************
1385 */
1386 ADDR_E_RETURNCODE Lib::ComputeBlockDimension(
1387 UINT_32* pWidth,
1388 UINT_32* pHeight,
1389 UINT_32* pDepth,
1390 UINT_32 bpp,
1391 AddrResourceType resourceType,
1392 AddrSwizzleMode swizzleMode) const
1393 {
1394 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1395
1396 UINT_32 eleBytes = bpp >> 3;
1397 UINT_32 microBlockSizeTableIndex = Log2(eleBytes);
1398 UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode);
1399
1400 if (IsThin(resourceType, swizzleMode))
1401 {
1402 UINT_32 log2blkSizeIn256B = log2blkSize - 8;
1403 UINT_32 widthAmp = log2blkSizeIn256B / 2;
1404 UINT_32 heightAmp = log2blkSizeIn256B - widthAmp;
1405
1406 ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block256_2d) / sizeof(Block256_2d[0]));
1407
1408 *pWidth = (Block256_2d[microBlockSizeTableIndex].w << widthAmp);
1409 *pHeight = (Block256_2d[microBlockSizeTableIndex].h << heightAmp);
1410 *pDepth = 1;
1411 }
1412 else if (IsThick(resourceType, swizzleMode))
1413 {
1414 UINT_32 log2blkSizeIn1KB = log2blkSize - 10;
1415 UINT_32 averageAmp = log2blkSizeIn1KB / 3;
1416 UINT_32 restAmp = log2blkSizeIn1KB % 3;
1417
1418 ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0]));
1419
1420 *pWidth = Block1K_3d[microBlockSizeTableIndex].w << averageAmp;
1421 *pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2));
1422 *pDepth = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0));
1423 }
1424 else
1425 {
1426 ADDR_ASSERT_ALWAYS();
1427 returnCode = ADDR_INVALIDPARAMS;
1428 }
1429
1430 return returnCode;
1431 }
1432
1433 /**
1434 ************************************************************************************************************************
1435 * Lib::GetMipTailDim
1436 *
1437 * @brief
1438 * Internal function to get out max dimension of first level in mip tail
1439 *
1440 * @return
1441 * Max Width/Height/Depth value of the first mip fitted in mip tail
1442 ************************************************************************************************************************
1443 */
1444 Dim3d Lib::GetMipTailDim(
1445 AddrResourceType resourceType,
1446 AddrSwizzleMode swizzleMode,
1447 UINT_32 blockWidth,
1448 UINT_32 blockHeight,
1449 UINT_32 blockDepth) const
1450 {
1451 Dim3d out = {blockWidth, blockHeight, blockDepth};
1452 UINT_32 log2blkSize = GetBlockSizeLog2(swizzleMode);
1453
1454 if (IsThick(resourceType, swizzleMode))
1455 {
1456 UINT_32 dim = log2blkSize % 3;
1457
1458 if (dim == 0)
1459 {
1460 out.h >>= 1;
1461 }
1462 else if (dim == 1)
1463 {
1464 out.w >>= 1;
1465 }
1466 else
1467 {
1468 out.d >>= 1;
1469 }
1470 }
1471 else
1472 {
1473 if (log2blkSize & 1)
1474 {
1475 out.h >>= 1;
1476 }
1477 else
1478 {
1479 out.w >>= 1;
1480 }
1481 }
1482
1483 return out;
1484 }
1485
1486 /**
1487 ************************************************************************************************************************
1488 * Lib::ComputeSurface2DMicroBlockOffset
1489 *
1490 * @brief
1491 * Internal function to calculate micro block (256B) offset from coord for 2D resource
1492 *
1493 * @return
1494 * micro block (256B) offset for 2D resource
1495 ************************************************************************************************************************
1496 */
1497 UINT_32 Lib::ComputeSurface2DMicroBlockOffset(
1498 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1499 {
1500 ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
1501
1502 UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1503 UINT_32 microBlockOffset = 0;
1504 if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1505 {
1506 UINT_32 xBits = pIn->x << log2ElementBytes;
1507 microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4);
1508 if (log2ElementBytes < 3)
1509 {
1510 microBlockOffset |= (pIn->y & 0x4) << 4;
1511 if (log2ElementBytes == 0)
1512 {
1513 microBlockOffset |= (pIn->y & 0x8) << 4;
1514 }
1515 else
1516 {
1517 microBlockOffset |= (xBits & 0x10) << 3;
1518 }
1519 }
1520 else
1521 {
1522 microBlockOffset |= (xBits & 0x30) << 2;
1523 }
1524 }
1525 else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode))
1526 {
1527 if (log2ElementBytes == 4)
1528 {
1529 microBlockOffset = (GetBit(pIn->x, 0) << 4) |
1530 (GetBit(pIn->y, 0) << 5) |
1531 (GetBit(pIn->x, 1) << 6) |
1532 (GetBit(pIn->y, 1) << 7);
1533 }
1534 else
1535 {
1536 microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes) |
1537 GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) |
1538 GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1539 GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1540 microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1541 (GetBit(pIn->y, 0) << 4) |
1542 GetBits(microBlockOffset, 4, 3, 5);
1543 }
1544 }
1545 else if (IsRotateSwizzle(pIn->swizzleMode))
1546 {
1547 microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) |
1548 GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) |
1549 GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1550 GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1551 microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1552 (GetBit(pIn->x, 0) << 4) |
1553 GetBits(microBlockOffset, 4, 3, 5);
1554 if (log2ElementBytes == 3)
1555 {
1556 microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) |
1557 GetBits(pIn->x, 1, 2, 6);
1558 }
1559 }
1560
1561 return microBlockOffset;
1562 }
1563
1564 /**
1565 ************************************************************************************************************************
1566 * Lib::ComputeSurface3DMicroBlockOffset
1567 *
1568 * @brief
1569 * Internal function to calculate micro block (1KB) offset from coord for 3D resource
1570 *
1571 * @return
1572 * micro block (1KB) offset for 3D resource
1573 ************************************************************************************************************************
1574 */
1575 UINT_32 Lib::ComputeSurface3DMicroBlockOffset(
1576 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1577 {
1578 ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode));
1579
1580 UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1581 UINT_32 microBlockOffset = 0;
1582 if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1583 {
1584 if (log2ElementBytes == 0)
1585 {
1586 microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1587 }
1588 else if (log2ElementBytes == 1)
1589 {
1590 microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1591 }
1592 else if (log2ElementBytes == 2)
1593 {
1594 microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1);
1595 }
1596 else if (log2ElementBytes == 3)
1597 {
1598 microBlockOffset = (pIn->x & 6) >> 1;
1599 }
1600 else
1601 {
1602 microBlockOffset = pIn->x & 3;
1603 }
1604
1605 microBlockOffset <<= 8;
1606
1607 UINT_32 xBits = pIn->x << log2ElementBytes;
1608 microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6);
1609 }
1610 else if (IsZOrderSwizzle(pIn->swizzleMode))
1611 {
1612 UINT_32 xh, yh, zh;
1613
1614 if (log2ElementBytes == 0)
1615 {
1616 microBlockOffset =
1617 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1618 microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4);
1619
1620 xh = pIn->x >> 3;
1621 yh = pIn->y >> 2;
1622 zh = pIn->slice >> 2;
1623 }
1624 else if (log2ElementBytes == 1)
1625 {
1626 microBlockOffset =
1627 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1628 microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5);
1629
1630 xh = pIn->x >> 2;
1631 yh = pIn->y >> 2;
1632 zh = pIn->slice >> 2;
1633 }
1634 else if (log2ElementBytes == 2)
1635 {
1636 microBlockOffset =
1637 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3);
1638 microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5);
1639
1640 xh = pIn->x >> 2;
1641 yh = pIn->y >> 2;
1642 zh = pIn->slice >> 1;
1643 }
1644 else if (log2ElementBytes == 3)
1645 {
1646 microBlockOffset =
1647 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2);
1648 microBlockOffset <<= 3;
1649
1650 xh = pIn->x >> 2;
1651 yh = pIn->y >> 1;
1652 zh = pIn->slice >> 1;
1653 }
1654 else
1655 {
1656 microBlockOffset =
1657 (((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4);
1658
1659 xh = pIn->x >> 1;
1660 yh = pIn->y >> 1;
1661 zh = pIn->slice >> 1;
1662 }
1663
1664 microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380);
1665 }
1666
1667 return microBlockOffset;
1668 }
1669
1670 /**
1671 ************************************************************************************************************************
1672 * Lib::GetPipeXorBits
1673 *
1674 * @brief
1675 * Internal function to get bits number for pipe/se xor operation
1676 *
1677 * @return
1678 * ADDR_E_RETURNCODE
1679 ************************************************************************************************************************
1680 */
1681 UINT_32 Lib::GetPipeXorBits(
1682 UINT_32 macroBlockBits) const
1683 {
1684 ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2);
1685
1686 // Total available xor bits
1687 UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2;
1688
1689 // Pipe/Se xor bits
1690 UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2);
1691
1692 return pipeBits;
1693 }
1694
1695 /**
1696 ************************************************************************************************************************
1697 * Lib::GetBankXorBits
1698 *
1699 * @brief
1700 * Internal function to get bits number for pipe/se xor operation
1701 *
1702 * @return
1703 * ADDR_E_RETURNCODE
1704 ************************************************************************************************************************
1705 */
1706 UINT_32 Lib::GetBankXorBits(
1707 UINT_32 macroBlockBits) const
1708 {
1709 UINT_32 pipeBits = GetPipeXorBits(macroBlockBits);
1710
1711 // Bank xor bits
1712 UINT_32 bankBits = Min(macroBlockBits - pipeBits - m_pipeInterleaveLog2, m_banksLog2);
1713
1714 return bankBits;
1715 }
1716
1717 /**
1718 ************************************************************************************************************************
1719 * Lib::Addr2GetPreferredSurfaceSetting
1720 *
1721 * @brief
1722 * Internal function to get suggested surface information for cliet to use
1723 *
1724 * @return
1725 * ADDR_E_RETURNCODE
1726 ************************************************************************************************************************
1727 */
1728 ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting(
1729 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
1730 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const
1731 {
1732 ADDR_E_RETURNCODE returnCode;
1733
1734 if ((GetFillSizeFieldsFlags() == TRUE) &&
1735 ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) ||
1736 (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT))))
1737 {
1738 returnCode = ADDR_INVALIDPARAMS;
1739 }
1740 else
1741 {
1742 returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut);
1743 }
1744
1745 return returnCode;
1746 }
1747
1748 /**
1749 ************************************************************************************************************************
1750 * Lib::ComputeBlock256Equation
1751 *
1752 * @brief
1753 * Compute equation for block 256B
1754 *
1755 * @return
1756 * If equation computed successfully
1757 *
1758 ************************************************************************************************************************
1759 */
1760 ADDR_E_RETURNCODE Lib::ComputeBlock256Equation(
1761 AddrResourceType rsrcType,
1762 AddrSwizzleMode swMode,
1763 UINT_32 elementBytesLog2,
1764 ADDR_EQUATION* pEquation) const
1765 {
1766 ADDR_E_RETURNCODE ret;
1767
1768 if (IsBlock256b(swMode))
1769 {
1770 ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);
1771 }
1772 else
1773 {
1774 ADDR_ASSERT_ALWAYS();
1775 ret = ADDR_INVALIDPARAMS;
1776 }
1777
1778 return ret;
1779 }
1780
1781 /**
1782 ************************************************************************************************************************
1783 * Lib::ComputeThinEquation
1784 *
1785 * @brief
1786 * Compute equation for 2D/3D resource which use THIN mode
1787 *
1788 * @return
1789 * If equation computed successfully
1790 *
1791 ************************************************************************************************************************
1792 */
1793 ADDR_E_RETURNCODE Lib::ComputeThinEquation(
1794 AddrResourceType rsrcType,
1795 AddrSwizzleMode swMode,
1796 UINT_32 elementBytesLog2,
1797 ADDR_EQUATION* pEquation) const
1798 {
1799 ADDR_E_RETURNCODE ret;
1800
1801 if (IsThin(rsrcType, swMode))
1802 {
1803 ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation);
1804 }
1805 else
1806 {
1807 ADDR_ASSERT_ALWAYS();
1808 ret = ADDR_INVALIDPARAMS;
1809 }
1810
1811 return ret;
1812 }
1813
1814 /**
1815 ************************************************************************************************************************
1816 * Lib::ComputeThickEquation
1817 *
1818 * @brief
1819 * Compute equation for 3D resource which use THICK mode
1820 *
1821 * @return
1822 * If equation computed successfully
1823 *
1824 ************************************************************************************************************************
1825 */
1826 ADDR_E_RETURNCODE Lib::ComputeThickEquation(
1827 AddrResourceType rsrcType,
1828 AddrSwizzleMode swMode,
1829 UINT_32 elementBytesLog2,
1830 ADDR_EQUATION* pEquation) const
1831 {
1832 ADDR_E_RETURNCODE ret;
1833
1834 if (IsThick(rsrcType, swMode))
1835 {
1836 ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation);
1837 }
1838 else
1839 {
1840 ADDR_ASSERT_ALWAYS();
1841 ret = ADDR_INVALIDPARAMS;
1842 }
1843
1844 return ret;
1845 }
1846
1847 /**
1848 ************************************************************************************************************************
1849 * Lib::ComputeQbStereoInfo
1850 *
1851 * @brief
1852 * Get quad buffer stereo information
1853 * @return
1854 * N/A
1855 ************************************************************************************************************************
1856 */
1857 VOID Lib::ComputeQbStereoInfo(
1858 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] updated pOut+pStereoInfo
1859 ) const
1860 {
1861 ADDR_ASSERT(pOut->bpp >= 8);
1862 ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
1863
1864 // Save original height
1865 pOut->pStereoInfo->eyeHeight = pOut->height;
1866
1867 // Right offset
1868 pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
1869
1870 // Double height
1871 pOut->height <<= 1;
1872
1873 ADDR_ASSERT(pOut->height <= MaxSurfaceHeight);
1874
1875 pOut->pixelHeight <<= 1;
1876
1877 // Double size
1878 pOut->surfSize <<= 1;
1879 }
1880
1881 } // V2
1882 } // Addr
1883