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