2 * Copyright © 2007-2019 Advanced Micro Devices, Inc.
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:
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.
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
28 ************************************************************************************************************************
29 * @file gfx10addrlib.cpp
30 * @brief Contain the implementation for the Gfx10Lib class.
31 ************************************************************************************************************************
34 #include "gfx10addrlib.h"
35 #include "gfx10_gb_reg.h"
36 #include "gfx10SwizzlePattern.h"
38 #include "amdgpu_asic_addr.h"
40 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
41 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
46 ************************************************************************************************************************
50 * Creates an Gfx10Lib object.
53 * Returns an Gfx10Lib object pointer.
54 ************************************************************************************************************************
56 Addr::Lib
* Gfx10HwlInit(const Client
* pClient
)
58 return V2::Gfx10Lib::CreateObj(pClient
);
64 ////////////////////////////////////////////////////////////////////////////////////////////////////
65 // Static Const Member
66 ////////////////////////////////////////////////////////////////////////////////////////////////////
68 const SwizzleModeFlags
Gfx10Lib::SwizzleModeTable
[ADDR_SW_MAX_TYPE
] =
69 {//Linear 256B 4KB 64KB Var Z Std Disp Rot XOR T RtOpt
70 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR
71 {0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_256B_S
72 {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_256B_D
73 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
75 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
76 {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_4KB_S
77 {0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_4KB_D
78 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
80 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
81 {0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0}, // ADDR_SW_64KB_S
82 {0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, // ADDR_SW_64KB_D
83 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
85 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
86 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
87 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
88 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
90 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
91 {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0}, // ADDR_SW_64KB_S_T
92 {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0}, // ADDR_SW_64KB_D_T
93 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
95 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
96 {0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_4KB_S_X
97 {0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_4KB_D_X
98 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
100 {0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_Z_X
101 {0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0}, // ADDR_SW_64KB_S_X
102 {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0}, // ADDR_SW_64KB_D_X
103 {0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1}, // ADDR_SW_64KB_R_X
105 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
106 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
107 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
108 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // Reserved
109 {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, // ADDR_SW_LINEAR_GENERAL
112 const Dim3d
Gfx10Lib::Block256_3d
[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};
114 const Dim3d
Gfx10Lib::Block64K_3d
[] = {{64, 32, 32}, {32 , 32, 32}, {32, 32, 16}, {32, 16, 16}, {16, 16, 16}};
115 const Dim3d
Gfx10Lib::Block4K_3d
[] = {{16, 16, 16}, {8, 16, 16}, {8, 16, 8}, {8, 8, 8}, {4, 8, 8}};
117 const Dim2d
Gfx10Lib::Block64K_2d
[] = {{256, 256}, {256 , 128}, {128, 128}, {128, 64}, {64, 64}};
118 const Dim2d
Gfx10Lib::Block4K_2d
[] = {{64, 64}, {64, 32}, {32, 32}, {32, 16}, {16, 16}};
120 const Dim3d
Gfx10Lib::Block64K_Log2_3d
[] = {{6, 5, 5}, {5, 5, 5}, {5, 5, 4}, {5, 4, 4}, {4, 4, 4}};
121 const Dim3d
Gfx10Lib::Block4K_Log2_3d
[] = {{4, 4, 4}, {3, 4, 4}, {3, 4, 3}, {3, 3, 3}, {2, 3, 3}};
123 const Dim2d
Gfx10Lib::Block64K_Log2_2d
[] = {{8, 8}, {8, 7}, {7, 7}, {7, 6}, {6, 6}};
124 const Dim2d
Gfx10Lib::Block4K_Log2_2d
[] = {{6, 6}, {6, 5}, {5, 5}, {5, 4}, {4, 4}};
127 ************************************************************************************************************************
133 ************************************************************************************************************************
135 Gfx10Lib::Gfx10Lib(const Client
* pClient
)
140 m_class
= AI_ADDRLIB
;
141 memset(&m_settings
, 0, sizeof(m_settings
));
142 memcpy(m_swizzleModeTable
, SwizzleModeTable
, sizeof(SwizzleModeTable
));
146 ************************************************************************************************************************
147 * Gfx10Lib::~Gfx10Lib
151 ************************************************************************************************************************
153 Gfx10Lib::~Gfx10Lib()
158 ************************************************************************************************************************
159 * Gfx10Lib::HwlComputeHtileInfo
162 * Interface function stub of AddrComputeHtilenfo
166 ************************************************************************************************************************
168 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeHtileInfo(
169 const ADDR2_COMPUTE_HTILE_INFO_INPUT
* pIn
, ///< [in] input structure
170 ADDR2_COMPUTE_HTILE_INFO_OUTPUT
* pOut
///< [out] output structure
173 ADDR_E_RETURNCODE ret
= ADDR_OK
;
175 if ((pIn
->swizzleMode
!= ADDR_SW_64KB_Z_X
) ||
176 (pIn
->hTileFlags
.pipeAligned
!= TRUE
))
178 ret
= ADDR_INVALIDPARAMS
;
183 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataDepthStencil
,
191 pOut
->pitch
= PowTwoAlign(pIn
->unalignedWidth
, metaBlk
.w
);
192 pOut
->height
= PowTwoAlign(pIn
->unalignedHeight
, metaBlk
.h
);
193 pOut
->baseAlign
= Max(metaBlkSize
, 1u << (m_pipesLog2
+ 11u));
194 pOut
->metaBlkWidth
= metaBlk
.w
;
195 pOut
->metaBlkHeight
= metaBlk
.h
;
197 if (pIn
->numMipLevels
> 1)
199 ADDR_ASSERT(pIn
->firstMipIdInTail
<= pIn
->numMipLevels
);
201 UINT_32 offset
= (pIn
->firstMipIdInTail
== pIn
->numMipLevels
) ? 0 : metaBlkSize
;
203 for (INT_32 i
= static_cast<INT_32
>(pIn
->firstMipIdInTail
) - 1; i
>=0; i
--)
205 UINT_32 mipWidth
, mipHeight
;
207 GetMipSize(pIn
->unalignedWidth
, pIn
->unalignedHeight
, 1, i
, &mipWidth
, &mipHeight
);
209 mipWidth
= PowTwoAlign(mipWidth
, metaBlk
.w
);
210 mipHeight
= PowTwoAlign(mipHeight
, metaBlk
.h
);
212 const UINT_32 pitchInM
= mipWidth
/ metaBlk
.w
;
213 const UINT_32 heightInM
= mipHeight
/ metaBlk
.h
;
214 const UINT_32 mipSliceSize
= pitchInM
* heightInM
* metaBlkSize
;
216 if (pOut
->pMipInfo
!= NULL
)
218 pOut
->pMipInfo
[i
].inMiptail
= FALSE
;
219 pOut
->pMipInfo
[i
].offset
= offset
;
220 pOut
->pMipInfo
[i
].sliceSize
= mipSliceSize
;
223 offset
+= mipSliceSize
;
226 pOut
->sliceSize
= offset
;
227 pOut
->metaBlkNumPerSlice
= offset
/ metaBlkSize
;
228 pOut
->htileBytes
= pOut
->sliceSize
* pIn
->numSlices
;
230 if (pOut
->pMipInfo
!= NULL
)
232 for (UINT_32 i
= pIn
->firstMipIdInTail
; i
< pIn
->numMipLevels
; i
++)
234 pOut
->pMipInfo
[i
].inMiptail
= TRUE
;
235 pOut
->pMipInfo
[i
].offset
= 0;
236 pOut
->pMipInfo
[i
].sliceSize
= 0;
239 if (pIn
->firstMipIdInTail
!= pIn
->numMipLevels
)
241 pOut
->pMipInfo
[pIn
->firstMipIdInTail
].sliceSize
= metaBlkSize
;
247 const UINT_32 pitchInM
= pOut
->pitch
/ metaBlk
.w
;
248 const UINT_32 heightInM
= pOut
->height
/ metaBlk
.h
;
250 pOut
->metaBlkNumPerSlice
= pitchInM
* heightInM
;
251 pOut
->sliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
252 pOut
->htileBytes
= pOut
->sliceSize
* pIn
->numSlices
;
254 if (pOut
->pMipInfo
!= NULL
)
256 pOut
->pMipInfo
[0].inMiptail
= FALSE
;
257 pOut
->pMipInfo
[0].offset
= 0;
258 pOut
->pMipInfo
[0].sliceSize
= pOut
->sliceSize
;
267 ************************************************************************************************************************
268 * Gfx10Lib::HwlComputeCmaskInfo
271 * Interface function stub of AddrComputeCmaskInfo
275 ************************************************************************************************************************
277 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeCmaskInfo(
278 const ADDR2_COMPUTE_CMASK_INFO_INPUT
* pIn
, ///< [in] input structure
279 ADDR2_COMPUTE_CMASK_INFO_OUTPUT
* pOut
///< [out] output structure
282 ADDR_E_RETURNCODE ret
= ADDR_OK
;
284 if ((pIn
->resourceType
!= ADDR_RSRC_TEX_2D
) ||
285 (pIn
->cMaskFlags
.pipeAligned
!= TRUE
))
287 ret
= ADDR_INVALIDPARAMS
;
292 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataFmask
,
300 pOut
->pitch
= PowTwoAlign(pIn
->unalignedWidth
, metaBlk
.w
);
301 pOut
->height
= PowTwoAlign(pIn
->unalignedHeight
, metaBlk
.h
);
302 pOut
->baseAlign
= metaBlkSize
;
303 pOut
->metaBlkWidth
= metaBlk
.w
;
304 pOut
->metaBlkHeight
= metaBlk
.h
;
306 if (pIn
->numMipLevels
> 1)
308 ADDR_ASSERT(pIn
->firstMipIdInTail
<= pIn
->numMipLevels
);
310 UINT_32 metaBlkPerSlice
= (pIn
->firstMipIdInTail
== pIn
->numMipLevels
) ? 0 : 1;
312 for (INT_32 i
= static_cast<INT_32
>(pIn
->firstMipIdInTail
) - 1; i
>= 0; i
--)
314 UINT_32 mipWidth
, mipHeight
;
316 GetMipSize(pIn
->unalignedWidth
, pIn
->unalignedHeight
, 1, i
, &mipWidth
, &mipHeight
);
318 mipWidth
= PowTwoAlign(mipWidth
, metaBlk
.w
);
319 mipHeight
= PowTwoAlign(mipHeight
, metaBlk
.h
);
321 const UINT_32 pitchInM
= mipWidth
/ metaBlk
.w
;
322 const UINT_32 heightInM
= mipHeight
/ metaBlk
.h
;
324 if (pOut
->pMipInfo
!= NULL
)
326 pOut
->pMipInfo
[i
].inMiptail
= FALSE
;
327 pOut
->pMipInfo
[i
].offset
= metaBlkPerSlice
* metaBlkSize
;
328 pOut
->pMipInfo
[i
].sliceSize
= pitchInM
* heightInM
* metaBlkSize
;
331 metaBlkPerSlice
+= pitchInM
* heightInM
;
334 pOut
->metaBlkNumPerSlice
= metaBlkPerSlice
;
336 if (pOut
->pMipInfo
!= NULL
)
338 for (UINT_32 i
= pIn
->firstMipIdInTail
; i
< pIn
->numMipLevels
; i
++)
340 pOut
->pMipInfo
[i
].inMiptail
= TRUE
;
341 pOut
->pMipInfo
[i
].offset
= 0;
342 pOut
->pMipInfo
[i
].sliceSize
= 0;
345 if (pIn
->firstMipIdInTail
!= pIn
->numMipLevels
)
347 pOut
->pMipInfo
[pIn
->firstMipIdInTail
].sliceSize
= metaBlkSize
;
353 const UINT_32 pitchInM
= pOut
->pitch
/ metaBlk
.w
;
354 const UINT_32 heightInM
= pOut
->height
/ metaBlk
.h
;
356 pOut
->metaBlkNumPerSlice
= pitchInM
* heightInM
;
358 if (pOut
->pMipInfo
!= NULL
)
360 pOut
->pMipInfo
[0].inMiptail
= FALSE
;
361 pOut
->pMipInfo
[0].offset
= 0;
362 pOut
->pMipInfo
[0].sliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
366 pOut
->sliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
367 pOut
->cmaskBytes
= pOut
->sliceSize
* pIn
->numSlices
;
374 ************************************************************************************************************************
375 * Gfx10Lib::HwlComputeDccInfo
378 * Interface function to compute DCC key info
382 ************************************************************************************************************************
384 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeDccInfo(
385 const ADDR2_COMPUTE_DCCINFO_INPUT
* pIn
, ///< [in] input structure
386 ADDR2_COMPUTE_DCCINFO_OUTPUT
* pOut
///< [out] output structure
389 ADDR_E_RETURNCODE ret
= ADDR_OK
;
391 if (IsLinear(pIn
->swizzleMode
) || IsBlock256b(pIn
->swizzleMode
))
393 // Hardware support dcc for 256 swizzle mode, but address lib will not support it because we only
394 // select 256 swizzle mode for small surface, and it's not helpful to enable dcc for small surface.
395 ret
= ADDR_INVALIDPARAMS
;
397 else if (m_settings
.dccUnsup3DSwDis
&& IsTex3d(pIn
->resourceType
) && IsDisplaySwizzle(pIn
->swizzleMode
))
399 // DCC is not supported on 3D Display surfaces for GFX10.0 and GFX10.1
400 ret
= ADDR_INVALIDPARAMS
;
404 // only SW_*_R_X surfaces may be DCC compressed when attached to the CB
405 ADDR_ASSERT(IsRtOptSwizzle(pIn
->swizzleMode
));
408 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
409 const UINT_32 numFragLog2
= Log2(pIn
->numFrags
);
410 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataColor
,
415 pIn
->dccKeyFlags
.pipeAligned
,
417 const BOOL_32 isThick
= IsThick(pIn
->resourceType
, pIn
->swizzleMode
);
419 pOut
->compressBlkWidth
= isThick
? Block256_3d
[elemLog2
].w
: Block256_2d
[elemLog2
].w
;
420 pOut
->compressBlkHeight
= isThick
? Block256_3d
[elemLog2
].h
: Block256_2d
[elemLog2
].h
;
421 pOut
->compressBlkDepth
= isThick
? Block256_3d
[elemLog2
].d
: 1;
423 pOut
->dccRamBaseAlign
= metaBlkSize
;
424 pOut
->metaBlkWidth
= metaBlk
.w
;
425 pOut
->metaBlkHeight
= metaBlk
.h
;
426 pOut
->metaBlkDepth
= metaBlk
.d
;
428 pOut
->pitch
= PowTwoAlign(pIn
->unalignedWidth
, metaBlk
.w
);
429 pOut
->height
= PowTwoAlign(pIn
->unalignedHeight
, metaBlk
.h
);
430 pOut
->depth
= PowTwoAlign(pIn
->numSlices
, metaBlk
.d
);
432 if (pIn
->numMipLevels
> 1)
434 ADDR_ASSERT(pIn
->firstMipIdInTail
<= pIn
->numMipLevels
);
436 UINT_32 offset
= (pIn
->firstMipIdInTail
== pIn
->numMipLevels
) ? 0 : metaBlkSize
;
438 for (INT_32 i
= static_cast<INT_32
>(pIn
->firstMipIdInTail
) - 1; i
>= 0; i
--)
440 UINT_32 mipWidth
, mipHeight
;
442 GetMipSize(pIn
->unalignedWidth
, pIn
->unalignedHeight
, 1, i
, &mipWidth
, &mipHeight
);
444 mipWidth
= PowTwoAlign(mipWidth
, metaBlk
.w
);
445 mipHeight
= PowTwoAlign(mipHeight
, metaBlk
.h
);
447 const UINT_32 pitchInM
= mipWidth
/ metaBlk
.w
;
448 const UINT_32 heightInM
= mipHeight
/ metaBlk
.h
;
449 const UINT_32 mipSliceSize
= pitchInM
* heightInM
* metaBlkSize
;
451 if (pOut
->pMipInfo
!= NULL
)
453 pOut
->pMipInfo
[i
].inMiptail
= FALSE
;
454 pOut
->pMipInfo
[i
].offset
= offset
;
455 pOut
->pMipInfo
[i
].sliceSize
= mipSliceSize
;
458 offset
+= mipSliceSize
;
461 pOut
->dccRamSliceSize
= offset
;
462 pOut
->metaBlkNumPerSlice
= offset
/ metaBlkSize
;
463 pOut
->dccRamSize
= pOut
->dccRamSliceSize
* (pOut
->depth
/ metaBlk
.d
);
465 if (pOut
->pMipInfo
!= NULL
)
467 for (UINT_32 i
= pIn
->firstMipIdInTail
; i
< pIn
->numMipLevels
; i
++)
469 pOut
->pMipInfo
[i
].inMiptail
= TRUE
;
470 pOut
->pMipInfo
[i
].offset
= 0;
471 pOut
->pMipInfo
[i
].sliceSize
= 0;
474 if (pIn
->firstMipIdInTail
!= pIn
->numMipLevels
)
476 pOut
->pMipInfo
[pIn
->firstMipIdInTail
].sliceSize
= metaBlkSize
;
482 const UINT_32 pitchInM
= pOut
->pitch
/ metaBlk
.w
;
483 const UINT_32 heightInM
= pOut
->height
/ metaBlk
.h
;
485 pOut
->metaBlkNumPerSlice
= pitchInM
* heightInM
;
486 pOut
->dccRamSliceSize
= pOut
->metaBlkNumPerSlice
* metaBlkSize
;
487 pOut
->dccRamSize
= pOut
->dccRamSliceSize
* (pOut
->depth
/ metaBlk
.d
);
489 if (pOut
->pMipInfo
!= NULL
)
491 pOut
->pMipInfo
[0].inMiptail
= FALSE
;
492 pOut
->pMipInfo
[0].offset
= 0;
493 pOut
->pMipInfo
[0].sliceSize
= pOut
->dccRamSliceSize
;
502 ************************************************************************************************************************
503 * Gfx10Lib::HwlComputeCmaskAddrFromCoord
506 * Interface function stub of AddrComputeCmaskAddrFromCoord
510 ************************************************************************************************************************
512 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeCmaskAddrFromCoord(
513 const ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
514 ADDR2_COMPUTE_CMASK_ADDRFROMCOORD_OUTPUT
* pOut
) ///< [out] output structure
516 ADDR2_COMPUTE_CMASK_INFO_INPUT input
= {0};
517 input
.size
= sizeof(input
);
518 input
.cMaskFlags
= pIn
->cMaskFlags
;
519 input
.colorFlags
= pIn
->colorFlags
;
520 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
521 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
522 input
.numSlices
= Max(pIn
->numSlices
, 1u);
523 input
.swizzleMode
= pIn
->swizzleMode
;
524 input
.resourceType
= pIn
->resourceType
;
526 ADDR2_COMPUTE_CMASK_INFO_OUTPUT output
= {0};
527 output
.size
= sizeof(output
);
529 ADDR_E_RETURNCODE returnCode
= ComputeCmaskInfo(&input
, &output
);
531 if (returnCode
== ADDR_OK
)
533 const UINT_32 fmaskBpp
= GetFmaskBpp(pIn
->numSamples
, pIn
->numFrags
);
534 const UINT_32 fmaskElemLog2
= Log2(fmaskBpp
>> 3);
535 const UINT_32 numPipeLog2
= m_pipesLog2
;
536 const UINT_32 pipeMask
= (1 << numPipeLog2
) - 1;
537 const UINT_32 fmaskBppType
= 4;
538 const UINT_32 numPipeType
= 8;
539 const UINT_32 index
= ((m_pipeInterleaveLog2
- 8) * (fmaskBppType
* numPipeType
)) +
540 ((numPipeLog2
+ 1) * fmaskBppType
) +
543 const UINT_64
* pPattern
= CMASK_64K
[index
];
544 const UINT_32 blkSizeLog2
= Log2(output
.metaBlkWidth
) + Log2(output
.metaBlkHeight
) - 7;
545 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
546 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
547 blkSizeLog2
+ 1, // +1 for nibble offset
552 const UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
553 const UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
554 const UINT_32 pb
= output
.pitch
/ output
.metaBlkWidth
;
555 const UINT_32 blkIndex
= (yb
* pb
) + xb
;
556 const UINT_32 pipeXor
= ((pIn
->pipeXor
& pipeMask
) << m_pipeInterleaveLog2
) & blkMask
;
558 pOut
->addr
= (output
.sliceSize
* pIn
->slice
) +
559 (blkIndex
* (1 << blkSizeLog2
)) +
560 ((blkOffset
>> 1) ^ pipeXor
);
561 pOut
->bitPosition
= (blkOffset
& 1) << 2;
568 ************************************************************************************************************************
569 * Gfx10Lib::HwlComputeHtileAddrFromCoord
572 * Interface function stub of AddrComputeHtileAddrFromCoord
576 ************************************************************************************************************************
578 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeHtileAddrFromCoord(
579 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
580 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT
* pOut
) ///< [out] output structure
582 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
584 if (pIn
->numMipLevels
> 1)
586 returnCode
= ADDR_NOTIMPLEMENTED
;
590 ADDR2_COMPUTE_HTILE_INFO_INPUT input
= {0};
591 input
.size
= sizeof(input
);
592 input
.hTileFlags
= pIn
->hTileFlags
;
593 input
.depthFlags
= pIn
->depthflags
;
594 input
.swizzleMode
= pIn
->swizzleMode
;
595 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
596 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
597 input
.numSlices
= Max(pIn
->numSlices
, 1u);
598 input
.numMipLevels
= 1;
600 ADDR2_COMPUTE_HTILE_INFO_OUTPUT output
= {0};
601 output
.size
= sizeof(output
);
603 returnCode
= ComputeHtileInfo(&input
, &output
);
605 if (returnCode
== ADDR_OK
)
607 const UINT_32 numSampleLog2
= Log2(pIn
->numSamples
);
608 const UINT_32 pipeMask
= (1 << m_pipesLog2
) - 1;
609 const UINT_32 index
= m_htileBaseIndex
+ numSampleLog2
;
610 const UINT_64
* pPattern
= HTILE_64K
[index
];
611 const UINT_32 blkSizeLog2
= Log2(output
.metaBlkWidth
) + Log2(output
.metaBlkHeight
) - 4;
612 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
613 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
614 blkSizeLog2
+ 1, // +1 for nibble offset
619 const UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
620 const UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
621 const UINT_32 pb
= output
.pitch
/ output
.metaBlkWidth
;
622 const UINT_32 blkIndex
= (yb
* pb
) + xb
;
623 const UINT_32 pipeXor
= ((pIn
->pipeXor
& pipeMask
) << m_pipeInterleaveLog2
) & blkMask
;
625 pOut
->addr
= (static_cast<UINT_64
>(output
.sliceSize
) * pIn
->slice
) +
626 (blkIndex
* (1 << blkSizeLog2
)) +
627 ((blkOffset
>> 1) ^ pipeXor
);
635 ************************************************************************************************************************
636 * Gfx10Lib::HwlComputeHtileCoordFromAddr
639 * Interface function stub of AddrComputeHtileCoordFromAddr
643 ************************************************************************************************************************
645 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeHtileCoordFromAddr(
646 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT
* pIn
, ///< [in] input structure
647 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT
* pOut
) ///< [out] output structure
649 ADDR_NOT_IMPLEMENTED();
655 ************************************************************************************************************************
656 * Gfx10Lib::HwlComputeDccAddrFromCoord
659 * Interface function stub of AddrComputeDccAddrFromCoord
663 ************************************************************************************************************************
665 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeDccAddrFromCoord(
666 const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
667 ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT
* pOut
) ///< [out] output structure
669 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
671 if ((pIn
->resourceType
!= ADDR_RSRC_TEX_2D
) ||
672 (pIn
->swizzleMode
!= ADDR_SW_64KB_R_X
) ||
673 (pIn
->dccKeyFlags
.linear
== TRUE
) ||
674 (pIn
->numFrags
> 1) ||
675 (pIn
->numMipLevels
> 1) ||
678 returnCode
= ADDR_NOTSUPPORTED
;
682 ADDR2_COMPUTE_DCCINFO_INPUT input
= {0};
683 input
.size
= sizeof(input
);
684 input
.dccKeyFlags
= pIn
->dccKeyFlags
;
685 input
.colorFlags
= pIn
->colorFlags
;
686 input
.swizzleMode
= pIn
->swizzleMode
;
687 input
.resourceType
= pIn
->resourceType
;
688 input
.bpp
= pIn
->bpp
;
689 input
.unalignedWidth
= Max(pIn
->unalignedWidth
, 1u);
690 input
.unalignedHeight
= Max(pIn
->unalignedHeight
, 1u);
691 input
.numSlices
= Max(pIn
->numSlices
, 1u);
692 input
.numFrags
= Max(pIn
->numFrags
, 1u);
693 input
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
695 ADDR2_COMPUTE_DCCINFO_OUTPUT output
= {0};
696 output
.size
= sizeof(output
);
698 returnCode
= ComputeDccInfo(&input
, &output
);
700 if (returnCode
== ADDR_OK
)
702 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
703 const UINT_32 numPipeLog2
= m_pipesLog2
;
704 const UINT_32 pipeMask
= (1 << numPipeLog2
) - 1;
705 const UINT_32 alignPipeType
= 7;
706 const UINT_32 unalignPipeType
= 3;
707 const UINT_32 numPipeType
= alignPipeType
+ unalignPipeType
;
708 UINT_32 index
= ((m_pipeInterleaveLog2
- 8) * (MaxNumOfBpp
* numPipeType
)) + elemLog2
;
710 if (pIn
->dccKeyFlags
.pipeAligned
)
712 index
+= (numPipeLog2
+ unalignPipeType
) * MaxNumOfBpp
;
716 index
+= Min(numPipeLog2
, 2u) * MaxNumOfBpp
;
719 const UINT_64
* pPattern
= DCC_64K_R_X
[index
];
720 const UINT_32 blkSizeLog2
= Log2(output
.metaBlkWidth
) + Log2(output
.metaBlkHeight
) + elemLog2
- 8;
721 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
722 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
723 blkSizeLog2
+ 1, // +1 for nibble offset
728 const UINT_32 xb
= pIn
->x
/ output
.metaBlkWidth
;
729 const UINT_32 yb
= pIn
->y
/ output
.metaBlkHeight
;
730 const UINT_32 pb
= output
.pitch
/ output
.metaBlkWidth
;
731 const UINT_32 blkIndex
= (yb
* pb
) + xb
;
732 const UINT_32 pipeXor
= ((pIn
->pipeXor
& pipeMask
) << m_pipeInterleaveLog2
) & blkMask
;
734 pOut
->addr
= (static_cast<UINT_64
>(output
.dccRamSliceSize
) * pIn
->slice
) +
735 (blkIndex
* (1 << blkSizeLog2
)) +
736 ((blkOffset
>> 1) ^ pipeXor
);
744 ************************************************************************************************************************
745 * Gfx10Lib::HwlInitGlobalParams
748 * Initializes global parameters
751 * TRUE if all settings are valid
753 ************************************************************************************************************************
755 BOOL_32
Gfx10Lib::HwlInitGlobalParams(
756 const ADDR_CREATE_INPUT
* pCreateIn
) ///< [in] create input
758 BOOL_32 valid
= TRUE
;
759 GB_ADDR_CONFIG gbAddrConfig
;
761 gbAddrConfig
.u32All
= pCreateIn
->regValue
.gbAddrConfig
;
763 // These values are copied from CModel code
764 switch (gbAddrConfig
.bits
.NUM_PIPES
)
766 case ADDR_CONFIG_1_PIPE
:
770 case ADDR_CONFIG_2_PIPE
:
774 case ADDR_CONFIG_4_PIPE
:
778 case ADDR_CONFIG_8_PIPE
:
782 case ADDR_CONFIG_16_PIPE
:
786 case ADDR_CONFIG_32_PIPE
:
790 case ADDR_CONFIG_64_PIPE
:
795 ADDR_ASSERT_ALWAYS();
800 switch (gbAddrConfig
.bits
.PIPE_INTERLEAVE_SIZE
)
802 case ADDR_CONFIG_PIPE_INTERLEAVE_256B
:
803 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_256B
;
804 m_pipeInterleaveLog2
= 8;
806 case ADDR_CONFIG_PIPE_INTERLEAVE_512B
:
807 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_512B
;
808 m_pipeInterleaveLog2
= 9;
810 case ADDR_CONFIG_PIPE_INTERLEAVE_1KB
:
811 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_1KB
;
812 m_pipeInterleaveLog2
= 10;
814 case ADDR_CONFIG_PIPE_INTERLEAVE_2KB
:
815 m_pipeInterleaveBytes
= ADDR_PIPEINTERLEAVE_2KB
;
816 m_pipeInterleaveLog2
= 11;
819 ADDR_ASSERT_ALWAYS();
824 // Addr::V2::Lib::ComputePipeBankXor()/ComputeSlicePipeBankXor() requires pipe interleave to be exactly 8 bits, and
825 // any larger value requires a post-process (left shift) on the output pipeBankXor bits.
826 ADDR_ASSERT(m_pipeInterleaveBytes
== ADDR_PIPEINTERLEAVE_256B
);
828 switch (gbAddrConfig
.bits
.MAX_COMPRESSED_FRAGS
)
830 case ADDR_CONFIG_1_MAX_COMPRESSED_FRAGMENTS
:
832 m_maxCompFragLog2
= 0;
834 case ADDR_CONFIG_2_MAX_COMPRESSED_FRAGMENTS
:
836 m_maxCompFragLog2
= 1;
838 case ADDR_CONFIG_4_MAX_COMPRESSED_FRAGMENTS
:
840 m_maxCompFragLog2
= 2;
842 case ADDR_CONFIG_8_MAX_COMPRESSED_FRAGMENTS
:
844 m_maxCompFragLog2
= 3;
847 ADDR_ASSERT_ALWAYS();
852 if (m_settings
.supportRbPlus
)
854 m_numPkrLog2
= gbAddrConfig
.bits
.NUM_PKRS
;
855 m_numSaLog2
= (m_numPkrLog2
> 0) ? (m_numPkrLog2
- 1) : 0;
857 ADDR_ASSERT((m_numPkrLog2
<= m_pipesLog2
) && ((m_pipesLog2
- m_numPkrLog2
) <= 2));
859 const UINT_32 maxPipeInterleaveType
= 3;
861 m_colorBaseIndex
= sizeof(SW_64K_R_X_1xaa_RBPLUS
) /
862 sizeof(SW_64K_R_X_1xaa_RBPLUS
[0]) /
863 maxPipeInterleaveType
*
864 (m_pipeInterleaveLog2
- 8);
865 m_htileBaseIndex
= sizeof(HTILE_64K_RBPLUS
) /
866 sizeof(HTILE_64K_RBPLUS
[0]) /
867 maxPipeInterleaveType
*
868 (m_pipeInterleaveLog2
- 8);
870 // Skip unaligned case
871 m_htileBaseIndex
+= MaxNumOfAA
;
873 if (m_numPkrLog2
< 2)
875 m_colorBaseIndex
+= m_pipesLog2
* MaxNumOfBpp
;
876 m_htileBaseIndex
+= m_pipesLog2
* MaxNumOfAA
;
880 m_colorBaseIndex
+= (2 * m_numPkrLog2
- 2 + m_pipesLog2
) * MaxNumOfBpp
;
882 const UINT_32 htilePipePerPkr
= 4;
884 m_htileBaseIndex
+= (m_numPkrLog2
- 1) * htilePipePerPkr
* MaxNumOfAA
+
885 (m_pipesLog2
+ 1 - m_numPkrLog2
) * MaxNumOfAA
;
890 const UINT_32 numPipeType
= static_cast<UINT_32
>(ADDR_CONFIG_64_PIPE
) -
891 static_cast<UINT_32
>(ADDR_CONFIG_1_PIPE
) +
894 m_colorBaseIndex
= (m_pipeInterleaveLog2
- 8) * (MaxNumOfBpp
* numPipeType
) +
895 (m_pipesLog2
* MaxNumOfBpp
);
897 m_htileBaseIndex
= (m_pipeInterleaveLog2
- 8) * (MaxNumOfAA
* (numPipeType
+ 1)) +
898 (m_pipesLog2
+ 1) * MaxNumOfAA
;
910 ************************************************************************************************************************
911 * Gfx10Lib::HwlConvertChipFamily
914 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
917 ************************************************************************************************************************
919 ChipFamily
Gfx10Lib::HwlConvertChipFamily(
920 UINT_32 chipFamily
, ///< [in] chip family defined in atiih.h
921 UINT_32 chipRevision
) ///< [in] chip revision defined in "asic_family"_id.h
923 ChipFamily family
= ADDR_CHIP_FAMILY_NAVI
;
925 m_settings
.dccUnsup3DSwDis
= 1;
930 m_settings
.isDcn2
= 1;
933 ADDR_ASSERT(!"Unknown chip family");
937 m_settings
.dsMipmapHtileFix
= 1;
939 if (ASICREV_IS_NAVI10_P(chipRevision
))
941 m_settings
.dsMipmapHtileFix
= 0;
944 m_configFlags
.use32bppFor422Fmt
= TRUE
;
950 ************************************************************************************************************************
951 * Gfx10Lib::GetBlk256SizeLog2
958 ************************************************************************************************************************
960 void Gfx10Lib::GetBlk256SizeLog2(
961 AddrResourceType resourceType
, ///< [in] Resource type
962 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
963 UINT_32 elemLog2
, ///< [in] element size log2
964 UINT_32 numSamplesLog2
, ///< [in] number of samples
965 Dim3d
* pBlock
///< [out] block size
968 if (IsThin(resourceType
, swizzleMode
))
970 UINT_32 blockBits
= 8 - elemLog2
;
972 if (IsZOrderSwizzle(swizzleMode
))
974 blockBits
-= numSamplesLog2
;
977 pBlock
->w
= (blockBits
>> 1) + (blockBits
& 1);
978 pBlock
->h
= (blockBits
>> 1);
983 ADDR_ASSERT(IsThick(resourceType
, swizzleMode
));
985 UINT_32 blockBits
= 8 - elemLog2
;
987 pBlock
->d
= (blockBits
/ 3) + (((blockBits
% 3) > 0) ? 1 : 0);
988 pBlock
->w
= (blockBits
/ 3) + (((blockBits
% 3) > 1) ? 1 : 0);
989 pBlock
->h
= (blockBits
/ 3);
994 ************************************************************************************************************************
995 * Gfx10Lib::GetCompressedBlockSizeLog2
998 * Get compress block size
1002 ************************************************************************************************************************
1004 void Gfx10Lib::GetCompressedBlockSizeLog2(
1005 Gfx10DataType dataType
, ///< [in] Data type
1006 AddrResourceType resourceType
, ///< [in] Resource type
1007 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1008 UINT_32 elemLog2
, ///< [in] element size log2
1009 UINT_32 numSamplesLog2
, ///< [in] number of samples
1010 Dim3d
* pBlock
///< [out] block size
1013 if (dataType
== Gfx10DataColor
)
1015 GetBlk256SizeLog2(resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
, pBlock
);
1019 ADDR_ASSERT((dataType
== Gfx10DataDepthStencil
) || (dataType
== Gfx10DataFmask
));
1027 ************************************************************************************************************************
1028 * Gfx10Lib::GetMetaOverlapLog2
1031 * Get meta block overlap
1035 ************************************************************************************************************************
1037 INT_32
Gfx10Lib::GetMetaOverlapLog2(
1038 Gfx10DataType dataType
, ///< [in] Data type
1039 AddrResourceType resourceType
, ///< [in] Resource type
1040 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1041 UINT_32 elemLog2
, ///< [in] element size log2
1042 UINT_32 numSamplesLog2
///< [in] number of samples
1048 GetCompressedBlockSizeLog2(dataType
, resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
, &compBlock
);
1049 GetBlk256SizeLog2(resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
, µBlock
);
1051 const INT_32 compSizeLog2
= compBlock
.w
+ compBlock
.h
+ compBlock
.d
;
1052 const INT_32 blk256SizeLog2
= microBlock
.w
+ microBlock
.h
+ microBlock
.d
;
1053 const INT_32 maxSizeLog2
= Max(compSizeLog2
, blk256SizeLog2
);
1054 const INT_32 numPipesLog2
= GetEffectiveNumPipes();
1055 INT_32 overlap
= numPipesLog2
- maxSizeLog2
;
1057 if ((numPipesLog2
> 1) && m_settings
.supportRbPlus
)
1062 // In 16Bpp 8xaa, we lose 1 overlap bit because the block size reduction eats into a pipe anchor bit (y4)
1063 if ((elemLog2
== 4) && (numSamplesLog2
== 3))
1067 overlap
= Max(overlap
, 0);
1072 ************************************************************************************************************************
1073 * Gfx10Lib::Get3DMetaOverlapLog2
1076 * Get 3d meta block overlap
1080 ************************************************************************************************************************
1082 INT_32
Gfx10Lib::Get3DMetaOverlapLog2(
1083 AddrResourceType resourceType
, ///< [in] Resource type
1084 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1085 UINT_32 elemLog2
///< [in] element size log2
1089 GetBlk256SizeLog2(resourceType
, swizzleMode
, elemLog2
, 0, µBlock
);
1091 INT_32 overlap
= GetEffectiveNumPipes() - static_cast<INT_32
>(microBlock
.w
);
1093 if (m_settings
.supportRbPlus
)
1098 if ((overlap
< 0) || (IsStandardSwizzle(resourceType
, swizzleMode
) == TRUE
))
1106 ************************************************************************************************************************
1107 * Gfx10Lib::GetPipeRotateAmount
1110 * Get pipe rotate amount
1113 * Pipe rotate amount
1114 ************************************************************************************************************************
1117 INT_32
Gfx10Lib::GetPipeRotateAmount(
1118 AddrResourceType resourceType
, ///< [in] Resource type
1119 AddrSwizzleMode swizzleMode
///< [in] Swizzle mode
1124 if (m_settings
.supportRbPlus
&& (m_pipesLog2
>= (m_numSaLog2
+ 1)) && (m_pipesLog2
> 1))
1126 amount
= ((m_pipesLog2
== (m_numSaLog2
+ 1)) && IsRbAligned(resourceType
, swizzleMode
)) ?
1127 1 : m_pipesLog2
- (m_numSaLog2
+ 1);
1134 ************************************************************************************************************************
1135 * Gfx10Lib::GetMetaBlkSize
1138 * Get metadata block size
1142 ************************************************************************************************************************
1144 UINT_32
Gfx10Lib::GetMetaBlkSize(
1145 Gfx10DataType dataType
, ///< [in] Data type
1146 AddrResourceType resourceType
, ///< [in] Resource type
1147 AddrSwizzleMode swizzleMode
, ///< [in] Swizzle mode
1148 UINT_32 elemLog2
, ///< [in] element size log2
1149 UINT_32 numSamplesLog2
, ///< [in] number of samples
1150 BOOL_32 pipeAlign
, ///< [in] pipe align
1151 Dim3d
* pBlock
///< [out] block size
1154 INT_32 metablkSizeLog2
;
1155 const INT_32 metaElemSizeLog2
= GetMetaElementSizeLog2(dataType
);
1156 const INT_32 metaCacheSizeLog2
= GetMetaCacheSizeLog2(dataType
);
1157 const INT_32 compBlkSizeLog2
= (dataType
== Gfx10DataColor
) ? 8 : 6 + numSamplesLog2
+ elemLog2
;
1158 const INT_32 metaBlkSamplesLog2
= (dataType
== Gfx10DataDepthStencil
) ?
1159 numSamplesLog2
: Min(numSamplesLog2
, m_maxCompFragLog2
);
1160 const INT_32 dataBlkSizeLog2
= GetBlockSizeLog2(swizzleMode
);
1161 INT_32 numPipesLog2
= m_pipesLog2
;
1163 if (IsThin(resourceType
, swizzleMode
))
1165 if ((pipeAlign
== FALSE
) ||
1166 (IsStandardSwizzle(resourceType
, swizzleMode
) == TRUE
) ||
1167 (IsDisplaySwizzle(resourceType
, swizzleMode
) == TRUE
))
1171 metablkSizeLog2
= Max(static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
, 12);
1172 metablkSizeLog2
= Min(metablkSizeLog2
, dataBlkSizeLog2
);
1176 metablkSizeLog2
= Min(dataBlkSizeLog2
, 12);
1181 if (m_settings
.supportRbPlus
&& (m_pipesLog2
== m_numSaLog2
+ 1) && (m_pipesLog2
> 1))
1186 INT_32 pipeRotateLog2
= GetPipeRotateAmount(resourceType
, swizzleMode
);
1188 if (numPipesLog2
>= 4)
1190 INT_32 overlapLog2
= GetMetaOverlapLog2(dataType
, resourceType
, swizzleMode
, elemLog2
, numSamplesLog2
);
1192 // In 16Bpe 8xaa, we have an extra overlap bit
1193 if ((pipeRotateLog2
> 0) &&
1195 (numSamplesLog2
== 3) &&
1196 (IsZOrderSwizzle(swizzleMode
) || (GetEffectiveNumPipes() > 3)))
1201 metablkSizeLog2
= metaCacheSizeLog2
+ overlapLog2
+ numPipesLog2
;
1202 metablkSizeLog2
= Max(metablkSizeLog2
, static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
);
1204 if (m_settings
.supportRbPlus
&&
1205 IsRtOptSwizzle(swizzleMode
) &&
1206 (numPipesLog2
== 6) &&
1207 (numSamplesLog2
== 3) &&
1208 (m_maxCompFragLog2
== 3) &&
1209 (metablkSizeLog2
< 15))
1211 metablkSizeLog2
= 15;
1216 metablkSizeLog2
= Max(static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
, 12);
1219 if (dataType
== Gfx10DataDepthStencil
)
1221 // For htile surfaces, pad meta block size to 2K * num_pipes
1222 metablkSizeLog2
= Max(metablkSizeLog2
, 11 + numPipesLog2
);
1225 const INT_32 compFragLog2
= Min(m_maxCompFragLog2
, numSamplesLog2
);
1227 if (IsRtOptSwizzle(swizzleMode
) && (compFragLog2
> 1) && (pipeRotateLog2
>= 1))
1229 const INT_32 tmp
= 8 + m_pipesLog2
+ Max(pipeRotateLog2
, compFragLog2
- 1);
1231 metablkSizeLog2
= Max(metablkSizeLog2
, tmp
);
1235 const INT_32 metablkBitsLog2
=
1236 metablkSizeLog2
+ compBlkSizeLog2
- elemLog2
- metaBlkSamplesLog2
- metaElemSizeLog2
;
1237 pBlock
->w
= 1 << ((metablkBitsLog2
>> 1) + (metablkBitsLog2
& 1));
1238 pBlock
->h
= 1 << (metablkBitsLog2
>> 1);
1243 ADDR_ASSERT(IsThick(resourceType
, swizzleMode
));
1247 if (m_settings
.supportRbPlus
&&
1248 (m_pipesLog2
== m_numSaLog2
+ 1) &&
1249 (m_pipesLog2
> 1) &&
1250 IsRbAligned(resourceType
, swizzleMode
))
1255 const INT_32 overlapLog2
= Get3DMetaOverlapLog2(resourceType
, swizzleMode
, elemLog2
);
1257 metablkSizeLog2
= metaCacheSizeLog2
+ overlapLog2
+ numPipesLog2
;
1258 metablkSizeLog2
= Max(metablkSizeLog2
, static_cast<INT_32
>(m_pipeInterleaveLog2
) + numPipesLog2
);
1259 metablkSizeLog2
= Max(metablkSizeLog2
, 12);
1263 metablkSizeLog2
= 12;
1266 const INT_32 metablkBitsLog2
=
1267 metablkSizeLog2
+ compBlkSizeLog2
- elemLog2
- metaBlkSamplesLog2
- metaElemSizeLog2
;
1268 pBlock
->w
= 1 << ((metablkBitsLog2
/ 3) + (((metablkBitsLog2
% 3) > 0) ? 1 : 0));
1269 pBlock
->h
= 1 << ((metablkBitsLog2
/ 3) + (((metablkBitsLog2
% 3) > 1) ? 1 : 0));
1270 pBlock
->d
= 1 << (metablkBitsLog2
/ 3);
1273 return (1 << static_cast<UINT_32
>(metablkSizeLog2
));
1277 ************************************************************************************************************************
1278 * Gfx10Lib::ConvertSwizzlePatternToEquation
1281 * Convert swizzle pattern to equation.
1285 ************************************************************************************************************************
1287 VOID
Gfx10Lib::ConvertSwizzlePatternToEquation(
1288 UINT_32 elemLog2
, ///< [in] element bytes log2
1289 AddrResourceType rsrcType
, ///< [in] resource type
1290 AddrSwizzleMode swMode
, ///< [in] swizzle mode
1291 const UINT_64
* pPattern
, ///< [in] swizzle pattern
1292 ADDR_EQUATION
* pEquation
) ///< [out] equation converted from swizzle pattern
1295 const ADDR_BIT_SETTING
* pSwizzle
= reinterpret_cast<const ADDR_BIT_SETTING
*>(pPattern
);
1296 const UINT_32 blockSizeLog2
= GetBlockSizeLog2(swMode
);
1298 pEquation
->numBits
= blockSizeLog2
;
1299 pEquation
->stackedDepthSlices
= FALSE
;
1301 for (UINT_32 i
= 0; i
< elemLog2
; i
++)
1303 pEquation
->addr
[i
].channel
= 0;
1304 pEquation
->addr
[i
].valid
= 1;
1305 pEquation
->addr
[i
].index
= i
;
1308 if (IsXor(swMode
) == FALSE
)
1310 for (UINT_32 i
= elemLog2
; i
< blockSizeLog2
; i
++)
1312 ADDR_ASSERT(IsPow2(pSwizzle
[i
].value
));
1314 if (pSwizzle
[i
].x
!= 0)
1316 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].x
)));
1318 pEquation
->addr
[i
].channel
= 0;
1319 pEquation
->addr
[i
].valid
= 1;
1320 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].x
) + elemLog2
;
1322 else if (pSwizzle
[i
].y
!= 0)
1324 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].y
)));
1326 pEquation
->addr
[i
].channel
= 1;
1327 pEquation
->addr
[i
].valid
= 1;
1328 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].y
);
1332 ADDR_ASSERT(pSwizzle
[i
].z
!= 0);
1333 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].z
)));
1335 pEquation
->addr
[i
].channel
= 2;
1336 pEquation
->addr
[i
].valid
= 1;
1337 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].z
);
1340 pEquation
->xor1
[i
].value
= 0;
1341 pEquation
->xor2
[i
].value
= 0;
1344 else if (IsThin(rsrcType
, swMode
))
1346 const UINT_32 blkXLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_2d
[elemLog2
].w
: Block64K_Log2_2d
[elemLog2
].w
;
1347 const UINT_32 blkYLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_2d
[elemLog2
].h
: Block64K_Log2_2d
[elemLog2
].h
;
1348 const UINT_32 blkXMask
= (1 << blkXLog2
) - 1;
1349 const UINT_32 blkYMask
= (1 << blkYLog2
) - 1;
1351 ADDR_BIT_SETTING swizzle
[ADDR_MAX_EQUATION_BIT
];
1354 UINT_32 bMask
= (1 << elemLog2
) - 1;
1356 for (UINT_32 i
= elemLog2
; i
< blockSizeLog2
; i
++)
1358 if (IsPow2(pSwizzle
[i
].value
))
1360 if (pSwizzle
[i
].x
!= 0)
1362 ADDR_ASSERT((xMask
& pSwizzle
[i
].x
) == 0);
1363 xMask
|= pSwizzle
[i
].x
;
1365 const UINT_32 xLog2
= Log2(pSwizzle
[i
].x
);
1367 ADDR_ASSERT(xLog2
< blkXLog2
);
1369 pEquation
->addr
[i
].channel
= 0;
1370 pEquation
->addr
[i
].valid
= 1;
1371 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1375 ADDR_ASSERT(pSwizzle
[i
].y
!= 0);
1376 ADDR_ASSERT((yMask
& pSwizzle
[i
].y
) == 0);
1377 yMask
|= pSwizzle
[i
].y
;
1379 pEquation
->addr
[i
].channel
= 1;
1380 pEquation
->addr
[i
].valid
= 1;
1381 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].y
);
1383 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1386 swizzle
[i
].value
= 0;
1391 if (pSwizzle
[i
].z
!= 0)
1393 ADDR_ASSERT(IsPow2(static_cast<UINT_32
>(pSwizzle
[i
].z
)));
1395 pEquation
->xor2
[i
].channel
= 2;
1396 pEquation
->xor2
[i
].valid
= 1;
1397 pEquation
->xor2
[i
].index
= Log2(pSwizzle
[i
].z
);
1400 swizzle
[i
].x
= pSwizzle
[i
].x
;
1401 swizzle
[i
].y
= pSwizzle
[i
].y
;
1402 swizzle
[i
].z
= swizzle
[i
].s
= 0;
1404 ADDR_ASSERT(IsPow2(swizzle
[i
].value
) == FALSE
);
1406 const UINT_32 xHi
= swizzle
[i
].x
& (~blkXMask
);
1410 ADDR_ASSERT(IsPow2(xHi
));
1411 ADDR_ASSERT(pEquation
->xor1
[i
].value
== 0);
1413 pEquation
->xor1
[i
].channel
= 0;
1414 pEquation
->xor1
[i
].valid
= 1;
1415 pEquation
->xor1
[i
].index
= Log2(xHi
) + elemLog2
;
1417 swizzle
[i
].x
&= blkXMask
;
1420 const UINT_32 yHi
= swizzle
[i
].y
& (~blkYMask
);
1424 ADDR_ASSERT(IsPow2(yHi
));
1428 ADDR_ASSERT(pEquation
->xor1
[i
].value
== 0);
1429 pEquation
->xor1
[i
].channel
= 1;
1430 pEquation
->xor1
[i
].valid
= 1;
1431 pEquation
->xor1
[i
].index
= Log2(yHi
);
1435 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1436 pEquation
->xor2
[i
].channel
= 1;
1437 pEquation
->xor2
[i
].valid
= 1;
1438 pEquation
->xor2
[i
].index
= Log2(yHi
);
1441 swizzle
[i
].y
&= blkYMask
;
1444 if (swizzle
[i
].value
== 0)
1451 const UINT_32 pipeIntMask
= (1 << m_pipeInterleaveLog2
) - 1;
1452 const UINT_32 blockMask
= (1 << blockSizeLog2
) - 1;
1454 ADDR_ASSERT((bMask
& pipeIntMask
) == pipeIntMask
);
1456 while (bMask
!= blockMask
)
1458 for (UINT_32 i
= m_pipeInterleaveLog2
; i
< blockSizeLog2
; i
++)
1460 if ((bMask
& (1 << i
)) == 0)
1462 if (IsPow2(swizzle
[i
].value
))
1464 if (swizzle
[i
].x
!= 0)
1466 ADDR_ASSERT((xMask
& swizzle
[i
].x
) == 0);
1467 xMask
|= swizzle
[i
].x
;
1469 const UINT_32 xLog2
= Log2(swizzle
[i
].x
);
1471 ADDR_ASSERT(xLog2
< blkXLog2
);
1473 pEquation
->addr
[i
].channel
= 0;
1474 pEquation
->addr
[i
].valid
= 1;
1475 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1479 ADDR_ASSERT(swizzle
[i
].y
!= 0);
1480 ADDR_ASSERT((yMask
& swizzle
[i
].y
) == 0);
1481 yMask
|= swizzle
[i
].y
;
1483 pEquation
->addr
[i
].channel
= 1;
1484 pEquation
->addr
[i
].valid
= 1;
1485 pEquation
->addr
[i
].index
= Log2(swizzle
[i
].y
);
1487 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1490 swizzle
[i
].value
= 0;
1495 const UINT_32 x
= swizzle
[i
].x
& xMask
;
1496 const UINT_32 y
= swizzle
[i
].y
& yMask
;
1500 ADDR_ASSERT(IsPow2(x
));
1502 if (pEquation
->xor1
[i
].value
== 0)
1504 pEquation
->xor1
[i
].channel
= 0;
1505 pEquation
->xor1
[i
].valid
= 1;
1506 pEquation
->xor1
[i
].index
= Log2(x
) + elemLog2
;
1510 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1511 pEquation
->xor2
[i
].channel
= 0;
1512 pEquation
->xor2
[i
].valid
= 1;
1513 pEquation
->xor2
[i
].index
= Log2(x
) + elemLog2
;
1519 ADDR_ASSERT(IsPow2(y
));
1521 if (pEquation
->xor1
[i
].value
== 0)
1523 pEquation
->xor1
[i
].channel
= 1;
1524 pEquation
->xor1
[i
].valid
= 1;
1525 pEquation
->xor1
[i
].index
= Log2(y
);
1529 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1530 pEquation
->xor2
[i
].channel
= 1;
1531 pEquation
->xor2
[i
].valid
= 1;
1532 pEquation
->xor2
[i
].index
= Log2(y
);
1543 ADDR_ASSERT((xMask
== blkXMask
) && (yMask
== blkYMask
));
1545 else if (IsEquationCompatibleThick(rsrcType
, swMode
))
1547 const UINT_32 blkXLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_3d
[elemLog2
].w
: Block64K_Log2_3d
[elemLog2
].w
;
1548 const UINT_32 blkYLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_3d
[elemLog2
].h
: Block64K_Log2_3d
[elemLog2
].h
;
1549 const UINT_32 blkZLog2
= (blockSizeLog2
== 12) ? Block4K_Log2_3d
[elemLog2
].d
: Block64K_Log2_3d
[elemLog2
].d
;
1550 const UINT_32 blkXMask
= (1 << blkXLog2
) - 1;
1551 const UINT_32 blkYMask
= (1 << blkYLog2
) - 1;
1552 const UINT_32 blkZMask
= (1 << blkZLog2
) - 1;
1554 ADDR_BIT_SETTING swizzle
[ADDR_MAX_EQUATION_BIT
];
1558 UINT_32 bMask
= (1 << elemLog2
) - 1;
1560 for (UINT_32 i
= elemLog2
; i
< blockSizeLog2
; i
++)
1562 if (IsPow2(pSwizzle
[i
].value
))
1564 if (pSwizzle
[i
].x
!= 0)
1566 ADDR_ASSERT((xMask
& pSwizzle
[i
].x
) == 0);
1567 xMask
|= pSwizzle
[i
].x
;
1569 const UINT_32 xLog2
= Log2(pSwizzle
[i
].x
);
1571 ADDR_ASSERT(xLog2
< blkXLog2
);
1573 pEquation
->addr
[i
].channel
= 0;
1574 pEquation
->addr
[i
].valid
= 1;
1575 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1577 else if (pSwizzle
[i
].y
!= 0)
1579 ADDR_ASSERT((yMask
& pSwizzle
[i
].y
) == 0);
1580 yMask
|= pSwizzle
[i
].y
;
1582 pEquation
->addr
[i
].channel
= 1;
1583 pEquation
->addr
[i
].valid
= 1;
1584 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].y
);
1586 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1590 ADDR_ASSERT(pSwizzle
[i
].z
!= 0);
1591 ADDR_ASSERT((zMask
& pSwizzle
[i
].z
) == 0);
1592 zMask
|= pSwizzle
[i
].z
;
1594 pEquation
->addr
[i
].channel
= 2;
1595 pEquation
->addr
[i
].valid
= 1;
1596 pEquation
->addr
[i
].index
= Log2(pSwizzle
[i
].z
);
1598 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkZLog2
);
1601 swizzle
[i
].value
= 0;
1606 swizzle
[i
].x
= pSwizzle
[i
].x
;
1607 swizzle
[i
].y
= pSwizzle
[i
].y
;
1608 swizzle
[i
].z
= pSwizzle
[i
].z
;
1611 ADDR_ASSERT(IsPow2(swizzle
[i
].value
) == FALSE
);
1613 const UINT_32 xHi
= swizzle
[i
].x
& (~blkXMask
);
1614 const UINT_32 yHi
= swizzle
[i
].y
& (~blkYMask
);
1615 const UINT_32 zHi
= swizzle
[i
].z
& (~blkZMask
);
1617 ADDR_ASSERT((xHi
== 0) || (yHi
== 0) || (zHi
== 0));
1621 ADDR_ASSERT(IsPow2(xHi
));
1622 ADDR_ASSERT(pEquation
->xor1
[i
].value
== 0);
1624 pEquation
->xor1
[i
].channel
= 0;
1625 pEquation
->xor1
[i
].valid
= 1;
1626 pEquation
->xor1
[i
].index
= Log2(xHi
) + elemLog2
;
1628 swizzle
[i
].x
&= blkXMask
;
1633 ADDR_ASSERT(IsPow2(yHi
));
1635 if (pEquation
->xor1
[i
].value
== 0)
1637 pEquation
->xor1
[i
].channel
= 1;
1638 pEquation
->xor1
[i
].valid
= 1;
1639 pEquation
->xor1
[i
].index
= Log2(yHi
);
1643 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1644 pEquation
->xor2
[i
].channel
= 1;
1645 pEquation
->xor2
[i
].valid
= 1;
1646 pEquation
->xor2
[i
].index
= Log2(yHi
);
1649 swizzle
[i
].y
&= blkYMask
;
1654 ADDR_ASSERT(IsPow2(zHi
));
1656 if (pEquation
->xor1
[i
].value
== 0)
1658 pEquation
->xor1
[i
].channel
= 2;
1659 pEquation
->xor1
[i
].valid
= 1;
1660 pEquation
->xor1
[i
].index
= Log2(zHi
);
1664 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1665 pEquation
->xor2
[i
].channel
= 2;
1666 pEquation
->xor2
[i
].valid
= 1;
1667 pEquation
->xor2
[i
].index
= Log2(zHi
);
1670 swizzle
[i
].z
&= blkZMask
;
1673 if (swizzle
[i
].value
== 0)
1680 const UINT_32 pipeIntMask
= (1 << m_pipeInterleaveLog2
) - 1;
1681 const UINT_32 blockMask
= (1 << blockSizeLog2
) - 1;
1683 ADDR_ASSERT((bMask
& pipeIntMask
) == pipeIntMask
);
1685 while (bMask
!= blockMask
)
1687 for (UINT_32 i
= m_pipeInterleaveLog2
; i
< blockSizeLog2
; i
++)
1689 if ((bMask
& (1 << i
)) == 0)
1691 if (IsPow2(swizzle
[i
].value
))
1693 if (swizzle
[i
].x
!= 0)
1695 ADDR_ASSERT((xMask
& swizzle
[i
].x
) == 0);
1696 xMask
|= swizzle
[i
].x
;
1698 const UINT_32 xLog2
= Log2(swizzle
[i
].x
);
1700 ADDR_ASSERT(xLog2
< blkXLog2
);
1702 pEquation
->addr
[i
].channel
= 0;
1703 pEquation
->addr
[i
].valid
= 1;
1704 pEquation
->addr
[i
].index
= xLog2
+ elemLog2
;
1706 else if (swizzle
[i
].y
!= 0)
1708 ADDR_ASSERT((yMask
& swizzle
[i
].y
) == 0);
1709 yMask
|= swizzle
[i
].y
;
1711 pEquation
->addr
[i
].channel
= 1;
1712 pEquation
->addr
[i
].valid
= 1;
1713 pEquation
->addr
[i
].index
= Log2(swizzle
[i
].y
);
1715 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkYLog2
);
1719 ADDR_ASSERT(swizzle
[i
].z
!= 0);
1720 ADDR_ASSERT((zMask
& swizzle
[i
].z
) == 0);
1721 zMask
|= swizzle
[i
].z
;
1723 pEquation
->addr
[i
].channel
= 2;
1724 pEquation
->addr
[i
].valid
= 1;
1725 pEquation
->addr
[i
].index
= Log2(swizzle
[i
].z
);
1727 ADDR_ASSERT(pEquation
->addr
[i
].index
< blkZLog2
);
1730 swizzle
[i
].value
= 0;
1735 const UINT_32 x
= swizzle
[i
].x
& xMask
;
1736 const UINT_32 y
= swizzle
[i
].y
& yMask
;
1737 const UINT_32 z
= swizzle
[i
].z
& zMask
;
1741 ADDR_ASSERT(IsPow2(x
));
1743 if (pEquation
->xor1
[i
].value
== 0)
1745 pEquation
->xor1
[i
].channel
= 0;
1746 pEquation
->xor1
[i
].valid
= 1;
1747 pEquation
->xor1
[i
].index
= Log2(x
) + elemLog2
;
1751 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1752 pEquation
->xor2
[i
].channel
= 0;
1753 pEquation
->xor2
[i
].valid
= 1;
1754 pEquation
->xor2
[i
].index
= Log2(x
) + elemLog2
;
1760 ADDR_ASSERT(IsPow2(y
));
1762 if (pEquation
->xor1
[i
].value
== 0)
1764 pEquation
->xor1
[i
].channel
= 1;
1765 pEquation
->xor1
[i
].valid
= 1;
1766 pEquation
->xor1
[i
].index
= Log2(y
);
1770 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1771 pEquation
->xor2
[i
].channel
= 1;
1772 pEquation
->xor2
[i
].valid
= 1;
1773 pEquation
->xor2
[i
].index
= Log2(y
);
1779 ADDR_ASSERT(IsPow2(z
));
1781 if (pEquation
->xor1
[i
].value
== 0)
1783 pEquation
->xor1
[i
].channel
= 2;
1784 pEquation
->xor1
[i
].valid
= 1;
1785 pEquation
->xor1
[i
].index
= Log2(z
);
1789 ADDR_ASSERT(pEquation
->xor2
[i
].value
== 0);
1790 pEquation
->xor2
[i
].channel
= 2;
1791 pEquation
->xor2
[i
].valid
= 1;
1792 pEquation
->xor2
[i
].index
= Log2(z
);
1804 ADDR_ASSERT((xMask
== blkXMask
) && (yMask
== blkYMask
) && (zMask
== blkZMask
));
1809 ************************************************************************************************************************
1810 * Gfx10Lib::InitEquationTable
1813 * Initialize Equation table.
1817 ************************************************************************************************************************
1819 VOID
Gfx10Lib::InitEquationTable()
1821 memset(m_equationTable
, 0, sizeof(m_equationTable
));
1823 for (UINT_32 rsrcTypeIdx
= 0; rsrcTypeIdx
< MaxRsrcType
; rsrcTypeIdx
++)
1825 const AddrResourceType rsrcType
= static_cast<AddrResourceType
>(rsrcTypeIdx
+ ADDR_RSRC_TEX_2D
);
1827 for (UINT_32 swModeIdx
= 0; swModeIdx
< MaxSwMode
; swModeIdx
++)
1829 const AddrSwizzleMode swMode
= static_cast<AddrSwizzleMode
>(swModeIdx
);
1831 for (UINT_32 elemLog2
= 0; elemLog2
< MaxElementBytesLog2
; elemLog2
++)
1833 UINT_32 equationIndex
= ADDR_INVALID_EQUATION_INDEX
;
1834 const UINT_64
* pPattern
= GetSwizzlePattern(swMode
, rsrcType
, elemLog2
, 1);
1836 if (pPattern
!= NULL
)
1838 ADDR_EQUATION equation
= {};
1840 ConvertSwizzlePatternToEquation(elemLog2
, rsrcType
, swMode
, pPattern
, &equation
);
1842 equationIndex
= m_numEquations
;
1843 ADDR_ASSERT(equationIndex
< EquationTableSize
);
1845 m_equationTable
[equationIndex
] = equation
;
1850 m_equationLookupTable
[rsrcTypeIdx
][swModeIdx
][elemLog2
] = equationIndex
;
1857 ************************************************************************************************************************
1858 * Gfx10Lib::HwlGetEquationIndex
1861 * Interface function stub of GetEquationIndex
1865 ************************************************************************************************************************
1867 UINT_32
Gfx10Lib::HwlGetEquationIndex(
1868 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
1869 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
1872 UINT_32 equationIdx
= ADDR_INVALID_EQUATION_INDEX
;
1874 if ((pIn
->resourceType
== ADDR_RSRC_TEX_2D
) ||
1875 (pIn
->resourceType
== ADDR_RSRC_TEX_3D
))
1877 const UINT_32 rsrcTypeIdx
= static_cast<UINT_32
>(pIn
->resourceType
) - 1;
1878 const UINT_32 swModeIdx
= static_cast<UINT_32
>(pIn
->swizzleMode
);
1879 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
1881 equationIdx
= m_equationLookupTable
[rsrcTypeIdx
][swModeIdx
][elemLog2
];
1884 if (pOut
->pMipInfo
!= NULL
)
1886 for (UINT_32 i
= 0; i
< pIn
->numMipLevels
; i
++)
1888 pOut
->pMipInfo
[i
].equationIndex
= equationIdx
;
1896 ************************************************************************************************************************
1897 * Gfx10Lib::IsValidDisplaySwizzleMode
1900 * Check if a swizzle mode is supported by display engine
1903 * TRUE is swizzle mode is supported by display engine
1904 ************************************************************************************************************************
1906 BOOL_32
Gfx10Lib::IsValidDisplaySwizzleMode(
1907 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in] input structure
1910 ADDR_ASSERT(pIn
->resourceType
== ADDR_RSRC_TEX_2D
);
1912 BOOL_32 support
= FALSE
;
1914 if (m_settings
.isDcn2
)
1916 switch (pIn
->swizzleMode
)
1919 case ADDR_SW_4KB_D_X
:
1920 case ADDR_SW_64KB_D
:
1921 case ADDR_SW_64KB_D_T
:
1922 case ADDR_SW_64KB_D_X
:
1923 support
= (pIn
->bpp
== 64);
1926 case ADDR_SW_LINEAR
:
1928 case ADDR_SW_4KB_S_X
:
1929 case ADDR_SW_64KB_S
:
1930 case ADDR_SW_64KB_S_T
:
1931 case ADDR_SW_64KB_S_X
:
1932 case ADDR_SW_64KB_R_X
:
1933 support
= (pIn
->bpp
<= 64);
1942 ADDR_NOT_IMPLEMENTED();
1949 ************************************************************************************************************************
1950 * Gfx10Lib::GetMaxNumMipsInTail
1953 * Return max number of mips in tails
1956 * Max number of mips in tails
1957 ************************************************************************************************************************
1959 UINT_32
Gfx10Lib::GetMaxNumMipsInTail(
1960 UINT_32 blockSizeLog2
, ///< block size log2
1961 BOOL_32 isThin
///< is thin or thick
1964 UINT_32 effectiveLog2
= blockSizeLog2
;
1966 if (isThin
== FALSE
)
1968 effectiveLog2
-= (blockSizeLog2
- 8) / 3;
1971 return (effectiveLog2
<= 11) ? (1 + (1 << (effectiveLog2
- 9))) : (effectiveLog2
- 4);
1975 ************************************************************************************************************************
1976 * Gfx10Lib::HwlComputePipeBankXor
1979 * Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address
1983 ************************************************************************************************************************
1985 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputePipeBankXor(
1986 const ADDR2_COMPUTE_PIPEBANKXOR_INPUT
* pIn
, ///< [in] input structure
1987 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT
* pOut
///< [out] output structure
1990 if (IsNonPrtXor(pIn
->swizzleMode
))
1992 const UINT_32 blockBits
= GetBlockSizeLog2(pIn
->swizzleMode
);
1993 const UINT_32 pipeBits
= GetPipeXorBits(blockBits
);
1994 const UINT_32 bankBits
= GetBankXorBits(blockBits
);
1996 UINT_32 pipeXor
= 0;
1997 UINT_32 bankXor
= 0;
2001 if (blockBits
== 16)
2003 const UINT_32 XorPatternLen
= 8;
2004 static const UINT_32 XorBank1b
[XorPatternLen
] = {0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80};
2005 static const UINT_32 XorBank2b
[XorPatternLen
] = {0x00, 0x80, 0x40, 0xC0, 0x80, 0x00, 0xC0, 0x40};
2006 static const UINT_32 XorBank3b
[XorPatternLen
] = {0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0};
2008 const UINT_32 index
= pIn
->surfIndex
% XorPatternLen
;
2012 bankXor
= XorBank1b
[index
];
2014 else if (bankBits
== 2)
2016 bankXor
= XorBank2b
[index
];
2020 bankXor
= XorBank3b
[index
];
2024 bankXor
>>= (2 - pipeBits
);
2030 pOut
->pipeBankXor
= bankXor
| pipeXor
;
2034 pOut
->pipeBankXor
= 0;
2041 ************************************************************************************************************************
2042 * Gfx10Lib::HwlComputeSlicePipeBankXor
2045 * Generate slice PipeBankXor value based on base PipeBankXor value and slice id
2049 ************************************************************************************************************************
2051 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSlicePipeBankXor(
2052 const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT
* pIn
, ///< [in] input structure
2053 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT
* pOut
///< [out] output structure
2056 if (IsNonPrtXor(pIn
->swizzleMode
))
2058 const UINT_32 blockBits
= GetBlockSizeLog2(pIn
->swizzleMode
);
2059 const UINT_32 pipeBits
= GetPipeXorBits(blockBits
);
2060 const UINT_32 pipeXor
= ReverseBitVector(pIn
->slice
, pipeBits
);
2062 pOut
->pipeBankXor
= pIn
->basePipeBankXor
^ pipeXor
;
2066 pOut
->pipeBankXor
= 0;
2073 ************************************************************************************************************************
2074 * Gfx10Lib::HwlComputeSubResourceOffsetForSwizzlePattern
2077 * Compute sub resource offset to support swizzle pattern
2081 ************************************************************************************************************************
2083 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSubResourceOffsetForSwizzlePattern(
2084 const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT
* pIn
, ///< [in] input structure
2085 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT
* pOut
///< [out] output structure
2088 ADDR_ASSERT(IsThin(pIn
->resourceType
, pIn
->swizzleMode
));
2090 pOut
->offset
= pIn
->slice
* pIn
->sliceSize
+ pIn
->macroBlockOffset
;
2096 ************************************************************************************************************************
2097 * Gfx10Lib::ValidateNonSwModeParams
2100 * Validate compute surface info params except swizzle mode
2103 * TRUE if parameters are valid, FALSE otherwise
2104 ************************************************************************************************************************
2106 BOOL_32
Gfx10Lib::ValidateNonSwModeParams(
2107 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
) const
2109 BOOL_32 valid
= TRUE
;
2111 if ((pIn
->bpp
== 0) || (pIn
->bpp
> 128) || (pIn
->width
== 0) || (pIn
->numFrags
> 8) || (pIn
->numSamples
> 16))
2113 ADDR_ASSERT_ALWAYS();
2117 if (pIn
->resourceType
>= ADDR_RSRC_MAX_TYPE
)
2119 ADDR_ASSERT_ALWAYS();
2123 const ADDR2_SURFACE_FLAGS flags
= pIn
->flags
;
2124 const AddrResourceType rsrcType
= pIn
->resourceType
;
2125 const BOOL_32 mipmap
= (pIn
->numMipLevels
> 1);
2126 const BOOL_32 msaa
= (pIn
->numFrags
> 1);
2127 const BOOL_32 display
= flags
.display
;
2128 const BOOL_32 tex3d
= IsTex3d(rsrcType
);
2129 const BOOL_32 tex2d
= IsTex2d(rsrcType
);
2130 const BOOL_32 tex1d
= IsTex1d(rsrcType
);
2131 const BOOL_32 stereo
= flags
.qbStereo
;
2133 // Resource type check
2136 if (msaa
|| display
|| stereo
)
2138 ADDR_ASSERT_ALWAYS();
2144 if ((msaa
&& mipmap
) || (stereo
&& msaa
) || (stereo
&& mipmap
))
2146 ADDR_ASSERT_ALWAYS();
2152 if (msaa
|| display
|| stereo
)
2154 ADDR_ASSERT_ALWAYS();
2160 ADDR_ASSERT_ALWAYS();
2168 ************************************************************************************************************************
2169 * Gfx10Lib::ValidateSwModeParams
2172 * Validate compute surface info related to swizzle mode
2175 * TRUE if parameters are valid, FALSE otherwise
2176 ************************************************************************************************************************
2178 BOOL_32
Gfx10Lib::ValidateSwModeParams(
2179 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
) const
2181 BOOL_32 valid
= TRUE
;
2183 if (pIn
->swizzleMode
>= ADDR_SW_MAX_TYPE
)
2185 ADDR_ASSERT_ALWAYS();
2189 const ADDR2_SURFACE_FLAGS flags
= pIn
->flags
;
2190 const AddrResourceType rsrcType
= pIn
->resourceType
;
2191 const AddrSwizzleMode swizzle
= pIn
->swizzleMode
;
2192 const BOOL_32 msaa
= (pIn
->numFrags
> 1);
2193 const BOOL_32 zbuffer
= flags
.depth
|| flags
.stencil
;
2194 const BOOL_32 color
= flags
.color
;
2195 const BOOL_32 display
= flags
.display
;
2196 const BOOL_32 tex3d
= IsTex3d(rsrcType
);
2197 const BOOL_32 tex2d
= IsTex2d(rsrcType
);
2198 const BOOL_32 tex1d
= IsTex1d(rsrcType
);
2199 const BOOL_32 thin3d
= flags
.view3dAs2dArray
;
2200 const BOOL_32 linear
= IsLinear(swizzle
);
2201 const BOOL_32 blk256B
= IsBlock256b(swizzle
);
2202 const BOOL_32 isNonPrtXor
= IsNonPrtXor(swizzle
);
2203 const BOOL_32 prt
= flags
.prt
;
2206 if ((pIn
->numFrags
> 1) &&
2207 (GetBlockSize(swizzle
) < (m_pipeInterleaveBytes
* pIn
->numFrags
)))
2209 // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
2210 ADDR_ASSERT_ALWAYS();
2214 if (display
&& (IsValidDisplaySwizzleMode(pIn
) == FALSE
))
2216 ADDR_ASSERT_ALWAYS();
2220 if ((pIn
->bpp
== 96) && (linear
== FALSE
))
2222 ADDR_ASSERT_ALWAYS();
2226 const UINT_32 swizzleMask
= 1 << swizzle
;
2228 // Resource type check
2231 if ((swizzleMask
& Gfx10Rsrc1dSwModeMask
) == 0)
2233 ADDR_ASSERT_ALWAYS();
2239 if (((swizzleMask
& Gfx10Rsrc2dSwModeMask
) == 0) ||
2240 (prt
&& ((swizzleMask
& Gfx10Rsrc2dPrtSwModeMask
) == 0)))
2242 ADDR_ASSERT_ALWAYS();
2248 if (((swizzleMask
& Gfx10Rsrc3dSwModeMask
) == 0) ||
2249 (prt
&& ((swizzleMask
& Gfx10Rsrc3dPrtSwModeMask
) == 0)) ||
2250 (thin3d
&& ((swizzleMask
& Gfx10Rsrc3dThinSwModeMask
) == 0)))
2252 ADDR_ASSERT_ALWAYS();
2257 // Swizzle type check
2260 if (zbuffer
|| msaa
|| (pIn
->bpp
== 0) || ((pIn
->bpp
% 8) != 0))
2262 ADDR_ASSERT_ALWAYS();
2266 else if (IsZOrderSwizzle(swizzle
))
2268 if ((pIn
->bpp
> 64) ||
2269 (msaa
&& (color
|| (pIn
->bpp
> 32))) ||
2270 ElemLib::IsBlockCompressed(pIn
->format
) ||
2271 ElemLib::IsMacroPixelPacked(pIn
->format
))
2273 ADDR_ASSERT_ALWAYS();
2277 else if (IsStandardSwizzle(rsrcType
, swizzle
))
2279 if (zbuffer
|| msaa
)
2281 ADDR_ASSERT_ALWAYS();
2285 else if (IsDisplaySwizzle(rsrcType
, swizzle
))
2287 if (zbuffer
|| msaa
)
2289 ADDR_ASSERT_ALWAYS();
2293 else if (IsRtOptSwizzle(swizzle
))
2297 ADDR_ASSERT_ALWAYS();
2303 ADDR_ASSERT_ALWAYS();
2310 if (zbuffer
|| tex3d
|| msaa
)
2312 ADDR_ASSERT_ALWAYS();
2321 ************************************************************************************************************************
2322 * Gfx10Lib::HwlComputeSurfaceInfoSanityCheck
2325 * Compute surface info sanity check
2329 ************************************************************************************************************************
2331 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceInfoSanityCheck(
2332 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
///< [in] input structure
2335 return ValidateNonSwModeParams(pIn
) && ValidateSwModeParams(pIn
) ? ADDR_OK
: ADDR_INVALIDPARAMS
;
2339 ************************************************************************************************************************
2340 * Gfx10Lib::HwlGetPreferredSurfaceSetting
2343 * Internal function to get suggested surface information for cliet to use
2347 ************************************************************************************************************************
2349 ADDR_E_RETURNCODE
Gfx10Lib::HwlGetPreferredSurfaceSetting(
2350 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT
* pIn
, ///< [in] input structure
2351 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT
* pOut
///< [out] output structure
2354 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
2356 if (pIn
->flags
.fmask
)
2358 pOut
->swizzleMode
= ADDR_SW_64KB_Z_X
;
2359 pOut
->resourceType
= ADDR_RSRC_TEX_2D
;
2360 pOut
->validBlockSet
.value
= AddrBlockSetMacro64KB
;
2361 pOut
->canXor
= TRUE
;
2362 pOut
->validSwTypeSet
.value
= AddrSwSetZ
;
2363 pOut
->clientPreferredSwSet
= pOut
->validSwTypeSet
;
2364 pOut
->validSwModeSet
.value
= Gfx10ZSwModeMask
;
2368 UINT_32 bpp
= pIn
->bpp
;
2369 UINT_32 width
= Max(pIn
->width
, 1u);
2370 UINT_32 height
= Max(pIn
->height
, 1u);
2372 // Set format to INVALID will skip this conversion
2373 if (pIn
->format
!= ADDR_FMT_INVALID
)
2375 ElemMode elemMode
= ADDR_UNCOMPRESSED
;
2376 UINT_32 expandX
, expandY
;
2378 // Get compression/expansion factors and element mode which indicates compression/expansion
2379 bpp
= GetElemLib()->GetBitsPerPixel(pIn
->format
,
2384 UINT_32 basePitch
= 0;
2385 GetElemLib()->AdjustSurfaceInfo(elemMode
,
2394 const UINT_32 numSlices
= Max(pIn
->numSlices
, 1u);
2395 const UINT_32 numMipLevels
= Max(pIn
->numMipLevels
, 1u);
2396 const UINT_32 numSamples
= Max(pIn
->numSamples
, 1u);
2397 const UINT_32 numFrags
= (pIn
->numFrags
== 0) ? numSamples
: pIn
->numFrags
;
2398 const BOOL_32 msaa
= (numFrags
> 1) || (numSamples
> 1);
2400 // Pre sanity check on non swizzle mode parameters
2401 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {};
2402 localIn
.flags
= pIn
->flags
;
2403 localIn
.resourceType
= pIn
->resourceType
;
2404 localIn
.format
= pIn
->format
;
2406 localIn
.width
= width
;
2407 localIn
.height
= height
;
2408 localIn
.numSlices
= numSlices
;
2409 localIn
.numMipLevels
= numMipLevels
;
2410 localIn
.numSamples
= numSamples
;
2411 localIn
.numFrags
= numFrags
;
2413 if (ValidateNonSwModeParams(&localIn
))
2415 // Forbid swizzle mode(s) by client setting
2416 ADDR2_SWMODE_SET allowedSwModeSet
= {};
2417 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.linear
? 0 : Gfx10LinearSwModeMask
;
2418 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.micro
? 0 : Gfx10Blk256BSwModeMask
;
2419 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.macro4KB
? 0 : Gfx10Blk4KBSwModeMask
;
2420 allowedSwModeSet
.value
|= pIn
->forbiddenBlock
.macro64KB
? 0 : Gfx10Blk64KBSwModeMask
;
2422 if (pIn
->preferredSwSet
.value
!= 0)
2424 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_Z
? ~0 : ~Gfx10ZSwModeMask
;
2425 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_S
? ~0 : ~Gfx10StandardSwModeMask
;
2426 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_D
? ~0 : ~Gfx10DisplaySwModeMask
;
2427 allowedSwModeSet
.value
&= pIn
->preferredSwSet
.sw_R
? ~0 : ~Gfx10RenderSwModeMask
;
2432 allowedSwModeSet
.value
&= ~Gfx10XorSwModeMask
;
2435 if (pIn
->maxAlign
> 0)
2437 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_64KB
))
2439 allowedSwModeSet
.value
&= ~Gfx10Blk64KBSwModeMask
;
2442 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_4KB
))
2444 allowedSwModeSet
.value
&= ~Gfx10Blk4KBSwModeMask
;
2447 if (pIn
->maxAlign
< GetBlockSize(ADDR_SW_256B
))
2449 allowedSwModeSet
.value
&= ~Gfx10Blk256BSwModeMask
;
2453 // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
2454 switch (pIn
->resourceType
)
2456 case ADDR_RSRC_TEX_1D
:
2457 allowedSwModeSet
.value
&= Gfx10Rsrc1dSwModeMask
;
2460 case ADDR_RSRC_TEX_2D
:
2461 allowedSwModeSet
.value
&= pIn
->flags
.prt
? Gfx10Rsrc2dPrtSwModeMask
: Gfx10Rsrc2dSwModeMask
;
2464 case ADDR_RSRC_TEX_3D
:
2465 allowedSwModeSet
.value
&= pIn
->flags
.prt
? Gfx10Rsrc3dPrtSwModeMask
: Gfx10Rsrc3dSwModeMask
;
2467 if (m_settings
.supportRbPlus
)
2469 allowedSwModeSet
.value
&= ~Gfx10DisplaySwModeMask
;
2472 if (pIn
->flags
.view3dAs2dArray
)
2474 allowedSwModeSet
.value
&= Gfx10Rsrc3dThinSwModeMask
;
2479 ADDR_ASSERT_ALWAYS();
2480 allowedSwModeSet
.value
= 0;
2484 if (ElemLib::IsBlockCompressed(pIn
->format
) ||
2485 ElemLib::IsMacroPixelPacked(pIn
->format
) ||
2487 (msaa
&& ((bpp
> 32) || pIn
->flags
.color
|| pIn
->flags
.unordered
)))
2489 allowedSwModeSet
.value
&= ~Gfx10ZSwModeMask
;
2492 if (pIn
->format
== ADDR_FMT_32_32_32
)
2494 allowedSwModeSet
.value
&= Gfx10LinearSwModeMask
;
2499 allowedSwModeSet
.value
&= Gfx10MsaaSwModeMask
;
2502 if (pIn
->flags
.depth
|| pIn
->flags
.stencil
)
2504 allowedSwModeSet
.value
&= Gfx10ZSwModeMask
;
2507 if (pIn
->flags
.display
)
2509 if (m_settings
.isDcn2
)
2511 allowedSwModeSet
.value
&= (bpp
== 64) ? Dcn2Bpp64SwModeMask
: Dcn2NonBpp64SwModeMask
;
2515 ADDR_NOT_IMPLEMENTED();
2519 if (allowedSwModeSet
.value
!= 0)
2522 // Post sanity check, at least AddrLib should accept the output generated by its own
2523 UINT_32 validateSwModeSet
= allowedSwModeSet
.value
;
2525 for (UINT_32 i
= 0; validateSwModeSet
!= 0; i
++)
2527 if (validateSwModeSet
& 1)
2529 localIn
.swizzleMode
= static_cast<AddrSwizzleMode
>(i
);
2530 ADDR_ASSERT(ValidateSwModeParams(&localIn
));
2533 validateSwModeSet
>>= 1;
2537 pOut
->resourceType
= pIn
->resourceType
;
2538 pOut
->validSwModeSet
= allowedSwModeSet
;
2539 pOut
->canXor
= (allowedSwModeSet
.value
& Gfx10XorSwModeMask
) ? TRUE
: FALSE
;
2540 pOut
->validBlockSet
= GetAllowedBlockSet(allowedSwModeSet
);
2541 pOut
->validSwTypeSet
= GetAllowedSwSet(allowedSwModeSet
);
2543 pOut
->clientPreferredSwSet
= pIn
->preferredSwSet
;
2545 if (pOut
->clientPreferredSwSet
.value
== 0)
2547 pOut
->clientPreferredSwSet
.value
= AddrSwSetAll
;
2550 if (allowedSwModeSet
.value
== Gfx10LinearSwModeMask
)
2552 pOut
->swizzleMode
= ADDR_SW_LINEAR
;
2556 // Always ignore linear swizzle mode if there is other choice.
2557 allowedSwModeSet
.swLinear
= 0;
2559 ADDR2_BLOCK_SET allowedBlockSet
= GetAllowedBlockSet(allowedSwModeSet
);
2561 // Determine block size if there is 2 or more block type candidates
2562 if (IsPow2(allowedBlockSet
.value
) == FALSE
)
2564 const AddrSwizzleMode swMode
[AddrBlockMaxTiledType
] = {ADDR_SW_256B
, ADDR_SW_4KB
, ADDR_SW_64KB
};
2565 Dim3d blkDim
[AddrBlockMaxTiledType
] = {{0}, {0}, {0}};
2566 Dim3d padDim
[AddrBlockMaxTiledType
] = {{0}, {0}, {0}};
2567 UINT_64 padSize
[AddrBlockMaxTiledType
] = {0};
2569 const UINT_32 ratioLow
= pIn
->flags
.minimizeAlign
? 1 : (pIn
->flags
.opt4space
? 3 : 2);
2570 const UINT_32 ratioHi
= pIn
->flags
.minimizeAlign
? 1 : (pIn
->flags
.opt4space
? 2 : 1);
2571 const UINT_64 sizeAlignInElement
= Max(NextPow2(pIn
->minSizeAlign
) / (bpp
>> 3), 1u);
2572 UINT_32 minSizeBlk
= AddrBlockMicro
;
2573 UINT_64 minSize
= 0;
2575 for (UINT_32 i
= AddrBlockMicro
; i
< AddrBlockMaxTiledType
; i
++)
2577 if (allowedBlockSet
.value
& (1 << i
))
2579 ComputeBlockDimensionForSurf(&blkDim
[i
].w
,
2587 padSize
[i
] = ComputePadSize(&blkDim
[i
], width
, height
, numSlices
, &padDim
[i
]);
2588 padSize
[i
] = PowTwoAlign(padSize
[i
], sizeAlignInElement
);
2590 if ((minSize
== 0) ||
2591 ((padSize
[i
] * ratioHi
) <= (minSize
* ratioLow
)))
2593 minSize
= padSize
[i
];
2599 if ((allowedBlockSet
.micro
== TRUE
) &&
2600 (width
<= blkDim
[AddrBlockMicro
].w
) &&
2601 (height
<= blkDim
[AddrBlockMicro
].h
))
2603 minSizeBlk
= AddrBlockMicro
;
2606 if (minSizeBlk
== AddrBlockMicro
)
2608 allowedSwModeSet
.value
&= Gfx10Blk256BSwModeMask
;
2610 else if (minSizeBlk
== AddrBlock4KB
)
2612 allowedSwModeSet
.value
&= Gfx10Blk4KBSwModeMask
;
2616 ADDR_ASSERT(minSizeBlk
== AddrBlock64KB
);
2617 allowedSwModeSet
.value
&= Gfx10Blk64KBSwModeMask
;
2621 // Block type should be determined.
2622 ADDR_ASSERT(IsPow2(GetAllowedBlockSet(allowedSwModeSet
).value
));
2624 ADDR2_SWTYPE_SET allowedSwSet
= GetAllowedSwSet(allowedSwModeSet
);
2626 // Determine swizzle type if there is 2 or more swizzle type candidates
2627 if (IsPow2(allowedSwSet
.value
) == FALSE
)
2629 if (ElemLib::IsBlockCompressed(pIn
->format
))
2631 if (allowedSwSet
.sw_D
)
2633 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2635 else if (allowedSwSet
.sw_S
)
2637 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2641 ADDR_ASSERT(allowedSwSet
.sw_R
);
2642 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2645 else if (ElemLib::IsMacroPixelPacked(pIn
->format
))
2647 if (allowedSwSet
.sw_S
)
2649 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2651 else if (allowedSwSet
.sw_D
)
2653 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2657 ADDR_ASSERT(allowedSwSet
.sw_R
);
2658 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2661 else if (pIn
->resourceType
== ADDR_RSRC_TEX_3D
)
2663 if (pIn
->flags
.color
&& GetAllowedBlockSet(allowedSwModeSet
).macro64KB
&& allowedSwSet
.sw_D
)
2665 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2667 else if (allowedSwSet
.sw_S
)
2669 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2671 else if (allowedSwSet
.sw_R
)
2673 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2677 ADDR_ASSERT(allowedSwSet
.sw_Z
);
2678 allowedSwModeSet
.value
&= Gfx10ZSwModeMask
;
2683 if (allowedSwSet
.sw_R
)
2685 allowedSwModeSet
.value
&= Gfx10RenderSwModeMask
;
2687 else if (allowedSwSet
.sw_D
)
2689 allowedSwModeSet
.value
&= Gfx10DisplaySwModeMask
;
2691 else if (allowedSwSet
.sw_S
)
2693 allowedSwModeSet
.value
&= Gfx10StandardSwModeMask
;
2697 ADDR_ASSERT(allowedSwSet
.sw_Z
);
2698 allowedSwModeSet
.value
&= Gfx10ZSwModeMask
;
2703 // Swizzle type should be determined.
2704 ADDR_ASSERT(IsPow2(GetAllowedSwSet(allowedSwModeSet
).value
));
2706 // Determine swizzle mode now - always select the "largest" swizzle mode for a given block type +
2707 // swizzle type combination. For example, for AddrBlock64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
2708 // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
2709 pOut
->swizzleMode
= static_cast<AddrSwizzleMode
>(Log2NonPow2(allowedSwModeSet
.value
));
2714 // Invalid combination...
2715 ADDR_ASSERT_ALWAYS();
2716 returnCode
= ADDR_INVALIDPARAMS
;
2721 // Invalid combination...
2722 ADDR_ASSERT_ALWAYS();
2723 returnCode
= ADDR_INVALIDPARAMS
;
2731 ************************************************************************************************************************
2732 * Gfx10Lib::ComputeStereoInfo
2735 * Compute height alignment and right eye pipeBankXor for stereo surface
2740 ************************************************************************************************************************
2742 ADDR_E_RETURNCODE
Gfx10Lib::ComputeStereoInfo(
2743 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< Compute surface info
2744 UINT_32 blkHeight
, ///< Block height
2745 UINT_32
* pAlignY
, ///< Stereo requested additional alignment in Y
2746 UINT_32
* pRightXor
///< Right eye xor
2749 ADDR_E_RETURNCODE ret
= ADDR_OK
;
2754 if (IsNonPrtXor(pIn
->swizzleMode
))
2756 const UINT_32 blkSizeLog2
= GetBlockSizeLog2(pIn
->swizzleMode
);
2757 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
2758 const UINT_32 rsrcType
= static_cast<UINT_32
>(pIn
->resourceType
) - 1;
2759 const UINT_32 swMode
= static_cast<UINT_32
>(pIn
->swizzleMode
);
2760 const UINT_32 eqIndex
= m_equationLookupTable
[rsrcType
][swMode
][elemLog2
];
2762 if (eqIndex
!= ADDR_INVALID_EQUATION_INDEX
)
2767 for (UINT_32 i
= m_pipeInterleaveLog2
; i
< blkSizeLog2
; i
++)
2769 if (m_equationTable
[eqIndex
].xor1
[i
].value
== 0)
2774 ADDR_ASSERT(m_equationTable
[eqIndex
].xor1
[i
].valid
== 1);
2776 if ((m_equationTable
[eqIndex
].xor1
[i
].channel
== 1) &&
2777 (m_equationTable
[eqIndex
].xor1
[i
].index
> yMax
))
2779 yMax
= m_equationTable
[eqIndex
].xor1
[i
].index
;
2784 const UINT_32 additionalAlign
= 1 << yMax
;
2786 if (additionalAlign
>= blkHeight
)
2788 *pAlignY
*= (additionalAlign
/ blkHeight
);
2790 const UINT_32 alignedHeight
= PowTwoAlign(pIn
->height
, additionalAlign
);
2792 if ((alignedHeight
>> yMax
) & 1)
2794 *pRightXor
= 1 << (yPos
- m_pipeInterleaveLog2
);
2800 ret
= ADDR_INVALIDPARAMS
;
2808 ************************************************************************************************************************
2809 * Gfx10Lib::HwlComputeSurfaceInfoTiled
2812 * Internal function to calculate alignment for tiled surface
2816 ************************************************************************************************************************
2818 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceInfoTiled(
2819 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2820 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2823 ADDR_E_RETURNCODE ret
;
2825 if (IsBlock256b(pIn
->swizzleMode
))
2827 ret
= ComputeSurfaceInfoMicroTiled(pIn
, pOut
);
2831 ret
= ComputeSurfaceInfoMacroTiled(pIn
, pOut
);
2838 ************************************************************************************************************************
2839 * Gfx10Lib::ComputeSurfaceInfoMicroTiled
2842 * Internal function to calculate alignment for micro tiled surface
2846 ************************************************************************************************************************
2848 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceInfoMicroTiled(
2849 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2850 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2853 ADDR_E_RETURNCODE ret
= ComputeBlockDimensionForSurf(&pOut
->blockWidth
,
2863 pOut
->mipChainPitch
= 0;
2864 pOut
->mipChainHeight
= 0;
2865 pOut
->mipChainSlice
= 0;
2866 pOut
->epitchIsHeight
= FALSE
;
2867 pOut
->mipChainInTail
= FALSE
;
2868 pOut
->firstMipIdInTail
= pIn
->numMipLevels
;
2870 const UINT_32 blockSize
= GetBlockSize(pIn
->swizzleMode
);
2872 pOut
->pitch
= PowTwoAlign(pIn
->width
, pOut
->blockWidth
);
2873 pOut
->height
= PowTwoAlign(pIn
->height
, pOut
->blockHeight
);
2874 pOut
->numSlices
= pIn
->numSlices
;
2875 pOut
->baseAlign
= blockSize
;
2877 if (pIn
->numMipLevels
> 1)
2879 const UINT_32 mip0Width
= pIn
->width
;
2880 const UINT_32 mip0Height
= pIn
->height
;
2881 UINT_64 mipSliceSize
= 0;
2883 for (INT_32 i
= static_cast<INT_32
>(pIn
->numMipLevels
) - 1; i
>= 0; i
--)
2885 UINT_32 mipWidth
, mipHeight
;
2887 GetMipSize(mip0Width
, mip0Height
, 1, i
, &mipWidth
, &mipHeight
);
2889 const UINT_32 mipActualWidth
= PowTwoAlign(mipWidth
, pOut
->blockWidth
);
2890 const UINT_32 mipActualHeight
= PowTwoAlign(mipHeight
, pOut
->blockHeight
);
2892 if (pOut
->pMipInfo
!= NULL
)
2894 pOut
->pMipInfo
[i
].pitch
= mipActualWidth
;
2895 pOut
->pMipInfo
[i
].height
= mipActualHeight
;
2896 pOut
->pMipInfo
[i
].depth
= 1;
2897 pOut
->pMipInfo
[i
].offset
= mipSliceSize
;
2898 pOut
->pMipInfo
[i
].mipTailOffset
= 0;
2899 pOut
->pMipInfo
[i
].macroBlockOffset
= mipSliceSize
;
2902 mipSliceSize
+= mipActualWidth
* mipActualHeight
* (pIn
->bpp
>> 3);
2905 pOut
->sliceSize
= mipSliceSize
;
2906 pOut
->surfSize
= mipSliceSize
* pOut
->numSlices
;
2910 pOut
->sliceSize
= static_cast<UINT_64
>(pOut
->pitch
) * pOut
->height
* (pIn
->bpp
>> 3);
2911 pOut
->surfSize
= pOut
->sliceSize
* pOut
->numSlices
;
2913 if (pOut
->pMipInfo
!= NULL
)
2915 pOut
->pMipInfo
[0].pitch
= pOut
->pitch
;
2916 pOut
->pMipInfo
[0].height
= pOut
->height
;
2917 pOut
->pMipInfo
[0].depth
= 1;
2918 pOut
->pMipInfo
[0].offset
= 0;
2919 pOut
->pMipInfo
[0].mipTailOffset
= 0;
2920 pOut
->pMipInfo
[0].macroBlockOffset
= 0;
2930 ************************************************************************************************************************
2931 * Gfx10Lib::ComputeSurfaceInfoMacroTiled
2934 * Internal function to calculate alignment for macro tiled surface
2938 ************************************************************************************************************************
2940 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceInfoMacroTiled(
2941 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
2942 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
2945 ADDR_E_RETURNCODE returnCode
= ComputeBlockDimensionForSurf(&pOut
->blockWidth
,
2953 if (returnCode
== ADDR_OK
)
2955 UINT_32 heightAlign
= pOut
->blockHeight
;
2957 if (pIn
->flags
.qbStereo
)
2959 UINT_32 rightXor
= 0;
2962 returnCode
= ComputeStereoInfo(pIn
, heightAlign
, &alignY
, &rightXor
);
2964 if (returnCode
== ADDR_OK
)
2966 pOut
->pStereoInfo
->rightSwizzle
= rightXor
;
2968 heightAlign
*= alignY
;
2972 if (returnCode
== ADDR_OK
)
2974 // Mip chain dimesion and epitch has no meaning in GFX10, set to default value
2975 pOut
->mipChainPitch
= 0;
2976 pOut
->mipChainHeight
= 0;
2977 pOut
->mipChainSlice
= 0;
2978 pOut
->epitchIsHeight
= FALSE
;
2979 pOut
->mipChainInTail
= FALSE
;
2980 pOut
->firstMipIdInTail
= pIn
->numMipLevels
;
2982 const UINT_32 blockSizeLog2
= GetBlockSizeLog2(pIn
->swizzleMode
);
2983 const UINT_32 blockSize
= 1 << blockSizeLog2
;
2985 pOut
->pitch
= PowTwoAlign(pIn
->width
, pOut
->blockWidth
);
2986 pOut
->height
= PowTwoAlign(pIn
->height
, heightAlign
);
2987 pOut
->numSlices
= PowTwoAlign(pIn
->numSlices
, pOut
->blockSlices
);
2988 pOut
->baseAlign
= blockSize
;
2990 if (pIn
->numMipLevels
> 1)
2992 const Dim3d tailMaxDim
= GetMipTailDim(pIn
->resourceType
,
2997 const UINT_32 mip0Width
= pIn
->width
;
2998 const UINT_32 mip0Height
= pIn
->height
;
2999 const BOOL_32 isThin
= IsThin(pIn
->resourceType
, pIn
->swizzleMode
);
3000 const UINT_32 mip0Depth
= isThin
? 1 : pIn
->numSlices
;
3001 const UINT_32 maxMipsInTail
= GetMaxNumMipsInTail(blockSizeLog2
, isThin
);
3002 const UINT_32 index
= Log2(pIn
->bpp
>> 3);
3003 UINT_32 firstMipInTail
= pIn
->numMipLevels
;
3004 UINT_64 mipChainSliceSize
= 0;
3005 UINT_64 mipSize
[MaxMipLevels
];
3006 UINT_64 mipSliceSize
[MaxMipLevels
];
3008 Dim3d fixedTailMaxDim
= tailMaxDim
;
3010 if (m_settings
.dsMipmapHtileFix
&& IsZOrderSwizzle(pIn
->swizzleMode
) && (index
<= 1))
3012 fixedTailMaxDim
.w
/= Block256_2d
[index
].w
/ Block256_2d
[2].w
;
3013 fixedTailMaxDim
.h
/= Block256_2d
[index
].h
/ Block256_2d
[2].h
;
3016 for (UINT_32 i
= 0; i
< pIn
->numMipLevels
; i
++)
3018 UINT_32 mipWidth
, mipHeight
, mipDepth
;
3020 GetMipSize(mip0Width
, mip0Height
, mip0Depth
, i
, &mipWidth
, &mipHeight
, &mipDepth
);
3022 if (IsInMipTail(fixedTailMaxDim
, maxMipsInTail
, mipWidth
, mipHeight
, pIn
->numMipLevels
- i
))
3025 mipChainSliceSize
+= blockSize
/ pOut
->blockSlices
;
3030 const UINT_32 pitch
= PowTwoAlign(mipWidth
, pOut
->blockWidth
);
3031 const UINT_32 height
= PowTwoAlign(mipHeight
, pOut
->blockHeight
);
3032 const UINT_32 depth
= PowTwoAlign(mipDepth
, pOut
->blockSlices
);
3033 const UINT_64 sliceSize
= static_cast<UINT_64
>(pitch
) * height
* (pIn
->bpp
>> 3);
3035 mipSize
[i
] = sliceSize
* depth
;
3036 mipSliceSize
[i
] = sliceSize
* pOut
->blockSlices
;
3037 mipChainSliceSize
+= sliceSize
;
3039 if (pOut
->pMipInfo
!= NULL
)
3041 pOut
->pMipInfo
[i
].pitch
= pitch
;
3042 pOut
->pMipInfo
[i
].height
= height
;
3043 pOut
->pMipInfo
[i
].depth
= depth
;
3048 pOut
->sliceSize
= mipChainSliceSize
;
3049 pOut
->surfSize
= mipChainSliceSize
* pOut
->numSlices
;
3050 pOut
->mipChainInTail
= (firstMipInTail
== 0) ? TRUE
: FALSE
;
3051 pOut
->firstMipIdInTail
= firstMipInTail
;
3053 if (pOut
->pMipInfo
!= NULL
)
3056 UINT_64 macroBlkOffset
= 0;
3057 UINT_32 tailMaxDepth
= 0;
3059 if (firstMipInTail
!= pIn
->numMipLevels
)
3061 UINT_32 mipWidth
, mipHeight
;
3063 GetMipSize(mip0Width
, mip0Height
, mip0Depth
, firstMipInTail
,
3064 &mipWidth
, &mipHeight
, &tailMaxDepth
);
3066 offset
= blockSize
* PowTwoAlign(tailMaxDepth
, pOut
->blockSlices
) / pOut
->blockSlices
;
3067 macroBlkOffset
= blockSize
;
3070 for (INT_32 i
= firstMipInTail
- 1; i
>= 0; i
--)
3072 pOut
->pMipInfo
[i
].offset
= offset
;
3073 pOut
->pMipInfo
[i
].macroBlockOffset
= macroBlkOffset
;
3074 pOut
->pMipInfo
[i
].mipTailOffset
= 0;
3076 offset
+= mipSize
[i
];
3077 macroBlkOffset
+= mipSliceSize
[i
];
3080 UINT_32 pitch
= tailMaxDim
.w
;
3081 UINT_32 height
= tailMaxDim
.h
;
3082 UINT_32 depth
= isThin
? 1 : PowTwoAlign(tailMaxDepth
, Block256_3d
[index
].d
);
3084 tailMaxDepth
= isThin
? 1 : (depth
/ Block256_3d
[index
].d
);
3086 for (UINT_32 i
= firstMipInTail
; i
< pIn
->numMipLevels
; i
++)
3088 const UINT_32 m
= maxMipsInTail
- 1 - (i
- firstMipInTail
);
3089 const UINT_32 mipOffset
= (m
> 6) ? (16 << m
) : (m
<< 8);
3091 pOut
->pMipInfo
[i
].offset
= mipOffset
* tailMaxDepth
;
3092 pOut
->pMipInfo
[i
].mipTailOffset
= mipOffset
;
3093 pOut
->pMipInfo
[i
].macroBlockOffset
= 0;
3095 pOut
->pMipInfo
[i
].pitch
= pitch
;
3096 pOut
->pMipInfo
[i
].height
= height
;
3097 pOut
->pMipInfo
[i
].depth
= depth
;
3099 UINT_32 mipX
= ((mipOffset
>> 9) & 1) |
3100 ((mipOffset
>> 10) & 2) |
3101 ((mipOffset
>> 11) & 4) |
3102 ((mipOffset
>> 12) & 8) |
3103 ((mipOffset
>> 13) & 16) |
3104 ((mipOffset
>> 14) & 32);
3105 UINT_32 mipY
= ((mipOffset
>> 8) & 1) |
3106 ((mipOffset
>> 9) & 2) |
3107 ((mipOffset
>> 10) & 4) |
3108 ((mipOffset
>> 11) & 8) |
3109 ((mipOffset
>> 12) & 16) |
3110 ((mipOffset
>> 13) & 32);
3112 if (blockSizeLog2
& 1)
3114 const UINT_32 temp
= mipX
;
3120 mipY
= (mipY
<< 1) | (mipX
& 1);
3127 pOut
->pMipInfo
[i
].mipTailCoordX
= mipX
* Block256_2d
[index
].w
;
3128 pOut
->pMipInfo
[i
].mipTailCoordY
= mipY
* Block256_2d
[index
].h
;
3129 pOut
->pMipInfo
[i
].mipTailCoordZ
= 0;
3131 pitch
= Max(pitch
>> 1, Block256_2d
[index
].w
);
3132 height
= Max(height
>> 1, Block256_2d
[index
].h
);
3137 pOut
->pMipInfo
[i
].mipTailCoordX
= mipX
* Block256_3d
[index
].w
;
3138 pOut
->pMipInfo
[i
].mipTailCoordY
= mipY
* Block256_3d
[index
].h
;
3139 pOut
->pMipInfo
[i
].mipTailCoordZ
= 0;
3141 pitch
= Max(pitch
>> 1, Block256_3d
[index
].w
);
3142 height
= Max(height
>> 1, Block256_3d
[index
].h
);
3143 depth
= PowTwoAlign(Max(depth
>> 1, 1u), Block256_3d
[index
].d
);
3150 pOut
->sliceSize
= static_cast<UINT_64
>(pOut
->pitch
) * pOut
->height
* (pIn
->bpp
>> 3) * pIn
->numFrags
;
3151 pOut
->surfSize
= pOut
->sliceSize
* pOut
->numSlices
;
3153 if (pOut
->pMipInfo
!= NULL
)
3155 pOut
->pMipInfo
[0].pitch
= pOut
->pitch
;
3156 pOut
->pMipInfo
[0].height
= pOut
->height
;
3157 pOut
->pMipInfo
[0].depth
= IsTex3d(pIn
->resourceType
)? pOut
->numSlices
: 1;
3158 pOut
->pMipInfo
[0].offset
= 0;
3159 pOut
->pMipInfo
[0].mipTailOffset
= 0;
3160 pOut
->pMipInfo
[0].macroBlockOffset
= 0;
3161 pOut
->pMipInfo
[0].mipTailCoordX
= 0;
3162 pOut
->pMipInfo
[0].mipTailCoordY
= 0;
3163 pOut
->pMipInfo
[0].mipTailCoordZ
= 0;
3173 ************************************************************************************************************************
3174 * Gfx10Lib::HwlComputeSurfaceAddrFromCoordTiled
3177 * Internal function to calculate address from coord for tiled swizzle surface
3181 ************************************************************************************************************************
3183 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceAddrFromCoordTiled(
3184 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3185 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3188 ADDR_E_RETURNCODE ret
;
3190 if (IsBlock256b(pIn
->swizzleMode
))
3192 ret
= ComputeSurfaceAddrFromCoordMicroTiled(pIn
, pOut
);
3196 ret
= ComputeSurfaceAddrFromCoordMacroTiled(pIn
, pOut
);
3203 ************************************************************************************************************************
3204 * Gfx10Lib::ComputeOffsetFromEquation
3207 * Compute offset from equation
3211 ************************************************************************************************************************
3213 UINT_32
Gfx10Lib::ComputeOffsetFromEquation(
3214 const ADDR_EQUATION
* pEq
, ///< Equation
3215 UINT_32 x
, ///< x coord in bytes
3216 UINT_32 y
, ///< y coord in pixel
3217 UINT_32 z
///< z coord in slice
3222 for (UINT_32 i
= 0; i
< pEq
->numBits
; i
++)
3226 if (pEq
->addr
[i
].valid
)
3228 if (pEq
->addr
[i
].channel
== 0)
3230 v
^= (x
>> pEq
->addr
[i
].index
) & 1;
3232 else if (pEq
->addr
[i
].channel
== 1)
3234 v
^= (y
>> pEq
->addr
[i
].index
) & 1;
3238 ADDR_ASSERT(pEq
->addr
[i
].channel
== 2);
3239 v
^= (z
>> pEq
->addr
[i
].index
) & 1;
3243 if (pEq
->xor1
[i
].valid
)
3245 if (pEq
->xor1
[i
].channel
== 0)
3247 v
^= (x
>> pEq
->xor1
[i
].index
) & 1;
3249 else if (pEq
->xor1
[i
].channel
== 1)
3251 v
^= (y
>> pEq
->xor1
[i
].index
) & 1;
3255 ADDR_ASSERT(pEq
->xor1
[i
].channel
== 2);
3256 v
^= (z
>> pEq
->xor1
[i
].index
) & 1;
3260 if (pEq
->xor2
[i
].valid
)
3262 if (pEq
->xor2
[i
].channel
== 0)
3264 v
^= (x
>> pEq
->xor2
[i
].index
) & 1;
3266 else if (pEq
->xor2
[i
].channel
== 1)
3268 v
^= (y
>> pEq
->xor2
[i
].index
) & 1;
3272 ADDR_ASSERT(pEq
->xor2
[i
].channel
== 2);
3273 v
^= (z
>> pEq
->xor2
[i
].index
) & 1;
3284 ************************************************************************************************************************
3285 * Gfx10Lib::ComputeOffsetFromSwizzlePattern
3288 * Compute offset from swizzle pattern
3292 ************************************************************************************************************************
3294 UINT_32
Gfx10Lib::ComputeOffsetFromSwizzlePattern(
3295 const UINT_64
* pPattern
, ///< Swizzle pattern
3296 UINT_32 numBits
, ///< Number of bits in pattern
3297 UINT_32 x
, ///< x coord in pixel
3298 UINT_32 y
, ///< y coord in pixel
3299 UINT_32 z
, ///< z coord in slice
3300 UINT_32 s
///< sample id
3304 const ADDR_BIT_SETTING
* pSwizzlePattern
= reinterpret_cast<const ADDR_BIT_SETTING
*>(pPattern
);
3306 for (UINT_32 i
= 0; i
< numBits
; i
++)
3310 if (pSwizzlePattern
[i
].x
!= 0)
3312 UINT_16 mask
= pSwizzlePattern
[i
].x
;
3327 if (pSwizzlePattern
[i
].y
!= 0)
3329 UINT_16 mask
= pSwizzlePattern
[i
].y
;
3344 if (pSwizzlePattern
[i
].z
!= 0)
3346 UINT_16 mask
= pSwizzlePattern
[i
].z
;
3361 if (pSwizzlePattern
[i
].s
!= 0)
3363 UINT_16 mask
= pSwizzlePattern
[i
].s
;
3385 ************************************************************************************************************************
3386 * Gfx10Lib::GetSwizzlePattern
3389 * Get swizzle pattern
3393 ************************************************************************************************************************
3395 const UINT_64
* Gfx10Lib::GetSwizzlePattern(
3396 AddrSwizzleMode swizzleMode
, ///< Swizzle mode
3397 AddrResourceType resourceType
, ///< Resource type
3398 UINT_32 elemLog2
, ///< Element size in bytes log2
3399 UINT_32 numFrag
///< Number of fragment
3402 const UINT_32 index
= IsXor(swizzleMode
) ? (m_colorBaseIndex
+ elemLog2
) : elemLog2
;
3403 const UINT_64
* pSwizzlePattern
= NULL
;
3404 const UINT_32 swizzleMask
= 1 << swizzleMode
;
3406 if (IsLinear(swizzleMode
))
3408 pSwizzlePattern
= NULL
;
3410 else if (resourceType
== ADDR_RSRC_TEX_3D
)
3412 ADDR_ASSERT(numFrag
== 1);
3414 if ((swizzleMask
& Gfx10Rsrc3dSwModeMask
) == 0)
3416 pSwizzlePattern
= NULL
;
3418 else if (IsRtOptSwizzle(swizzleMode
))
3420 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_1xaa_RBPLUS
[index
] : SW_64K_R_X_1xaa
[index
];
3422 else if (IsZOrderSwizzle(swizzleMode
))
3424 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_1xaa_RBPLUS
[index
] : SW_64K_Z_X_1xaa
[index
];
3426 else if (IsDisplaySwizzle(resourceType
, swizzleMode
))
3428 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_D_X
);
3429 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D3_X_RBPLUS
[index
] : SW_64K_D3_X
[index
];
3433 ADDR_ASSERT(IsStandardSwizzle(resourceType
, swizzleMode
));
3435 if (IsBlock4kb(swizzleMode
))
3437 if (swizzleMode
== ADDR_SW_4KB_S
)
3439 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S3_RBPLUS
[index
] : SW_4K_S3
[index
];
3443 ADDR_ASSERT(swizzleMode
== ADDR_SW_4KB_S_X
);
3444 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S3_X_RBPLUS
[index
] : SW_4K_S3_X
[index
];
3449 if (swizzleMode
== ADDR_SW_64KB_S
)
3451 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S3_RBPLUS
[index
] : SW_64K_S3
[index
];
3453 else if (swizzleMode
== ADDR_SW_64KB_S_X
)
3455 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S3_X_RBPLUS
[index
] : SW_64K_S3_X
[index
];
3459 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_S_T
);
3460 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S3_T_RBPLUS
[index
] : SW_64K_S3_T
[index
];
3468 if ((swizzleMask
& Gfx10Rsrc2dSwModeMask
) == 0)
3470 pSwizzlePattern
= NULL
;
3472 else if (IsBlock256b(swizzleMode
))
3474 if (swizzleMode
== ADDR_SW_256B_S
)
3476 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_256_S_RBPLUS
[index
] : SW_256_S
[index
];
3480 ADDR_ASSERT(swizzleMode
== ADDR_SW_256B_D
);
3481 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_256_D_RBPLUS
[index
] : SW_256_D
[index
];
3484 else if (IsBlock4kb(swizzleMode
))
3486 if (IsStandardSwizzle(resourceType
, swizzleMode
))
3488 if (swizzleMode
== ADDR_SW_4KB_S
)
3490 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S_RBPLUS
[index
] : SW_4K_S
[index
];
3494 ADDR_ASSERT(swizzleMode
== ADDR_SW_4KB_S_X
);
3495 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_S_X_RBPLUS
[index
] : SW_4K_S_X
[index
];
3500 if (swizzleMode
== ADDR_SW_4KB_D
)
3502 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_D_RBPLUS
[index
] : SW_4K_D
[index
];
3506 ADDR_ASSERT(swizzleMode
== ADDR_SW_4KB_D_X
);
3507 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_4K_D_X_RBPLUS
[index
] : SW_4K_D_X
[index
];
3513 if (IsRtOptSwizzle(swizzleMode
))
3517 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_1xaa_RBPLUS
[index
] : SW_64K_R_X_1xaa
[index
];
3519 else if (numFrag
== 2)
3521 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_2xaa_RBPLUS
[index
] : SW_64K_R_X_2xaa
[index
];
3523 else if (numFrag
== 4)
3525 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_4xaa_RBPLUS
[index
] : SW_64K_R_X_4xaa
[index
];
3529 ADDR_ASSERT(numFrag
== 8);
3530 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_R_X_8xaa_RBPLUS
[index
] : SW_64K_R_X_8xaa
[index
];
3533 else if (IsZOrderSwizzle(swizzleMode
))
3537 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_1xaa_RBPLUS
[index
] : SW_64K_Z_X_1xaa
[index
];
3539 else if (numFrag
== 2)
3541 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_2xaa_RBPLUS
[index
] : SW_64K_Z_X_2xaa
[index
];
3543 else if (numFrag
== 4)
3545 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_4xaa_RBPLUS
[index
] : SW_64K_Z_X_4xaa
[index
];
3549 ADDR_ASSERT(numFrag
== 8);
3550 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_Z_X_8xaa_RBPLUS
[index
] : SW_64K_Z_X_8xaa
[index
];
3553 else if (IsDisplaySwizzle(resourceType
, swizzleMode
))
3555 if (swizzleMode
== ADDR_SW_64KB_D
)
3557 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D_RBPLUS
[index
] : SW_64K_D
[index
];
3559 else if (swizzleMode
== ADDR_SW_64KB_D_X
)
3561 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D_X_RBPLUS
[index
] : SW_64K_D_X
[index
];
3565 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_D_T
);
3566 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_D_T_RBPLUS
[index
] : SW_64K_D_T
[index
];
3571 if (swizzleMode
== ADDR_SW_64KB_S
)
3573 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S_RBPLUS
[index
] : SW_64K_S
[index
];
3575 else if (swizzleMode
== ADDR_SW_64KB_S_X
)
3577 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S_X_RBPLUS
[index
] : SW_64K_S_X
[index
];
3581 ADDR_ASSERT(swizzleMode
== ADDR_SW_64KB_S_T
);
3582 pSwizzlePattern
= m_settings
.supportRbPlus
? SW_64K_S_T_RBPLUS
[index
] : SW_64K_S_T
[index
];
3588 return pSwizzlePattern
;
3592 ************************************************************************************************************************
3593 * Gfx10Lib::ComputeSurfaceAddrFromCoordMicroTiled
3596 * Internal function to calculate address from coord for micro tiled swizzle surface
3600 ************************************************************************************************************************
3602 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceAddrFromCoordMicroTiled(
3603 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3604 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3607 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
3608 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
3609 ADDR2_MIP_INFO mipInfo
[MaxMipLevels
];
3611 localIn
.swizzleMode
= pIn
->swizzleMode
;
3612 localIn
.flags
= pIn
->flags
;
3613 localIn
.resourceType
= pIn
->resourceType
;
3614 localIn
.bpp
= pIn
->bpp
;
3615 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
3616 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
3617 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
3618 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
3619 localIn
.numSamples
= Max(pIn
->numSamples
, 1u);
3620 localIn
.numFrags
= Max(pIn
->numFrags
, 1u);
3621 localOut
.pMipInfo
= mipInfo
;
3623 ADDR_E_RETURNCODE ret
= ComputeSurfaceInfoMicroTiled(&localIn
, &localOut
);
3627 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
3628 const UINT_32 rsrcType
= static_cast<UINT_32
>(pIn
->resourceType
) - 1;
3629 const UINT_32 swMode
= static_cast<UINT_32
>(pIn
->swizzleMode
);
3630 const UINT_32 eqIndex
= m_equationLookupTable
[rsrcType
][swMode
][elemLog2
];
3632 if (eqIndex
!= ADDR_INVALID_EQUATION_INDEX
)
3634 const UINT_32 pb
= mipInfo
[pIn
->mipId
].pitch
/ localOut
.blockWidth
;
3635 const UINT_32 yb
= pIn
->y
/ localOut
.blockHeight
;
3636 const UINT_32 xb
= pIn
->x
/ localOut
.blockWidth
;
3637 const UINT_32 blockIndex
= yb
* pb
+ xb
;
3638 const UINT_32 blockSize
= 256;
3639 const UINT_32 blk256Offset
= ComputeOffsetFromEquation(&m_equationTable
[eqIndex
],
3643 pOut
->addr
= localOut
.sliceSize
* pIn
->slice
+
3644 mipInfo
[pIn
->mipId
].macroBlockOffset
+
3645 (blockIndex
* blockSize
) +
3650 ret
= ADDR_INVALIDPARAMS
;
3658 ************************************************************************************************************************
3659 * Gfx10Lib::ComputeSurfaceAddrFromCoordMacroTiled
3662 * Internal function to calculate address from coord for macro tiled swizzle surface
3666 ************************************************************************************************************************
3668 ADDR_E_RETURNCODE
Gfx10Lib::ComputeSurfaceAddrFromCoordMacroTiled(
3669 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT
* pIn
, ///< [in] input structure
3670 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT
* pOut
///< [out] output structure
3673 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn
= {0};
3674 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut
= {0};
3675 ADDR2_MIP_INFO mipInfo
[MaxMipLevels
];
3677 localIn
.swizzleMode
= pIn
->swizzleMode
;
3678 localIn
.flags
= pIn
->flags
;
3679 localIn
.resourceType
= pIn
->resourceType
;
3680 localIn
.bpp
= pIn
->bpp
;
3681 localIn
.width
= Max(pIn
->unalignedWidth
, 1u);
3682 localIn
.height
= Max(pIn
->unalignedHeight
, 1u);
3683 localIn
.numSlices
= Max(pIn
->numSlices
, 1u);
3684 localIn
.numMipLevels
= Max(pIn
->numMipLevels
, 1u);
3685 localIn
.numSamples
= Max(pIn
->numSamples
, 1u);
3686 localIn
.numFrags
= Max(pIn
->numFrags
, 1u);
3687 localOut
.pMipInfo
= mipInfo
;
3689 ADDR_E_RETURNCODE ret
= ComputeSurfaceInfoMacroTiled(&localIn
, &localOut
);
3693 const UINT_32 elemLog2
= Log2(pIn
->bpp
>> 3);
3694 const UINT_32 blkSizeLog2
= GetBlockSizeLog2(pIn
->swizzleMode
);
3695 const UINT_32 blkMask
= (1 << blkSizeLog2
) - 1;
3696 const UINT_32 pipeMask
= (1 << m_pipesLog2
) - 1;
3697 const UINT_32 bankMask
= ((1 << GetBankXorBits(blkSizeLog2
)) - 1) << (m_pipesLog2
+ ColumnBits
);
3698 const UINT_32 pipeBankXor
= IsXor(pIn
->swizzleMode
) ?
3699 (((pIn
->pipeBankXor
& (pipeMask
| bankMask
)) << m_pipeInterleaveLog2
) & blkMask
) : 0;
3701 if (localIn
.numFrags
> 1)
3703 const UINT_64
* pPattern
= GetSwizzlePattern(pIn
->swizzleMode
,
3708 if (pPattern
!= NULL
)
3710 const UINT_32 pb
= localOut
.pitch
/ localOut
.blockWidth
;
3711 const UINT_32 yb
= pIn
->y
/ localOut
.blockHeight
;
3712 const UINT_32 xb
= pIn
->x
/ localOut
.blockWidth
;
3713 const UINT_64 blkIdx
= yb
* pb
+ xb
;
3714 const UINT_32 blkOffset
= ComputeOffsetFromSwizzlePattern(pPattern
,
3720 pOut
->addr
= (localOut
.sliceSize
* pIn
->slice
) +
3721 (blkIdx
<< blkSizeLog2
) +
3722 (blkOffset
^ pipeBankXor
);
3726 ret
= ADDR_INVALIDPARAMS
;
3731 const UINT_32 rsrcIdx
= (pIn
->resourceType
== ADDR_RSRC_TEX_3D
) ? 1 : 0;
3732 const UINT_32 swMode
= static_cast<UINT_32
>(pIn
->swizzleMode
);
3733 const UINT_32 eqIndex
= m_equationLookupTable
[rsrcIdx
][swMode
][elemLog2
];
3735 if (eqIndex
!= ADDR_INVALID_EQUATION_INDEX
)
3737 const BOOL_32 inTail
= (mipInfo
[pIn
->mipId
].mipTailOffset
!= 0) ? TRUE
: FALSE
;
3738 const BOOL_32 isThin
= IsThin(pIn
->resourceType
, pIn
->swizzleMode
);
3739 const UINT_64 sliceSize
= isThin
? localOut
.sliceSize
: (localOut
.sliceSize
* localOut
.blockSlices
);
3740 const UINT_32 sliceId
= isThin
? pIn
->slice
: (pIn
->slice
/ localOut
.blockSlices
);
3741 const UINT_32 x
= inTail
? (pIn
->x
+ mipInfo
[pIn
->mipId
].mipTailCoordX
) : pIn
->x
;
3742 const UINT_32 y
= inTail
? (pIn
->y
+ mipInfo
[pIn
->mipId
].mipTailCoordY
) : pIn
->y
;
3743 const UINT_32 z
= inTail
? (pIn
->slice
+ mipInfo
[pIn
->mipId
].mipTailCoordZ
) : pIn
->slice
;
3744 const UINT_32 pb
= mipInfo
[pIn
->mipId
].pitch
/ localOut
.blockWidth
;
3745 const UINT_32 yb
= pIn
->y
/ localOut
.blockHeight
;
3746 const UINT_32 xb
= pIn
->x
/ localOut
.blockWidth
;
3747 const UINT_64 blkIdx
= yb
* pb
+ xb
;
3748 const UINT_32 blkOffset
= ComputeOffsetFromEquation(&m_equationTable
[eqIndex
],
3752 pOut
->addr
= sliceSize
* sliceId
+
3753 mipInfo
[pIn
->mipId
].macroBlockOffset
+
3754 (blkIdx
<< blkSizeLog2
) +
3755 (blkOffset
^ pipeBankXor
);
3759 ret
= ADDR_INVALIDPARAMS
;
3768 ************************************************************************************************************************
3769 * Gfx10Lib::HwlComputeMaxBaseAlignments
3772 * Gets maximum alignments
3774 * maximum alignments
3775 ************************************************************************************************************************
3777 UINT_32
Gfx10Lib::HwlComputeMaxBaseAlignments() const
3779 return GetBlockSize(ADDR_SW_64KB
);
3783 ************************************************************************************************************************
3784 * Gfx10Lib::HwlComputeMaxMetaBaseAlignments
3787 * Gets maximum alignments for metadata
3789 * maximum alignments for metadata
3790 ************************************************************************************************************************
3792 UINT_32
Gfx10Lib::HwlComputeMaxMetaBaseAlignments() const
3794 // Max base alignment for Htile
3795 Dim3d metaBlk
= {0};
3796 const UINT_32 metaBlkSize
= GetMetaBlkSize(Gfx10DataDepthStencil
,
3804 const UINT_32 maxBaseAlignHtile
= Max(metaBlkSize
, 1u << (m_pipesLog2
+ 11u));
3806 // Max base alignment for Cmask
3807 const UINT_32 maxBaseAlignCmask
= GetMetaBlkSize(Gfx10DataFmask
,
3815 // Max base alignment for 2D Dcc
3816 const AddrSwizzleMode ValidSwizzleModeForDcc2D
[] =
3823 UINT_32 maxBaseAlignDcc2D
= 0;
3825 for (UINT_32 swIdx
= 0; swIdx
< sizeof(ValidSwizzleModeForDcc2D
) / sizeof(ValidSwizzleModeForDcc2D
[0]); swIdx
++)
3827 for (UINT_32 bppLog2
= 0; bppLog2
< MaxNumOfBpp
; bppLog2
++)
3829 for (UINT_32 numFragLog2
= 0; numFragLog2
< 4; numFragLog2
++)
3831 const UINT_32 metaBlkSize2D
= GetMetaBlkSize(Gfx10DataColor
,
3833 ValidSwizzleModeForDcc2D
[swIdx
],
3839 maxBaseAlignDcc2D
= Max(maxBaseAlignDcc2D
, metaBlkSize2D
);
3844 // Max base alignment for 3D Dcc
3845 const AddrSwizzleMode ValidSwizzleModeForDcc3D
[] =
3853 UINT_32 maxBaseAlignDcc3D
= 0;
3855 for (UINT_32 swIdx
= 0; swIdx
< sizeof(ValidSwizzleModeForDcc3D
) / sizeof(ValidSwizzleModeForDcc3D
[0]); swIdx
++)
3857 for (UINT_32 bppLog2
= 0; bppLog2
< MaxNumOfBpp
; bppLog2
++)
3859 const UINT_32 metaBlkSize3D
= GetMetaBlkSize(Gfx10DataColor
,
3861 ValidSwizzleModeForDcc3D
[swIdx
],
3867 maxBaseAlignDcc3D
= Max(maxBaseAlignDcc3D
, metaBlkSize3D
);
3871 return Max(Max(maxBaseAlignHtile
, maxBaseAlignCmask
), Max(maxBaseAlignDcc2D
, maxBaseAlignDcc3D
));
3875 ************************************************************************************************************************
3876 * Gfx10Lib::GetMetaElementSizeLog2
3879 * Gets meta data element size log2
3881 * Meta data element size log2
3882 ************************************************************************************************************************
3884 INT_32
Gfx10Lib::GetMetaElementSizeLog2(
3885 Gfx10DataType dataType
) ///< Data surface type
3887 INT_32 elemSizeLog2
= 0;
3889 if (dataType
== Gfx10DataColor
)
3893 else if (dataType
== Gfx10DataDepthStencil
)
3899 ADDR_ASSERT(dataType
== Gfx10DataFmask
);
3903 return elemSizeLog2
;
3907 ************************************************************************************************************************
3908 * Gfx10Lib::GetMetaCacheSizeLog2
3911 * Gets meta data cache line size log2
3913 * Meta data cache line size log2
3914 ************************************************************************************************************************
3916 INT_32
Gfx10Lib::GetMetaCacheSizeLog2(
3917 Gfx10DataType dataType
) ///< Data surface type
3919 INT_32 cacheSizeLog2
= 0;
3921 if (dataType
== Gfx10DataColor
)
3925 else if (dataType
== Gfx10DataDepthStencil
)
3931 ADDR_ASSERT(dataType
== Gfx10DataFmask
);
3934 return cacheSizeLog2
;
3938 ************************************************************************************************************************
3939 * Gfx10Lib::HwlComputeSurfaceInfoLinear
3942 * Internal function to calculate alignment for linear surface
3946 ************************************************************************************************************************
3948 ADDR_E_RETURNCODE
Gfx10Lib::HwlComputeSurfaceInfoLinear(
3949 const ADDR2_COMPUTE_SURFACE_INFO_INPUT
* pIn
, ///< [in] input structure
3950 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT
* pOut
///< [out] output structure
3953 ADDR_E_RETURNCODE returnCode
= ADDR_OK
;
3955 if (IsTex1d(pIn
->resourceType
) && (pIn
->height
> 1))
3957 returnCode
= ADDR_INVALIDPARAMS
;
3961 const UINT_32 elementBytes
= pIn
->bpp
>> 3;
3962 const UINT_32 pitchAlign
= (pIn
->swizzleMode
== ADDR_SW_LINEAR_GENERAL
) ? 1 : (256 / elementBytes
);
3963 const UINT_32 mipDepth
= (pIn
->resourceType
== ADDR_RSRC_TEX_3D
) ? pIn
->numSlices
: 1;
3964 UINT_32 pitch
= PowTwoAlign(pIn
->width
, pitchAlign
);
3965 UINT_32 actualHeight
= pIn
->height
;
3966 UINT_64 sliceSize
= 0;
3968 if (pIn
->numMipLevels
> 1)
3970 for (INT_32 i
= static_cast<INT_32
>(pIn
->numMipLevels
) - 1; i
>= 0; i
--)
3972 UINT_32 mipWidth
, mipHeight
;
3974 GetMipSize(pIn
->width
, pIn
->height
, 1, i
, &mipWidth
, &mipHeight
);
3976 const UINT_32 mipActualWidth
= PowTwoAlign(mipWidth
, pitchAlign
);
3978 if (pOut
->pMipInfo
!= NULL
)
3980 pOut
->pMipInfo
[i
].pitch
= mipActualWidth
;
3981 pOut
->pMipInfo
[i
].height
= mipHeight
;
3982 pOut
->pMipInfo
[i
].depth
= mipDepth
;
3983 pOut
->pMipInfo
[i
].offset
= sliceSize
;
3984 pOut
->pMipInfo
[i
].mipTailOffset
= 0;
3985 pOut
->pMipInfo
[i
].macroBlockOffset
= sliceSize
;
3988 sliceSize
+= static_cast<UINT_64
>(mipActualWidth
) * mipHeight
* elementBytes
;
3993 returnCode
= ApplyCustomizedPitchHeight(pIn
, elementBytes
, pitchAlign
, &pitch
, &actualHeight
);
3995 if (returnCode
== ADDR_OK
)
3997 sliceSize
= static_cast<UINT_64
>(pitch
) * actualHeight
* elementBytes
;
3999 if (pOut
->pMipInfo
!= NULL
)
4001 pOut
->pMipInfo
[0].pitch
= pitch
;
4002 pOut
->pMipInfo
[0].height
= actualHeight
;
4003 pOut
->pMipInfo
[0].depth
= mipDepth
;
4004 pOut
->pMipInfo
[0].offset
= 0;
4005 pOut
->pMipInfo
[0].mipTailOffset
= 0;
4006 pOut
->pMipInfo
[0].macroBlockOffset
= 0;
4011 if (returnCode
== ADDR_OK
)
4013 pOut
->pitch
= pitch
;
4014 pOut
->height
= actualHeight
;
4015 pOut
->numSlices
= pIn
->numSlices
;
4016 pOut
->sliceSize
= sliceSize
;
4017 pOut
->surfSize
= sliceSize
* pOut
->numSlices
;
4018 pOut
->baseAlign
= (pIn
->swizzleMode
== ADDR_SW_LINEAR_GENERAL
) ? elementBytes
: 256;
4019 pOut
->blockWidth
= pitchAlign
;
4020 pOut
->blockHeight
= 1;
4021 pOut
->blockSlices
= 1;
4023 // Following members are useless on GFX10
4024 pOut
->mipChainPitch
= 0;
4025 pOut
->mipChainHeight
= 0;
4026 pOut
->mipChainSlice
= 0;
4027 pOut
->epitchIsHeight
= FALSE
;
4029 // Post calculation validate
4030 ADDR_ASSERT(pOut
->sliceSize
> 0);