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