1 /*
2 ************************************************************************************************************************
3 *
4 * Copyright (C) 2007-2024 Advanced Micro Devices, Inc. All rights reserved.
5 * SPDX-License-Identifier: MIT
6 *
7 ***********************************************************************************************************************/
8
9
10 /**
11 ************************************************************************************************************************
12 * @file addrlib2.cpp
13 * @brief Contains the implementation for the AddrLib2 base class.
14 ************************************************************************************************************************
15 */
16
17 #include "addrinterface.h"
18 #include "addrlib2.h"
19 #include "addrcommon.h"
20
21 namespace Addr
22 {
23 namespace V2
24 {
25
26 ////////////////////////////////////////////////////////////////////////////////////////////////////
27 // Static Const Member
28 ////////////////////////////////////////////////////////////////////////////////////////////////////
29
30 const Dim2d Lib::Block256_2d[] = {{16, 16}, {16, 8}, {8, 8}, {8, 4}, {4, 4}};
31
32 const Dim3d Lib::Block1K_3d[] = {{16, 8, 8}, {8, 8, 8}, {8, 8, 4}, {8, 4, 4}, {4, 4, 4}};
33
34 ////////////////////////////////////////////////////////////////////////////////////////////////////
35 // Constructor/Destructor
36 ////////////////////////////////////////////////////////////////////////////////////////////////////
37
38 /**
39 ************************************************************************************************************************
40 * Lib::Lib
41 *
42 * @brief
43 * Constructor for the Addr::V2::Lib class
44 *
45 ************************************************************************************************************************
46 */
Lib()47 Lib::Lib()
48 :
49 Addr::Lib(),
50 m_se(0),
51 m_rbPerSe(0),
52 m_maxCompFrag(0),
53 m_banksLog2(0),
54 m_pipesLog2(0),
55 m_seLog2(0),
56 m_rbPerSeLog2(0),
57 m_maxCompFragLog2(0),
58 m_pipeInterleaveLog2(0),
59 m_blockVarSizeLog2(0),
60 m_numEquations(0)
61 {
62 }
63
64 /**
65 ************************************************************************************************************************
66 * Lib::Lib
67 *
68 * @brief
69 * Constructor for the AddrLib2 class with hClient as parameter
70 *
71 ************************************************************************************************************************
72 */
Lib(const Client * pClient)73 Lib::Lib(const Client* pClient)
74 :
75 Addr::Lib(pClient),
76 m_se(0),
77 m_rbPerSe(0),
78 m_maxCompFrag(0),
79 m_banksLog2(0),
80 m_pipesLog2(0),
81 m_seLog2(0),
82 m_rbPerSeLog2(0),
83 m_maxCompFragLog2(0),
84 m_pipeInterleaveLog2(0),
85 m_blockVarSizeLog2(0),
86 m_numEquations(0)
87 {
88 }
89
90 /**
91 ************************************************************************************************************************
92 * Lib::~Lib
93 *
94 * @brief
95 * Destructor for the AddrLib2 class
96 *
97 ************************************************************************************************************************
98 */
~Lib()99 Lib::~Lib()
100 {
101 }
102
103 /**
104 ************************************************************************************************************************
105 * Lib::GetLib
106 *
107 * @brief
108 * Get Addr::V2::Lib pointer
109 *
110 * @return
111 * An Addr::V2::Lib class pointer
112 ************************************************************************************************************************
113 */
GetLib(ADDR_HANDLE hLib)114 Lib* Lib::GetLib(
115 ADDR_HANDLE hLib) ///< [in] handle of ADDR_HANDLE
116 {
117 Addr::Lib* pAddrLib = Addr::Lib::GetLib(hLib);
118 if ((pAddrLib != NULL) &&
119 (pAddrLib->GetChipFamily() <= ADDR_CHIP_FAMILY_VI))
120 {
121 // only GFX9+ ASIC can use AddrLib2 function.
122 ADDR_ASSERT_ALWAYS();
123 hLib = NULL;
124 }
125
126 return static_cast<Lib*>(pAddrLib);
127 }
128
129
130 ////////////////////////////////////////////////////////////////////////////////////////////////////
131 // Surface Methods
132 ////////////////////////////////////////////////////////////////////////////////////////////////////
133
134
135 /**
136 ************************************************************************************************************************
137 * Lib::ComputeSurfaceInfo
138 *
139 * @brief
140 * Interface function stub of AddrComputeSurfaceInfo.
141 *
142 * @return
143 * ADDR_E_RETURNCODE
144 ************************************************************************************************************************
145 */
ComputeSurfaceInfo(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const146 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfo(
147 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
148 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
149 ) const
150 {
151 ADDR_E_RETURNCODE returnCode = ADDR_OK;
152
153 if (GetFillSizeFieldsFlags() == TRUE)
154 {
155 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)) ||
156 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT)))
157 {
158 returnCode = ADDR_PARAMSIZEMISMATCH;
159 }
160 }
161
162 // Adjust coming parameters.
163 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = *pIn;
164 localIn.width = Max(pIn->width, 1u);
165 localIn.height = Max(pIn->height, 1u);
166 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
167 localIn.numSlices = Max(pIn->numSlices, 1u);
168 localIn.numSamples = Max(pIn->numSamples, 1u);
169 localIn.numFrags = (localIn.numFrags == 0) ? localIn.numSamples : pIn->numFrags;
170
171 UINT_32 expandX = 1;
172 UINT_32 expandY = 1;
173 ElemMode elemMode = ADDR_UNCOMPRESSED;
174
175 if (returnCode == ADDR_OK)
176 {
177 // Set format to INVALID will skip this conversion
178 if (localIn.format != ADDR_FMT_INVALID)
179 {
180 // Get compression/expansion factors and element mode which indicates compression/expansion
181 localIn.bpp = GetElemLib()->GetBitsPerPixel(localIn.format,
182 &elemMode,
183 &expandX,
184 &expandY);
185
186 // Special flag for 96 bit surface. 96 (or 48 if we support) bit surface's width is
187 // pre-multiplied by 3 and bpp is divided by 3. So pitch alignment for linear-
188 // aligned does not meet 64-pixel in real. We keep special handling in hwl since hw
189 // restrictions are different.
190 // Also Mip 1+ needs an element pitch of 32 bits so we do not need this workaround
191 // but we use this flag to skip RestoreSurfaceInfo below
192
193 if ((elemMode == ADDR_EXPANDED) && (expandX > 1))
194 {
195 ADDR_ASSERT(IsLinear(localIn.swizzleMode));
196 }
197
198 UINT_32 basePitch = 0;
199 GetElemLib()->AdjustSurfaceInfo(elemMode,
200 expandX,
201 expandY,
202 &localIn.bpp,
203 &basePitch,
204 &localIn.width,
205 &localIn.height);
206
207 // Overwrite these parameters if we have a valid format
208 }
209
210 if (localIn.bpp != 0)
211 {
212 localIn.width = Max(localIn.width, 1u);
213 localIn.height = Max(localIn.height, 1u);
214 }
215 else // Rule out some invalid parameters
216 {
217 ADDR_ASSERT_ALWAYS();
218
219 returnCode = ADDR_INVALIDPARAMS;
220 }
221 }
222
223 if (returnCode == ADDR_OK)
224 {
225 returnCode = ComputeSurfaceInfoSanityCheck(&localIn);
226 }
227
228 if (returnCode == ADDR_OK)
229 {
230 VerifyMipLevelInfo(pIn);
231
232 if (IsLinear(pIn->swizzleMode))
233 {
234 // linear mode
235 returnCode = ComputeSurfaceInfoLinear(&localIn, pOut);
236 }
237 else
238 {
239 // tiled mode
240 returnCode = ComputeSurfaceInfoTiled(&localIn, pOut);
241 }
242
243 if (returnCode == ADDR_OK)
244 {
245 pOut->bpp = localIn.bpp;
246 pOut->pixelPitch = pOut->pitch;
247 pOut->pixelHeight = pOut->height;
248 pOut->pixelMipChainPitch = pOut->mipChainPitch;
249 pOut->pixelMipChainHeight = pOut->mipChainHeight;
250 pOut->pixelBits = localIn.bpp;
251
252 if (localIn.format != ADDR_FMT_INVALID)
253 {
254 UINT_32 pixelBits = pOut->pixelBits;
255
256 GetElemLib()->RestoreSurfaceInfo(elemMode,
257 expandX,
258 expandY,
259 &pOut->pixelBits,
260 &pOut->pixelPitch,
261 &pOut->pixelHeight);
262
263 GetElemLib()->RestoreSurfaceInfo(elemMode,
264 expandX,
265 expandY,
266 &pixelBits,
267 &pOut->pixelMipChainPitch,
268 &pOut->pixelMipChainHeight);
269
270 if ((localIn.numMipLevels > 1) && (pOut->pMipInfo != NULL))
271 {
272 for (UINT_32 i = 0; i < localIn.numMipLevels; i++)
273 {
274 pOut->pMipInfo[i].pixelPitch = pOut->pMipInfo[i].pitch;
275 pOut->pMipInfo[i].pixelHeight = pOut->pMipInfo[i].height;
276
277 GetElemLib()->RestoreSurfaceInfo(elemMode,
278 expandX,
279 expandY,
280 &pixelBits,
281 &pOut->pMipInfo[i].pixelPitch,
282 &pOut->pMipInfo[i].pixelHeight);
283 }
284 }
285 }
286
287 if (localIn.flags.needEquation && (Log2(localIn.numFrags) == 0))
288 {
289 pOut->equationIndex = GetEquationIndex(&localIn, pOut);
290 if ((localIn.flags.allowExtEquation == 0) &&
291 (pOut->equationIndex != ADDR_INVALID_EQUATION_INDEX) &&
292 (m_equationTable[pOut->equationIndex].numBitComponents > ADDR_MAX_LEGACY_EQUATION_COMP))
293 {
294 pOut->equationIndex = ADDR_INVALID_EQUATION_INDEX;
295 }
296 }
297
298 if (localIn.flags.qbStereo)
299 {
300 if (pOut->pStereoInfo != NULL)
301 {
302 ComputeQbStereoInfo(pOut);
303 #if DEBUG
304 ValidateStereoInfo(pIn, pOut);
305 #endif
306 }
307 }
308 }
309 }
310
311 ADDR_ASSERT(pOut->surfSize != 0);
312
313 ValidBaseAlignments(pOut->baseAlign);
314
315 return returnCode;
316 }
317
318 /**
319 ************************************************************************************************************************
320 * Lib::ComputeSurfaceInfo
321 *
322 * @brief
323 * Interface function stub of AddrComputeSurfaceInfo.
324 *
325 * @return
326 * ADDR_E_RETURNCODE
327 ************************************************************************************************************************
328 */
ComputeSurfaceAddrFromCoord(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const329 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoord(
330 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
331 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
332 ) const
333 {
334 ADDR_E_RETURNCODE returnCode = ADDR_OK;
335
336 if (GetFillSizeFieldsFlags() == TRUE)
337 {
338 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT)) ||
339 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT)))
340 {
341 returnCode = ADDR_PARAMSIZEMISMATCH;
342 }
343 }
344
345 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT localIn = *pIn;
346 localIn.unalignedWidth = Max(pIn->unalignedWidth, 1u);
347 localIn.unalignedHeight = Max(pIn->unalignedHeight, 1u);
348 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
349 localIn.numSlices = Max(pIn->numSlices, 1u);
350 localIn.numSamples = Max(pIn->numSamples, 1u);
351 localIn.numFrags = Max(pIn->numFrags, 1u);
352
353 if ((localIn.bpp < 8) ||
354 (localIn.bpp > 128) ||
355 ((localIn.bpp % 8) != 0) ||
356 (localIn.sample >= localIn.numSamples) ||
357 (localIn.slice >= localIn.numSlices) ||
358 (localIn.mipId >= localIn.numMipLevels) ||
359 (IsTex3d(localIn.resourceType) &&
360 (Valid3DMipSliceIdConstraint(localIn.numSlices, localIn.mipId, localIn.slice) == FALSE)))
361 {
362 returnCode = ADDR_INVALIDPARAMS;
363 }
364
365 if (returnCode == ADDR_OK)
366 {
367 if (IsLinear(localIn.swizzleMode))
368 {
369 returnCode = ComputeSurfaceAddrFromCoordLinear(&localIn, pOut);
370 }
371 else
372 {
373 returnCode = ComputeSurfaceAddrFromCoordTiled(&localIn, pOut);
374 }
375
376 if (returnCode == ADDR_OK)
377 {
378 pOut->prtBlockIndex = static_cast<UINT_32>(pOut->addr / (64 * 1024));
379 }
380 }
381
382 return returnCode;
383 }
384
385 /**
386 ************************************************************************************************************************
387 * Lib::CopyLinearSurface
388 *
389 * @brief
390 * Implements uncompressed linear copies between memory and images.
391 *
392 * @return
393 * ADDR_E_RETURNCODE
394 ************************************************************************************************************************
395 */
CopyLinearSurface(const ADDR2_COPY_MEMSURFACE_INPUT * pIn,const ADDR2_COPY_MEMSURFACE_REGION * pRegions,UINT_32 regionCount,bool surfaceIsDst) const396 ADDR_E_RETURNCODE Lib::CopyLinearSurface(
397 const ADDR2_COPY_MEMSURFACE_INPUT* pIn,
398 const ADDR2_COPY_MEMSURFACE_REGION* pRegions,
399 UINT_32 regionCount,
400 bool surfaceIsDst) const
401 {
402 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
403 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
404 ADDR2_MIP_INFO mipInfo[MaxMipLevels] = {{0}};
405 ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
406 ADDR_E_RETURNCODE returnCode = ADDR_OK;
407
408 if (pIn->numSamples > 1)
409 {
410 returnCode = ADDR_INVALIDPARAMS;
411 }
412
413 localIn.size = sizeof(localIn);
414 localIn.flags = pIn->flags;
415 localIn.swizzleMode = pIn->swizzleMode;
416 localIn.resourceType = pIn->resourceType;
417 localIn.format = pIn->format;
418 localIn.bpp = pIn->bpp;
419 localIn.width = Max(pIn->unAlignedDims.width, 1u);
420 localIn.height = Max(pIn->unAlignedDims.height, 1u);
421 localIn.numSlices = Max(pIn->unAlignedDims.depth, 1u);
422 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
423 localIn.numSamples = Max(pIn->numSamples, 1u);
424
425 if (localIn.numMipLevels <= 1)
426 {
427 localIn.pitchInElement = pIn->pitchInElement;
428 }
429
430 localOut.size = sizeof(localOut);
431 localOut.pMipInfo = mipInfo;
432
433 if (returnCode == ADDR_OK)
434 {
435 returnCode = ComputeSurfaceInfo(&localIn, &localOut);
436 }
437
438 if (returnCode == ADDR_OK)
439 {
440 for (UINT_32 regionIdx = 0; regionIdx < regionCount; regionIdx++)
441 {
442 const ADDR2_COPY_MEMSURFACE_REGION* pCurRegion = &pRegions[regionIdx];
443
444 void* pMipBase = VoidPtrInc(pIn->pMappedSurface,
445 (pIn->singleSubres ? 0 : mipInfo[pCurRegion->mipId].offset));
446
447 const size_t lineSizeBytes = (localIn.bpp >> 3) * pCurRegion->copyDims.width;
448 const size_t lineImgPitchBytes = (localIn.bpp >> 3) * mipInfo[pCurRegion->mipId].pitch;
449
450 for (UINT_32 sliceIdx = 0; sliceIdx < pCurRegion->copyDims.depth; sliceIdx++)
451 {
452 UINT_32 sliceCoord = sliceIdx + pCurRegion->slice;
453 size_t imgOffsetInMip = (localOut.sliceSize * sliceCoord) +
454 (lineImgPitchBytes * pCurRegion->y) +
455 (pCurRegion->x * (pIn->bpp >> 3));
456 size_t memOffset = sliceIdx * pCurRegion->memSlicePitch;
457
458 for (UINT_32 yIdx = 0; yIdx < pCurRegion->copyDims.height; yIdx++)
459 {
460 if (surfaceIsDst)
461 {
462 memcpy(VoidPtrInc(pMipBase, imgOffsetInMip), VoidPtrInc(pCurRegion->pMem, memOffset), lineSizeBytes);
463 }
464 else
465 {
466 memcpy(VoidPtrInc(pCurRegion->pMem, memOffset), VoidPtrInc(pMipBase, imgOffsetInMip), lineSizeBytes);
467 }
468
469 imgOffsetInMip += lineImgPitchBytes;
470 memOffset += pCurRegion->memRowPitch;
471 }
472 }
473 }
474 }
475
476 return returnCode;
477 }
478
479 /**
480 ************************************************************************************************************************
481 * Lib::CopyMemToSurface
482 *
483 * @brief
484 * Interface function stub of Addr2CopyMemToSurface.
485 *
486 * @return
487 * ADDR_E_RETURNCODE
488 ************************************************************************************************************************
489 */
CopyMemToSurface(const ADDR2_COPY_MEMSURFACE_INPUT * pIn,const ADDR2_COPY_MEMSURFACE_REGION * pRegions,UINT_32 regionCount) const490 ADDR_E_RETURNCODE Lib::CopyMemToSurface(
491 const ADDR2_COPY_MEMSURFACE_INPUT* pIn,
492 const ADDR2_COPY_MEMSURFACE_REGION* pRegions,
493 UINT_32 regionCount) const
494 {
495 ADDR_E_RETURNCODE returnCode = ADDR_OK;
496
497 if ((regionCount == 0) || (pRegions == NULL))
498 {
499 returnCode = ADDR_INVALIDPARAMS;
500 }
501 else if (GetFillSizeFieldsFlags() == TRUE)
502 {
503 if (pIn->size != sizeof(ADDR2_COPY_MEMSURFACE_INPUT))
504 {
505 returnCode = ADDR_INVALIDPARAMS;
506 }
507 else
508 {
509 UINT_32 baseSlice = pRegions[0].slice;
510 UINT_32 baseMip = pRegions[0].mipId;
511 BOOL_32 singleSubres = pIn->singleSubres;
512 for (UINT_32 i = 0; i < regionCount; i++)
513 {
514 if (pRegions[i].size != sizeof(ADDR2_COPY_MEMSURFACE_REGION))
515 {
516 returnCode = ADDR_INVALIDPARAMS;
517 break;
518 }
519 if (singleSubres &&
520 ((pRegions[i].copyDims.depth != 1) ||
521 (pRegions[i].slice != baseSlice) ||
522 (pRegions[i].mipId != baseMip)))
523 {
524 // Copy will cover multiple/interleaved subresources, a
525 // mapped pointer to a single subres cannot be valid.
526 returnCode = ADDR_INVALIDPARAMS;
527 break;
528 }
529 }
530 }
531 }
532
533 if (returnCode == ADDR_OK)
534 {
535 if (IsLinear(pIn->swizzleMode))
536 {
537 returnCode = CopyLinearSurface(pIn, pRegions, regionCount, true);
538 }
539 else
540 {
541 returnCode = HwlCopyMemToSurface(pIn, pRegions, regionCount);
542 }
543 }
544
545 return returnCode;
546 }
547
548 /**
549 ************************************************************************************************************************
550 * Lib::CopySurfaceToMem
551 *
552 * @brief
553 * Interface function stub of Addr2CopySurfaceToMem.
554 *
555 * @return
556 * ADDR_E_RETURNCODE
557 ************************************************************************************************************************
558 */
CopySurfaceToMem(const ADDR2_COPY_MEMSURFACE_INPUT * pIn,const ADDR2_COPY_MEMSURFACE_REGION * pRegions,UINT_32 regionCount) const559 ADDR_E_RETURNCODE Lib::CopySurfaceToMem(
560 const ADDR2_COPY_MEMSURFACE_INPUT* pIn,
561 const ADDR2_COPY_MEMSURFACE_REGION* pRegions,
562 UINT_32 regionCount) const
563 {
564 ADDR_E_RETURNCODE returnCode = ADDR_OK;
565
566 if (regionCount == 0)
567 {
568 returnCode = ADDR_INVALIDPARAMS;
569 }
570 else if (GetFillSizeFieldsFlags() == TRUE)
571 {
572 if (pIn->size != sizeof(ADDR2_COPY_MEMSURFACE_INPUT))
573 {
574 returnCode = ADDR_INVALIDPARAMS;
575 }
576 else
577 {
578 UINT_32 baseSlice = pRegions[0].slice;
579 UINT_32 baseMip = pRegions[0].mipId;
580 BOOL_32 singleSubres = pIn->singleSubres;
581 for (UINT_32 i = 0; i < regionCount; i++)
582 {
583 if (pRegions[i].size != sizeof(ADDR2_COPY_MEMSURFACE_REGION))
584 {
585 returnCode = ADDR_INVALIDPARAMS;
586 break;
587 }
588 if (singleSubres &&
589 ((pRegions[i].copyDims.depth != 1) ||
590 (pRegions[i].slice != baseSlice) ||
591 (pRegions[i].mipId != baseMip)))
592 {
593 // Copy will cover multiple/interleaved subresources, a
594 // mapped pointer to a single subres cannot be valid.
595 returnCode = ADDR_INVALIDPARAMS;
596 break;
597 }
598 }
599 }
600 }
601
602 if (returnCode == ADDR_OK)
603 {
604 if (IsLinear(pIn->swizzleMode))
605 {
606 returnCode = CopyLinearSurface(pIn, pRegions, regionCount, false);
607 }
608 else
609 {
610 returnCode = HwlCopySurfaceToMem(pIn, pRegions, regionCount);
611 }
612 }
613
614 return returnCode;
615 }
616
617 /**
618 ************************************************************************************************************************
619 * Lib::ComputeSurfaceCoordFromAddr
620 *
621 * @brief
622 * Interface function stub of ComputeSurfaceCoordFromAddr.
623 *
624 * @return
625 * ADDR_E_RETURNCODE
626 ************************************************************************************************************************
627 */
ComputeSurfaceCoordFromAddr(const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const628 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddr(
629 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
630 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
631 ) const
632 {
633 ADDR_E_RETURNCODE returnCode = ADDR_OK;
634
635 if (GetFillSizeFieldsFlags() == TRUE)
636 {
637 if ((pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT)) ||
638 (pOut->size != sizeof(ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT)))
639 {
640 returnCode = ADDR_PARAMSIZEMISMATCH;
641 }
642 }
643
644 if ((pIn->bpp < 8) ||
645 (pIn->bpp > 128) ||
646 ((pIn->bpp % 8) != 0) ||
647 (pIn->bitPosition >= 8))
648 {
649 returnCode = ADDR_INVALIDPARAMS;
650 }
651
652 if (returnCode == ADDR_OK)
653 {
654 if (IsLinear(pIn->swizzleMode))
655 {
656 returnCode = ComputeSurfaceCoordFromAddrLinear(pIn, pOut);
657 }
658 else
659 {
660 returnCode = ComputeSurfaceCoordFromAddrTiled(pIn, pOut);
661 }
662 }
663
664 return returnCode;
665 }
666
667
668 ////////////////////////////////////////////////////////////////////////////////////////////////////
669 // CMASK/HTILE
670 ////////////////////////////////////////////////////////////////////////////////////////////////////
671
672 /**
673 ************************************************************************************************************************
674 * Lib::ComputeHtileInfo
675 *
676 * @brief
677 * Interface function stub of AddrComputeHtilenfo
678 *
679 * @return
680 * ADDR_E_RETURNCODE
681 ************************************************************************************************************************
682 */
ComputeHtileInfo(const ADDR2_COMPUTE_HTILE_INFO_INPUT * pIn,ADDR2_COMPUTE_HTILE_INFO_OUTPUT * pOut) const683 ADDR_E_RETURNCODE Lib::ComputeHtileInfo(
684 const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure
685 ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure
686 ) const
687 {
688 ADDR_E_RETURNCODE returnCode;
689
690 if ((GetFillSizeFieldsFlags() == TRUE) &&
691 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_INPUT)) ||
692 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_INFO_OUTPUT))))
693 {
694 returnCode = ADDR_INVALIDPARAMS;
695 }
696 else
697 {
698 returnCode = HwlComputeHtileInfo(pIn, pOut);
699
700 ValidMetaBaseAlignments(pOut->baseAlign);
701 }
702
703 return returnCode;
704 }
705
706 /**
707 ************************************************************************************************************************
708 * Lib::ComputeHtileAddrFromCoord
709 *
710 * @brief
711 * Interface function stub of AddrComputeHtileAddrFromCoord
712 *
713 * @return
714 * ADDR_E_RETURNCODE
715 ************************************************************************************************************************
716 */
ComputeHtileAddrFromCoord(const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT * pOut)717 ADDR_E_RETURNCODE Lib::ComputeHtileAddrFromCoord(
718 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
719 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
720 {
721 ADDR_E_RETURNCODE returnCode;
722
723 if ((GetFillSizeFieldsFlags() == TRUE) &&
724 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT)) ||
725 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT))))
726 {
727 returnCode = ADDR_INVALIDPARAMS;
728 }
729 else
730 {
731 returnCode = HwlComputeHtileAddrFromCoord(pIn, pOut);
732 }
733
734 return returnCode;
735 }
736
737 /**
738 ************************************************************************************************************************
739 * Lib::ComputeHtileCoordFromAddr
740 *
741 * @brief
742 * Interface function stub of AddrComputeHtileCoordFromAddr
743 *
744 * @return
745 * ADDR_E_RETURNCODE
746 ************************************************************************************************************************
747 */
ComputeHtileCoordFromAddr(const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT * pOut)748 ADDR_E_RETURNCODE Lib::ComputeHtileCoordFromAddr(
749 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
750 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) ///< [out] output structure
751 {
752 ADDR_E_RETURNCODE returnCode;
753
754 if ((GetFillSizeFieldsFlags() == TRUE) &&
755 ((pIn->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT)) ||
756 (pOut->size != sizeof(ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT))))
757 {
758 returnCode = ADDR_INVALIDPARAMS;
759 }
760 else
761 {
762 returnCode = HwlComputeHtileCoordFromAddr(pIn, pOut);
763 }
764
765 return returnCode;
766 }
767
768 /**
769 ************************************************************************************************************************
770 * Lib::ComputeCmaskInfo
771 *
772 * @brief
773 * Interface function stub of AddrComputeCmaskInfo
774 *
775 * @return
776 * ADDR_E_RETURNCODE
777 ************************************************************************************************************************
778 */
ComputeCmaskInfo(const ADDR2_COMPUTE_CMASK_INFO_INPUT * pIn,ADDR2_COMPUTE_CMASK_INFO_OUTPUT * pOut) const779 ADDR_E_RETURNCODE Lib::ComputeCmaskInfo(
780 const ADDR2_COMPUTE_CMASK_INFO_INPUT* pIn, ///< [in] input structure
781 ADDR2_COMPUTE_CMASK_INFO_OUTPUT* pOut ///< [out] output structure
782 ) const
783 {
784 ADDR_E_RETURNCODE returnCode;
785
786 if ((GetFillSizeFieldsFlags() == TRUE) &&
787 ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_INPUT)) ||
788 (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_INFO_OUTPUT))))
789 {
790 returnCode = ADDR_INVALIDPARAMS;
791 }
792 else if (pIn->cMaskFlags.linear)
793 {
794 returnCode = ADDR_INVALIDPARAMS;
795 }
796 else
797 {
798 returnCode = HwlComputeCmaskInfo(pIn, pOut);
799
800 ValidMetaBaseAlignments(pOut->baseAlign);
801 }
802
803 return returnCode;
804 }
805
806 /**
807 ************************************************************************************************************************
808 * Lib::ComputeCmaskAddrFromCoord
809 *
810 * @brief
811 * Interface function stub of AddrComputeCmaskAddrFromCoord
812 *
813 * @return
814 * ADDR_E_RETURNCODE
815 ************************************************************************************************************************
816 */
ComputeCmaskAddrFromCoord(const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT * pOut)817 ADDR_E_RETURNCODE Lib::ComputeCmaskAddrFromCoord(
818 const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
819 ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
820 {
821 ADDR_E_RETURNCODE returnCode;
822
823 if ((GetFillSizeFieldsFlags() == TRUE) &&
824 ((pIn->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT)) ||
825 (pOut->size != sizeof(ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT))))
826 {
827 returnCode = ADDR_INVALIDPARAMS;
828 }
829 else
830 {
831 returnCode = HwlComputeCmaskAddrFromCoord(pIn, pOut);
832 }
833
834 return returnCode;
835 }
836
837 /**
838 ************************************************************************************************************************
839 * Lib::ComputeCmaskCoordFromAddr
840 *
841 * @brief
842 * Interface function stub of AddrComputeCmaskCoordFromAddr
843 *
844 * @return
845 * ADDR_E_RETURNCODE
846 ************************************************************************************************************************
847 */
ComputeCmaskCoordFromAddr(const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT * pOut) const848 ADDR_E_RETURNCODE Lib::ComputeCmaskCoordFromAddr(
849 const ADDR2_COMPUTE_CMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
850 ADDR2_COMPUTE_CMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
851 ) const
852 {
853 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
854
855 ADDR_NOT_IMPLEMENTED();
856
857 return returnCode;
858 }
859
860 /**
861 ************************************************************************************************************************
862 * Lib::ComputeFmaskInfo
863 *
864 * @brief
865 * Interface function stub of ComputeFmaskInfo.
866 *
867 * @return
868 * ADDR_E_RETURNCODE
869 ************************************************************************************************************************
870 */
ComputeFmaskInfo(const ADDR2_COMPUTE_FMASK_INFO_INPUT * pIn,ADDR2_COMPUTE_FMASK_INFO_OUTPUT * pOut)871 ADDR_E_RETURNCODE Lib::ComputeFmaskInfo(
872 const ADDR2_COMPUTE_FMASK_INFO_INPUT* pIn, ///< [in] input structure
873 ADDR2_COMPUTE_FMASK_INFO_OUTPUT* pOut ///< [out] output structure
874 )
875 {
876 ADDR_E_RETURNCODE returnCode;
877
878 BOOL_32 valid = (IsZOrderSwizzle(pIn->swizzleMode) == TRUE) &&
879 ((pIn->numSamples > 0) || (pIn->numFrags > 0));
880
881 if (GetFillSizeFieldsFlags())
882 {
883 if ((pIn->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_INPUT)) ||
884 (pOut->size != sizeof(ADDR2_COMPUTE_FMASK_INFO_OUTPUT)))
885 {
886 valid = FALSE;
887 }
888 }
889
890 if (valid == FALSE)
891 {
892 returnCode = ADDR_INVALIDPARAMS;
893 }
894 else
895 {
896 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
897 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
898
899 localIn.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT);
900 localOut.size = sizeof(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT);
901
902 localIn.swizzleMode = pIn->swizzleMode;
903 localIn.numSlices = Max(pIn->numSlices, 1u);
904 localIn.width = Max(pIn->unalignedWidth, 1u);
905 localIn.height = Max(pIn->unalignedHeight, 1u);
906 localIn.bpp = GetFmaskBpp(pIn->numSamples, pIn->numFrags);
907 localIn.flags.fmask = 1;
908 localIn.numFrags = 1;
909 localIn.numSamples = 1;
910 localIn.resourceType = ADDR_RSRC_TEX_2D;
911
912 if (localIn.bpp == 8)
913 {
914 localIn.format = ADDR_FMT_8;
915 }
916 else if (localIn.bpp == 16)
917 {
918 localIn.format = ADDR_FMT_16;
919 }
920 else if (localIn.bpp == 32)
921 {
922 localIn.format = ADDR_FMT_32;
923 }
924 else
925 {
926 localIn.format = ADDR_FMT_32_32;
927 }
928
929 returnCode = ComputeSurfaceInfo(&localIn, &localOut);
930
931 if (returnCode == ADDR_OK)
932 {
933 pOut->pitch = localOut.pitch;
934 pOut->height = localOut.height;
935 pOut->baseAlign = localOut.baseAlign;
936 pOut->numSlices = localOut.numSlices;
937 pOut->fmaskBytes = static_cast<UINT_32>(localOut.surfSize);
938 pOut->sliceSize = static_cast<UINT_32>(localOut.sliceSize);
939 pOut->bpp = localIn.bpp;
940 pOut->numSamples = 1;
941 }
942 }
943
944 ValidBaseAlignments(pOut->baseAlign);
945
946 return returnCode;
947 }
948
949 /**
950 ************************************************************************************************************************
951 * Lib::ComputeFmaskAddrFromCoord
952 *
953 * @brief
954 * Interface function stub of ComputeFmaskAddrFromCoord.
955 *
956 * @return
957 * ADDR_E_RETURNCODE
958 ************************************************************************************************************************
959 */
ComputeFmaskAddrFromCoord(const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT * pOut) const960 ADDR_E_RETURNCODE Lib::ComputeFmaskAddrFromCoord(
961 const ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
962 ADDR2_COMPUTE_FMASK_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
963 ) const
964 {
965 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
966
967 ADDR_NOT_IMPLEMENTED();
968
969 return returnCode;
970 }
971
972 /**
973 ************************************************************************************************************************
974 * Lib::ComputeFmaskCoordFromAddr
975 *
976 * @brief
977 * Interface function stub of ComputeFmaskAddrFromCoord.
978 *
979 * @return
980 * ADDR_E_RETURNCODE
981 ************************************************************************************************************************
982 */
ComputeFmaskCoordFromAddr(const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT * pOut) const983 ADDR_E_RETURNCODE Lib::ComputeFmaskCoordFromAddr(
984 const ADDR2_COMPUTE_FMASK_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
985 ADDR2_COMPUTE_FMASK_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
986 ) const
987 {
988 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
989
990 ADDR_NOT_IMPLEMENTED();
991
992 return returnCode;
993 }
994
995 /**
996 ************************************************************************************************************************
997 * Lib::ComputeDccInfo
998 *
999 * @brief
1000 * Interface function to compute DCC key info
1001 *
1002 * @return
1003 * return code of HwlComputeDccInfo
1004 ************************************************************************************************************************
1005 */
ComputeDccInfo(const ADDR2_COMPUTE_DCCINFO_INPUT * pIn,ADDR2_COMPUTE_DCCINFO_OUTPUT * pOut) const1006 ADDR_E_RETURNCODE Lib::ComputeDccInfo(
1007 const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure
1008 ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure
1009 ) const
1010 {
1011 ADDR_E_RETURNCODE returnCode;
1012
1013 if ((GetFillSizeFieldsFlags() == TRUE) &&
1014 ((pIn->size != sizeof(ADDR2_COMPUTE_DCCINFO_INPUT)) ||
1015 (pOut->size != sizeof(ADDR2_COMPUTE_DCCINFO_OUTPUT))))
1016 {
1017 returnCode = ADDR_INVALIDPARAMS;
1018 }
1019 else
1020 {
1021 returnCode = HwlComputeDccInfo(pIn, pOut);
1022
1023 ValidMetaBaseAlignments(pOut->dccRamBaseAlign);
1024 }
1025
1026 return returnCode;
1027 }
1028
1029 /**
1030 ************************************************************************************************************************
1031 * Lib::ComputeDccAddrFromCoord
1032 *
1033 * @brief
1034 * Interface function stub of ComputeDccAddrFromCoord
1035 *
1036 * @return
1037 * ADDR_E_RETURNCODE
1038 ************************************************************************************************************************
1039 */
ComputeDccAddrFromCoord(const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT * pOut)1040 ADDR_E_RETURNCODE Lib::ComputeDccAddrFromCoord(
1041 const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1042 ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
1043 {
1044 ADDR_E_RETURNCODE returnCode;
1045
1046 if ((GetFillSizeFieldsFlags() == TRUE) &&
1047 ((pIn->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT)) ||
1048 (pOut->size != sizeof(ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT))))
1049 {
1050 returnCode = ADDR_INVALIDPARAMS;
1051 }
1052 else
1053 {
1054 returnCode = HwlSupportComputeDccAddrFromCoord(pIn);
1055
1056 if (returnCode == ADDR_OK)
1057 {
1058 HwlComputeDccAddrFromCoord(pIn, pOut);
1059 }
1060 }
1061
1062 return returnCode;
1063 }
1064
1065 /**
1066 ************************************************************************************************************************
1067 * Lib::ComputePipeBankXor
1068 *
1069 * @brief
1070 * Interface function stub of Addr2ComputePipeBankXor.
1071 *
1072 * @return
1073 * ADDR_E_RETURNCODE
1074 ************************************************************************************************************************
1075 */
ComputePipeBankXor(const ADDR2_COMPUTE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT * pOut)1076 ADDR_E_RETURNCODE Lib::ComputePipeBankXor(
1077 const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn,
1078 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut)
1079 {
1080 ADDR_E_RETURNCODE returnCode;
1081
1082 if ((GetFillSizeFieldsFlags() == TRUE) &&
1083 ((pIn->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_INPUT)) ||
1084 (pOut->size != sizeof(ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT))))
1085 {
1086 returnCode = ADDR_INVALIDPARAMS;
1087 }
1088 else
1089 {
1090 returnCode = HwlComputePipeBankXor(pIn, pOut);
1091 }
1092
1093 return returnCode;
1094 }
1095
1096 /**
1097 ************************************************************************************************************************
1098 * Lib::ComputeSlicePipeBankXor
1099 *
1100 * @brief
1101 * Interface function stub of Addr2ComputeSlicePipeBankXor.
1102 *
1103 * @return
1104 * ADDR_E_RETURNCODE
1105 ************************************************************************************************************************
1106 */
ComputeSlicePipeBankXor(const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT * pOut)1107 ADDR_E_RETURNCODE Lib::ComputeSlicePipeBankXor(
1108 const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn,
1109 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut)
1110 {
1111 ADDR_E_RETURNCODE returnCode;
1112
1113 if ((GetFillSizeFieldsFlags() == TRUE) &&
1114 ((pIn->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT)) ||
1115 (pOut->size != sizeof(ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT))))
1116 {
1117 returnCode = ADDR_INVALIDPARAMS;
1118 }
1119 else if ((IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE) ||
1120 (IsNonPrtXor(pIn->swizzleMode) == FALSE) ||
1121 (pIn->numSamples > 1))
1122 {
1123 returnCode = ADDR_NOTSUPPORTED;
1124 }
1125 else if ((pIn->bpe != 0) &&
1126 (pIn->bpe != 8) &&
1127 (pIn->bpe != 16) &&
1128 (pIn->bpe != 32) &&
1129 (pIn->bpe != 64) &&
1130 (pIn->bpe != 128))
1131 {
1132 returnCode = ADDR_INVALIDPARAMS;
1133 }
1134 else
1135 {
1136 returnCode = HwlComputeSlicePipeBankXor(pIn, pOut);
1137 }
1138
1139 return returnCode;
1140 }
1141
1142 /**
1143 ************************************************************************************************************************
1144 * Lib::ComputeSubResourceOffsetForSwizzlePattern
1145 *
1146 * @brief
1147 * Interface function stub of Addr2ComputeSubResourceOffsetForSwizzlePattern.
1148 *
1149 * @return
1150 * ADDR_E_RETURNCODE
1151 ************************************************************************************************************************
1152 */
ComputeSubResourceOffsetForSwizzlePattern(const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT * pIn,ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT * pOut)1153 ADDR_E_RETURNCODE Lib::ComputeSubResourceOffsetForSwizzlePattern(
1154 const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn,
1155 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut)
1156 {
1157 ADDR_E_RETURNCODE returnCode;
1158
1159 if ((GetFillSizeFieldsFlags() == TRUE) &&
1160 ((pIn->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT)) ||
1161 (pOut->size != sizeof(ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT))))
1162 {
1163 returnCode = ADDR_INVALIDPARAMS;
1164 }
1165 else
1166 {
1167 returnCode = HwlComputeSubResourceOffsetForSwizzlePattern(pIn, pOut);
1168 }
1169
1170 return returnCode;
1171 }
1172
1173 /**
1174 ************************************************************************************************************************
1175 * Lib::ComputeNonBlockCompressedView
1176 *
1177 * @brief
1178 * Interface function stub of Addr2ComputeNonBlockCompressedView.
1179 *
1180 * @return
1181 * ADDR_E_RETURNCODE
1182 ************************************************************************************************************************
1183 */
ComputeNonBlockCompressedView(const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT * pIn,ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT * pOut)1184 ADDR_E_RETURNCODE Lib::ComputeNonBlockCompressedView(
1185 const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn,
1186 ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT* pOut)
1187 {
1188 ADDR_E_RETURNCODE returnCode;
1189
1190 if ((GetFillSizeFieldsFlags() == TRUE) &&
1191 ((pIn->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT)) ||
1192 (pOut->size != sizeof(ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT))))
1193 {
1194 returnCode = ADDR_INVALIDPARAMS;
1195 }
1196 else
1197 {
1198 returnCode = HwlComputeNonBlockCompressedView(pIn, pOut);
1199 }
1200
1201 return returnCode;
1202 }
1203
1204 /**
1205 ************************************************************************************************************************
1206 * Lib::ExtractPipeBankXor
1207 *
1208 * @brief
1209 * Internal function to extract bank and pipe xor bits from combined xor bits.
1210 *
1211 * @return
1212 * ADDR_E_RETURNCODE
1213 ************************************************************************************************************************
1214 */
ExtractPipeBankXor(UINT_32 pipeBankXor,UINT_32 bankBits,UINT_32 pipeBits,UINT_32 * pBankX,UINT_32 * pPipeX)1215 ADDR_E_RETURNCODE Lib::ExtractPipeBankXor(
1216 UINT_32 pipeBankXor,
1217 UINT_32 bankBits,
1218 UINT_32 pipeBits,
1219 UINT_32* pBankX,
1220 UINT_32* pPipeX)
1221 {
1222 ADDR_E_RETURNCODE returnCode;
1223
1224 if (pipeBankXor < (1u << (pipeBits + bankBits)))
1225 {
1226 *pPipeX = pipeBankXor % (1 << pipeBits);
1227 *pBankX = pipeBankXor >> pipeBits;
1228 returnCode = ADDR_OK;
1229 }
1230 else
1231 {
1232 ADDR_ASSERT_ALWAYS();
1233 returnCode = ADDR_INVALIDPARAMS;
1234 }
1235
1236 return returnCode;
1237 }
1238
1239 /**
1240 ************************************************************************************************************************
1241 * Lib::ComputeSurfaceInfoSanityCheck
1242 *
1243 * @brief
1244 * Internal function to do basic sanity check before compute surface info
1245 *
1246 * @return
1247 * ADDR_E_RETURNCODE
1248 ************************************************************************************************************************
1249 */
ComputeSurfaceInfoSanityCheck(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1250 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoSanityCheck(
1251 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure
1252 ) const
1253 {
1254 ADDR_E_RETURNCODE returnCode;
1255
1256 if ((GetFillSizeFieldsFlags() == TRUE) &&
1257 (pIn->size != sizeof(ADDR2_COMPUTE_SURFACE_INFO_INPUT)))
1258 {
1259 returnCode = ADDR_INVALIDPARAMS;
1260 }
1261 else
1262 {
1263 returnCode = HwlComputeSurfaceInfoSanityCheck(pIn);
1264 }
1265
1266 return returnCode;
1267 }
1268
1269 /**
1270 ************************************************************************************************************************
1271 * Lib::ApplyCustomizedPitchHeight
1272 *
1273 * @brief
1274 * Helper function to override hw required row pitch/slice pitch by customrized one
1275 *
1276 * @return
1277 * ADDR_E_RETURNCODE
1278 ************************************************************************************************************************
1279 */
ApplyCustomizedPitchHeight(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 elementBytes,UINT_32 pitchAlignInElement,UINT_32 * pPitch,UINT_32 * pHeight) const1280 ADDR_E_RETURNCODE Lib::ApplyCustomizedPitchHeight(
1281 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1282 UINT_32 elementBytes, ///< [in] element bytes per element
1283 UINT_32 pitchAlignInElement, ///< [in] pitch alignment in element
1284 UINT_32* pPitch, ///< [in/out] pitch
1285 UINT_32* pHeight ///< [in/out] height
1286 ) const
1287 {
1288 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1289
1290 if (pIn->numMipLevels <= 1)
1291 {
1292 if (pIn->pitchInElement > 0)
1293 {
1294 if ((pIn->pitchInElement % pitchAlignInElement) != 0)
1295 {
1296 returnCode = ADDR_INVALIDPARAMS;
1297 }
1298 else if (pIn->pitchInElement < (*pPitch))
1299 {
1300 returnCode = ADDR_INVALIDPARAMS;
1301 }
1302 else
1303 {
1304 *pPitch = pIn->pitchInElement;
1305 }
1306 }
1307
1308 if (returnCode == ADDR_OK)
1309 {
1310 if (pIn->sliceAlign > 0)
1311 {
1312 UINT_32 customizedHeight = pIn->sliceAlign / elementBytes / (*pPitch);
1313
1314 if (customizedHeight * elementBytes * (*pPitch) != pIn->sliceAlign)
1315 {
1316 returnCode = ADDR_INVALIDPARAMS;
1317 }
1318 else if ((pIn->numSlices > 1) && ((*pHeight) != customizedHeight))
1319 {
1320 returnCode = ADDR_INVALIDPARAMS;
1321 }
1322 else
1323 {
1324 *pHeight = customizedHeight;
1325 }
1326 }
1327 }
1328 }
1329
1330 return returnCode;
1331 }
1332
1333 /**
1334 ************************************************************************************************************************
1335 * Lib::ComputeSurfaceInfoLinear
1336 *
1337 * @brief
1338 * Internal function to calculate alignment for linear swizzle surface
1339 *
1340 * @return
1341 * ADDR_E_RETURNCODE
1342 ************************************************************************************************************************
1343 */
ComputeSurfaceInfoLinear(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1344 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoLinear(
1345 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1346 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
1347 ) const
1348 {
1349 return HwlComputeSurfaceInfoLinear(pIn, pOut);
1350 }
1351
1352 /**
1353 ************************************************************************************************************************
1354 * Lib::ComputeSurfaceInfoTiled
1355 *
1356 * @brief
1357 * Internal function to calculate alignment for tiled swizzle surface
1358 *
1359 * @return
1360 * ADDR_E_RETURNCODE
1361 ************************************************************************************************************************
1362 */
ComputeSurfaceInfoTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1363 ADDR_E_RETURNCODE Lib::ComputeSurfaceInfoTiled(
1364 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1365 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
1366 ) const
1367 {
1368 return HwlComputeSurfaceInfoTiled(pIn, pOut);
1369 }
1370
1371 /**
1372 ************************************************************************************************************************
1373 * Lib::ComputeSurfaceAddrFromCoordLinear
1374 *
1375 * @brief
1376 * Internal function to calculate address from coord for linear swizzle surface
1377 *
1378 * @return
1379 * ADDR_E_RETURNCODE
1380 ************************************************************************************************************************
1381 */
ComputeSurfaceAddrFromCoordLinear(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const1382 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordLinear(
1383 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1384 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1385 ) const
1386 {
1387 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1388 BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1) && (pIn->pipeBankXor == 0);
1389
1390 if (valid)
1391 {
1392 if (IsTex1d(pIn->resourceType))
1393 {
1394 valid = (pIn->y == 0);
1395 }
1396 }
1397
1398 if (valid)
1399 {
1400 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
1401 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1402 ADDR2_MIP_INFO mipInfo[MaxMipLevels];
1403 ADDR_ASSERT(pIn->numMipLevels <= MaxMipLevels);
1404
1405 localIn.bpp = pIn->bpp;
1406 localIn.swizzleMode = pIn->swizzleMode;
1407 localIn.flags = pIn->flags;
1408 localIn.width = Max(pIn->unalignedWidth, 1u);
1409 localIn.height = Max(pIn->unalignedHeight, 1u);
1410 localIn.numSlices = Max(pIn->numSlices, 1u);
1411 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1412 localIn.resourceType = pIn->resourceType;
1413
1414 if (localIn.numMipLevels <= 1)
1415 {
1416 localIn.pitchInElement = pIn->pitchInElement;
1417 }
1418
1419 localOut.pMipInfo = mipInfo;
1420
1421 returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1422
1423 if (returnCode == ADDR_OK)
1424 {
1425 pOut->addr = (localOut.sliceSize * pIn->slice) +
1426 mipInfo[pIn->mipId].offset +
1427 (pIn->y * mipInfo[pIn->mipId].pitch + pIn->x) * (pIn->bpp >> 3);
1428 pOut->bitPosition = 0;
1429 }
1430 else
1431 {
1432 valid = FALSE;
1433 }
1434 }
1435
1436 if (valid == FALSE)
1437 {
1438 returnCode = ADDR_INVALIDPARAMS;
1439 }
1440
1441 return returnCode;
1442 }
1443
1444 /**
1445 ************************************************************************************************************************
1446 * Lib::ComputeSurfaceAddrFromCoordTiled
1447 *
1448 * @brief
1449 * Internal function to calculate address from coord for tiled swizzle surface
1450 *
1451 * @return
1452 * ADDR_E_RETURNCODE
1453 ************************************************************************************************************************
1454 */
ComputeSurfaceAddrFromCoordTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const1455 ADDR_E_RETURNCODE Lib::ComputeSurfaceAddrFromCoordTiled(
1456 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
1457 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
1458 ) const
1459 {
1460 return HwlComputeSurfaceAddrFromCoordTiled(pIn, pOut);
1461 }
1462
1463 /**
1464 ************************************************************************************************************************
1465 * Lib::ComputeSurfaceCoordFromAddrLinear
1466 *
1467 * @brief
1468 * Internal function to calculate coord from address for linear swizzle surface
1469 *
1470 * @return
1471 * ADDR_E_RETURNCODE
1472 ************************************************************************************************************************
1473 */
ComputeSurfaceCoordFromAddrLinear(const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const1474 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrLinear(
1475 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1476 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1477 ) const
1478 {
1479 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1480
1481 BOOL_32 valid = (pIn->numSamples <= 1) && (pIn->numFrags <= 1);
1482
1483 if (valid)
1484 {
1485 if (IsTex1d(pIn->resourceType))
1486 {
1487 valid = (pIn->unalignedHeight == 1);
1488 }
1489 }
1490
1491 if (valid)
1492 {
1493 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {0};
1494 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {0};
1495 localIn.bpp = pIn->bpp;
1496 localIn.swizzleMode = pIn->swizzleMode;
1497 localIn.flags = pIn->flags;
1498 localIn.width = Max(pIn->unalignedWidth, 1u);
1499 localIn.height = Max(pIn->unalignedHeight, 1u);
1500 localIn.numSlices = Max(pIn->numSlices, 1u);
1501 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
1502 localIn.resourceType = pIn->resourceType;
1503 if (localIn.numMipLevels <= 1)
1504 {
1505 localIn.pitchInElement = pIn->pitchInElement;
1506 }
1507 returnCode = ComputeSurfaceInfoLinear(&localIn, &localOut);
1508
1509 if (returnCode == ADDR_OK)
1510 {
1511 pOut->slice = static_cast<UINT_32>(pIn->addr / localOut.sliceSize);
1512 pOut->sample = 0;
1513
1514 UINT_32 offsetInSlice = static_cast<UINT_32>(pIn->addr % localOut.sliceSize);
1515 UINT_32 elementBytes = pIn->bpp >> 3;
1516 UINT_32 mipOffsetInSlice = 0;
1517 UINT_32 mipSize = 0;
1518 UINT_32 mipId = 0;
1519 for (; mipId < pIn->numMipLevels ; mipId++)
1520 {
1521 if (IsTex1d(pIn->resourceType))
1522 {
1523 mipSize = localOut.pitch * elementBytes;
1524 }
1525 else
1526 {
1527 UINT_32 currentMipHeight = (PowTwoAlign(localIn.height, (1 << mipId))) >> mipId;
1528 mipSize = currentMipHeight * localOut.pitch * elementBytes;
1529 }
1530
1531 if (mipSize == 0)
1532 {
1533 valid = FALSE;
1534 break;
1535 }
1536 else if ((mipSize + mipOffsetInSlice) > offsetInSlice)
1537 {
1538 break;
1539 }
1540 else
1541 {
1542 mipOffsetInSlice += mipSize;
1543 if ((mipId == (pIn->numMipLevels - 1)) ||
1544 (mipOffsetInSlice >= localOut.sliceSize))
1545 {
1546 valid = FALSE;
1547 }
1548 }
1549 }
1550
1551 if (valid)
1552 {
1553 pOut->mipId = mipId;
1554
1555 UINT_32 elemOffsetInMip = (offsetInSlice - mipOffsetInSlice) / elementBytes;
1556 if (IsTex1d(pIn->resourceType))
1557 {
1558 if (elemOffsetInMip < localOut.pitch)
1559 {
1560 pOut->x = elemOffsetInMip;
1561 pOut->y = 0;
1562 }
1563 else
1564 {
1565 valid = FALSE;
1566 }
1567 }
1568 else
1569 {
1570 pOut->y = elemOffsetInMip / localOut.pitch;
1571 pOut->x = elemOffsetInMip % localOut.pitch;
1572 }
1573
1574 if ((pOut->slice >= pIn->numSlices) ||
1575 (pOut->mipId >= pIn->numMipLevels) ||
1576 (pOut->x >= Max((pIn->unalignedWidth >> pOut->mipId), 1u)) ||
1577 (pOut->y >= Max((pIn->unalignedHeight >> pOut->mipId), 1u)) ||
1578 (IsTex3d(pIn->resourceType) &&
1579 (FALSE == Valid3DMipSliceIdConstraint(pIn->numSlices,
1580 pOut->mipId,
1581 pOut->slice))))
1582 {
1583 valid = FALSE;
1584 }
1585 }
1586 }
1587 else
1588 {
1589 valid = FALSE;
1590 }
1591 }
1592
1593 if (valid == FALSE)
1594 {
1595 returnCode = ADDR_INVALIDPARAMS;
1596 }
1597
1598 return returnCode;
1599 }
1600
1601 /**
1602 ************************************************************************************************************************
1603 * Lib::ComputeSurfaceCoordFromAddrTiled
1604 *
1605 * @brief
1606 * Internal function to calculate coord from address for tiled swizzle surface
1607 *
1608 * @return
1609 * ADDR_E_RETURNCODE
1610 ************************************************************************************************************************
1611 */
ComputeSurfaceCoordFromAddrTiled(const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT * pOut) const1612 ADDR_E_RETURNCODE Lib::ComputeSurfaceCoordFromAddrTiled(
1613 const ADDR2_COMPUTE_SURFACE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
1614 ADDR2_COMPUTE_SURFACE_COORDFROMADDR_OUTPUT* pOut ///< [out] output structure
1615 ) const
1616 {
1617 ADDR_E_RETURNCODE returnCode = ADDR_NOTIMPLEMENTED;
1618
1619 ADDR_NOT_IMPLEMENTED();
1620
1621 return returnCode;
1622 }
1623
1624 /**
1625 ************************************************************************************************************************
1626 * Lib::ComputeBlockDimensionForSurf
1627 *
1628 * @brief
1629 * Internal function to get block width/height/depth in element from surface input params.
1630 *
1631 * @return
1632 * ADDR_E_RETURNCODE
1633 ************************************************************************************************************************
1634 */
ComputeBlockDimensionForSurf(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,UINT_32 numSamples,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1635 ADDR_E_RETURNCODE Lib::ComputeBlockDimensionForSurf(
1636 UINT_32* pWidth,
1637 UINT_32* pHeight,
1638 UINT_32* pDepth,
1639 UINT_32 bpp,
1640 UINT_32 numSamples,
1641 AddrResourceType resourceType,
1642 AddrSwizzleMode swizzleMode) const
1643 {
1644 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1645
1646 if (IsThick(resourceType, swizzleMode))
1647 {
1648 ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);
1649 }
1650 else if (IsThin(resourceType, swizzleMode))
1651 {
1652 ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, numSamples, resourceType, swizzleMode);
1653 }
1654 else
1655 {
1656 ADDR_ASSERT_ALWAYS();
1657 returnCode = ADDR_INVALIDPARAMS;
1658 }
1659
1660 return returnCode;
1661 }
1662
1663 /**
1664 ************************************************************************************************************************
1665 * Lib::ComputeThinBlockDimension
1666 *
1667 * @brief
1668 * Internal function to get thin block width/height/depth in element from surface input params.
1669 *
1670 * @return
1671 * N/A
1672 ************************************************************************************************************************
1673 */
ComputeThinBlockDimension(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,UINT_32 numSamples,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1674 VOID Lib::ComputeThinBlockDimension(
1675 UINT_32* pWidth,
1676 UINT_32* pHeight,
1677 UINT_32* pDepth,
1678 UINT_32 bpp,
1679 UINT_32 numSamples,
1680 AddrResourceType resourceType,
1681 AddrSwizzleMode swizzleMode) const
1682 {
1683 ADDR_ASSERT(IsThin(resourceType, swizzleMode));
1684
1685 // GFX9/GFX10 use different dimension amplifying logic: say for 128KB block + 1xAA + 1BPE, the dimension of thin
1686 // swizzle mode will be [256W * 512H] on GFX9 ASICs and [512W * 256H] on GFX10 ASICs. Since GFX10 is newer HWL so we
1687 // make its implementation into base class (in order to save future change on new HWLs)
1688 const UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);
1689 const UINT_32 log2EleBytes = Log2(bpp >> 3);
1690 const UINT_32 log2Samples = Log2(Max(numSamples, 1u));
1691 const UINT_32 log2NumEle = log2BlkSize - log2EleBytes - log2Samples;
1692
1693 // For "1xAA/4xAA cases" or "2xAA/8xAA + odd log2BlkSize cases", width == height or width == 2 * height;
1694 // For other cases, height == width or height == 2 * width
1695 const BOOL_32 widthPrecedent = ((log2Samples & 1) == 0) || ((log2BlkSize & 1) != 0);
1696 const UINT_32 log2Width = (log2NumEle + (widthPrecedent ? 1 : 0)) / 2;
1697
1698 *pWidth = 1u << log2Width;
1699 *pHeight = 1u << (log2NumEle - log2Width);
1700 *pDepth = 1;
1701 }
1702
1703 /**
1704 ************************************************************************************************************************
1705 * Lib::ComputeBlockDimension
1706 *
1707 * @brief
1708 * Internal function to get block width/height/depth in element without considering MSAA case
1709 *
1710 * @return
1711 * ADDR_E_RETURNCODE
1712 ************************************************************************************************************************
1713 */
ComputeBlockDimension(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1714 ADDR_E_RETURNCODE Lib::ComputeBlockDimension(
1715 UINT_32* pWidth,
1716 UINT_32* pHeight,
1717 UINT_32* pDepth,
1718 UINT_32 bpp,
1719 AddrResourceType resourceType,
1720 AddrSwizzleMode swizzleMode) const
1721 {
1722 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1723
1724 if (IsThick(resourceType, swizzleMode))
1725 {
1726 ComputeThickBlockDimension(pWidth, pHeight, pDepth, bpp, resourceType, swizzleMode);
1727 }
1728 else if (IsThin(resourceType, swizzleMode))
1729 {
1730 ComputeThinBlockDimension(pWidth, pHeight, pDepth, bpp, 0, resourceType, swizzleMode);
1731 }
1732 else
1733 {
1734 ADDR_ASSERT_ALWAYS();
1735 returnCode = ADDR_INVALIDPARAMS;
1736 }
1737
1738 return returnCode;
1739 }
1740
1741 /**
1742 ************************************************************************************************************************
1743 * Lib::ComputeThickBlockDimension
1744 *
1745 * @brief
1746 * Internal function to get block width/height/depth in element for thick swizzle mode
1747 *
1748 * @return
1749 * N/A
1750 ************************************************************************************************************************
1751 */
ComputeThickBlockDimension(UINT_32 * pWidth,UINT_32 * pHeight,UINT_32 * pDepth,UINT_32 bpp,AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const1752 VOID Lib::ComputeThickBlockDimension(
1753 UINT_32* pWidth,
1754 UINT_32* pHeight,
1755 UINT_32* pDepth,
1756 UINT_32 bpp,
1757 AddrResourceType resourceType,
1758 AddrSwizzleMode swizzleMode) const
1759 {
1760 ADDR_ASSERT(IsThick(resourceType, swizzleMode));
1761
1762 const UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);
1763 const UINT_32 eleBytes = bpp >> 3;
1764 const UINT_32 microBlockSizeTableIndex = Log2(eleBytes);
1765
1766 ADDR_ASSERT(microBlockSizeTableIndex < sizeof(Block1K_3d) / sizeof(Block1K_3d[0]));
1767
1768 const UINT_32 log2blkSizeIn1KB = log2BlkSize - 10;
1769 const UINT_32 averageAmp = log2blkSizeIn1KB / 3;
1770 const UINT_32 restAmp = log2blkSizeIn1KB % 3;
1771
1772 *pWidth = Block1K_3d[microBlockSizeTableIndex].w << averageAmp;
1773 *pHeight = Block1K_3d[microBlockSizeTableIndex].h << (averageAmp + (restAmp / 2));
1774 *pDepth = Block1K_3d[microBlockSizeTableIndex].d << (averageAmp + ((restAmp != 0) ? 1 : 0));
1775 }
1776
1777 /**
1778 ************************************************************************************************************************
1779 * Lib::GetMipTailDim
1780 *
1781 * @brief
1782 * Internal function to get out max dimension of first level in mip tail
1783 *
1784 * @return
1785 * Max Width/Height/Depth value of the first mip fitted in mip tail
1786 ************************************************************************************************************************
1787 */
GetMipTailDim(AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 blockWidth,UINT_32 blockHeight,UINT_32 blockDepth) const1788 Dim3d Lib::GetMipTailDim(
1789 AddrResourceType resourceType,
1790 AddrSwizzleMode swizzleMode,
1791 UINT_32 blockWidth,
1792 UINT_32 blockHeight,
1793 UINT_32 blockDepth) const
1794 {
1795 Dim3d out = {blockWidth, blockHeight, blockDepth};
1796 UINT_32 log2BlkSize = GetBlockSizeLog2(swizzleMode);
1797
1798 if (IsThick(resourceType, swizzleMode))
1799 {
1800 UINT_32 dim = log2BlkSize % 3;
1801
1802 if (dim == 0)
1803 {
1804 out.h >>= 1;
1805 }
1806 else if (dim == 1)
1807 {
1808 out.w >>= 1;
1809 }
1810 else
1811 {
1812 out.d >>= 1;
1813 }
1814 }
1815 else
1816 {
1817 ADDR_ASSERT(IsThin(resourceType, swizzleMode));
1818
1819 #if DEBUG
1820 // GFX9/GFX10 use different dimension shrinking logic for mipmap tail: say for 128KB block + 2BPE, the maximum
1821 // dimension of mipmap tail level will be [256W * 128H] on GFX9 ASICs and [128W * 256H] on GFX10 ASICs. Since
1822 // GFX10 is newer HWL so we make its implementation into base class, in order to save future change on new HWLs.
1823 // And assert log2BlkSize will always be an even value on GFX9, so we never need the logic wrapped by DEBUG...
1824 if ((log2BlkSize & 1) && (m_chipFamily == ADDR_CHIP_FAMILY_AI))
1825 {
1826 // Should never go here...
1827 ADDR_ASSERT_ALWAYS();
1828
1829 out.h >>= 1;
1830 }
1831 else
1832 #endif
1833 {
1834 out.w >>= 1;
1835 }
1836 }
1837
1838 return out;
1839 }
1840
1841 /**
1842 ************************************************************************************************************************
1843 * Lib::ComputeSurface2DMicroBlockOffset
1844 *
1845 * @brief
1846 * Internal function to calculate micro block (256B) offset from coord for 2D resource
1847 *
1848 * @return
1849 * micro block (256B) offset for 2D resource
1850 ************************************************************************************************************************
1851 */
ComputeSurface2DMicroBlockOffset(const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn) const1852 UINT_32 Lib::ComputeSurface2DMicroBlockOffset(
1853 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1854 {
1855 ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
1856
1857 UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1858 UINT_32 microBlockOffset = 0;
1859 if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1860 {
1861 UINT_32 xBits = pIn->x << log2ElementBytes;
1862 microBlockOffset = (xBits & 0xf) | ((pIn->y & 0x3) << 4);
1863 if (log2ElementBytes < 3)
1864 {
1865 microBlockOffset |= (pIn->y & 0x4) << 4;
1866 if (log2ElementBytes == 0)
1867 {
1868 microBlockOffset |= (pIn->y & 0x8) << 4;
1869 }
1870 else
1871 {
1872 microBlockOffset |= (xBits & 0x10) << 3;
1873 }
1874 }
1875 else
1876 {
1877 microBlockOffset |= (xBits & 0x30) << 2;
1878 }
1879 }
1880 else if (IsDisplaySwizzle(pIn->resourceType, pIn->swizzleMode))
1881 {
1882 if (log2ElementBytes == 4)
1883 {
1884 microBlockOffset = (GetBit(pIn->x, 0) << 4) |
1885 (GetBit(pIn->y, 0) << 5) |
1886 (GetBit(pIn->x, 1) << 6) |
1887 (GetBit(pIn->y, 1) << 7);
1888 }
1889 else
1890 {
1891 microBlockOffset = GetBits(pIn->x, 0, 3, log2ElementBytes) |
1892 GetBits(pIn->y, 1, 2, 3 + log2ElementBytes) |
1893 GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1894 GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1895 microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1896 (GetBit(pIn->y, 0) << 4) |
1897 GetBits(microBlockOffset, 4, 3, 5);
1898 }
1899 }
1900 else if (IsRotateSwizzle(pIn->swizzleMode))
1901 {
1902 microBlockOffset = GetBits(pIn->y, 0, 3, log2ElementBytes) |
1903 GetBits(pIn->x, 1, 2, 3 + log2ElementBytes) |
1904 GetBits(pIn->x, 3, 1, 5 + log2ElementBytes) |
1905 GetBits(pIn->y, 3, 1, 6 + log2ElementBytes);
1906 microBlockOffset = GetBits(microBlockOffset, 0, 4, 0) |
1907 (GetBit(pIn->x, 0) << 4) |
1908 GetBits(microBlockOffset, 4, 3, 5);
1909 if (log2ElementBytes == 3)
1910 {
1911 microBlockOffset = GetBits(microBlockOffset, 0, 6, 0) |
1912 GetBits(pIn->x, 1, 2, 6);
1913 }
1914 }
1915
1916 return microBlockOffset;
1917 }
1918
1919 /**
1920 ************************************************************************************************************************
1921 * Lib::ComputeSurface3DMicroBlockOffset
1922 *
1923 * @brief
1924 * Internal function to calculate micro block (1KB) offset from coord for 3D resource
1925 *
1926 * @return
1927 * micro block (1KB) offset for 3D resource
1928 ************************************************************************************************************************
1929 */
ComputeSurface3DMicroBlockOffset(const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn) const1930 UINT_32 Lib::ComputeSurface3DMicroBlockOffset(
1931 const _ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn) const
1932 {
1933 ADDR_ASSERT(IsThick(pIn->resourceType, pIn->swizzleMode));
1934
1935 UINT_32 log2ElementBytes = Log2(pIn->bpp >> 3);
1936 UINT_32 microBlockOffset = 0;
1937 if (IsStandardSwizzle(pIn->resourceType, pIn->swizzleMode))
1938 {
1939 if (log2ElementBytes == 0)
1940 {
1941 microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1942 }
1943 else if (log2ElementBytes == 1)
1944 {
1945 microBlockOffset = ((pIn->slice & 4) >> 2) | ((pIn->y & 4) >> 1);
1946 }
1947 else if (log2ElementBytes == 2)
1948 {
1949 microBlockOffset = ((pIn->y & 4) >> 2) | ((pIn->x & 4) >> 1);
1950 }
1951 else if (log2ElementBytes == 3)
1952 {
1953 microBlockOffset = (pIn->x & 6) >> 1;
1954 }
1955 else
1956 {
1957 microBlockOffset = pIn->x & 3;
1958 }
1959
1960 microBlockOffset <<= 8;
1961
1962 UINT_32 xBits = pIn->x << log2ElementBytes;
1963 microBlockOffset |= (xBits & 0xf) | ((pIn->y & 0x3) << 4) | ((pIn->slice & 0x3) << 6);
1964 }
1965 else if (IsZOrderSwizzle(pIn->swizzleMode))
1966 {
1967 UINT_32 xh, yh, zh;
1968
1969 if (log2ElementBytes == 0)
1970 {
1971 microBlockOffset =
1972 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1973 microBlockOffset = microBlockOffset | ((pIn->slice & 3) << 4) | ((pIn->x & 4) << 4);
1974
1975 xh = pIn->x >> 3;
1976 yh = pIn->y >> 2;
1977 zh = pIn->slice >> 2;
1978 }
1979 else if (log2ElementBytes == 1)
1980 {
1981 microBlockOffset =
1982 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->y & 2) << 2);
1983 microBlockOffset = (microBlockOffset << 1) | ((pIn->slice & 3) << 5);
1984
1985 xh = pIn->x >> 2;
1986 yh = pIn->y >> 2;
1987 zh = pIn->slice >> 2;
1988 }
1989 else if (log2ElementBytes == 2)
1990 {
1991 microBlockOffset =
1992 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->x & 2) << 1) | ((pIn->slice & 1) << 3);
1993 microBlockOffset = (microBlockOffset << 2) | ((pIn->y & 2) << 5);
1994
1995 xh = pIn->x >> 2;
1996 yh = pIn->y >> 2;
1997 zh = pIn->slice >> 1;
1998 }
1999 else if (log2ElementBytes == 3)
2000 {
2001 microBlockOffset =
2002 (pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2) | ((pIn->x & 2) << 2);
2003 microBlockOffset <<= 3;
2004
2005 xh = pIn->x >> 2;
2006 yh = pIn->y >> 1;
2007 zh = pIn->slice >> 1;
2008 }
2009 else
2010 {
2011 microBlockOffset =
2012 (((pIn->x & 1) | ((pIn->y & 1) << 1) | ((pIn->slice & 1) << 2)) << 4);
2013
2014 xh = pIn->x >> 1;
2015 yh = pIn->y >> 1;
2016 zh = pIn->slice >> 1;
2017 }
2018
2019 microBlockOffset |= ((MortonGen3d(xh, yh, zh, 1) << 7) & 0x380);
2020 }
2021
2022 return microBlockOffset;
2023 }
2024
2025 /**
2026 ************************************************************************************************************************
2027 * Lib::GetPipeXorBits
2028 *
2029 * @brief
2030 * Internal function to get bits number for pipe/se xor operation
2031 *
2032 * @return
2033 * ADDR_E_RETURNCODE
2034 ************************************************************************************************************************
2035 */
GetPipeXorBits(UINT_32 macroBlockBits) const2036 UINT_32 Lib::GetPipeXorBits(
2037 UINT_32 macroBlockBits) const
2038 {
2039 ADDR_ASSERT(macroBlockBits >= m_pipeInterleaveLog2);
2040
2041 // Total available xor bits
2042 UINT_32 xorBits = macroBlockBits - m_pipeInterleaveLog2;
2043
2044 // Pipe/Se xor bits
2045 UINT_32 pipeBits = Min(xorBits, m_pipesLog2 + m_seLog2);
2046
2047 return pipeBits;
2048 }
2049
2050 /**
2051 ************************************************************************************************************************
2052 * Lib::Addr2GetPreferredSurfaceSetting
2053 *
2054 * @brief
2055 * Internal function to get suggested surface information for cliet to use
2056 *
2057 * @return
2058 * ADDR_E_RETURNCODE
2059 ************************************************************************************************************************
2060 */
Addr2GetPreferredSurfaceSetting(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const2061 ADDR_E_RETURNCODE Lib::Addr2GetPreferredSurfaceSetting(
2062 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
2063 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const
2064 {
2065 ADDR_E_RETURNCODE returnCode;
2066
2067 if ((GetFillSizeFieldsFlags() == TRUE) &&
2068 ((pIn->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_INPUT)) ||
2069 (pOut->size != sizeof(ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT))))
2070 {
2071 returnCode = ADDR_INVALIDPARAMS;
2072 }
2073 else
2074 {
2075 returnCode = HwlGetPreferredSurfaceSetting(pIn, pOut);
2076 }
2077
2078 return returnCode;
2079 }
2080
2081 /**
2082 ************************************************************************************************************************
2083 * Lib::GetPossibleSwizzleModes
2084 *
2085 * @brief
2086 * Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from
2087 *
2088 * @return
2089 * ADDR_E_RETURNCODE
2090 ************************************************************************************************************************
2091 */
GetPossibleSwizzleModes(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const2092 ADDR_E_RETURNCODE Lib::GetPossibleSwizzleModes(
2093 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn,
2094 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut) const
2095 {
2096 return HwlGetPossibleSwizzleModes(pIn, pOut);
2097 }
2098
2099 /**
2100 ************************************************************************************************************************
2101 * Lib::GetAllowedBlockSet
2102 *
2103 * @brief
2104 * Returns the set of allowed block sizes given the allowed swizzle modes and resource type
2105 *
2106 * @return
2107 * ADDR_E_RETURNCODE
2108 ************************************************************************************************************************
2109 */
GetAllowedBlockSet(ADDR2_SWMODE_SET allowedSwModeSet,AddrResourceType rsrcType,ADDR2_BLOCK_SET * pAllowedBlockSet) const2110 ADDR_E_RETURNCODE Lib::GetAllowedBlockSet(
2111 ADDR2_SWMODE_SET allowedSwModeSet,
2112 AddrResourceType rsrcType,
2113 ADDR2_BLOCK_SET* pAllowedBlockSet) const
2114 {
2115 return HwlGetAllowedBlockSet(allowedSwModeSet, rsrcType, pAllowedBlockSet);
2116 }
2117
2118 /**
2119 ************************************************************************************************************************
2120 * Lib::GetAllowedSwSet
2121 *
2122 * @brief
2123 * Returns the set of allowed swizzle types given the allowed swizzle modes
2124 *
2125 * @return
2126 * ADDR_E_RETURNCODE
2127 ************************************************************************************************************************
2128 */
GetAllowedSwSet(ADDR2_SWMODE_SET allowedSwModeSet,ADDR2_SWTYPE_SET * pAllowedSwSet) const2129 ADDR_E_RETURNCODE Lib::GetAllowedSwSet(
2130 ADDR2_SWMODE_SET allowedSwModeSet,
2131 ADDR2_SWTYPE_SET* pAllowedSwSet) const
2132 {
2133 return HwlGetAllowedSwSet(allowedSwModeSet, pAllowedSwSet);
2134 }
2135
2136 /**
2137 ************************************************************************************************************************
2138 * Lib::ComputeBlock256Equation
2139 *
2140 * @brief
2141 * Compute equation for block 256B
2142 *
2143 * @return
2144 * If equation computed successfully
2145 *
2146 ************************************************************************************************************************
2147 */
ComputeBlock256Equation(AddrResourceType rsrcType,AddrSwizzleMode swMode,UINT_32 elementBytesLog2,ADDR_EQUATION * pEquation) const2148 ADDR_E_RETURNCODE Lib::ComputeBlock256Equation(
2149 AddrResourceType rsrcType,
2150 AddrSwizzleMode swMode,
2151 UINT_32 elementBytesLog2,
2152 ADDR_EQUATION* pEquation) const
2153 {
2154 ADDR_E_RETURNCODE ret;
2155
2156 if (IsBlock256b(swMode))
2157 {
2158 ret = HwlComputeBlock256Equation(rsrcType, swMode, elementBytesLog2, pEquation);
2159 }
2160 else
2161 {
2162 ADDR_ASSERT_ALWAYS();
2163 ret = ADDR_INVALIDPARAMS;
2164 }
2165
2166 return ret;
2167 }
2168
2169 /**
2170 ************************************************************************************************************************
2171 * Lib::ComputeThinEquation
2172 *
2173 * @brief
2174 * Compute equation for 2D/3D resource which use THIN mode
2175 *
2176 * @return
2177 * If equation computed successfully
2178 *
2179 ************************************************************************************************************************
2180 */
ComputeThinEquation(AddrResourceType rsrcType,AddrSwizzleMode swMode,UINT_32 elementBytesLog2,ADDR_EQUATION * pEquation) const2181 ADDR_E_RETURNCODE Lib::ComputeThinEquation(
2182 AddrResourceType rsrcType,
2183 AddrSwizzleMode swMode,
2184 UINT_32 elementBytesLog2,
2185 ADDR_EQUATION* pEquation) const
2186 {
2187 ADDR_E_RETURNCODE ret;
2188
2189 if (IsThin(rsrcType, swMode))
2190 {
2191 ret = HwlComputeThinEquation(rsrcType, swMode, elementBytesLog2, pEquation);
2192 }
2193 else
2194 {
2195 ADDR_ASSERT_ALWAYS();
2196 ret = ADDR_INVALIDPARAMS;
2197 }
2198
2199 return ret;
2200 }
2201
2202 /**
2203 ************************************************************************************************************************
2204 * Lib::ComputeThickEquation
2205 *
2206 * @brief
2207 * Compute equation for 3D resource which use THICK mode
2208 *
2209 * @return
2210 * If equation computed successfully
2211 *
2212 ************************************************************************************************************************
2213 */
ComputeThickEquation(AddrResourceType rsrcType,AddrSwizzleMode swMode,UINT_32 elementBytesLog2,ADDR_EQUATION * pEquation) const2214 ADDR_E_RETURNCODE Lib::ComputeThickEquation(
2215 AddrResourceType rsrcType,
2216 AddrSwizzleMode swMode,
2217 UINT_32 elementBytesLog2,
2218 ADDR_EQUATION* pEquation) const
2219 {
2220 ADDR_E_RETURNCODE ret;
2221
2222 if (IsThick(rsrcType, swMode))
2223 {
2224 ret = HwlComputeThickEquation(rsrcType, swMode, elementBytesLog2, pEquation);
2225 }
2226 else
2227 {
2228 ADDR_ASSERT_ALWAYS();
2229 ret = ADDR_INVALIDPARAMS;
2230 }
2231
2232 return ret;
2233 }
2234
2235 /**
2236 ************************************************************************************************************************
2237 * Lib::ComputeQbStereoInfo
2238 *
2239 * @brief
2240 * Get quad buffer stereo information
2241 * @return
2242 * N/A
2243 ************************************************************************************************************************
2244 */
ComputeQbStereoInfo(ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2245 VOID Lib::ComputeQbStereoInfo(
2246 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in,out] updated pOut+pStereoInfo
2247 ) const
2248 {
2249 ADDR_ASSERT(pOut->bpp >= 8);
2250 ADDR_ASSERT((pOut->surfSize % pOut->baseAlign) == 0);
2251
2252 // Save original height
2253 pOut->pStereoInfo->eyeHeight = pOut->height;
2254
2255 // Right offset
2256 pOut->pStereoInfo->rightOffset = static_cast<UINT_32>(pOut->surfSize);
2257
2258 // Double height
2259 pOut->height <<= 1;
2260
2261 ADDR_ASSERT(pOut->height <= MaxSurfaceHeight);
2262
2263 pOut->pixelHeight <<= 1;
2264
2265 // Double size
2266 pOut->surfSize <<= 1;
2267 pOut->sliceSize <<= 1;
2268 }
2269
2270 /**
2271 ************************************************************************************************************************
2272 * Lib::FilterInvalidEqSwizzleMode
2273 *
2274 * @brief
2275 * Filter out swizzle mode(s) if it doesn't have valid equation index
2276 *
2277 * @return
2278 * N/A
2279 ************************************************************************************************************************
2280 */
FilterInvalidEqSwizzleMode(ADDR2_SWMODE_SET & allowedSwModeSet,AddrResourceType resourceType,UINT_32 elemLog2,UINT_32 maxComponents) const2281 VOID Lib::FilterInvalidEqSwizzleMode(
2282 ADDR2_SWMODE_SET& allowedSwModeSet,
2283 AddrResourceType resourceType,
2284 UINT_32 elemLog2,
2285 UINT_32 maxComponents
2286 ) const
2287 {
2288 if (resourceType != ADDR_RSRC_TEX_1D)
2289 {
2290 UINT_32 allowedSwModeSetVal = allowedSwModeSet.value;
2291 const UINT_32 rsrcTypeIdx = static_cast<UINT_32>(resourceType) - 1;
2292 UINT_32 validSwModeSet = allowedSwModeSetVal;
2293
2294 for (UINT_32 swModeIdx = 1; validSwModeSet != 0; swModeIdx++)
2295 {
2296 if (validSwModeSet & 1)
2297 {
2298 UINT_32 equation = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];
2299 if (equation == ADDR_INVALID_EQUATION_INDEX)
2300 {
2301 allowedSwModeSetVal &= ~(1u << swModeIdx);
2302 }
2303 else if (m_equationTable[equation].numBitComponents > maxComponents)
2304 {
2305 allowedSwModeSetVal &= ~(1u << swModeIdx);
2306 }
2307 }
2308
2309 validSwModeSet >>= 1;
2310 }
2311
2312 // Only apply the filtering if at least one valid swizzle mode remains
2313 if (allowedSwModeSetVal != 0)
2314 {
2315 allowedSwModeSet.value = allowedSwModeSetVal;
2316 }
2317 }
2318 }
2319
2320 #if DEBUG
2321 /**
2322 ************************************************************************************************************************
2323 * Lib::ValidateStereoInfo
2324 *
2325 * @brief
2326 * Validate stereo info by checking a few typical cases
2327 *
2328 * @return
2329 * N/A
2330 ************************************************************************************************************************
2331 */
ValidateStereoInfo(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,const ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2332 VOID Lib::ValidateStereoInfo(
2333 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
2334 const ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [in] output structure
2335 ) const
2336 {
2337 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT addrIn = {};
2338 addrIn.size = sizeof(addrIn);
2339 addrIn.swizzleMode = pIn->swizzleMode;
2340 addrIn.flags = pIn->flags;
2341 addrIn.flags.qbStereo = 0;
2342 addrIn.resourceType = pIn->resourceType;
2343 addrIn.bpp = pIn->bpp;
2344 addrIn.unalignedWidth = pIn->width;
2345 addrIn.numSlices = pIn->numSlices;
2346 addrIn.numMipLevels = pIn->numMipLevels;
2347 addrIn.numSamples = pIn->numSamples;
2348 addrIn.numFrags = pIn->numFrags;
2349
2350 // Call Addr2ComputePipeBankXor() and validate different pbXor value if necessary...
2351 const UINT_32 pbXor = 0;
2352
2353 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT addrOut = {};
2354 addrOut.size = sizeof(addrOut);
2355
2356 // Make the array to be {0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096} for full test
2357 const UINT_32 TestCoord[] = {0};
2358
2359 for (UINT_32 xIdx = 0; xIdx < sizeof(TestCoord) / sizeof(TestCoord[0]); xIdx++)
2360 {
2361 if (TestCoord[xIdx] < pIn->width)
2362 {
2363 addrIn.x = TestCoord[xIdx];
2364
2365 for (UINT_32 yIdx = 0; yIdx < sizeof(TestCoord) / sizeof(TestCoord[0]); yIdx++)
2366 {
2367 if (TestCoord[yIdx] < pIn->height)
2368 {
2369 addrIn.y = TestCoord[yIdx] + pOut->pStereoInfo->eyeHeight;
2370 addrIn.pipeBankXor = pbXor ^ pOut->pStereoInfo->rightSwizzle;
2371 addrIn.unalignedHeight = pIn->height + pOut->pStereoInfo->eyeHeight;
2372
2373 ADDR_E_RETURNCODE ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);
2374 ADDR_ASSERT(ret == ADDR_OK);
2375
2376 const UINT_64 rightEyeOffsetFromBase = addrOut.addr;
2377
2378 addrIn.y = TestCoord[yIdx];
2379 addrIn.pipeBankXor = pbXor;
2380 addrIn.unalignedHeight = pIn->height;
2381
2382 ret = ComputeSurfaceAddrFromCoord(&addrIn, &addrOut);
2383 ADDR_ASSERT(ret == ADDR_OK);
2384
2385 const UINT_64 rightEyeOffsetRelative = addrOut.addr;
2386
2387 ADDR_ASSERT(rightEyeOffsetFromBase == rightEyeOffsetRelative + pOut->pStereoInfo->rightOffset);
2388 }
2389 }
2390 }
2391 }
2392 }
2393 #endif
2394
2395 } // V2
2396 } // Addr
2397
2398