1 /*
2 ************************************************************************************************************************
3 *
4 * Copyright (C) 2007-2022 Advanced Micro Devices, Inc. All rights reserved.
5 * SPDX-License-Identifier: MIT
6 *
7 ***********************************************************************************************************************/
8
9 /**
10 ************************************************************************************************************************
11 * @file gfx11addrlib.cpp
12 * @brief Contain the implementation for the Gfx11Lib class.
13 ************************************************************************************************************************
14 */
15
16 #include "gfx11addrlib.h"
17 #include "gfx11_gb_reg.h"
18
19 #include "amdgpu_asic_addr.h"
20
21 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
22 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
23
24 namespace Addr
25 {
26 /**
27 ************************************************************************************************************************
28 * Gfx11HwlInit
29 *
30 * @brief
31 * Creates an Gfx11Lib object.
32 *
33 * @return
34 * Returns an Gfx11Lib object pointer.
35 ************************************************************************************************************************
36 */
Gfx11HwlInit(const Client * pClient)37 Addr::Lib* Gfx11HwlInit(const Client* pClient)
38 {
39 return V2::Gfx11Lib::CreateObj(pClient);
40 }
41
42 namespace V2
43 {
44
45 ////////////////////////////////////////////////////////////////////////////////////////////////////
46 // Static Const Member
47 ////////////////////////////////////////////////////////////////////////////////////////////////////
48
49 const SwizzleModeFlags Gfx11Lib::SwizzleModeTable[ADDR_SW_MAX_TYPE] =
50 {//Linear 256B 4KB 64KB 256KB Z Std Disp Rot XOR T RtOpt Reserved
51 {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // ADDR_SW_LINEAR
52 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
53 {{0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}}, // ADDR_SW_256B_D
54 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
55
56 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
57 {{0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}}, // ADDR_SW_4KB_S
58 {{0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}}, // ADDR_SW_4KB_D
59 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
60
61 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
62 {{0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0}}, // ADDR_SW_64KB_S
63 {{0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0}}, // ADDR_SW_64KB_D
64 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
65
66 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
67 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
68 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
69 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
70
71 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
72 {{0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0}}, // ADDR_SW_64KB_S_T
73 {{0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0}}, // ADDR_SW_64KB_D_T
74 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
75
76 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
77 {{0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0}}, // ADDR_SW_4KB_S_X
78 {{0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0}}, // ADDR_SW_4KB_D_X
79 {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // Reserved
80
81 {{0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0}}, // ADDR_SW_64KB_Z_X
82 {{0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0}}, // ADDR_SW_64KB_S_X
83 {{0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0}}, // ADDR_SW_64KB_D_X
84 {{0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0}}, // ADDR_SW_64KB_R_X
85
86 {{0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0}}, // ADDR_SW_256KB_Z_X
87 {{0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0}}, // ADDR_SW_256KB_S_X
88 {{0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0}}, // ADDR_SW_256KB_D_X
89 {{0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0}}, // ADDR_SW_256KB_R_X
90 {{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}, // ADDR_SW_LINEAR_GENERAL
91 };
92
93 const Dim3d Gfx11Lib::Block256_3d[] = {{8, 4, 8}, {4, 4, 8}, {4, 4, 4}, {4, 2, 4}, {2, 2, 4}};
94
95 const Dim3d Gfx11Lib::Block256K_Log2_3d[] = {{6, 6, 6}, {5, 6, 6}, {5, 6, 5}, {5, 5, 5}, {4, 5, 5}};
96 const Dim3d Gfx11Lib::Block64K_Log2_3d[] = {{6, 5, 5}, {5, 5, 5}, {5, 5, 4}, {5, 4, 4}, {4, 4, 4}};
97 const Dim3d Gfx11Lib::Block4K_Log2_3d[] = {{4, 4, 4}, {3, 4, 4}, {3, 4, 3}, {3, 3, 3}, {2, 3, 3}};
98
99 /**
100 ************************************************************************************************************************
101 * Gfx11Lib::Gfx11Lib
102 *
103 * @brief
104 * Constructor
105 *
106 ************************************************************************************************************************
107 */
Gfx11Lib(const Client * pClient)108 Gfx11Lib::Gfx11Lib(const Client* pClient)
109 :
110 Lib(pClient),
111 m_numPkrLog2(0),
112 m_numSaLog2(0),
113 m_colorBaseIndex(0),
114 m_htileBaseIndex(0),
115 m_dccBaseIndex(0)
116 {
117 memset(&m_settings, 0, sizeof(m_settings));
118 memcpy(m_swizzleModeTable, SwizzleModeTable, sizeof(SwizzleModeTable));
119 }
120
121 /**
122 ************************************************************************************************************************
123 * Gfx11Lib::~Gfx11Lib
124 *
125 * @brief
126 * Destructor
127 ************************************************************************************************************************
128 */
~Gfx11Lib()129 Gfx11Lib::~Gfx11Lib()
130 {
131 }
132
133 /**
134 ************************************************************************************************************************
135 * Gfx11Lib::HwlComputeHtileInfo
136 *
137 * @brief
138 * Interface function stub of AddrComputeHtilenfo
139 *
140 * @return
141 * ADDR_E_RETURNCODE
142 ************************************************************************************************************************
143 */
HwlComputeHtileInfo(const ADDR2_COMPUTE_HTILE_INFO_INPUT * pIn,ADDR2_COMPUTE_HTILE_INFO_OUTPUT * pOut) const144 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileInfo(
145 const ADDR2_COMPUTE_HTILE_INFO_INPUT* pIn, ///< [in] input structure
146 ADDR2_COMPUTE_HTILE_INFO_OUTPUT* pOut ///< [out] output structure
147 ) const
148 {
149 ADDR_E_RETURNCODE ret = ADDR_OK;
150
151 if ((pIn->swizzleMode != ADDR_SW_64KB_Z_X) &&
152 (pIn->swizzleMode != ADDR_SW_256KB_Z_X) &&
153 (pIn->hTileFlags.pipeAligned != TRUE))
154 {
155 ret = ADDR_INVALIDPARAMS;
156 }
157 else
158 {
159 Dim3d metaBlk = {};
160 const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx11DataDepthStencil,
161 ADDR_RSRC_TEX_2D,
162 pIn->swizzleMode,
163 0,
164 0,
165 TRUE,
166 &metaBlk);
167
168 pOut->pitch = PowTwoAlign(pIn->unalignedWidth, metaBlk.w);
169 pOut->height = PowTwoAlign(pIn->unalignedHeight, metaBlk.h);
170 pOut->baseAlign = Max(metaBlkSize, 1u << (m_pipesLog2 + 11u));
171 pOut->metaBlkWidth = metaBlk.w;
172 pOut->metaBlkHeight = metaBlk.h;
173
174 if (pIn->numMipLevels > 1)
175 {
176 ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);
177
178 UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;
179
180 for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >=0; i--)
181 {
182 UINT_32 mipWidth, mipHeight;
183
184 GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);
185
186 mipWidth = PowTwoAlign(mipWidth, metaBlk.w);
187 mipHeight = PowTwoAlign(mipHeight, metaBlk.h);
188
189 const UINT_32 pitchInM = mipWidth / metaBlk.w;
190 const UINT_32 heightInM = mipHeight / metaBlk.h;
191 const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;
192
193 if (pOut->pMipInfo != NULL)
194 {
195 pOut->pMipInfo[i].inMiptail = FALSE;
196 pOut->pMipInfo[i].offset = offset;
197 pOut->pMipInfo[i].sliceSize = mipSliceSize;
198 }
199
200 offset += mipSliceSize;
201 }
202
203 pOut->sliceSize = offset;
204 pOut->metaBlkNumPerSlice = offset / metaBlkSize;
205 pOut->htileBytes = pOut->sliceSize * pIn->numSlices;
206
207 if (pOut->pMipInfo != NULL)
208 {
209 for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)
210 {
211 pOut->pMipInfo[i].inMiptail = TRUE;
212 pOut->pMipInfo[i].offset = 0;
213 pOut->pMipInfo[i].sliceSize = 0;
214 }
215
216 if (pIn->firstMipIdInTail != pIn->numMipLevels)
217 {
218 pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;
219 }
220 }
221 }
222 else
223 {
224 const UINT_32 pitchInM = pOut->pitch / metaBlk.w;
225 const UINT_32 heightInM = pOut->height / metaBlk.h;
226
227 pOut->metaBlkNumPerSlice = pitchInM * heightInM;
228 pOut->sliceSize = pOut->metaBlkNumPerSlice * metaBlkSize;
229 pOut->htileBytes = pOut->sliceSize * pIn->numSlices;
230
231 if (pOut->pMipInfo != NULL)
232 {
233 pOut->pMipInfo[0].inMiptail = FALSE;
234 pOut->pMipInfo[0].offset = 0;
235 pOut->pMipInfo[0].sliceSize = pOut->sliceSize;
236 }
237 }
238
239 // Get the HTILE address equation (copied from HtileAddrFromCoord).
240 // HTILE addressing depends on the number of samples, but this code doesn't support it yet.
241 const UINT_32 index = m_htileBaseIndex;
242 const UINT_8* patIdxTable = GFX11_HTILE_PATIDX;
243
244 ADDR_C_ASSERT(sizeof(GFX11_HTILE_SW_PATTERN[patIdxTable[index]]) == 72 * 2);
245 pOut->equation.gfx10_bits = (UINT_16 *)GFX11_HTILE_SW_PATTERN[patIdxTable[index]];
246 }
247
248 return ret;
249 }
250
251 /**
252 ************************************************************************************************************************
253 * Gfx11Lib::HwlComputeDccInfo
254 *
255 * @brief
256 * Interface function to compute DCC key info
257 *
258 * @return
259 * ADDR_E_RETURNCODE
260 ************************************************************************************************************************
261 */
HwlComputeDccInfo(const ADDR2_COMPUTE_DCCINFO_INPUT * pIn,ADDR2_COMPUTE_DCCINFO_OUTPUT * pOut) const262 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeDccInfo(
263 const ADDR2_COMPUTE_DCCINFO_INPUT* pIn, ///< [in] input structure
264 ADDR2_COMPUTE_DCCINFO_OUTPUT* pOut ///< [out] output structure
265 ) const
266 {
267 ADDR_E_RETURNCODE ret = ADDR_OK;
268
269 if (IsLinear(pIn->swizzleMode) || IsBlock256b(pIn->swizzleMode))
270 {
271 ret = ADDR_INVALIDPARAMS;
272 }
273 else
274 {
275 const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
276 const UINT_32 numFragLog2 = Log2(Max(pIn->numFrags, 1u));
277 Dim3d compBlock = {};
278
279 GetCompressedBlockSizeLog2(Gfx11DataColor,
280 pIn->resourceType,
281 pIn->swizzleMode,
282 elemLog2,
283 numFragLog2,
284 &compBlock);
285 pOut->compressBlkWidth = 1 << compBlock.w;
286 pOut->compressBlkHeight = 1 << compBlock.h;
287 pOut->compressBlkDepth = 1 << compBlock.d;
288
289 if (ret == ADDR_OK)
290 {
291 Dim3d metaBlk = {};
292 const UINT_32 metaBlkSize = GetMetaBlkSize(Gfx11DataColor,
293 pIn->resourceType,
294 pIn->swizzleMode,
295 elemLog2,
296 numFragLog2,
297 pIn->dccKeyFlags.pipeAligned,
298 &metaBlk);
299
300 pOut->dccRamBaseAlign = metaBlkSize;
301 pOut->metaBlkWidth = metaBlk.w;
302 pOut->metaBlkHeight = metaBlk.h;
303 pOut->metaBlkDepth = metaBlk.d;
304 pOut->metaBlkSize = metaBlkSize;
305
306 pOut->pitch = PowTwoAlign(pIn->unalignedWidth, metaBlk.w);
307 pOut->height = PowTwoAlign(pIn->unalignedHeight, metaBlk.h);
308 pOut->depth = PowTwoAlign(Max(pIn->numSlices, 1u), metaBlk.d);
309
310 if (pIn->numMipLevels > 1)
311 {
312 ADDR_ASSERT(pIn->firstMipIdInTail <= pIn->numMipLevels);
313
314 UINT_32 offset = (pIn->firstMipIdInTail == pIn->numMipLevels) ? 0 : metaBlkSize;
315
316 for (INT_32 i = static_cast<INT_32>(pIn->firstMipIdInTail) - 1; i >= 0; i--)
317 {
318 UINT_32 mipWidth, mipHeight;
319
320 GetMipSize(pIn->unalignedWidth, pIn->unalignedHeight, 1, i, &mipWidth, &mipHeight);
321
322 mipWidth = PowTwoAlign(mipWidth, metaBlk.w);
323 mipHeight = PowTwoAlign(mipHeight, metaBlk.h);
324
325 const UINT_32 pitchInM = mipWidth / metaBlk.w;
326 const UINT_32 heightInM = mipHeight / metaBlk.h;
327 const UINT_32 mipSliceSize = pitchInM * heightInM * metaBlkSize;
328
329 if (pOut->pMipInfo != NULL)
330 {
331 pOut->pMipInfo[i].inMiptail = FALSE;
332 pOut->pMipInfo[i].offset = offset;
333 pOut->pMipInfo[i].sliceSize = mipSliceSize;
334 }
335
336 offset += mipSliceSize;
337 }
338
339 pOut->dccRamSliceSize = offset;
340 pOut->metaBlkNumPerSlice = offset / metaBlkSize;
341 pOut->dccRamSize = pOut->dccRamSliceSize * (pOut->depth / metaBlk.d);
342
343 if (pOut->pMipInfo != NULL)
344 {
345 for (UINT_32 i = pIn->firstMipIdInTail; i < pIn->numMipLevels; i++)
346 {
347 pOut->pMipInfo[i].inMiptail = TRUE;
348 pOut->pMipInfo[i].offset = 0;
349 pOut->pMipInfo[i].sliceSize = 0;
350 }
351
352 if (pIn->firstMipIdInTail != pIn->numMipLevels)
353 {
354 pOut->pMipInfo[pIn->firstMipIdInTail].sliceSize = metaBlkSize;
355 }
356 }
357 }
358 else
359 {
360 const UINT_32 pitchInM = pOut->pitch / metaBlk.w;
361 const UINT_32 heightInM = pOut->height / metaBlk.h;
362
363 pOut->metaBlkNumPerSlice = pitchInM * heightInM;
364 pOut->dccRamSliceSize = pOut->metaBlkNumPerSlice * metaBlkSize;
365 pOut->dccRamSize = pOut->dccRamSliceSize * (pOut->depth / metaBlk.d);
366
367 if (pOut->pMipInfo != NULL)
368 {
369 pOut->pMipInfo[0].inMiptail = FALSE;
370 pOut->pMipInfo[0].offset = 0;
371 pOut->pMipInfo[0].sliceSize = pOut->dccRamSliceSize;
372 }
373 }
374
375 // Get the DCC address equation (copied from DccAddrFromCoord)
376 const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
377 const UINT_32 numPipeLog2 = m_pipesLog2;
378 UINT_32 index = m_dccBaseIndex + elemLog2;
379 const UINT_8* patIdxTable = (pIn->swizzleMode == ADDR_SW_64KB_R_X) ?
380 GFX11_DCC_64K_R_X_PATIDX : GFX11_DCC_256K_R_X_PATIDX;
381
382 if (pIn->dccKeyFlags.pipeAligned)
383 {
384 index += MaxNumOfBpp;
385
386 if (m_numPkrLog2 < 2)
387 {
388 index += m_pipesLog2 * MaxNumOfBpp;
389 }
390 else
391 {
392 // 4 groups for "m_numPkrLog2 < 2" case
393 index += 4 * MaxNumOfBpp;
394
395 const UINT_32 dccPipePerPkr = 3;
396
397 index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +
398 (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;
399 }
400 }
401
402 ADDR_C_ASSERT(sizeof(GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]]) == 68 * 2);
403 pOut->equation.gfx10_bits = (UINT_16*)GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]];
404 }
405 }
406
407 return ret;
408 }
409
410 /**
411 ************************************************************************************************************************
412 * Gfx11Lib::HwlComputeHtileAddrFromCoord
413 *
414 * @brief
415 * Interface function stub of AddrComputeHtileAddrFromCoord
416 *
417 * @return
418 * ADDR_E_RETURNCODE
419 ************************************************************************************************************************
420 */
HwlComputeHtileAddrFromCoord(const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT * pOut)421 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileAddrFromCoord(
422 const ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
423 ADDR2_COMPUTE_HTILE_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
424 {
425 ADDR_E_RETURNCODE returnCode = ADDR_OK;
426
427 if (pIn->numMipLevels > 1)
428 {
429 returnCode = ADDR_NOTIMPLEMENTED;
430 }
431 else
432 {
433 ADDR2_COMPUTE_HTILE_INFO_INPUT input = {};
434 input.size = sizeof(input);
435 input.hTileFlags = pIn->hTileFlags;
436 input.depthFlags = pIn->depthflags;
437 input.swizzleMode = pIn->swizzleMode;
438 input.unalignedWidth = Max(pIn->unalignedWidth, 1u);
439 input.unalignedHeight = Max(pIn->unalignedHeight, 1u);
440 input.numSlices = Max(pIn->numSlices, 1u);
441 input.numMipLevels = 1;
442
443 ADDR2_COMPUTE_HTILE_INFO_OUTPUT output = {};
444 output.size = sizeof(output);
445
446 returnCode = ComputeHtileInfo(&input, &output);
447
448 if (returnCode == ADDR_OK)
449 {
450 const UINT_32 numSampleLog2 = Log2(pIn->numSamples);
451 const UINT_32 pipeMask = (1 << m_pipesLog2) - 1;
452 const UINT_32 index = m_htileBaseIndex + numSampleLog2;
453 const UINT_8* patIdxTable = GFX11_HTILE_PATIDX;
454 const UINT_32 blkSizeLog2 = Log2(output.metaBlkWidth) + Log2(output.metaBlkHeight) - 4;
455 const UINT_32 blkMask = (1 << blkSizeLog2) - 1;
456 const UINT_32 blkOffset = ComputeOffsetFromSwizzlePattern(GFX11_HTILE_SW_PATTERN[patIdxTable[index]],
457 blkSizeLog2 + 1, // +1 for nibble offset
458 pIn->x,
459 pIn->y,
460 pIn->slice,
461 0);
462 const UINT_32 xb = pIn->x / output.metaBlkWidth;
463 const UINT_32 yb = pIn->y / output.metaBlkHeight;
464 const UINT_32 pb = output.pitch / output.metaBlkWidth;
465 const UINT_32 blkIndex = (yb * pb) + xb;
466 const UINT_32 pipeXor = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;
467
468 pOut->addr = (static_cast<UINT_64>(output.sliceSize) * pIn->slice) +
469 (blkIndex * (1 << blkSizeLog2)) +
470 ((blkOffset >> 1) ^ pipeXor);
471 }
472 }
473
474 return returnCode;
475 }
476
477 /**
478 ************************************************************************************************************************
479 * Gfx11Lib::HwlComputeHtileCoordFromAddr
480 *
481 * @brief
482 * Interface function stub of AddrComputeHtileCoordFromAddr
483 *
484 * @return
485 * ADDR_E_RETURNCODE
486 ************************************************************************************************************************
487 */
HwlComputeHtileCoordFromAddr(const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT * pIn,ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT * pOut)488 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeHtileCoordFromAddr(
489 const ADDR2_COMPUTE_HTILE_COORDFROMADDR_INPUT* pIn, ///< [in] input structure
490 ADDR2_COMPUTE_HTILE_COORDFROMADDR_OUTPUT* pOut) ///< [out] output structure
491 {
492 ADDR_NOT_IMPLEMENTED();
493
494 return ADDR_OK;
495 }
496
497 /**
498 ************************************************************************************************************************
499 * Gfx11Lib::HwlSupportComputeDccAddrFromCoord
500 *
501 * @brief
502 * Check whether HwlComputeDccAddrFromCoord() can be done for the input parameter
503 *
504 * @return
505 * ADDR_E_RETURNCODE
506 ************************************************************************************************************************
507 */
HwlSupportComputeDccAddrFromCoord(const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT * pIn)508 ADDR_E_RETURNCODE Gfx11Lib::HwlSupportComputeDccAddrFromCoord(
509 const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn)
510 {
511 ADDR_E_RETURNCODE returnCode = ADDR_OK;
512
513 if ((pIn->resourceType != ADDR_RSRC_TEX_2D) ||
514 ((pIn->swizzleMode != ADDR_SW_64KB_R_X) &&
515 (pIn->swizzleMode != ADDR_SW_256KB_R_X)) ||
516 (pIn->dccKeyFlags.linear == TRUE) ||
517 (pIn->numFrags > 1) ||
518 (pIn->numMipLevels > 1) ||
519 (pIn->mipId > 0))
520 {
521 returnCode = ADDR_NOTSUPPORTED;
522 }
523 else if ((pIn->pitch == 0) ||
524 (pIn->metaBlkWidth == 0) ||
525 (pIn->metaBlkHeight == 0) ||
526 (pIn->slice > 0 && pIn->dccRamSliceSize == 0))
527 {
528 returnCode = ADDR_NOTSUPPORTED;
529 }
530
531 return returnCode;
532 }
533
534 /**
535 ************************************************************************************************************************
536 * Gfx11Lib::HwlComputeDccAddrFromCoord
537 *
538 * @brief
539 * Interface function stub of AddrComputeDccAddrFromCoord
540 *
541 * @return
542 * N/A
543 ************************************************************************************************************************
544 */
HwlComputeDccAddrFromCoord(const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT * pOut)545 VOID Gfx11Lib::HwlComputeDccAddrFromCoord(
546 const ADDR2_COMPUTE_DCC_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
547 ADDR2_COMPUTE_DCC_ADDRFROMCOORD_OUTPUT* pOut) ///< [out] output structure
548 {
549 const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
550 const UINT_32 numPipeLog2 = m_pipesLog2;
551 const UINT_32 pipeMask = (1 << numPipeLog2) - 1;
552 UINT_32 index = m_dccBaseIndex + elemLog2;
553 const UINT_8* patIdxTable = (pIn->swizzleMode == ADDR_SW_64KB_R_X) ?
554 GFX11_DCC_64K_R_X_PATIDX : GFX11_DCC_256K_R_X_PATIDX;
555
556 if (pIn->dccKeyFlags.pipeAligned)
557 {
558 index += MaxNumOfBpp;
559
560 if (m_numPkrLog2 < 2)
561 {
562 index += m_pipesLog2 * MaxNumOfBpp;
563 }
564 else
565 {
566 // 4 groups for "m_numPkrLog2 < 2" case
567 index += 4 * MaxNumOfBpp;
568
569 const UINT_32 dccPipePerPkr = 3;
570
571 index += (m_numPkrLog2 - 2) * dccPipePerPkr * MaxNumOfBpp +
572 (m_pipesLog2 - m_numPkrLog2) * MaxNumOfBpp;
573 }
574 }
575
576 const UINT_32 blkSizeLog2 = Log2(pIn->metaBlkWidth) + Log2(pIn->metaBlkHeight) + elemLog2 - 8;
577 const UINT_32 blkMask = (1 << blkSizeLog2) - 1;
578 const UINT_32 blkOffset = ComputeOffsetFromSwizzlePattern(GFX11_DCC_R_X_SW_PATTERN[patIdxTable[index]],
579 blkSizeLog2 + 1, // +1 for nibble offset
580 pIn->x,
581 pIn->y,
582 pIn->slice,
583 0);
584 const UINT_32 xb = pIn->x / pIn->metaBlkWidth;
585 const UINT_32 yb = pIn->y / pIn->metaBlkHeight;
586 const UINT_32 pb = pIn->pitch / pIn->metaBlkWidth;
587 const UINT_32 blkIndex = (yb * pb) + xb;
588 const UINT_32 pipeXor = ((pIn->pipeXor & pipeMask) << m_pipeInterleaveLog2) & blkMask;
589
590 pOut->addr = (static_cast<UINT_64>(pIn->dccRamSliceSize) * pIn->slice) +
591 (blkIndex * (1 << blkSizeLog2)) +
592 ((blkOffset >> 1) ^ pipeXor);
593 }
594
595 /**
596 ************************************************************************************************************************
597 * Gfx11Lib::HwlInitGlobalParams
598 *
599 * @brief
600 * Initializes global parameters
601 *
602 * @return
603 * TRUE if all settings are valid
604 *
605 ************************************************************************************************************************
606 */
HwlInitGlobalParams(const ADDR_CREATE_INPUT * pCreateIn)607 BOOL_32 Gfx11Lib::HwlInitGlobalParams(
608 const ADDR_CREATE_INPUT* pCreateIn) ///< [in] create input
609 {
610 BOOL_32 valid = TRUE;
611 GB_ADDR_CONFIG_GFX11 gbAddrConfig;
612
613 gbAddrConfig.u32All = pCreateIn->regValue.gbAddrConfig;
614
615 switch (gbAddrConfig.bits.NUM_PIPES)
616 {
617 case ADDR_CONFIG_1_PIPE:
618 m_pipes = 1;
619 m_pipesLog2 = 0;
620 break;
621 case ADDR_CONFIG_2_PIPE:
622 m_pipes = 2;
623 m_pipesLog2 = 1;
624 break;
625 case ADDR_CONFIG_4_PIPE:
626 m_pipes = 4;
627 m_pipesLog2 = 2;
628 break;
629 case ADDR_CONFIG_8_PIPE:
630 m_pipes = 8;
631 m_pipesLog2 = 3;
632 break;
633 case ADDR_CONFIG_16_PIPE:
634 m_pipes = 16;
635 m_pipesLog2 = 4;
636 break;
637 case ADDR_CONFIG_32_PIPE:
638 m_pipes = 32;
639 m_pipesLog2 = 5;
640 break;
641 case ADDR_CONFIG_64_PIPE:
642 m_pipes = 64;
643 m_pipesLog2 = 6;
644 break;
645 default:
646 ADDR_ASSERT_ALWAYS();
647 valid = FALSE;
648 break;
649 }
650
651 switch (gbAddrConfig.bits.PIPE_INTERLEAVE_SIZE)
652 {
653 case ADDR_CONFIG_PIPE_INTERLEAVE_256B:
654 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_256B;
655 m_pipeInterleaveLog2 = 8;
656 break;
657 case ADDR_CONFIG_PIPE_INTERLEAVE_512B:
658 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_512B;
659 m_pipeInterleaveLog2 = 9;
660 break;
661 case ADDR_CONFIG_PIPE_INTERLEAVE_1KB:
662 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_1KB;
663 m_pipeInterleaveLog2 = 10;
664 break;
665 case ADDR_CONFIG_PIPE_INTERLEAVE_2KB:
666 m_pipeInterleaveBytes = ADDR_PIPEINTERLEAVE_2KB;
667 m_pipeInterleaveLog2 = 11;
668 break;
669 default:
670 ADDR_ASSERT_ALWAYS();
671 valid = FALSE;
672 break;
673 }
674
675 // Addr::V2::Lib::ComputePipeBankXor()/ComputeSlicePipeBankXor() requires pipe interleave to be exactly 8 bits, and
676 // any larger value requires a post-process (left shift) on the output pipeBankXor bits.
677 // And more importantly, SW AddrLib doesn't support sw equation/pattern for PI != 256 case.
678 ADDR_ASSERT(m_pipeInterleaveBytes == ADDR_PIPEINTERLEAVE_256B);
679
680 // These fields are deprecated on GFX11; they do nothing on HW.
681 m_maxCompFrag = 1;
682 m_maxCompFragLog2 = 0;
683
684 // Skip unaligned case
685 m_htileBaseIndex += MaxNumOfAA;
686
687 m_htileBaseIndex += m_pipesLog2 * MaxNumOfAA;
688 m_colorBaseIndex += m_pipesLog2 * MaxNumOfBpp;
689
690 m_numPkrLog2 = gbAddrConfig.bits.NUM_PKRS;
691 m_numSaLog2 = (m_numPkrLog2 > 0) ? (m_numPkrLog2 - 1) : 0;
692
693 ADDR_ASSERT((m_numPkrLog2 <= m_pipesLog2) && ((m_pipesLog2 - m_numPkrLog2) <= 2));
694
695 if (m_numPkrLog2 >= 2)
696 {
697 m_colorBaseIndex += (2 * m_numPkrLog2 - 2) * MaxNumOfBpp;
698 m_htileBaseIndex += (m_numPkrLog2 - 1) * 3 * MaxNumOfAA;
699 }
700
701 // There is no so-called VAR swizzle mode on GFX11 and instead there are 4 256KB swizzle modes. Here we treat 256KB
702 // swizzle mode as "VAR" swizzle mode for reusing exising facilities (e.g GetBlockSizeLog2()) provided by base class
703 m_blockVarSizeLog2 = 18;
704
705 if (valid)
706 {
707 InitEquationTable();
708 }
709
710 return valid;
711 }
712
713 /**
714 ************************************************************************************************************************
715 * Gfx11Lib::HwlConvertChipFamily
716 *
717 * @brief
718 * Convert familyID defined in atiid.h to ChipFamily and set m_chipFamily/m_chipRevision
719 * @return
720 * ChipFamily
721 ************************************************************************************************************************
722 */
HwlConvertChipFamily(UINT_32 chipFamily,UINT_32 chipRevision)723 ChipFamily Gfx11Lib::HwlConvertChipFamily(
724 UINT_32 chipFamily, ///< [in] chip family defined in atiih.h
725 UINT_32 chipRevision) ///< [in] chip revision defined in "asic_family"_id.h
726 {
727 ChipFamily family = ADDR_CHIP_FAMILY_NAVI;
728
729 switch (chipFamily)
730 {
731 case FAMILY_NV3:
732 if (ASICREV_IS_NAVI31_P(chipRevision))
733 {
734 }
735 if (ASICREV_IS_NAVI32_P(chipRevision))
736 {
737 }
738 if (ASICREV_IS_NAVI33_P(chipRevision))
739 {
740 }
741 break;
742 case FAMILY_GFX1150:
743 if (ASICREV_IS_GFX1150(chipRevision))
744 {
745 m_settings.isGfx1150 = 1;
746 }
747 break;
748 case FAMILY_GFX1103:
749 m_settings.isGfx1103 = 1;
750 break;
751 default:
752 ADDR_ASSERT(!"Unknown chip family");
753 break;
754 }
755
756 m_configFlags.use32bppFor422Fmt = TRUE;
757
758 return family;
759 }
760
761 /**
762 ************************************************************************************************************************
763 * Gfx11Lib::GetBlk256SizeLog2
764 *
765 * @brief
766 * Get block 256 size
767 *
768 * @return
769 * N/A
770 ************************************************************************************************************************
771 */
GetBlk256SizeLog2(AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2,Dim3d * pBlock) const772 void Gfx11Lib::GetBlk256SizeLog2(
773 AddrResourceType resourceType, ///< [in] Resource type
774 AddrSwizzleMode swizzleMode, ///< [in] Swizzle mode
775 UINT_32 elemLog2, ///< [in] element size log2
776 UINT_32 numSamplesLog2, ///< [in] number of samples
777 Dim3d* pBlock ///< [out] block size
778 ) const
779 {
780 if (IsThin(resourceType, swizzleMode))
781 {
782 UINT_32 blockBits = 8 - elemLog2;
783
784 // On GFX11, Z and R modes are the same thing.
785 if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
786 {
787 blockBits -= numSamplesLog2;
788 }
789
790 pBlock->w = (blockBits >> 1) + (blockBits & 1);
791 pBlock->h = (blockBits >> 1);
792 pBlock->d = 0;
793 }
794 else
795 {
796 ADDR_ASSERT(IsThick(resourceType, swizzleMode));
797
798 UINT_32 blockBits = 8 - elemLog2;
799
800 pBlock->d = (blockBits / 3) + (((blockBits % 3) > 0) ? 1 : 0);
801 pBlock->w = (blockBits / 3) + (((blockBits % 3) > 1) ? 1 : 0);
802 pBlock->h = (blockBits / 3);
803 }
804 }
805
806 /**
807 ************************************************************************************************************************
808 * Gfx11Lib::GetCompressedBlockSizeLog2
809 *
810 * @brief
811 * Get compress block size
812 *
813 * @return
814 * N/A
815 ************************************************************************************************************************
816 */
GetCompressedBlockSizeLog2(Gfx11DataType dataType,AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2,Dim3d * pBlock) const817 void Gfx11Lib::GetCompressedBlockSizeLog2(
818 Gfx11DataType dataType, ///< [in] Data type
819 AddrResourceType resourceType, ///< [in] Resource type
820 AddrSwizzleMode swizzleMode, ///< [in] Swizzle mode
821 UINT_32 elemLog2, ///< [in] element size log2
822 UINT_32 numSamplesLog2, ///< [in] number of samples
823 Dim3d* pBlock ///< [out] block size
824 ) const
825 {
826 if (dataType == Gfx11DataColor)
827 {
828 GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, pBlock);
829 }
830 else
831 {
832 ADDR_ASSERT(dataType == Gfx11DataDepthStencil);
833 pBlock->w = 3;
834 pBlock->h = 3;
835 pBlock->d = 0;
836 }
837 }
838
839 /**
840 ************************************************************************************************************************
841 * Gfx11Lib::GetMetaOverlapLog2
842 *
843 * @brief
844 * Get meta block overlap
845 *
846 * @return
847 * N/A
848 ************************************************************************************************************************
849 */
GetMetaOverlapLog2(Gfx11DataType dataType,AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2) const850 INT_32 Gfx11Lib::GetMetaOverlapLog2(
851 Gfx11DataType dataType, ///< [in] Data type
852 AddrResourceType resourceType, ///< [in] Resource type
853 AddrSwizzleMode swizzleMode, ///< [in] Swizzle mode
854 UINT_32 elemLog2, ///< [in] element size log2
855 UINT_32 numSamplesLog2 ///< [in] number of samples
856 ) const
857 {
858 Dim3d compBlock;
859 Dim3d microBlock;
860
861 GetCompressedBlockSizeLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2, &compBlock);
862 GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, numSamplesLog2, µBlock);
863
864 const INT_32 compSizeLog2 = compBlock.w + compBlock.h + compBlock.d;
865 const INT_32 blk256SizeLog2 = microBlock.w + microBlock.h + microBlock.d;
866 const INT_32 maxSizeLog2 = Max(compSizeLog2, blk256SizeLog2);
867 const INT_32 numPipesLog2 = GetEffectiveNumPipes();
868 INT_32 overlap = numPipesLog2 - maxSizeLog2;
869
870 if (numPipesLog2 > 1)
871 {
872 overlap++;
873 }
874
875 // In 16Bpp 8xaa, we lose 1 overlap bit because the block size reduction eats into a pipe anchor bit (y4)
876 if ((elemLog2 == 4) && (numSamplesLog2 == 3))
877 {
878 overlap--;
879 }
880 overlap = Max(overlap, 0);
881 return overlap;
882 }
883
884 /**
885 ************************************************************************************************************************
886 * Gfx11Lib::Get3DMetaOverlapLog2
887 *
888 * @brief
889 * Get 3d meta block overlap
890 *
891 * @return
892 * N/A
893 ************************************************************************************************************************
894 */
Get3DMetaOverlapLog2(AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2) const895 INT_32 Gfx11Lib::Get3DMetaOverlapLog2(
896 AddrResourceType resourceType, ///< [in] Resource type
897 AddrSwizzleMode swizzleMode, ///< [in] Swizzle mode
898 UINT_32 elemLog2 ///< [in] element size log2
899 ) const
900 {
901 Dim3d microBlock;
902 GetBlk256SizeLog2(resourceType, swizzleMode, elemLog2, 0, µBlock);
903
904 INT_32 overlap = GetEffectiveNumPipes() - static_cast<INT_32>(microBlock.w);
905
906 overlap++;
907
908 if ((overlap < 0) || (IsStandardSwizzle(resourceType, swizzleMode) == TRUE))
909 {
910 overlap = 0;
911 }
912 return overlap;
913 }
914
915 /**
916 ************************************************************************************************************************
917 * Gfx11Lib::GetPipeRotateAmount
918 *
919 * @brief
920 * Get pipe rotate amount
921 *
922 * @return
923 * Pipe rotate amount
924 ************************************************************************************************************************
925 */
926
GetPipeRotateAmount(AddrResourceType resourceType,AddrSwizzleMode swizzleMode) const927 INT_32 Gfx11Lib::GetPipeRotateAmount(
928 AddrResourceType resourceType, ///< [in] Resource type
929 AddrSwizzleMode swizzleMode ///< [in] Swizzle mode
930 ) const
931 {
932 INT_32 amount = 0;
933
934 if ((m_pipesLog2 >= (m_numSaLog2 + 1)) && (m_pipesLog2 > 1))
935 {
936 amount = ((m_pipesLog2 == (m_numSaLog2 + 1)) && IsRbAligned(resourceType, swizzleMode)) ?
937 1 : m_pipesLog2 - (m_numSaLog2 + 1);
938 }
939
940 return amount;
941 }
942
943 /**
944 ************************************************************************************************************************
945 * Gfx11Lib::GetMetaBlkSize
946 *
947 * @brief
948 * Get metadata block size
949 *
950 * @return
951 * Meta block size
952 ************************************************************************************************************************
953 */
GetMetaBlkSize(Gfx11DataType dataType,AddrResourceType resourceType,AddrSwizzleMode swizzleMode,UINT_32 elemLog2,UINT_32 numSamplesLog2,BOOL_32 pipeAlign,Dim3d * pBlock) const954 UINT_32 Gfx11Lib::GetMetaBlkSize(
955 Gfx11DataType dataType, ///< [in] Data type
956 AddrResourceType resourceType, ///< [in] Resource type
957 AddrSwizzleMode swizzleMode, ///< [in] Swizzle mode
958 UINT_32 elemLog2, ///< [in] element size log2
959 UINT_32 numSamplesLog2, ///< [in] number of samples
960 BOOL_32 pipeAlign, ///< [in] pipe align
961 Dim3d* pBlock ///< [out] block size
962 ) const
963 {
964 INT_32 metablkSizeLog2;
965
966 const INT_32 metaElemSizeLog2 = GetMetaElementSizeLog2(dataType);
967 const INT_32 metaCacheSizeLog2 = GetMetaCacheSizeLog2(dataType);
968 const INT_32 compBlkSizeLog2 = (dataType == Gfx11DataColor) ? 8 : 6 + numSamplesLog2 + elemLog2;
969 const INT_32 metaBlkSamplesLog2 = numSamplesLog2;
970 const INT_32 dataBlkSizeLog2 = GetBlockSizeLog2(swizzleMode);
971 INT_32 numPipesLog2 = m_pipesLog2;
972
973 if (IsThin(resourceType, swizzleMode))
974 {
975 if ((pipeAlign == FALSE) ||
976 (IsStandardSwizzle(resourceType, swizzleMode) == TRUE) ||
977 (IsDisplaySwizzle(resourceType, swizzleMode) == TRUE))
978 {
979 if (pipeAlign)
980 {
981 metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);
982 metablkSizeLog2 = Min(metablkSizeLog2, dataBlkSizeLog2);
983 }
984 else
985 {
986 metablkSizeLog2 = Min(dataBlkSizeLog2, 12);
987 }
988 }
989 else
990 {
991 if ((m_pipesLog2 == m_numSaLog2 + 1) && (m_pipesLog2 > 1))
992 {
993 numPipesLog2++;
994 }
995
996 INT_32 pipeRotateLog2 = GetPipeRotateAmount(resourceType, swizzleMode);
997
998 if (numPipesLog2 >= 4)
999 {
1000 INT_32 overlapLog2 = GetMetaOverlapLog2(dataType, resourceType, swizzleMode, elemLog2, numSamplesLog2);
1001
1002 // In 16Bpe 8xaa, we have an extra overlap bit
1003 if ((pipeRotateLog2 > 0) &&
1004 (elemLog2 == 4) &&
1005 (numSamplesLog2 == 3) &&
1006 (IsZOrderSwizzle(swizzleMode) || (GetEffectiveNumPipes() > 3)))
1007 {
1008 overlapLog2++;
1009 }
1010
1011 metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;
1012 metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);
1013 }
1014 else
1015 {
1016 metablkSizeLog2 = Max(static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2, 12);
1017 }
1018
1019 if (dataType == Gfx11DataDepthStencil)
1020 {
1021 // For htile surfaces, pad meta block size to 2K * num_pipes
1022 metablkSizeLog2 = Max(metablkSizeLog2, 11 + numPipesLog2);
1023 }
1024
1025 const INT_32 compFragLog2 = numSamplesLog2;
1026
1027 if (IsRtOptSwizzle(swizzleMode) && (compFragLog2 > 1) && (pipeRotateLog2 >= 1))
1028 {
1029 const INT_32 tmp = 8 + m_pipesLog2 + Max(pipeRotateLog2, compFragLog2 - 1);
1030
1031 metablkSizeLog2 = Max(metablkSizeLog2, tmp);
1032 }
1033 }
1034
1035 const INT_32 metablkBitsLog2 =
1036 metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;
1037 pBlock->w = 1 << ((metablkBitsLog2 >> 1) + (metablkBitsLog2 & 1));
1038 pBlock->h = 1 << (metablkBitsLog2 >> 1);
1039 pBlock->d = 1;
1040 }
1041 else
1042 {
1043 ADDR_ASSERT(IsThick(resourceType, swizzleMode));
1044
1045 if (pipeAlign)
1046 {
1047 if ((m_pipesLog2 == m_numSaLog2 + 1) &&
1048 (m_pipesLog2 > 1) &&
1049 IsRbAligned(resourceType, swizzleMode))
1050 {
1051 numPipesLog2++;
1052 }
1053
1054 const INT_32 overlapLog2 = Get3DMetaOverlapLog2(resourceType, swizzleMode, elemLog2);
1055
1056 metablkSizeLog2 = metaCacheSizeLog2 + overlapLog2 + numPipesLog2;
1057 metablkSizeLog2 = Max(metablkSizeLog2, static_cast<INT_32>(m_pipeInterleaveLog2) + numPipesLog2);
1058 metablkSizeLog2 = Max(metablkSizeLog2, 12);
1059 }
1060 else
1061 {
1062 metablkSizeLog2 = 12;
1063 }
1064
1065 const INT_32 metablkBitsLog2 =
1066 metablkSizeLog2 + compBlkSizeLog2 - elemLog2 - metaBlkSamplesLog2 - metaElemSizeLog2;
1067 pBlock->w = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 0) ? 1 : 0));
1068 pBlock->h = 1 << ((metablkBitsLog2 / 3) + (((metablkBitsLog2 % 3) > 1) ? 1 : 0));
1069 pBlock->d = 1 << (metablkBitsLog2 / 3);
1070 }
1071
1072 return (1 << static_cast<UINT_32>(metablkSizeLog2));
1073 }
1074
1075 /**
1076 ************************************************************************************************************************
1077 * Gfx11Lib::ConvertSwizzlePatternToEquation
1078 *
1079 * @brief
1080 * Convert swizzle pattern to equation.
1081 *
1082 * @return
1083 * N/A
1084 ************************************************************************************************************************
1085 */
ConvertSwizzlePatternToEquation(UINT_32 elemLog2,AddrResourceType rsrcType,AddrSwizzleMode swMode,const ADDR_SW_PATINFO * pPatInfo,ADDR_EQUATION * pEquation) const1086 VOID Gfx11Lib::ConvertSwizzlePatternToEquation(
1087 UINT_32 elemLog2, ///< [in] element bytes log2
1088 AddrResourceType rsrcType, ///< [in] resource type
1089 AddrSwizzleMode swMode, ///< [in] swizzle mode
1090 const ADDR_SW_PATINFO* pPatInfo, ///< [in] swizzle pattern infor
1091 ADDR_EQUATION* pEquation) ///< [out] equation converted from swizzle pattern
1092 const
1093 {
1094 ADDR_BIT_SETTING fullSwizzlePattern[ADDR_MAX_EQUATION_BIT];
1095 GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
1096
1097 const ADDR_BIT_SETTING* pSwizzle = fullSwizzlePattern;
1098 const UINT_32 blockSizeLog2 = GetBlockSizeLog2(swMode);
1099 memset(pEquation, 0, sizeof(ADDR_EQUATION));
1100 pEquation->numBits = blockSizeLog2;
1101 pEquation->numBitComponents = pPatInfo->maxItemCount;
1102 pEquation->stackedDepthSlices = FALSE;
1103
1104 for (UINT_32 i = 0; i < elemLog2; i++)
1105 {
1106 pEquation->addr[i].channel = 0;
1107 pEquation->addr[i].valid = 1;
1108 pEquation->addr[i].index = i;
1109 }
1110
1111 if (IsXor(swMode) == FALSE)
1112 {
1113 // Use simplified logic when we only have one bit-component
1114 for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
1115 {
1116 ADDR_ASSERT(IsPow2(pSwizzle[i].value));
1117
1118 if (pSwizzle[i].x != 0)
1119 {
1120 ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].x)));
1121
1122 pEquation->addr[i].channel = 0;
1123 pEquation->addr[i].valid = 1;
1124 pEquation->addr[i].index = Log2(pSwizzle[i].x) + elemLog2;
1125 }
1126 else if (pSwizzle[i].y != 0)
1127 {
1128 ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].y)));
1129
1130 pEquation->addr[i].channel = 1;
1131 pEquation->addr[i].valid = 1;
1132 pEquation->addr[i].index = Log2(pSwizzle[i].y);
1133 }
1134 else
1135 {
1136 ADDR_ASSERT(pSwizzle[i].z != 0);
1137 ADDR_ASSERT(IsPow2(static_cast<UINT_32>(pSwizzle[i].z)));
1138
1139 pEquation->addr[i].channel = 2;
1140 pEquation->addr[i].valid = 1;
1141 pEquation->addr[i].index = Log2(pSwizzle[i].z);
1142 }
1143 }
1144 }
1145 else
1146 {
1147 Dim3d dim;
1148 ComputeBlockDimension(&dim.w, &dim.h, &dim.d, 8u << elemLog2, rsrcType, swMode);
1149
1150 const UINT_32 blkXLog2 = Log2(dim.w);
1151 const UINT_32 blkYLog2 = Log2(dim.h);
1152 const UINT_32 blkZLog2 = Log2(dim.d);
1153 const UINT_32 blkXMask = dim.w - 1;
1154 const UINT_32 blkYMask = dim.h - 1;
1155 const UINT_32 blkZMask = dim.d - 1;
1156
1157 ADDR_BIT_SETTING swizzle[ADDR_MAX_EQUATION_BIT] = {};
1158 memcpy(&swizzle, pSwizzle, sizeof(swizzle));
1159 UINT_32 xMask = 0;
1160 UINT_32 yMask = 0;
1161 UINT_32 zMask = 0;
1162
1163 for (UINT_32 i = elemLog2; i < blockSizeLog2; i++)
1164 {
1165 for (UINT_32 bitComp = 0; bitComp < ADDR_MAX_EQUATION_COMP; bitComp++)
1166 {
1167 if (swizzle[i].value == 0)
1168 {
1169 ADDR_ASSERT(bitComp != 0); // Bits above element size must have at least one addr-bit
1170 ADDR_ASSERT(bitComp <= pPatInfo->maxItemCount);
1171 break;
1172 }
1173
1174 if (swizzle[i].x != 0)
1175 {
1176 const UINT_32 xLog2 = BitScanForward(swizzle[i].x);
1177 swizzle[i].x = UnsetLeastBit(swizzle[i].x);
1178 xMask |= (1 << xLog2);
1179
1180 pEquation->comps[bitComp][i].channel = 0;
1181 pEquation->comps[bitComp][i].valid = 1;
1182 pEquation->comps[bitComp][i].index = xLog2 + elemLog2;
1183 }
1184 else if (swizzle[i].y != 0)
1185 {
1186 const UINT_32 yLog2 = BitScanForward(swizzle[i].y);
1187 swizzle[i].y = UnsetLeastBit(swizzle[i].y);
1188 yMask |= (1 << yLog2);
1189
1190 pEquation->comps[bitComp][i].channel = 1;
1191 pEquation->comps[bitComp][i].valid = 1;
1192 pEquation->comps[bitComp][i].index = yLog2;
1193 }
1194 else if (swizzle[i].z != 0)
1195 {
1196 const UINT_32 zLog2 = BitScanForward(swizzle[i].z);
1197 swizzle[i].z = UnsetLeastBit(swizzle[i].z);
1198 zMask |= (1 << zLog2);
1199
1200 pEquation->comps[bitComp][i].channel = 2;
1201 pEquation->comps[bitComp][i].valid = 1;
1202 pEquation->comps[bitComp][i].index = zLog2;
1203 }
1204 else
1205 {
1206 // This function doesn't handle MSAA (must update block dims, here, and consumers)
1207 ADDR_ASSERT_ALWAYS();
1208 }
1209 }
1210 ADDR_ASSERT(swizzle[i].value == 0); // We missed an xor? Are there too many?
1211 }
1212
1213 // We missed an address bit for coords inside the block?
1214 // That means two coords will land on the same addr, which is bad.
1215 ADDR_ASSERT(((xMask & blkXMask) == blkXMask) &&
1216 ((yMask & blkYMask) == blkYMask) &&
1217 ((zMask & blkZMask) == blkZMask));
1218 // We're sourcing from outside our block? That won't fly for PRTs, which need to be movable.
1219 // Non-xor modes can also be used for 2D PRTs but they're handled in the simplified logic above.
1220 ADDR_ASSERT((IsPrt(swMode) == false) ||
1221 ((xMask == blkXMask) &&
1222 (yMask == blkYMask) &&
1223 (zMask == blkZMask)));
1224 }
1225 }
1226
1227 /**
1228 ************************************************************************************************************************
1229 * Gfx11Lib::InitEquationTable
1230 *
1231 * @brief
1232 * Initialize Equation table.
1233 *
1234 * @return
1235 * N/A
1236 ************************************************************************************************************************
1237 */
InitEquationTable()1238 VOID Gfx11Lib::InitEquationTable()
1239 {
1240 memset(m_equationTable, 0, sizeof(m_equationTable));
1241
1242 for (UINT_32 rsrcTypeIdx = 0; rsrcTypeIdx < MaxRsrcType; rsrcTypeIdx++)
1243 {
1244 const AddrResourceType rsrcType = static_cast<AddrResourceType>(rsrcTypeIdx + ADDR_RSRC_TEX_2D);
1245
1246 for (UINT_32 swModeIdx = 0; swModeIdx < MaxSwModeType; swModeIdx++)
1247 {
1248 const AddrSwizzleMode swMode = static_cast<AddrSwizzleMode>(swModeIdx);
1249
1250 for (UINT_32 elemLog2 = 0; elemLog2 < MaxElementBytesLog2; elemLog2++)
1251 {
1252 UINT_32 equationIndex = ADDR_INVALID_EQUATION_INDEX;
1253 const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(swMode, rsrcType, elemLog2, 1);
1254
1255 if (pPatInfo != NULL)
1256 {
1257 ADDR_ASSERT(IsValidSwMode(swMode));
1258 ADDR_EQUATION equation = {};
1259
1260 ConvertSwizzlePatternToEquation(elemLog2, rsrcType, swMode, pPatInfo, &equation);
1261
1262 equationIndex = m_numEquations;
1263 ADDR_ASSERT(equationIndex < EquationTableSize);
1264
1265 m_equationTable[equationIndex] = equation;
1266
1267 m_numEquations++;
1268 }
1269
1270 m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2] = equationIndex;
1271 }
1272 }
1273 }
1274 }
1275
1276 /**
1277 ************************************************************************************************************************
1278 * Gfx11Lib::HwlGetEquationIndex
1279 *
1280 * @brief
1281 * Interface function stub of GetEquationIndex
1282 *
1283 * @return
1284 * ADDR_E_RETURNCODE
1285 ************************************************************************************************************************
1286 */
HwlGetEquationIndex(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const1287 UINT_32 Gfx11Lib::HwlGetEquationIndex(
1288 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
1289 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
1290 ) const
1291 {
1292 UINT_32 equationIdx = ADDR_INVALID_EQUATION_INDEX;
1293
1294 if ((pIn->resourceType == ADDR_RSRC_TEX_2D) ||
1295 (pIn->resourceType == ADDR_RSRC_TEX_3D))
1296 {
1297 const UINT_32 rsrcTypeIdx = static_cast<UINT_32>(pIn->resourceType) - 1;
1298 const UINT_32 swModeIdx = static_cast<UINT_32>(pIn->swizzleMode);
1299 const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
1300
1301 equationIdx = m_equationLookupTable[rsrcTypeIdx][swModeIdx][elemLog2];
1302 }
1303
1304 if (pOut->pMipInfo != NULL)
1305 {
1306 for (UINT_32 i = 0; i < pIn->numMipLevels; i++)
1307 {
1308 pOut->pMipInfo[i].equationIndex = equationIdx;
1309 }
1310 }
1311
1312 return equationIdx;
1313 }
1314
1315 /**
1316 ************************************************************************************************************************
1317 * Gfx11Lib::GetValidDisplaySwizzleModes
1318 *
1319 * @brief
1320 * Get valid swizzle modes mask for displayable surface
1321 *
1322 * @return
1323 * Valid swizzle modes mask for displayable surface
1324 ************************************************************************************************************************
1325 */
GetValidDisplaySwizzleModes(UINT_32 bpp) const1326 UINT_32 Gfx11Lib::GetValidDisplaySwizzleModes(
1327 UINT_32 bpp
1328 ) const
1329 {
1330 UINT_32 swModeMask = 0;
1331
1332 if (bpp <= 64)
1333 {
1334 const ChipFamily family = GetChipFamily();
1335
1336 swModeMask = Dcn32SwModeMask;
1337
1338 if (false
1339 || (m_settings.isGfx1103)
1340 || (m_settings.isGfx1150)
1341 )
1342 {
1343 // Not all GPUs support displaying with 256kB swizzle modes.
1344 swModeMask &= ~((1u << ADDR_SW_256KB_D_X) |
1345 (1u << ADDR_SW_256KB_R_X));
1346 }
1347 }
1348
1349 return swModeMask;
1350 }
1351
1352 /**
1353 ************************************************************************************************************************
1354 * Gfx11Lib::IsValidDisplaySwizzleMode
1355 *
1356 * @brief
1357 * Check if a swizzle mode is supported by display engine
1358 *
1359 * @return
1360 * TRUE is swizzle mode is supported by display engine
1361 ************************************************************************************************************************
1362 */
IsValidDisplaySwizzleMode(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1363 BOOL_32 Gfx11Lib::IsValidDisplaySwizzleMode(
1364 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure
1365 ) const
1366 {
1367 ADDR_ASSERT(pIn->resourceType == ADDR_RSRC_TEX_2D);
1368
1369 return (GetValidDisplaySwizzleModes(pIn->bpp) & (1 << pIn->swizzleMode)) ? TRUE : FALSE;
1370 }
1371
1372 /**
1373 ************************************************************************************************************************
1374 * Gfx11Lib::GetMaxNumMipsInTail
1375 *
1376 * @brief
1377 * Return max number of mips in tails
1378 *
1379 * @return
1380 * Max number of mips in tails
1381 ************************************************************************************************************************
1382 */
GetMaxNumMipsInTail(UINT_32 blockSizeLog2,BOOL_32 isThin) const1383 UINT_32 Gfx11Lib::GetMaxNumMipsInTail(
1384 UINT_32 blockSizeLog2, ///< block size log2
1385 BOOL_32 isThin ///< is thin or thick
1386 ) const
1387 {
1388 UINT_32 effectiveLog2 = blockSizeLog2;
1389
1390 if (isThin == FALSE)
1391 {
1392 effectiveLog2 -= (blockSizeLog2 - 8) / 3;
1393 }
1394
1395 return (effectiveLog2 <= 11) ? (1 + (1 << (effectiveLog2 - 9))) : (effectiveLog2 - 4);
1396 }
1397
1398 /**
1399 ************************************************************************************************************************
1400 * Gfx11Lib::HwlComputePipeBankXor
1401 *
1402 * @brief
1403 * Generate a PipeBankXor value to be ORed into bits above pipeInterleaveBits of address
1404 *
1405 * @return
1406 * PipeBankXor value
1407 ************************************************************************************************************************
1408 */
HwlComputePipeBankXor(const ADDR2_COMPUTE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT * pOut) const1409 ADDR_E_RETURNCODE Gfx11Lib::HwlComputePipeBankXor(
1410 const ADDR2_COMPUTE_PIPEBANKXOR_INPUT* pIn, ///< [in] input structure
1411 ADDR2_COMPUTE_PIPEBANKXOR_OUTPUT* pOut ///< [out] output structure
1412 ) const
1413 {
1414 if (IsNonPrtXor(pIn->swizzleMode))
1415 {
1416 pOut->pipeBankXor = 0;
1417 }
1418 else
1419 {
1420 pOut->pipeBankXor = 0;
1421 }
1422
1423 return ADDR_OK;
1424 }
1425
1426 /**
1427 ************************************************************************************************************************
1428 * Gfx11Lib::HwlComputeSlicePipeBankXor
1429 *
1430 * @brief
1431 * Generate slice PipeBankXor value based on base PipeBankXor value and slice id
1432 *
1433 * @return
1434 * PipeBankXor value
1435 ************************************************************************************************************************
1436 */
HwlComputeSlicePipeBankXor(const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT * pIn,ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT * pOut) const1437 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSlicePipeBankXor(
1438 const ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, ///< [in] input structure
1439 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut ///< [out] output structure
1440 ) const
1441 {
1442 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1443
1444 if (IsNonPrtXor(pIn->swizzleMode))
1445 {
1446 if (pIn->bpe == 0)
1447 {
1448 ADDR_ASSERT_ALWAYS();
1449
1450 // Require a valid bytes-per-element value passed from client...
1451 returnCode = ADDR_INVALIDPARAMS;
1452 }
1453 else
1454 {
1455 const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,
1456 pIn->resourceType,
1457 Log2(pIn->bpe >> 3),
1458 1);
1459
1460 if (pPatInfo != NULL)
1461 {
1462 ADDR_BIT_SETTING fullSwizzlePattern[20];
1463 GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
1464
1465 const UINT_32 pipeBankXorOffset =
1466 ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),
1467 GetBlockSizeLog2(pIn->swizzleMode),
1468 0,
1469 0,
1470 pIn->slice,
1471 0);
1472
1473 const UINT_32 pipeBankXor = pipeBankXorOffset >> m_pipeInterleaveLog2;
1474
1475 // Should have no bit set under pipe interleave
1476 ADDR_ASSERT((pipeBankXor << m_pipeInterleaveLog2) == pipeBankXorOffset);
1477
1478 pOut->pipeBankXor = pIn->basePipeBankXor ^ pipeBankXor;
1479 }
1480 else
1481 {
1482 // Should never come here...
1483 ADDR_NOT_IMPLEMENTED();
1484
1485 returnCode = ADDR_NOTSUPPORTED;
1486 }
1487 }
1488 }
1489 else
1490 {
1491 pOut->pipeBankXor = 0;
1492 }
1493
1494 return returnCode;
1495 }
1496
1497 /**
1498 ************************************************************************************************************************
1499 * Gfx11Lib::HwlComputeSubResourceOffsetForSwizzlePattern
1500 *
1501 * @brief
1502 * Compute sub resource offset to support swizzle pattern
1503 *
1504 * @return
1505 * Offset
1506 ************************************************************************************************************************
1507 */
HwlComputeSubResourceOffsetForSwizzlePattern(const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT * pIn,ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT * pOut) const1508 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSubResourceOffsetForSwizzlePattern(
1509 const ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, ///< [in] input structure
1510 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut ///< [out] output structure
1511 ) const
1512 {
1513 ADDR_ASSERT(IsThin(pIn->resourceType, pIn->swizzleMode));
1514
1515 pOut->offset = pIn->slice * pIn->sliceSize + pIn->macroBlockOffset;
1516
1517 return ADDR_OK;
1518 }
1519
1520 /**
1521 ************************************************************************************************************************
1522 * Gfx11Lib::HwlComputeNonBlockCompressedView
1523 *
1524 * @brief
1525 * Compute non-block-compressed view for a given mipmap level/slice.
1526 *
1527 * @return
1528 * ADDR_E_RETURNCODE
1529 ************************************************************************************************************************
1530 */
HwlComputeNonBlockCompressedView(const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT * pIn,ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT * pOut) const1531 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeNonBlockCompressedView(
1532 const ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn, ///< [in] input structure
1533 ADDR2_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT* pOut ///< [out] output structure
1534 ) const
1535 {
1536 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1537
1538 if (IsThin(pIn->resourceType, pIn->swizzleMode) == FALSE)
1539 {
1540 // Only thin swizzle mode can have a NonBC view...
1541 returnCode = ADDR_INVALIDPARAMS;
1542 }
1543 else if (((pIn->format < ADDR_FMT_ASTC_4x4) || (pIn->format > ADDR_FMT_ETC2_128BPP)) &&
1544 ((pIn->format < ADDR_FMT_BC1) || (pIn->format > ADDR_FMT_BC7)))
1545 {
1546 // Only support BC1~BC7, ASTC, or ETC2 for now...
1547 returnCode = ADDR_NOTSUPPORTED;
1548 }
1549 else
1550 {
1551 UINT_32 bcWidth, bcHeight;
1552 UINT_32 bpp = GetElemLib()->GetBitsPerPixel(pIn->format, NULL, &bcWidth, &bcHeight);
1553
1554 ADDR2_COMPUTE_SURFACE_INFO_INPUT infoIn = {};
1555 infoIn.flags = pIn->flags;
1556 infoIn.swizzleMode = pIn->swizzleMode;
1557 infoIn.resourceType = pIn->resourceType;
1558 infoIn.bpp = bpp;
1559 infoIn.width = RoundUpQuotient(pIn->width, bcWidth);
1560 infoIn.height = RoundUpQuotient(pIn->height, bcHeight);
1561 infoIn.numSlices = pIn->numSlices;
1562 infoIn.numMipLevels = pIn->numMipLevels;
1563 infoIn.numSamples = 1;
1564 infoIn.numFrags = 1;
1565
1566 ADDR2_MIP_INFO mipInfo[MaxMipLevels] = {};
1567
1568 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT infoOut = {};
1569 infoOut.pMipInfo = mipInfo;
1570
1571 const BOOL_32 tiled = (pIn->swizzleMode != ADDR_SW_LINEAR) ? TRUE : FALSE;
1572
1573 if (tiled)
1574 {
1575 returnCode = HwlComputeSurfaceInfoTiled(&infoIn, &infoOut);
1576 }
1577 else
1578 {
1579 returnCode = HwlComputeSurfaceInfoLinear(&infoIn, &infoOut);
1580 }
1581
1582 if (returnCode == ADDR_OK)
1583 {
1584 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT subOffIn = {};
1585 subOffIn.swizzleMode = infoIn.swizzleMode;
1586 subOffIn.resourceType = infoIn.resourceType;
1587 subOffIn.slice = pIn->slice;
1588 subOffIn.sliceSize = infoOut.sliceSize;
1589 subOffIn.macroBlockOffset = mipInfo[pIn->mipId].macroBlockOffset;
1590 subOffIn.mipTailOffset = mipInfo[pIn->mipId].mipTailOffset;
1591
1592 ADDR2_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT subOffOut = {};
1593
1594 // For any mipmap level, move nonBc view base address by offset
1595 HwlComputeSubResourceOffsetForSwizzlePattern(&subOffIn, &subOffOut);
1596 pOut->offset = subOffOut.offset;
1597
1598 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_INPUT slicePbXorIn = {};
1599 slicePbXorIn.bpe = infoIn.bpp;
1600 slicePbXorIn.swizzleMode = infoIn.swizzleMode;
1601 slicePbXorIn.resourceType = infoIn.resourceType;
1602 slicePbXorIn.basePipeBankXor = pIn->pipeBankXor;
1603 slicePbXorIn.slice = pIn->slice;
1604
1605 ADDR2_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT slicePbXorOut = {};
1606
1607 // For any mipmap level, nonBc view should use computed pbXor
1608 HwlComputeSlicePipeBankXor(&slicePbXorIn, &slicePbXorOut);
1609 pOut->pipeBankXor = slicePbXorOut.pipeBankXor;
1610
1611 const BOOL_32 inTail = tiled && (pIn->mipId >= infoOut.firstMipIdInTail) ? TRUE : FALSE;
1612 const UINT_32 requestMipWidth = RoundUpQuotient(Max(pIn->width >> pIn->mipId, 1u), bcWidth);
1613 const UINT_32 requestMipHeight = RoundUpQuotient(Max(pIn->height >> pIn->mipId, 1u), bcHeight);
1614
1615 if (inTail)
1616 {
1617 // For mipmap level that is in mip tail block, hack a lot of things...
1618 // Basically all mipmap levels in tail block will be viewed as a small mipmap chain that all levels
1619 // are fit in tail block:
1620
1621 // - mipId = relative mip id (which is counted from first mip ID in tail in original mip chain)
1622 pOut->mipId = pIn->mipId - infoOut.firstMipIdInTail;
1623
1624 // - at least 2 mipmap levels (since only 1 mipmap level will not be viewed as mipmap!)
1625 pOut->numMipLevels = Max(infoIn.numMipLevels - infoOut.firstMipIdInTail, 2u);
1626
1627 // - (mip0) width = requestMipWidth << mipId, the value can't exceed mip tail dimension threshold
1628 pOut->unalignedWidth = Min(requestMipWidth << pOut->mipId, infoOut.blockWidth / 2);
1629
1630 // - (mip0) height = requestMipHeight << mipId, the value can't exceed mip tail dimension threshold
1631 pOut->unalignedHeight = Min(requestMipHeight << pOut->mipId, infoOut.blockHeight);
1632 }
1633 // This check should cover at least mipId == 0
1634 else if (requestMipWidth << pIn->mipId == infoIn.width)
1635 {
1636 // For mipmap level [N] that is not in mip tail block and downgraded without losing element:
1637 // - only one mipmap level and mipId = 0
1638 pOut->mipId = 0;
1639 pOut->numMipLevels = 1;
1640
1641 // (mip0) width = requestMipWidth
1642 pOut->unalignedWidth = requestMipWidth;
1643
1644 // (mip0) height = requestMipHeight
1645 pOut->unalignedHeight = requestMipHeight;
1646 }
1647 else
1648 {
1649 // For mipmap level [N] that is not in mip tail block and downgraded with element losing,
1650 // We have to make it a multiple mipmap view (2 levels view here), add one extra element if needed,
1651 // because single mip view may have different pitch value than original (multiple) mip view...
1652 // A simple case would be:
1653 // - 64KB block swizzle mode, 8 Bytes-Per-Element. Block dim = [0x80, 0x40]
1654 // - 2 mipmap levels with API mip0 width = 0x401/mip1 width = 0x200 and non-BC view
1655 // mip0 width = 0x101/mip1 width = 0x80
1656 // By multiple mip view, the pitch for mip level 1 would be 0x100 bytes, due to rounding up logic in
1657 // GetMipSize(), and by single mip level view the pitch will only be 0x80 bytes.
1658
1659 // - 2 levels and mipId = 1
1660 pOut->mipId = 1;
1661 pOut->numMipLevels = 2;
1662
1663 const UINT_32 upperMipWidth = RoundUpQuotient(Max(pIn->width >> (pIn->mipId - 1), 1u), bcWidth);
1664 const UINT_32 upperMipHeight = RoundUpQuotient(Max(pIn->height >> (pIn->mipId - 1), 1u), bcHeight);
1665
1666 const BOOL_32 needToAvoidInTail =
1667 tiled && (requestMipWidth <= infoOut.blockWidth / 2) && (requestMipHeight <= infoOut.blockHeight) ?
1668 TRUE : FALSE;
1669
1670 const UINT_32 hwMipWidth = PowTwoAlign(ShiftCeil(infoIn.width, pIn->mipId), infoOut.blockWidth);
1671 const UINT_32 hwMipHeight = PowTwoAlign(ShiftCeil(infoIn.height, pIn->mipId), infoOut.blockHeight);
1672
1673 const BOOL_32 needExtraWidth =
1674 ((upperMipWidth < requestMipWidth * 2) ||
1675 ((upperMipWidth == requestMipWidth * 2) &&
1676 ((needToAvoidInTail == TRUE) ||
1677 (hwMipWidth > PowTwoAlign(requestMipWidth, infoOut.blockWidth))))) ? TRUE : FALSE;
1678
1679 const BOOL_32 needExtraHeight =
1680 ((upperMipHeight < requestMipHeight * 2) ||
1681 ((upperMipHeight == requestMipHeight * 2) &&
1682 ((needToAvoidInTail == TRUE) ||
1683 (hwMipHeight > PowTwoAlign(requestMipHeight, infoOut.blockHeight))))) ? TRUE : FALSE;
1684
1685 // (mip0) width = requestLastMipLevelWidth
1686 pOut->unalignedWidth = upperMipWidth + (needExtraWidth ? 1: 0);
1687
1688 // (mip0) height = requestLastMipLevelHeight
1689 pOut->unalignedHeight = upperMipHeight + (needExtraHeight ? 1: 0);
1690 }
1691
1692 // Assert the downgrading from this mip[0] width would still generate correct mip[N] width
1693 ADDR_ASSERT(ShiftRight(pOut->unalignedWidth, pOut->mipId) == requestMipWidth);
1694 // Assert the downgrading from this mip[0] height would still generate correct mip[N] height
1695 ADDR_ASSERT(ShiftRight(pOut->unalignedHeight, pOut->mipId) == requestMipHeight);
1696 }
1697 }
1698
1699 return returnCode;
1700 }
1701
1702 /**
1703 ************************************************************************************************************************
1704 * Gfx11Lib::ValidateNonSwModeParams
1705 *
1706 * @brief
1707 * Validate compute surface info params except swizzle mode
1708 *
1709 * @return
1710 * TRUE if parameters are valid, FALSE otherwise
1711 ************************************************************************************************************************
1712 */
ValidateNonSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1713 BOOL_32 Gfx11Lib::ValidateNonSwModeParams(
1714 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
1715 {
1716 BOOL_32 valid = TRUE;
1717
1718 if ((pIn->bpp == 0) || (pIn->bpp > 128) || (pIn->width == 0) || (pIn->numFrags > 8))
1719 {
1720 ADDR_ASSERT_ALWAYS();
1721 valid = FALSE;
1722 }
1723 else if (pIn->flags.fmask == 1)
1724 {
1725 // There is no FMASK for GFX11 ASICs
1726 ADDR_ASSERT_ALWAYS();
1727 valid = FALSE;
1728 }
1729 else if (pIn->numSamples > 8)
1730 {
1731 // There is no EQAA support for GFX11 ASICs, so the max number of sample is 8
1732 ADDR_ASSERT_ALWAYS();
1733 valid = FALSE;
1734 }
1735 else if ((pIn->numFrags != 0) && (pIn->numSamples != pIn->numFrags))
1736 {
1737 // There is no EQAA support for GFX11 ASICs, so the number of sample has to be same as number of fragment
1738 ADDR_ASSERT_ALWAYS();
1739 valid = FALSE;
1740 }
1741
1742 const ADDR2_SURFACE_FLAGS flags = pIn->flags;
1743 const AddrResourceType rsrcType = pIn->resourceType;
1744 const BOOL_32 mipmap = (pIn->numMipLevels > 1);
1745 const BOOL_32 msaa = (pIn->numSamples > 1);
1746 const BOOL_32 display = flags.display;
1747 const BOOL_32 tex3d = IsTex3d(rsrcType);
1748 const BOOL_32 tex2d = IsTex2d(rsrcType);
1749 const BOOL_32 tex1d = IsTex1d(rsrcType);
1750 const BOOL_32 stereo = flags.qbStereo;
1751
1752 // Resource type check
1753 if (tex1d)
1754 {
1755 if (msaa || display || stereo)
1756 {
1757 ADDR_ASSERT_ALWAYS();
1758 valid = FALSE;
1759 }
1760 }
1761 else if (tex2d)
1762 {
1763 if ((msaa && mipmap) || (stereo && msaa) || (stereo && mipmap))
1764 {
1765 ADDR_ASSERT_ALWAYS();
1766 valid = FALSE;
1767 }
1768 }
1769 else if (tex3d)
1770 {
1771 if (msaa || display || stereo)
1772 {
1773 ADDR_ASSERT_ALWAYS();
1774 valid = FALSE;
1775 }
1776 }
1777 else
1778 {
1779 ADDR_ASSERT_ALWAYS();
1780 valid = FALSE;
1781 }
1782
1783 return valid;
1784 }
1785
1786 /**
1787 ************************************************************************************************************************
1788 * Gfx11Lib::ValidateSwModeParams
1789 *
1790 * @brief
1791 * Validate compute surface info related to swizzle mode
1792 *
1793 * @return
1794 * TRUE if parameters are valid, FALSE otherwise
1795 ************************************************************************************************************************
1796 */
ValidateSwModeParams(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1797 BOOL_32 Gfx11Lib::ValidateSwModeParams(
1798 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn) const
1799 {
1800 BOOL_32 valid = TRUE;
1801
1802 if (pIn->swizzleMode >= ADDR_SW_MAX_TYPE)
1803 {
1804 ADDR_ASSERT_ALWAYS();
1805 valid = FALSE;
1806 }
1807 else if (IsValidSwMode(pIn->swizzleMode) == FALSE)
1808 {
1809 ADDR_ASSERT_ALWAYS();
1810 valid = FALSE;
1811 }
1812
1813 const ADDR2_SURFACE_FLAGS flags = pIn->flags;
1814 const AddrResourceType rsrcType = pIn->resourceType;
1815 const AddrSwizzleMode swizzle = pIn->swizzleMode;
1816 const BOOL_32 msaa = (pIn->numSamples > 1);
1817 const BOOL_32 zbuffer = flags.depth || flags.stencil;
1818 const BOOL_32 color = flags.color;
1819 const BOOL_32 display = flags.display;
1820 const BOOL_32 tex3d = IsTex3d(rsrcType);
1821 const BOOL_32 tex2d = IsTex2d(rsrcType);
1822 const BOOL_32 tex1d = IsTex1d(rsrcType);
1823 const BOOL_32 thin3d = flags.view3dAs2dArray;
1824 const BOOL_32 linear = IsLinear(swizzle);
1825 const BOOL_32 blk256B = IsBlock256b(swizzle);
1826 const BOOL_32 isNonPrtXor = IsNonPrtXor(swizzle);
1827 const BOOL_32 prt = flags.prt;
1828
1829 // Misc check
1830 if (msaa && (GetBlockSize(swizzle) < (m_pipeInterleaveBytes * pIn->numSamples)))
1831 {
1832 // MSAA surface must have blk_bytes/pipe_interleave >= num_samples
1833 ADDR_ASSERT_ALWAYS();
1834 valid = FALSE;
1835 }
1836
1837 if (display && (IsValidDisplaySwizzleMode(pIn) == FALSE))
1838 {
1839 ADDR_ASSERT_ALWAYS();
1840 valid = FALSE;
1841 }
1842
1843 if ((pIn->bpp == 96) && (linear == FALSE))
1844 {
1845 ADDR_ASSERT_ALWAYS();
1846 valid = FALSE;
1847 }
1848
1849 const UINT_32 swizzleMask = 1 << swizzle;
1850
1851 // Resource type check
1852 if (tex1d)
1853 {
1854 if ((swizzleMask & Gfx11Rsrc1dSwModeMask) == 0)
1855 {
1856 ADDR_ASSERT_ALWAYS();
1857 valid = FALSE;
1858 }
1859 }
1860 else if (tex2d)
1861 {
1862 if ((swizzleMask & Gfx11Rsrc2dSwModeMask) == 0)
1863 {
1864 ADDR_ASSERT_ALWAYS();
1865 valid = FALSE;
1866 }
1867 else if (prt && ((swizzleMask & Gfx11Rsrc2dPrtSwModeMask) == 0))
1868 {
1869 ADDR_ASSERT_ALWAYS();
1870 valid = FALSE;
1871 }
1872 }
1873 else if (tex3d)
1874 {
1875 if (((swizzleMask & Gfx11Rsrc3dSwModeMask) == 0) ||
1876 (prt && ((swizzleMask & Gfx11Rsrc3dPrtSwModeMask) == 0)) ||
1877 (thin3d && ((swizzleMask & Gfx11Rsrc3dThinSwModeMask) == 0)))
1878 {
1879 ADDR_ASSERT_ALWAYS();
1880 valid = FALSE;
1881 }
1882 }
1883
1884 // Swizzle type check
1885 if (linear)
1886 {
1887 if (zbuffer || msaa || (pIn->bpp == 0) || ((pIn->bpp % 8) != 0))
1888 {
1889 ADDR_ASSERT_ALWAYS();
1890 valid = FALSE;
1891 }
1892 }
1893 else if (IsZOrderSwizzle(swizzle))
1894 {
1895 if ((pIn->bpp > 64) ||
1896 (msaa && (color || (pIn->bpp > 32))) ||
1897 ElemLib::IsBlockCompressed(pIn->format) ||
1898 ElemLib::IsMacroPixelPacked(pIn->format))
1899 {
1900 ADDR_ASSERT_ALWAYS();
1901 valid = FALSE;
1902 }
1903 }
1904 else if (IsStandardSwizzle(rsrcType, swizzle))
1905 {
1906 if (zbuffer || msaa)
1907 {
1908 ADDR_ASSERT_ALWAYS();
1909 valid = FALSE;
1910 }
1911 }
1912 else if (IsDisplaySwizzle(rsrcType, swizzle))
1913 {
1914 if (zbuffer || msaa)
1915 {
1916 ADDR_ASSERT_ALWAYS();
1917 valid = FALSE;
1918 }
1919 }
1920 else if (IsRtOptSwizzle(swizzle))
1921 {
1922 if (zbuffer)
1923 {
1924 ADDR_ASSERT_ALWAYS();
1925 valid = FALSE;
1926 }
1927 }
1928 else
1929 {
1930 ADDR_ASSERT_ALWAYS();
1931 valid = FALSE;
1932 }
1933
1934 // Block type check
1935 if (blk256B)
1936 {
1937 if (zbuffer || tex3d || msaa)
1938 {
1939 ADDR_ASSERT_ALWAYS();
1940 valid = FALSE;
1941 }
1942 }
1943
1944 return valid;
1945 }
1946
1947 /**
1948 ************************************************************************************************************************
1949 * Gfx11Lib::HwlComputeSurfaceInfoSanityCheck
1950 *
1951 * @brief
1952 * Compute surface info sanity check
1953 *
1954 * @return
1955 * Offset
1956 ************************************************************************************************************************
1957 */
HwlComputeSurfaceInfoSanityCheck(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn) const1958 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoSanityCheck(
1959 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn ///< [in] input structure
1960 ) const
1961 {
1962 return ValidateNonSwModeParams(pIn) && ValidateSwModeParams(pIn) ? ADDR_OK : ADDR_INVALIDPARAMS;
1963 }
1964
1965 /**
1966 ************************************************************************************************************************
1967 * Gfx11Lib::HwlGetPreferredSurfaceSetting
1968 *
1969 * @brief
1970 * Internal function to get suggested surface information for cliet to use
1971 *
1972 * @return
1973 * ADDR_E_RETURNCODE
1974 ************************************************************************************************************************
1975 */
HwlGetPreferredSurfaceSetting(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const1976 ADDR_E_RETURNCODE Gfx11Lib::HwlGetPreferredSurfaceSetting(
1977 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, ///< [in] input structure
1978 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut ///< [out] output structure
1979 ) const
1980 {
1981 ADDR_E_RETURNCODE returnCode = ADDR_OK;
1982
1983 if (pIn->flags.fmask)
1984 {
1985 // There is no FMASK for GFX11 ASICs.
1986 ADDR_ASSERT_ALWAYS();
1987
1988 returnCode = ADDR_INVALIDPARAMS;
1989 }
1990 else
1991 {
1992 UINT_32 bpp = pIn->bpp;
1993 UINT_32 width = Max(pIn->width, 1u);
1994 UINT_32 height = Max(pIn->height, 1u);
1995
1996 // Set format to INVALID will skip this conversion
1997 if (pIn->format != ADDR_FMT_INVALID)
1998 {
1999 ElemMode elemMode = ADDR_UNCOMPRESSED;
2000 UINT_32 expandX, expandY;
2001
2002 // Get compression/expansion factors and element mode which indicates compression/expansion
2003 bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
2004 &elemMode,
2005 &expandX,
2006 &expandY);
2007
2008 UINT_32 basePitch = 0;
2009 GetElemLib()->AdjustSurfaceInfo(elemMode,
2010 expandX,
2011 expandY,
2012 &bpp,
2013 &basePitch,
2014 &width,
2015 &height);
2016 }
2017
2018 const UINT_32 numSlices = Max(pIn->numSlices, 1u);
2019 const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);
2020 const UINT_32 numSamples = Max(pIn->numSamples, 1u);
2021 const BOOL_32 msaa = numSamples > 1;
2022
2023 // Pre sanity check on non swizzle mode parameters
2024 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
2025 localIn.flags = pIn->flags;
2026 localIn.resourceType = pIn->resourceType;
2027 localIn.format = pIn->format;
2028 localIn.bpp = bpp;
2029 localIn.width = width;
2030 localIn.height = height;
2031 localIn.numSlices = numSlices;
2032 localIn.numMipLevels = numMipLevels;
2033 localIn.numSamples = numSamples;
2034 localIn.numFrags = numSamples;
2035
2036 if (ValidateNonSwModeParams(&localIn))
2037 {
2038 // Forbid swizzle mode(s) by client setting
2039 ADDR2_SWMODE_SET allowedSwModeSet = {};
2040 allowedSwModeSet.value |= pIn->forbiddenBlock.linear ? 0 : Gfx11LinearSwModeMask;
2041 allowedSwModeSet.value |= pIn->forbiddenBlock.micro ? 0 : Gfx11Blk256BSwModeMask;
2042 allowedSwModeSet.value |=
2043 pIn->forbiddenBlock.macroThin4KB ? 0 :
2044 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? 0 : Gfx11Blk4KBSwModeMask);
2045 allowedSwModeSet.value |=
2046 pIn->forbiddenBlock.macroThick4KB ? 0 :
2047 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick4KBSwModeMask : 0);
2048 allowedSwModeSet.value |=
2049 pIn->forbiddenBlock.macroThin64KB ? 0 :
2050 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThin64KBSwModeMask : Gfx11Blk64KBSwModeMask);
2051 allowedSwModeSet.value |=
2052 pIn->forbiddenBlock.macroThick64KB ? 0 :
2053 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick64KBSwModeMask : 0);
2054 allowedSwModeSet.value |=
2055 pIn->forbiddenBlock.gfx11.thin256KB ? 0 :
2056 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThin256KBSwModeMask : Gfx11Blk256KBSwModeMask);
2057 allowedSwModeSet.value |=
2058 pIn->forbiddenBlock.gfx11.thick256KB ? 0 :
2059 ((pIn->resourceType == ADDR_RSRC_TEX_3D) ? Gfx11Rsrc3dThick256KBSwModeMask : 0);
2060
2061 if (pIn->preferredSwSet.value != 0)
2062 {
2063 allowedSwModeSet.value &= pIn->preferredSwSet.sw_Z ? ~0 : ~Gfx11ZSwModeMask;
2064 allowedSwModeSet.value &= pIn->preferredSwSet.sw_S ? ~0 : ~Gfx11StandardSwModeMask;
2065 allowedSwModeSet.value &= pIn->preferredSwSet.sw_D ? ~0 : ~Gfx11DisplaySwModeMask;
2066 allowedSwModeSet.value &= pIn->preferredSwSet.sw_R ? ~0 : ~Gfx11RenderSwModeMask;
2067 }
2068
2069 if (pIn->noXor)
2070 {
2071 allowedSwModeSet.value &= ~Gfx11XorSwModeMask;
2072 }
2073
2074 if (pIn->maxAlign > 0)
2075 {
2076 if (pIn->maxAlign < Size256K)
2077 {
2078 allowedSwModeSet.value &= ~Gfx11Blk256KBSwModeMask;
2079 }
2080
2081 if (pIn->maxAlign < Size64K)
2082 {
2083 allowedSwModeSet.value &= ~Gfx11Blk64KBSwModeMask;
2084 }
2085
2086 if (pIn->maxAlign < Size4K)
2087 {
2088 allowedSwModeSet.value &= ~Gfx11Blk4KBSwModeMask;
2089 }
2090
2091 if (pIn->maxAlign < Size256)
2092 {
2093 allowedSwModeSet.value &= ~Gfx11Blk256BSwModeMask;
2094 }
2095 }
2096
2097 // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
2098 switch (pIn->resourceType)
2099 {
2100 case ADDR_RSRC_TEX_1D:
2101 allowedSwModeSet.value &= Gfx11Rsrc1dSwModeMask;
2102 break;
2103
2104 case ADDR_RSRC_TEX_2D:
2105 allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc2dPrtSwModeMask : Gfx11Rsrc2dSwModeMask;
2106 break;
2107
2108 case ADDR_RSRC_TEX_3D:
2109 allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc3dPrtSwModeMask : Gfx11Rsrc3dSwModeMask;
2110
2111 if (pIn->flags.view3dAs2dArray)
2112 {
2113 allowedSwModeSet.value &= Gfx11Rsrc3dThinSwModeMask;
2114 }
2115 break;
2116
2117 default:
2118 ADDR_ASSERT_ALWAYS();
2119 allowedSwModeSet.value = 0;
2120 break;
2121 }
2122
2123 if (ElemLib::IsBlockCompressed(pIn->format) ||
2124 ElemLib::IsMacroPixelPacked(pIn->format) ||
2125 (bpp > 64) ||
2126 (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
2127 {
2128 allowedSwModeSet.value &= ~Gfx11ZSwModeMask;
2129 }
2130
2131 if (pIn->format == ADDR_FMT_32_32_32)
2132 {
2133 allowedSwModeSet.value &= Gfx11LinearSwModeMask;
2134 }
2135
2136 if (msaa)
2137 {
2138 allowedSwModeSet.value &= Gfx11MsaaSwModeMask;
2139 }
2140
2141 if (pIn->flags.depth || pIn->flags.stencil)
2142 {
2143 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2144 }
2145
2146 if (pIn->flags.display)
2147 {
2148 allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);
2149 }
2150
2151 if (allowedSwModeSet.value != 0)
2152 {
2153 #if DEBUG
2154 // Post sanity check, at least AddrLib should accept the output generated by its own
2155 UINT_32 validateSwModeSet = allowedSwModeSet.value;
2156
2157 for (UINT_32 i = 0; validateSwModeSet != 0; i++)
2158 {
2159 if (validateSwModeSet & 1)
2160 {
2161 localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
2162 ADDR_ASSERT(ValidateSwModeParams(&localIn));
2163 }
2164
2165 validateSwModeSet >>= 1;
2166 }
2167 #endif
2168
2169 pOut->resourceType = pIn->resourceType;
2170 pOut->validSwModeSet = allowedSwModeSet;
2171 pOut->canXor = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;
2172
2173 GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &(pOut->validBlockSet));
2174 GetAllowedSwSet(allowedSwModeSet, &(pOut->validSwTypeSet));
2175
2176 pOut->clientPreferredSwSet = pIn->preferredSwSet;
2177
2178 if (pOut->clientPreferredSwSet.value == 0)
2179 {
2180 pOut->clientPreferredSwSet.value = AddrSwSetAll;
2181 }
2182
2183 // Apply optional restrictions
2184 if (pIn->flags.needEquation)
2185 {
2186 UINT_32 components = pIn->flags.allowExtEquation ? ADDR_MAX_EQUATION_COMP :
2187 ADDR_MAX_LEGACY_EQUATION_COMP;
2188 FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
2189 }
2190
2191 if (allowedSwModeSet.value == Gfx11LinearSwModeMask)
2192 {
2193 pOut->swizzleMode = ADDR_SW_LINEAR;
2194 }
2195 else
2196 {
2197 const BOOL_32 computeMinSize = (pIn->flags.minimizeAlign == 1) || (pIn->memoryBudget >= 1.0);
2198
2199 if ((height > 1) && (computeMinSize == FALSE))
2200 {
2201 // Always ignore linear swizzle mode if:
2202 // 1. This is a (2D/3D) resource with height > 1
2203 // 2. Client doesn't require computing minimize size
2204 allowedSwModeSet.swLinear = 0;
2205 }
2206
2207 ADDR2_BLOCK_SET allowedBlockSet = {};
2208 GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);
2209
2210 // Determine block size if there are 2 or more block type candidates
2211 if (IsPow2(allowedBlockSet.value) == FALSE)
2212 {
2213 AddrSwizzleMode swMode[AddrBlockMaxTiledType] = {};
2214
2215 swMode[AddrBlockLinear] = ADDR_SW_LINEAR;
2216
2217 if (pOut->resourceType == ADDR_RSRC_TEX_3D)
2218 {
2219 swMode[AddrBlockThick4KB] = ADDR_SW_4KB_S_X;
2220 swMode[AddrBlockThin64KB] = ADDR_SW_64KB_R_X;
2221 swMode[AddrBlockThick64KB] = ADDR_SW_64KB_S_X;
2222 swMode[AddrBlockThin256KB] = ADDR_SW_256KB_R_X;
2223 swMode[AddrBlockThick256KB] = ADDR_SW_256KB_S_X;
2224 }
2225 else
2226 {
2227 swMode[AddrBlockMicro] = ADDR_SW_256B_D;
2228 swMode[AddrBlockThin4KB] = ADDR_SW_4KB_D_X;
2229 swMode[AddrBlockThin64KB] = ADDR_SW_64KB_D_X;
2230 swMode[AddrBlockThin256KB] = ADDR_SW_256KB_D_X;
2231 }
2232
2233 UINT_64 padSize[AddrBlockMaxTiledType] = {};
2234
2235 const UINT_32 ratioLow = computeMinSize ? 1 : (pIn->flags.opt4space ? 3 : 2);
2236 const UINT_32 ratioHi = computeMinSize ? 1 : (pIn->flags.opt4space ? 2 : 1);
2237 const UINT_64 sizeAlignInElement = Max(NextPow2(pIn->minSizeAlign) / (bpp >> 3), 1u);
2238 UINT_32 minSizeBlk = AddrBlockMicro;
2239 UINT_64 minSize = 0;
2240
2241 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
2242
2243 for (UINT_32 i = AddrBlockLinear; i < AddrBlockMaxTiledType; i++)
2244 {
2245 if (Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
2246 {
2247 localIn.swizzleMode = swMode[i];
2248
2249 if (localIn.swizzleMode == ADDR_SW_LINEAR)
2250 {
2251 returnCode = HwlComputeSurfaceInfoLinear(&localIn, &localOut);
2252 }
2253 else
2254 {
2255 returnCode = HwlComputeSurfaceInfoTiled(&localIn, &localOut);
2256 }
2257
2258 if (returnCode == ADDR_OK)
2259 {
2260 padSize[i] = localOut.surfSize;
2261
2262 if ((minSize == 0) ||
2263 Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], ratioLow, ratioHi))
2264 {
2265 minSize = padSize[i];
2266 minSizeBlk = i;
2267 }
2268 }
2269 else
2270 {
2271 ADDR_ASSERT_ALWAYS();
2272 break;
2273 }
2274 }
2275 }
2276
2277 if (pIn->memoryBudget > 1.0)
2278 {
2279 // If minimum size is given by swizzle mode with bigger-block type, then don't ever check
2280 // smaller-block type again in coming loop
2281 switch (minSizeBlk)
2282 {
2283 case AddrBlockThick256KB:
2284 allowedBlockSet.gfx11.thin256KB = 0;
2285 case AddrBlockThin256KB:
2286 allowedBlockSet.macroThick64KB = 0;
2287 case AddrBlockThick64KB:
2288 allowedBlockSet.macroThin64KB = 0;
2289 case AddrBlockThin64KB:
2290 allowedBlockSet.macroThick4KB = 0;
2291 case AddrBlockThick4KB:
2292 allowedBlockSet.macroThin4KB = 0;
2293 case AddrBlockThin4KB:
2294 allowedBlockSet.micro = 0;
2295 case AddrBlockMicro:
2296 allowedBlockSet.linear = 0;
2297 case AddrBlockLinear:
2298 break;
2299
2300 default:
2301 ADDR_ASSERT_ALWAYS();
2302 break;
2303 }
2304
2305 for (UINT_32 i = AddrBlockMicro; i < AddrBlockMaxTiledType; i++)
2306 {
2307 if ((i != minSizeBlk) &&
2308 Addr2IsBlockTypeAvailable(allowedBlockSet, static_cast<::AddrBlockType>(i)))
2309 {
2310 if (Addr2BlockTypeWithinMemoryBudget(minSize, padSize[i], 0, 0, pIn->memoryBudget) == FALSE)
2311 {
2312 // Clear the block type if the memory waste is unacceptable
2313 allowedBlockSet.value &= ~(1u << (i - 1));
2314 }
2315 }
2316 }
2317
2318 // Remove linear block type if 2 or more block types are allowed
2319 if (IsPow2(allowedBlockSet.value) == FALSE)
2320 {
2321 allowedBlockSet.linear = 0;
2322 }
2323
2324 // Select the biggest allowed block type
2325 minSizeBlk = Log2NonPow2(allowedBlockSet.value) + 1;
2326
2327 if (minSizeBlk == static_cast<UINT_32>(AddrBlockMaxTiledType))
2328 {
2329 minSizeBlk = AddrBlockLinear;
2330 }
2331 }
2332
2333 switch (minSizeBlk)
2334 {
2335 case AddrBlockLinear:
2336 allowedSwModeSet.value &= Gfx11LinearSwModeMask;
2337 break;
2338
2339 case AddrBlockMicro:
2340 ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);
2341 allowedSwModeSet.value &= Gfx11Blk256BSwModeMask;
2342 break;
2343
2344 case AddrBlockThin4KB:
2345 ADDR_ASSERT(pOut->resourceType != ADDR_RSRC_TEX_3D);
2346 allowedSwModeSet.value &= Gfx11Blk4KBSwModeMask;
2347 break;
2348
2349 case AddrBlockThick4KB:
2350 ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);
2351 allowedSwModeSet.value &= Gfx11Rsrc3dThick4KBSwModeMask;
2352 break;
2353
2354 case AddrBlockThin64KB:
2355 allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?
2356 Gfx11Rsrc3dThin64KBSwModeMask : Gfx11Blk64KBSwModeMask;
2357 break;
2358
2359 case AddrBlockThick64KB:
2360 ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);
2361 allowedSwModeSet.value &= Gfx11Rsrc3dThick64KBSwModeMask;
2362 break;
2363
2364 case AddrBlockThin256KB:
2365 allowedSwModeSet.value &= (pOut->resourceType == ADDR_RSRC_TEX_3D) ?
2366 Gfx11Rsrc3dThin256KBSwModeMask : Gfx11Blk256KBSwModeMask;
2367 break;
2368
2369 case AddrBlockThick256KB:
2370 ADDR_ASSERT(pOut->resourceType == ADDR_RSRC_TEX_3D);
2371 allowedSwModeSet.value &= Gfx11Rsrc3dThick256KBSwModeMask;
2372 break;
2373
2374 default:
2375 ADDR_ASSERT_ALWAYS();
2376 allowedSwModeSet.value = 0;
2377 break;
2378 }
2379 }
2380
2381 // Block type should be determined.
2382 GetAllowedBlockSet(allowedSwModeSet, pOut->resourceType, &allowedBlockSet);
2383 ADDR_ASSERT(IsPow2(allowedBlockSet.value));
2384
2385 ADDR2_SWTYPE_SET allowedSwSet = {};
2386 GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);
2387
2388 // Determine swizzle type if there are 2 or more swizzle type candidates
2389 if ((allowedSwSet.value != 0) && (IsPow2(allowedSwSet.value) == FALSE))
2390 {
2391 if (ElemLib::IsBlockCompressed(pIn->format))
2392 {
2393 if (allowedSwSet.sw_D)
2394 {
2395 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2396 }
2397 else if (allowedSwSet.sw_S)
2398 {
2399 allowedSwModeSet.value &= Gfx11StandardSwModeMask;
2400 }
2401 else
2402 {
2403 ADDR_ASSERT(allowedSwSet.sw_R);
2404 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2405 }
2406 }
2407 else if (ElemLib::IsMacroPixelPacked(pIn->format))
2408 {
2409 if (allowedSwSet.sw_S)
2410 {
2411 allowedSwModeSet.value &= Gfx11StandardSwModeMask;
2412 }
2413 else if (allowedSwSet.sw_D)
2414 {
2415 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2416 }
2417 else
2418 {
2419 ADDR_ASSERT(allowedSwSet.sw_R);
2420 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2421 }
2422 }
2423 else if (pIn->resourceType == ADDR_RSRC_TEX_3D)
2424 {
2425 if (pIn->flags.color && allowedSwSet.sw_R)
2426 {
2427 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2428 }
2429 else if (allowedSwSet.sw_S)
2430 {
2431 allowedSwModeSet.value &= Gfx11StandardSwModeMask;
2432 }
2433 else if (allowedSwSet.sw_D)
2434 {
2435 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2436 }
2437 else
2438 {
2439 ADDR_ASSERT(allowedSwSet.sw_Z);
2440 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2441 }
2442 }
2443 else
2444 {
2445 if (allowedSwSet.sw_R)
2446 {
2447 allowedSwModeSet.value &= Gfx11RenderSwModeMask;
2448 }
2449 else if (allowedSwSet.sw_D)
2450 {
2451 allowedSwModeSet.value &= Gfx11DisplaySwModeMask;
2452 }
2453 else if (allowedSwSet.sw_Z)
2454 {
2455 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2456 }
2457 else
2458 {
2459 ADDR_ASSERT_ALWAYS();
2460 }
2461 }
2462
2463 // Swizzle type should be determined.
2464 GetAllowedSwSet(allowedSwModeSet, &allowedSwSet);
2465 ADDR_ASSERT(IsPow2(allowedSwSet.value));
2466 }
2467
2468 // Determine swizzle mode now. Always select the "largest" swizzle mode for a given block type +
2469 // swizzle type combination. E.g, for AddrBlockThin64KB + ADDR_SW_S, select SW_64KB_S_X(25) if it's
2470 // available, or otherwise select SW_64KB_S_T(17) if it's available, or otherwise select SW_64KB_S(9).
2471 pOut->swizzleMode = static_cast<AddrSwizzleMode>(Log2NonPow2(allowedSwModeSet.value));
2472 }
2473 }
2474 else
2475 {
2476 // Invalid combination...
2477 ADDR_ASSERT_ALWAYS();
2478 returnCode = ADDR_INVALIDPARAMS;
2479 }
2480 }
2481 else
2482 {
2483 // Invalid combination...
2484 ADDR_ASSERT_ALWAYS();
2485 returnCode = ADDR_INVALIDPARAMS;
2486 }
2487 }
2488
2489 return returnCode;
2490 }
2491
2492 /**
2493 ************************************************************************************************************************
2494 * Gfx11Lib::HwlGetPossibleSwizzleModes
2495 *
2496 * @brief
2497 * Returns a list of swizzle modes that are valid from the hardware's perspective for the client to choose from
2498 *
2499 * @return
2500 * ADDR_E_RETURNCODE
2501 ************************************************************************************************************************
2502 */
HwlGetPossibleSwizzleModes(const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT * pIn,ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT * pOut) const2503 ADDR_E_RETURNCODE Gfx11Lib::HwlGetPossibleSwizzleModes(
2504 const ADDR2_GET_PREFERRED_SURF_SETTING_INPUT* pIn, ///< [in] input structure
2505 ADDR2_GET_PREFERRED_SURF_SETTING_OUTPUT* pOut ///< [out] output structure
2506 ) const
2507 {
2508 ADDR_E_RETURNCODE returnCode = ADDR_OK;
2509
2510 if (pIn->flags.fmask)
2511 {
2512 // There is no FMASK for GFX11 ASICs.
2513 ADDR_ASSERT_ALWAYS();
2514
2515 returnCode = ADDR_INVALIDPARAMS;
2516 }
2517 else
2518 {
2519 UINT_32 bpp = pIn->bpp;
2520 UINT_32 width = Max(pIn->width, 1u);
2521 UINT_32 height = Max(pIn->height, 1u);
2522
2523 // Set format to INVALID will skip this conversion
2524 if (pIn->format != ADDR_FMT_INVALID)
2525 {
2526 ElemMode elemMode = ADDR_UNCOMPRESSED;
2527 UINT_32 expandX, expandY;
2528
2529 // Get compression/expansion factors and element mode which indicates compression/expansion
2530 bpp = GetElemLib()->GetBitsPerPixel(pIn->format,
2531 &elemMode,
2532 &expandX,
2533 &expandY);
2534
2535 UINT_32 basePitch = 0;
2536 GetElemLib()->AdjustSurfaceInfo(elemMode,
2537 expandX,
2538 expandY,
2539 &bpp,
2540 &basePitch,
2541 &width,
2542 &height);
2543 }
2544
2545 const UINT_32 numSlices = Max(pIn->numSlices, 1u);
2546 const UINT_32 numMipLevels = Max(pIn->numMipLevels, 1u);
2547 const UINT_32 numSamples = Max(pIn->numSamples, 1u);
2548 const BOOL_32 msaa = numSamples > 1;
2549
2550 // Pre sanity check on non swizzle mode parameters
2551 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
2552 localIn.flags = pIn->flags;
2553 localIn.resourceType = pIn->resourceType;
2554 localIn.format = pIn->format;
2555 localIn.bpp = bpp;
2556 localIn.width = width;
2557 localIn.height = height;
2558 localIn.numSlices = numSlices;
2559 localIn.numMipLevels = numMipLevels;
2560 localIn.numSamples = numSamples;
2561 localIn.numFrags = numSamples;
2562
2563 if (ValidateNonSwModeParams(&localIn))
2564 {
2565 // Allow appropriate swizzle modes by default
2566 ADDR2_SWMODE_SET allowedSwModeSet = {};
2567 allowedSwModeSet.value |= Gfx11LinearSwModeMask | Gfx11Blk256BSwModeMask;
2568 if (pIn->resourceType == ADDR_RSRC_TEX_3D)
2569 {
2570 allowedSwModeSet.value |= Gfx11Rsrc3dThick4KBSwModeMask |
2571 Gfx11Rsrc3dThin64KBSwModeMask |
2572 Gfx11Rsrc3dThick64KBSwModeMask |
2573 Gfx11Rsrc3dThin256KBSwModeMask |
2574 Gfx11Rsrc3dThick256KBSwModeMask;
2575 }
2576 else
2577 {
2578 allowedSwModeSet.value |= Gfx11Blk4KBSwModeMask | Gfx11Blk64KBSwModeMask | Gfx11Blk256KBSwModeMask;
2579 }
2580
2581 // Filter out invalid swizzle mode(s) by image attributes and HW restrictions
2582 switch (pIn->resourceType)
2583 {
2584 case ADDR_RSRC_TEX_1D:
2585 allowedSwModeSet.value &= Gfx11Rsrc1dSwModeMask;
2586 break;
2587
2588 case ADDR_RSRC_TEX_2D:
2589 allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc2dPrtSwModeMask : Gfx11Rsrc2dSwModeMask;
2590 break;
2591
2592 case ADDR_RSRC_TEX_3D:
2593 allowedSwModeSet.value &= pIn->flags.prt ? Gfx11Rsrc3dPrtSwModeMask : Gfx11Rsrc3dSwModeMask;
2594
2595 if (pIn->flags.view3dAs2dArray)
2596 {
2597 allowedSwModeSet.value &= Gfx11Rsrc3dThinSwModeMask;
2598 }
2599 break;
2600
2601 default:
2602 ADDR_ASSERT_ALWAYS();
2603 allowedSwModeSet.value = 0;
2604 break;
2605 }
2606
2607 // TODO: figure out if following restrictions are correct on GFX11...
2608 if (ElemLib::IsBlockCompressed(pIn->format) ||
2609 ElemLib::IsMacroPixelPacked(pIn->format) ||
2610 (bpp > 64) ||
2611 (msaa && ((bpp > 32) || pIn->flags.color || pIn->flags.unordered)))
2612 {
2613 allowedSwModeSet.value &= ~Gfx11ZSwModeMask;
2614 }
2615
2616 if (pIn->format == ADDR_FMT_32_32_32)
2617 {
2618 allowedSwModeSet.value &= Gfx11LinearSwModeMask;
2619 }
2620
2621 if (msaa)
2622 {
2623 allowedSwModeSet.value &= Gfx11MsaaSwModeMask;
2624 }
2625
2626 if (pIn->flags.depth || pIn->flags.stencil)
2627 {
2628 allowedSwModeSet.value &= Gfx11ZSwModeMask;
2629 }
2630
2631 if (pIn->flags.display)
2632 {
2633 allowedSwModeSet.value &= GetValidDisplaySwizzleModes(bpp);
2634 }
2635
2636 if (allowedSwModeSet.value != 0)
2637 {
2638 #if DEBUG
2639 // Post sanity check, at least AddrLib should accept the output generated by its own
2640 UINT_32 validateSwModeSet = allowedSwModeSet.value;
2641
2642 for (UINT_32 i = 0; validateSwModeSet != 0; i++)
2643 {
2644 if (validateSwModeSet & 1)
2645 {
2646 localIn.swizzleMode = static_cast<AddrSwizzleMode>(i);
2647 ADDR_ASSERT(ValidateSwModeParams(&localIn));
2648 }
2649
2650 validateSwModeSet >>= 1;
2651 }
2652 #endif
2653
2654 pOut->resourceType = pIn->resourceType;
2655 pOut->clientPreferredSwSet = pIn->preferredSwSet;
2656
2657 if (pOut->clientPreferredSwSet.value == 0)
2658 {
2659 pOut->clientPreferredSwSet.value = AddrSwSetAll;
2660 }
2661
2662 if (pIn->flags.needEquation)
2663 {
2664 UINT_32 components = pIn->flags.allowExtEquation ? ADDR_MAX_EQUATION_COMP :
2665 ADDR_MAX_LEGACY_EQUATION_COMP;
2666 FilterInvalidEqSwizzleMode(allowedSwModeSet, pIn->resourceType, Log2(bpp >> 3), components);
2667 }
2668
2669 pOut->validSwModeSet = allowedSwModeSet;
2670 pOut->canXor = (allowedSwModeSet.value & Gfx11XorSwModeMask) ? TRUE : FALSE;
2671 }
2672 else
2673 {
2674 // Invalid combination...
2675 ADDR_ASSERT_ALWAYS();
2676 returnCode = ADDR_INVALIDPARAMS;
2677 }
2678 }
2679 else
2680 {
2681 // Invalid combination...
2682 ADDR_ASSERT_ALWAYS();
2683 returnCode = ADDR_INVALIDPARAMS;
2684 }
2685 }
2686
2687 return returnCode;
2688 }
2689
2690 /**
2691 ************************************************************************************************************************
2692 * Gfx11Lib::HwlGetAllowedBlockSet
2693 *
2694 * @brief
2695 * Returns the set of allowed block sizes given the allowed swizzle modes and resource type
2696 *
2697 * @return
2698 * ADDR_E_RETURNCODE
2699 ************************************************************************************************************************
2700 */
HwlGetAllowedBlockSet(ADDR2_SWMODE_SET allowedSwModeSet,AddrResourceType rsrcType,ADDR2_BLOCK_SET * pAllowedBlockSet) const2701 ADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedBlockSet(
2702 ADDR2_SWMODE_SET allowedSwModeSet, ///< [in] allowed swizzle modes
2703 AddrResourceType rsrcType, ///< [in] resource type
2704 ADDR2_BLOCK_SET* pAllowedBlockSet ///< [out] allowed block sizes
2705 ) const
2706 {
2707 ADDR2_BLOCK_SET allowedBlockSet = {};
2708
2709 allowedBlockSet.micro = (allowedSwModeSet.value & Gfx11Blk256BSwModeMask) ? TRUE : FALSE;
2710 allowedBlockSet.linear = (allowedSwModeSet.value & Gfx11LinearSwModeMask) ? TRUE : FALSE;
2711
2712 if (rsrcType == ADDR_RSRC_TEX_3D)
2713 {
2714 allowedBlockSet.macroThick4KB = (allowedSwModeSet.value & Gfx11Rsrc3dThick4KBSwModeMask) ? TRUE : FALSE;
2715 allowedBlockSet.macroThin64KB = (allowedSwModeSet.value & Gfx11Rsrc3dThin64KBSwModeMask) ? TRUE : FALSE;
2716 allowedBlockSet.macroThick64KB = (allowedSwModeSet.value & Gfx11Rsrc3dThick64KBSwModeMask) ? TRUE : FALSE;
2717 allowedBlockSet.gfx11.thin256KB = (allowedSwModeSet.value & Gfx11Rsrc3dThin256KBSwModeMask) ? TRUE : FALSE;
2718 allowedBlockSet.gfx11.thick256KB = (allowedSwModeSet.value & Gfx11Rsrc3dThick256KBSwModeMask) ? TRUE : FALSE;
2719 }
2720 else
2721 {
2722 allowedBlockSet.macroThin4KB = (allowedSwModeSet.value & Gfx11Blk4KBSwModeMask) ? TRUE : FALSE;
2723 allowedBlockSet.macroThin64KB = (allowedSwModeSet.value & Gfx11Blk64KBSwModeMask) ? TRUE : FALSE;
2724 allowedBlockSet.gfx11.thin256KB = (allowedSwModeSet.value & Gfx11Blk256KBSwModeMask) ? TRUE : FALSE;
2725 }
2726
2727 *pAllowedBlockSet = allowedBlockSet;
2728 return ADDR_OK;
2729 }
2730
2731 /**
2732 ************************************************************************************************************************
2733 * Gfx11Lib::HwlGetAllowedSwSet
2734 *
2735 * @brief
2736 * Returns the set of allowed swizzle types given the allowed swizzle modes
2737 * @return
2738 * ADDR_E_RETURNCODE
2739 ************************************************************************************************************************
2740 */
HwlGetAllowedSwSet(ADDR2_SWMODE_SET allowedSwModeSet,ADDR2_SWTYPE_SET * pAllowedSwSet) const2741 ADDR_E_RETURNCODE Gfx11Lib::HwlGetAllowedSwSet(
2742 ADDR2_SWMODE_SET allowedSwModeSet, ///< [in] allowed swizzle modes
2743 ADDR2_SWTYPE_SET* pAllowedSwSet ///< [out] allowed swizzle types
2744 ) const
2745 {
2746 ADDR2_SWTYPE_SET allowedSwSet = {};
2747
2748 allowedSwSet.sw_Z = (allowedSwModeSet.value & Gfx11ZSwModeMask) ? TRUE : FALSE;
2749 allowedSwSet.sw_S = (allowedSwModeSet.value & Gfx11StandardSwModeMask) ? TRUE : FALSE;
2750 allowedSwSet.sw_D = (allowedSwModeSet.value & Gfx11DisplaySwModeMask) ? TRUE : FALSE;
2751 allowedSwSet.sw_R = (allowedSwModeSet.value & Gfx11RenderSwModeMask) ? TRUE : FALSE;
2752
2753 *pAllowedSwSet = allowedSwSet;
2754 return ADDR_OK;
2755 }
2756
2757 /**
2758 ************************************************************************************************************************
2759 * Gfx11Lib::ComputeStereoInfo
2760 *
2761 * @brief
2762 * Compute height alignment and right eye pipeBankXor for stereo surface
2763 *
2764 * @return
2765 * Error code
2766 *
2767 ************************************************************************************************************************
2768 */
ComputeStereoInfo(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,UINT_32 * pAlignY,UINT_32 * pRightXor) const2769 ADDR_E_RETURNCODE Gfx11Lib::ComputeStereoInfo(
2770 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< Compute surface info
2771 UINT_32* pAlignY, ///< Stereo requested additional alignment in Y
2772 UINT_32* pRightXor ///< Right eye xor
2773 ) const
2774 {
2775 ADDR_E_RETURNCODE ret = ADDR_OK;
2776
2777 *pRightXor = 0;
2778
2779 if (IsNonPrtXor(pIn->swizzleMode))
2780 {
2781 const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);
2782 const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
2783 const UINT_32 rsrcType = static_cast<UINT_32>(pIn->resourceType) - 1;
2784 const UINT_32 swMode = static_cast<UINT_32>(pIn->swizzleMode);
2785 const UINT_32 eqIndex = m_equationLookupTable[rsrcType][swMode][elemLog2];
2786
2787 if (eqIndex != ADDR_INVALID_EQUATION_INDEX)
2788 {
2789 UINT_32 yMax = 0;
2790 UINT_32 yPosMask = 0;
2791
2792 // First get "max y bit"
2793 for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)
2794 {
2795 ADDR_ASSERT(m_equationTable[eqIndex].addr[i].valid == 1);
2796
2797 if ((m_equationTable[eqIndex].addr[i].channel == 1) &&
2798 (m_equationTable[eqIndex].addr[i].index > yMax))
2799 {
2800 yMax = m_equationTable[eqIndex].addr[i].index;
2801 }
2802
2803 if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&
2804 (m_equationTable[eqIndex].xor1[i].channel == 1) &&
2805 (m_equationTable[eqIndex].xor1[i].index > yMax))
2806 {
2807 yMax = m_equationTable[eqIndex].xor1[i].index;
2808 }
2809
2810 if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&
2811 (m_equationTable[eqIndex].xor2[i].channel == 1) &&
2812 (m_equationTable[eqIndex].xor2[i].index > yMax))
2813 {
2814 yMax = m_equationTable[eqIndex].xor2[i].index;
2815 }
2816 }
2817
2818 // Then loop again for populating a position mask of "max Y bit"
2819 for (UINT_32 i = m_pipeInterleaveLog2; i < blkSizeLog2; i++)
2820 {
2821 if ((m_equationTable[eqIndex].addr[i].channel == 1) &&
2822 (m_equationTable[eqIndex].addr[i].index == yMax))
2823 {
2824 yPosMask |= 1u << i;
2825 }
2826 else if ((m_equationTable[eqIndex].xor1[i].valid == 1) &&
2827 (m_equationTable[eqIndex].xor1[i].channel == 1) &&
2828 (m_equationTable[eqIndex].xor1[i].index == yMax))
2829 {
2830 yPosMask |= 1u << i;
2831 }
2832 else if ((m_equationTable[eqIndex].xor2[i].valid == 1) &&
2833 (m_equationTable[eqIndex].xor2[i].channel == 1) &&
2834 (m_equationTable[eqIndex].xor2[i].index == yMax))
2835 {
2836 yPosMask |= 1u << i;
2837 }
2838 }
2839
2840 const UINT_32 additionalAlign = 1 << yMax;
2841
2842 if (additionalAlign >= *pAlignY)
2843 {
2844 *pAlignY = additionalAlign;
2845
2846 const UINT_32 alignedHeight = PowTwoAlign(pIn->height, additionalAlign);
2847
2848 if ((alignedHeight >> yMax) & 1)
2849 {
2850 *pRightXor = yPosMask >> m_pipeInterleaveLog2;
2851 }
2852 }
2853 }
2854 else
2855 {
2856 ret = ADDR_INVALIDPARAMS;
2857 }
2858 }
2859
2860 return ret;
2861 }
2862
2863 /**
2864 ************************************************************************************************************************
2865 * Gfx11Lib::HwlComputeSurfaceInfoTiled
2866 *
2867 * @brief
2868 * Internal function to calculate alignment for tiled surface
2869 *
2870 * @return
2871 * ADDR_E_RETURNCODE
2872 ************************************************************************************************************************
2873 */
HwlComputeSurfaceInfoTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2874 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoTiled(
2875 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
2876 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
2877 ) const
2878 {
2879 ADDR_E_RETURNCODE ret;
2880
2881 // Mip chain dimesion and epitch has no meaning in GFX11, set to default value
2882 pOut->mipChainPitch = 0;
2883 pOut->mipChainHeight = 0;
2884 pOut->mipChainSlice = 0;
2885 pOut->epitchIsHeight = FALSE;
2886
2887 // Following information will be provided in ComputeSurfaceInfoMacroTiled() if necessary
2888 pOut->mipChainInTail = FALSE;
2889 pOut->firstMipIdInTail = pIn->numMipLevels;
2890
2891 if (IsBlock256b(pIn->swizzleMode))
2892 {
2893 ret = ComputeSurfaceInfoMicroTiled(pIn, pOut);
2894 }
2895 else
2896 {
2897 ret = ComputeSurfaceInfoMacroTiled(pIn, pOut);
2898 }
2899
2900 return ret;
2901 }
2902
2903 /**
2904 ************************************************************************************************************************
2905 * Gfx11Lib::ComputeSurfaceInfoMicroTiled
2906 *
2907 * @brief
2908 * Internal function to calculate alignment for micro tiled surface
2909 *
2910 * @return
2911 * ADDR_E_RETURNCODE
2912 ************************************************************************************************************************
2913 */
ComputeSurfaceInfoMicroTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2914 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceInfoMicroTiled(
2915 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
2916 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
2917 ) const
2918 {
2919 ADDR_E_RETURNCODE ret = ComputeBlockDimensionForSurf(&pOut->blockWidth,
2920 &pOut->blockHeight,
2921 &pOut->blockSlices,
2922 pIn->bpp,
2923 pIn->numSamples,
2924 pIn->resourceType,
2925 pIn->swizzleMode);
2926
2927 if (ret == ADDR_OK)
2928 {
2929 const UINT_32 blockSize = GetBlockSize(pIn->swizzleMode);
2930
2931 pOut->pitch = PowTwoAlign(pIn->width, pOut->blockWidth);
2932 pOut->height = PowTwoAlign(pIn->height, pOut->blockHeight);
2933 pOut->numSlices = pIn->numSlices;
2934 pOut->baseAlign = blockSize;
2935
2936 if (pIn->numMipLevels > 1)
2937 {
2938 const UINT_32 mip0Width = pIn->width;
2939 const UINT_32 mip0Height = pIn->height;
2940 UINT_64 mipSliceSize = 0;
2941
2942 for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)
2943 {
2944 UINT_32 mipWidth, mipHeight;
2945
2946 GetMipSize(mip0Width, mip0Height, 1, i, &mipWidth, &mipHeight);
2947
2948 const UINT_32 mipActualWidth = PowTwoAlign(mipWidth, pOut->blockWidth);
2949 const UINT_32 mipActualHeight = PowTwoAlign(mipHeight, pOut->blockHeight);
2950
2951 if (pOut->pMipInfo != NULL)
2952 {
2953 pOut->pMipInfo[i].pitch = mipActualWidth;
2954 pOut->pMipInfo[i].height = mipActualHeight;
2955 pOut->pMipInfo[i].depth = 1;
2956 pOut->pMipInfo[i].offset = mipSliceSize;
2957 pOut->pMipInfo[i].mipTailOffset = 0;
2958 pOut->pMipInfo[i].macroBlockOffset = mipSliceSize;
2959 }
2960
2961 mipSliceSize += mipActualWidth * mipActualHeight * (pIn->bpp >> 3);
2962 }
2963
2964 pOut->sliceSize = mipSliceSize;
2965 pOut->surfSize = mipSliceSize * pOut->numSlices;
2966 }
2967 else
2968 {
2969 pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3);
2970 pOut->surfSize = pOut->sliceSize * pOut->numSlices;
2971
2972 if (pOut->pMipInfo != NULL)
2973 {
2974 pOut->pMipInfo[0].pitch = pOut->pitch;
2975 pOut->pMipInfo[0].height = pOut->height;
2976 pOut->pMipInfo[0].depth = 1;
2977 pOut->pMipInfo[0].offset = 0;
2978 pOut->pMipInfo[0].mipTailOffset = 0;
2979 pOut->pMipInfo[0].macroBlockOffset = 0;
2980 }
2981 }
2982
2983 }
2984
2985 return ret;
2986 }
2987
2988 /**
2989 ************************************************************************************************************************
2990 * Gfx11Lib::ComputeSurfaceInfoMacroTiled
2991 *
2992 * @brief
2993 * Internal function to calculate alignment for macro tiled surface
2994 *
2995 * @return
2996 * ADDR_E_RETURNCODE
2997 ************************************************************************************************************************
2998 */
ComputeSurfaceInfoMacroTiled(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const2999 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceInfoMacroTiled(
3000 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
3001 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
3002 ) const
3003 {
3004 ADDR_E_RETURNCODE returnCode = ComputeBlockDimensionForSurf(&pOut->blockWidth,
3005 &pOut->blockHeight,
3006 &pOut->blockSlices,
3007 pIn->bpp,
3008 pIn->numSamples,
3009 pIn->resourceType,
3010 pIn->swizzleMode);
3011
3012 if (returnCode == ADDR_OK)
3013 {
3014 UINT_32 heightAlign = pOut->blockHeight;
3015
3016 if (pIn->flags.qbStereo)
3017 {
3018 UINT_32 rightXor = 0;
3019
3020 returnCode = ComputeStereoInfo(pIn, &heightAlign, &rightXor);
3021
3022 if (returnCode == ADDR_OK)
3023 {
3024 pOut->pStereoInfo->rightSwizzle = rightXor;
3025 }
3026 }
3027
3028 if (returnCode == ADDR_OK)
3029 {
3030 const UINT_32 blockSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);
3031 const UINT_32 blockSize = 1 << blockSizeLog2;
3032
3033 pOut->pitch = PowTwoAlign(pIn->width, pOut->blockWidth);
3034 pOut->height = PowTwoAlign(pIn->height, heightAlign);
3035 pOut->numSlices = PowTwoAlign(pIn->numSlices, pOut->blockSlices);
3036 pOut->baseAlign = blockSize;
3037
3038 if (pIn->numMipLevels > 1)
3039 {
3040 const Dim3d tailMaxDim = GetMipTailDim(pIn->resourceType,
3041 pIn->swizzleMode,
3042 pOut->blockWidth,
3043 pOut->blockHeight,
3044 pOut->blockSlices);
3045 const UINT_32 mip0Width = pIn->width;
3046 const UINT_32 mip0Height = pIn->height;
3047 const BOOL_32 isThin = IsThin(pIn->resourceType, pIn->swizzleMode);
3048 const UINT_32 mip0Depth = isThin ? 1 : pIn->numSlices;
3049 const UINT_32 maxMipsInTail = GetMaxNumMipsInTail(blockSizeLog2, isThin);
3050 const UINT_32 index = Log2(pIn->bpp >> 3);
3051 UINT_32 firstMipInTail = pIn->numMipLevels;
3052 UINT_64 mipChainSliceSize = 0;
3053 UINT_64 mipSize[MaxMipLevels];
3054 UINT_64 mipSliceSize[MaxMipLevels];
3055
3056 // For htile, we need to make z16 and stencil enter the mip tail at the same time as z32 would
3057 Dim3d fixedTailMaxDim = tailMaxDim;
3058 if (IsZOrderSwizzle(pIn->swizzleMode) && (index <= 1))
3059 {
3060 fixedTailMaxDim.w /= Block256_2d[index].w / Block256_2d[2].w;
3061 fixedTailMaxDim.h /= Block256_2d[index].w / Block256_2d[2].w;
3062 }
3063
3064 for (UINT_32 i = 0; i < pIn->numMipLevels; i++)
3065 {
3066 UINT_32 mipWidth, mipHeight, mipDepth;
3067
3068 GetMipSize(mip0Width, mip0Height, mip0Depth, i, &mipWidth, &mipHeight, &mipDepth);
3069
3070 if (IsInMipTail(fixedTailMaxDim, maxMipsInTail, mipWidth, mipHeight, pIn->numMipLevels - i))
3071 {
3072 firstMipInTail = i;
3073 mipChainSliceSize += blockSize / pOut->blockSlices;
3074 break;
3075 }
3076 else
3077 {
3078 const UINT_32 pitch = PowTwoAlign(mipWidth, pOut->blockWidth);
3079 const UINT_32 height = PowTwoAlign(mipHeight, pOut->blockHeight);
3080 const UINT_32 depth = PowTwoAlign(mipDepth, pOut->blockSlices);
3081 const UINT_64 sliceSize = static_cast<UINT_64>(pitch) * height * (pIn->bpp >> 3);
3082
3083 mipSize[i] = sliceSize * depth;
3084 mipSliceSize[i] = sliceSize * pOut->blockSlices;
3085 mipChainSliceSize += sliceSize;
3086
3087 if (pOut->pMipInfo != NULL)
3088 {
3089 pOut->pMipInfo[i].pitch = pitch;
3090 pOut->pMipInfo[i].height = height;
3091 pOut->pMipInfo[i].depth = depth;
3092 }
3093 }
3094 }
3095
3096 pOut->sliceSize = mipChainSliceSize;
3097 pOut->surfSize = mipChainSliceSize * pOut->numSlices;
3098 pOut->mipChainInTail = (firstMipInTail == 0) ? TRUE : FALSE;
3099 pOut->firstMipIdInTail = firstMipInTail;
3100
3101 if (pOut->pMipInfo != NULL)
3102 {
3103 UINT_64 offset = 0;
3104 UINT_64 macroBlkOffset = 0;
3105 UINT_32 tailMaxDepth = 0;
3106
3107 if (firstMipInTail != pIn->numMipLevels)
3108 {
3109 UINT_32 mipWidth, mipHeight;
3110
3111 GetMipSize(mip0Width, mip0Height, mip0Depth, firstMipInTail,
3112 &mipWidth, &mipHeight, &tailMaxDepth);
3113
3114 offset = blockSize * PowTwoAlign(tailMaxDepth, pOut->blockSlices) / pOut->blockSlices;
3115 macroBlkOffset = blockSize;
3116 }
3117
3118 for (INT_32 i = firstMipInTail - 1; i >= 0; i--)
3119 {
3120 pOut->pMipInfo[i].offset = offset;
3121 pOut->pMipInfo[i].macroBlockOffset = macroBlkOffset;
3122 pOut->pMipInfo[i].mipTailOffset = 0;
3123
3124 offset += mipSize[i];
3125 macroBlkOffset += mipSliceSize[i];
3126 }
3127
3128 UINT_32 pitch = tailMaxDim.w;
3129 UINT_32 height = tailMaxDim.h;
3130 UINT_32 depth = isThin ? 1 : PowTwoAlign(tailMaxDepth, Block256_3d[index].d);
3131
3132 tailMaxDepth = isThin ? 1 : (depth / Block256_3d[index].d);
3133
3134 for (UINT_32 i = firstMipInTail; i < pIn->numMipLevels; i++)
3135 {
3136 const UINT_32 m = maxMipsInTail - 1 - (i - firstMipInTail);
3137 const UINT_32 mipOffset = (m > 6) ? (16 << m) : (m << 8);
3138
3139 pOut->pMipInfo[i].offset = mipOffset * tailMaxDepth;
3140 pOut->pMipInfo[i].mipTailOffset = mipOffset;
3141 pOut->pMipInfo[i].macroBlockOffset = 0;
3142
3143 pOut->pMipInfo[i].pitch = pitch;
3144 pOut->pMipInfo[i].height = height;
3145 pOut->pMipInfo[i].depth = depth;
3146
3147 UINT_32 mipX = ((mipOffset >> 9) & 1) |
3148 ((mipOffset >> 10) & 2) |
3149 ((mipOffset >> 11) & 4) |
3150 ((mipOffset >> 12) & 8) |
3151 ((mipOffset >> 13) & 16) |
3152 ((mipOffset >> 14) & 32);
3153 UINT_32 mipY = ((mipOffset >> 8) & 1) |
3154 ((mipOffset >> 9) & 2) |
3155 ((mipOffset >> 10) & 4) |
3156 ((mipOffset >> 11) & 8) |
3157 ((mipOffset >> 12) & 16) |
3158 ((mipOffset >> 13) & 32);
3159
3160 if (blockSizeLog2 & 1)
3161 {
3162 const UINT_32 temp = mipX;
3163 mipX = mipY;
3164 mipY = temp;
3165
3166 if (index & 1)
3167 {
3168 mipY = (mipY << 1) | (mipX & 1);
3169 mipX = mipX >> 1;
3170 }
3171 }
3172
3173 if (isThin)
3174 {
3175 pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_2d[index].w;
3176 pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_2d[index].h;
3177 pOut->pMipInfo[i].mipTailCoordZ = 0;
3178
3179 pitch = Max(pitch >> 1, Block256_2d[index].w);
3180 height = Max(height >> 1, Block256_2d[index].h);
3181 depth = 1;
3182 }
3183 else
3184 {
3185 pOut->pMipInfo[i].mipTailCoordX = mipX * Block256_3d[index].w;
3186 pOut->pMipInfo[i].mipTailCoordY = mipY * Block256_3d[index].h;
3187 pOut->pMipInfo[i].mipTailCoordZ = 0;
3188
3189 pitch = Max(pitch >> 1, Block256_3d[index].w);
3190 height = Max(height >> 1, Block256_3d[index].h);
3191 depth = PowTwoAlign(Max(depth >> 1, 1u), Block256_3d[index].d);
3192 }
3193 }
3194 }
3195 }
3196 else
3197 {
3198 pOut->sliceSize = static_cast<UINT_64>(pOut->pitch) * pOut->height * (pIn->bpp >> 3) * pIn->numSamples;
3199 pOut->surfSize = pOut->sliceSize * pOut->numSlices;
3200
3201 if (pOut->pMipInfo != NULL)
3202 {
3203 pOut->pMipInfo[0].pitch = pOut->pitch;
3204 pOut->pMipInfo[0].height = pOut->height;
3205 pOut->pMipInfo[0].depth = IsTex3d(pIn->resourceType)? pOut->numSlices : 1;
3206 pOut->pMipInfo[0].offset = 0;
3207 pOut->pMipInfo[0].mipTailOffset = 0;
3208 pOut->pMipInfo[0].macroBlockOffset = 0;
3209 pOut->pMipInfo[0].mipTailCoordX = 0;
3210 pOut->pMipInfo[0].mipTailCoordY = 0;
3211 pOut->pMipInfo[0].mipTailCoordZ = 0;
3212 }
3213 }
3214 }
3215 }
3216
3217 return returnCode;
3218 }
3219
3220 /**
3221 ************************************************************************************************************************
3222 * Gfx11Lib::HwlComputeSurfaceAddrFromCoordTiled
3223 *
3224 * @brief
3225 * Internal function to calculate address from coord for tiled swizzle surface
3226 *
3227 * @return
3228 * ADDR_E_RETURNCODE
3229 ************************************************************************************************************************
3230 */
HwlComputeSurfaceAddrFromCoordTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const3231 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceAddrFromCoordTiled(
3232 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3233 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3234 ) const
3235 {
3236 ADDR_E_RETURNCODE ret;
3237
3238 if (IsBlock256b(pIn->swizzleMode))
3239 {
3240 ret = ComputeSurfaceAddrFromCoordMicroTiled(pIn, pOut);
3241 }
3242 else
3243 {
3244 ret = ComputeSurfaceAddrFromCoordMacroTiled(pIn, pOut);
3245 }
3246
3247 return ret;
3248 }
3249
3250 /**
3251 ************************************************************************************************************************
3252 * Gfx11Lib::ComputeOffsetFromEquation
3253 *
3254 * @brief
3255 * Compute offset from equation
3256 *
3257 * @return
3258 * Offset
3259 ************************************************************************************************************************
3260 */
ComputeOffsetFromEquation(const ADDR_EQUATION * pEq,UINT_32 x,UINT_32 y,UINT_32 z) const3261 UINT_32 Gfx11Lib::ComputeOffsetFromEquation(
3262 const ADDR_EQUATION* pEq, ///< Equation
3263 UINT_32 x, ///< x coord in bytes
3264 UINT_32 y, ///< y coord in pixel
3265 UINT_32 z ///< z coord in slice
3266 ) const
3267 {
3268 UINT_32 offset = 0;
3269
3270 for (UINT_32 i = 0; i < pEq->numBits; i++)
3271 {
3272 UINT_32 v = 0;
3273
3274 for (UINT_32 c = 0; c < pEq->numBitComponents; c++)
3275 {
3276 if (pEq->comps[c][i].valid)
3277 {
3278 if (pEq->comps[c][i].channel == 0)
3279 {
3280 v ^= (x >> pEq->comps[c][i].index) & 1;
3281 }
3282 else if (pEq->comps[c][i].channel == 1)
3283 {
3284 v ^= (y >> pEq->comps[c][i].index) & 1;
3285 }
3286 else
3287 {
3288 ADDR_ASSERT(pEq->comps[c][i].channel == 2);
3289 v ^= (z >> pEq->comps[c][i].index) & 1;
3290 }
3291 }
3292 }
3293
3294 offset |= (v << i);
3295 }
3296
3297 return offset;
3298 }
3299
3300 /**
3301 ************************************************************************************************************************
3302 * Gfx11Lib::ComputeOffsetFromSwizzlePattern
3303 *
3304 * @brief
3305 * Compute offset from swizzle pattern
3306 *
3307 * @return
3308 * Offset
3309 ************************************************************************************************************************
3310 */
ComputeOffsetFromSwizzlePattern(const UINT_64 * pPattern,UINT_32 numBits,UINT_32 x,UINT_32 y,UINT_32 z,UINT_32 s) const3311 UINT_32 Gfx11Lib::ComputeOffsetFromSwizzlePattern(
3312 const UINT_64* pPattern, ///< Swizzle pattern
3313 UINT_32 numBits, ///< Number of bits in pattern
3314 UINT_32 x, ///< x coord in pixel
3315 UINT_32 y, ///< y coord in pixel
3316 UINT_32 z, ///< z coord in slice
3317 UINT_32 s ///< sample id
3318 ) const
3319 {
3320 UINT_32 offset = 0;
3321 const ADDR_BIT_SETTING* pSwizzlePattern = reinterpret_cast<const ADDR_BIT_SETTING*>(pPattern);
3322
3323 for (UINT_32 i = 0; i < numBits; i++)
3324 {
3325 UINT_32 v = 0;
3326
3327 if (pSwizzlePattern[i].x != 0)
3328 {
3329 UINT_16 mask = pSwizzlePattern[i].x;
3330 UINT_32 xBits = x;
3331
3332 while (mask != 0)
3333 {
3334 if (mask & 1)
3335 {
3336 v ^= xBits & 1;
3337 }
3338
3339 xBits >>= 1;
3340 mask >>= 1;
3341 }
3342 }
3343
3344 if (pSwizzlePattern[i].y != 0)
3345 {
3346 UINT_16 mask = pSwizzlePattern[i].y;
3347 UINT_32 yBits = y;
3348
3349 while (mask != 0)
3350 {
3351 if (mask & 1)
3352 {
3353 v ^= yBits & 1;
3354 }
3355
3356 yBits >>= 1;
3357 mask >>= 1;
3358 }
3359 }
3360
3361 if (pSwizzlePattern[i].z != 0)
3362 {
3363 UINT_16 mask = pSwizzlePattern[i].z;
3364 UINT_32 zBits = z;
3365
3366 while (mask != 0)
3367 {
3368 if (mask & 1)
3369 {
3370 v ^= zBits & 1;
3371 }
3372
3373 zBits >>= 1;
3374 mask >>= 1;
3375 }
3376 }
3377
3378 if (pSwizzlePattern[i].s != 0)
3379 {
3380 UINT_16 mask = pSwizzlePattern[i].s;
3381 UINT_32 sBits = s;
3382
3383 while (mask != 0)
3384 {
3385 if (mask & 1)
3386 {
3387 v ^= sBits & 1;
3388 }
3389
3390 sBits >>= 1;
3391 mask >>= 1;
3392 }
3393 }
3394
3395 offset |= (v << i);
3396 }
3397
3398 return offset;
3399 }
3400
3401 /**
3402 ************************************************************************************************************************
3403 * Gfx11Lib::GetSwizzlePatternInfo
3404 *
3405 * @brief
3406 * Get swizzle pattern
3407 *
3408 * @return
3409 * Swizzle pattern information
3410 ************************************************************************************************************************
3411 */
GetSwizzlePatternInfo(AddrSwizzleMode swizzleMode,AddrResourceType resourceType,UINT_32 elemLog2,UINT_32 numFrag) const3412 const ADDR_SW_PATINFO* Gfx11Lib::GetSwizzlePatternInfo(
3413 AddrSwizzleMode swizzleMode, ///< Swizzle mode
3414 AddrResourceType resourceType, ///< Resource type
3415 UINT_32 elemLog2, ///< Element size in bytes log2
3416 UINT_32 numFrag ///< Number of fragment
3417 ) const
3418 {
3419 const UINT_32 index = IsXor(swizzleMode) ? (m_colorBaseIndex + elemLog2) : elemLog2;
3420 const ADDR_SW_PATINFO* patInfo = NULL;
3421 const UINT_32 swizzleMask = 1 << swizzleMode;
3422 const BOOL_32 isBlock256k = IsBlock256kb(swizzleMode);
3423 const BOOL_32 isBlock64K = IsBlock64kb(swizzleMode);
3424
3425 if (IsLinear(swizzleMode) == FALSE)
3426 {
3427 if (resourceType == ADDR_RSRC_TEX_3D)
3428 {
3429 ADDR_ASSERT(numFrag == 1);
3430
3431 if ((swizzleMask & Gfx11Rsrc3dSwModeMask) != 0)
3432 {
3433 if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
3434 {
3435 if (isBlock256k)
3436 {
3437 ADDR_ASSERT((swizzleMode == ADDR_SW_256KB_Z_X) || (swizzleMode == ADDR_SW_256KB_R_X));
3438 patInfo = GFX11_SW_256K_ZR_X_1xaa_PATINFO;
3439 }
3440 else if (isBlock64K)
3441 {
3442 ADDR_ASSERT((swizzleMode == ADDR_SW_64KB_Z_X) || (swizzleMode == ADDR_SW_64KB_R_X));
3443 patInfo = GFX11_SW_64K_ZR_X_1xaa_PATINFO;
3444 }
3445 else
3446 {
3447 ADDR_ASSERT_ALWAYS();
3448 }
3449 }
3450 else if (IsDisplaySwizzle(resourceType, swizzleMode))
3451 {
3452 if (isBlock256k)
3453 {
3454 ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_D_X);
3455 // patInfo = GFX11_SW_256K_D3_X_PATINFO;
3456 }
3457 else if (isBlock64K)
3458 {
3459 ADDR_ASSERT(swizzleMode == ADDR_SW_64KB_D_X);
3460 patInfo = GFX11_SW_64K_D3_X_PATINFO;
3461 }
3462 else
3463 {
3464 ADDR_ASSERT_ALWAYS();
3465 }
3466 }
3467 else
3468 {
3469 ADDR_ASSERT(IsStandardSwizzle(resourceType, swizzleMode));
3470
3471 if (isBlock256k)
3472 {
3473 ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_S_X);
3474 patInfo = GFX11_SW_256K_S3_X_PATINFO;
3475 }
3476 else if (isBlock64K)
3477 {
3478 if (swizzleMode == ADDR_SW_64KB_S)
3479 {
3480 patInfo = GFX11_SW_64K_S3_PATINFO;
3481 }
3482 else if (swizzleMode == ADDR_SW_64KB_S_X)
3483 {
3484 patInfo = GFX11_SW_64K_S3_X_PATINFO;
3485 }
3486 else if (swizzleMode == ADDR_SW_64KB_S_T)
3487 {
3488 patInfo = GFX11_SW_64K_S3_T_PATINFO;
3489 }
3490 else
3491 {
3492 ADDR_ASSERT_ALWAYS();
3493 }
3494 }
3495 else if (IsBlock4kb(swizzleMode))
3496 {
3497 if (swizzleMode == ADDR_SW_4KB_S)
3498 {
3499 patInfo = GFX11_SW_4K_S3_PATINFO;
3500 }
3501 else if (swizzleMode == ADDR_SW_4KB_S_X)
3502 {
3503 patInfo = GFX11_SW_4K_S3_X_PATINFO;
3504 }
3505 else
3506 {
3507 ADDR_ASSERT_ALWAYS();
3508 }
3509 }
3510 else
3511 {
3512 ADDR_ASSERT_ALWAYS();
3513 }
3514 }
3515 }
3516 }
3517 else
3518 {
3519 if ((swizzleMask & Gfx11Rsrc2dSwModeMask) != 0)
3520 {
3521 if (IsBlock256b(swizzleMode))
3522 {
3523 ADDR_ASSERT(swizzleMode == ADDR_SW_256B_D);
3524 patInfo = GFX11_SW_256_D_PATINFO;
3525 }
3526 else if (IsBlock4kb(swizzleMode))
3527 {
3528 if (swizzleMode == ADDR_SW_4KB_D)
3529 {
3530 patInfo = GFX11_SW_4K_D_PATINFO;
3531 }
3532 else if (swizzleMode == ADDR_SW_4KB_D_X)
3533 {
3534 patInfo = GFX11_SW_4K_D_X_PATINFO;
3535 }
3536 else
3537 {
3538 ADDR_ASSERT_ALWAYS();
3539 }
3540 }
3541 else if (isBlock64K)
3542 {
3543 if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
3544 {
3545 if (numFrag == 1)
3546 {
3547 patInfo = GFX11_SW_64K_ZR_X_1xaa_PATINFO;
3548 }
3549 else if (numFrag == 2)
3550 {
3551 patInfo = GFX11_SW_64K_ZR_X_2xaa_PATINFO;
3552 }
3553 else if (numFrag == 4)
3554 {
3555 patInfo = GFX11_SW_64K_ZR_X_4xaa_PATINFO;
3556 }
3557 else if (numFrag == 8)
3558 {
3559 patInfo = GFX11_SW_64K_ZR_X_8xaa_PATINFO;
3560 }
3561 else
3562 {
3563 ADDR_ASSERT_ALWAYS();
3564 }
3565 }
3566 else if (IsDisplaySwizzle(resourceType, swizzleMode))
3567 {
3568 if (swizzleMode == ADDR_SW_64KB_D)
3569 {
3570 patInfo = GFX11_SW_64K_D_PATINFO;
3571 }
3572 else if (swizzleMode == ADDR_SW_64KB_D_X)
3573 {
3574 patInfo = GFX11_SW_64K_D_X_PATINFO;
3575 }
3576 else if (swizzleMode == ADDR_SW_64KB_D_T)
3577 {
3578 patInfo = GFX11_SW_64K_D_T_PATINFO;
3579 }
3580 else
3581 {
3582 ADDR_ASSERT_ALWAYS();
3583 }
3584 }
3585 else
3586 {
3587 ADDR_ASSERT_ALWAYS();
3588 }
3589 }
3590 else if (isBlock256k)
3591 {
3592 if (IsZOrderSwizzle(swizzleMode) || IsRtOptSwizzle(swizzleMode))
3593 {
3594 if (numFrag == 1)
3595 {
3596 patInfo = GFX11_SW_256K_ZR_X_1xaa_PATINFO;
3597 }
3598 else if (numFrag == 2)
3599 {
3600 patInfo = GFX11_SW_256K_ZR_X_2xaa_PATINFO;
3601 }
3602 else if (numFrag == 4)
3603 {
3604 patInfo = GFX11_SW_256K_ZR_X_4xaa_PATINFO;
3605 }
3606 else if (numFrag == 8)
3607 {
3608 patInfo = GFX11_SW_256K_ZR_X_8xaa_PATINFO;
3609 }
3610 else
3611 {
3612 ADDR_ASSERT_ALWAYS();
3613 }
3614 }
3615 else if (IsDisplaySwizzle(resourceType, swizzleMode))
3616 {
3617 ADDR_ASSERT(swizzleMode == ADDR_SW_256KB_D_X);
3618 patInfo = GFX11_SW_256K_D_X_PATINFO;
3619 }
3620 else
3621 {
3622 ADDR_ASSERT_ALWAYS();
3623 }
3624 }
3625 else
3626 {
3627 ADDR_ASSERT_ALWAYS();
3628 }
3629 }
3630 }
3631 }
3632
3633 return (patInfo != NULL) ? &patInfo[index] : NULL;
3634 }
3635
3636 /**
3637 ************************************************************************************************************************
3638 * Gfx11Lib::ComputeSurfaceAddrFromCoordMicroTiled
3639 *
3640 * @brief
3641 * Internal function to calculate address from coord for micro tiled swizzle surface
3642 *
3643 * @return
3644 * ADDR_E_RETURNCODE
3645 ************************************************************************************************************************
3646 */
ComputeSurfaceAddrFromCoordMicroTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const3647 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceAddrFromCoordMicroTiled(
3648 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3649 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3650 ) const
3651 {
3652 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
3653 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
3654 ADDR2_MIP_INFO mipInfo[MaxMipLevels];
3655
3656 localIn.swizzleMode = pIn->swizzleMode;
3657 localIn.flags = pIn->flags;
3658 localIn.resourceType = pIn->resourceType;
3659 localIn.bpp = pIn->bpp;
3660 localIn.width = Max(pIn->unalignedWidth, 1u);
3661 localIn.height = Max(pIn->unalignedHeight, 1u);
3662 localIn.numSlices = Max(pIn->numSlices, 1u);
3663 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
3664 localIn.numSamples = Max(pIn->numSamples, 1u);
3665 localIn.numFrags = localIn.numSamples;
3666 localOut.pMipInfo = mipInfo;
3667
3668 ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMicroTiled(&localIn, &localOut);
3669
3670 if (ret == ADDR_OK)
3671 {
3672 const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
3673 const UINT_32 rsrcType = static_cast<UINT_32>(pIn->resourceType) - 1;
3674 const UINT_32 swMode = static_cast<UINT_32>(pIn->swizzleMode);
3675 const UINT_32 eqIndex = m_equationLookupTable[rsrcType][swMode][elemLog2];
3676
3677 if (eqIndex != ADDR_INVALID_EQUATION_INDEX)
3678 {
3679 const UINT_32 pb = mipInfo[pIn->mipId].pitch / localOut.blockWidth;
3680 const UINT_32 yb = pIn->y / localOut.blockHeight;
3681 const UINT_32 xb = pIn->x / localOut.blockWidth;
3682 const UINT_32 blockIndex = yb * pb + xb;
3683 const UINT_32 blockSize = 256;
3684 const UINT_32 blk256Offset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],
3685 pIn->x << elemLog2,
3686 pIn->y,
3687 0);
3688 pOut->addr = localOut.sliceSize * pIn->slice +
3689 mipInfo[pIn->mipId].macroBlockOffset +
3690 (blockIndex * blockSize) +
3691 blk256Offset;
3692 }
3693 else
3694 {
3695 ret = ADDR_INVALIDPARAMS;
3696 }
3697 }
3698
3699 return ret;
3700 }
3701
3702 /**
3703 ************************************************************************************************************************
3704 * Gfx11Lib::ComputeSurfaceAddrFromCoordMacroTiled
3705 *
3706 * @brief
3707 * Internal function to calculate address from coord for macro tiled swizzle surface
3708 *
3709 * @return
3710 * ADDR_E_RETURNCODE
3711 ************************************************************************************************************************
3712 */
ComputeSurfaceAddrFromCoordMacroTiled(const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut) const3713 ADDR_E_RETURNCODE Gfx11Lib::ComputeSurfaceAddrFromCoordMacroTiled(
3714 const ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, ///< [in] input structure
3715 ADDR2_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut ///< [out] output structure
3716 ) const
3717 {
3718 ADDR2_COMPUTE_SURFACE_INFO_INPUT localIn = {};
3719 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT localOut = {};
3720 ADDR2_MIP_INFO mipInfo[MaxMipLevels];
3721
3722 localIn.swizzleMode = pIn->swizzleMode;
3723 localIn.flags = pIn->flags;
3724 localIn.resourceType = pIn->resourceType;
3725 localIn.bpp = pIn->bpp;
3726 localIn.width = Max(pIn->unalignedWidth, 1u);
3727 localIn.height = Max(pIn->unalignedHeight, 1u);
3728 localIn.numSlices = Max(pIn->numSlices, 1u);
3729 localIn.numMipLevels = Max(pIn->numMipLevels, 1u);
3730 localIn.numSamples = Max(pIn->numSamples, 1u);
3731 localIn.numFrags = localIn.numSamples;
3732 localOut.pMipInfo = mipInfo;
3733
3734 ADDR_E_RETURNCODE ret = ComputeSurfaceInfoMacroTiled(&localIn, &localOut);
3735
3736 if (ret == ADDR_OK)
3737 {
3738 const UINT_32 elemLog2 = Log2(pIn->bpp >> 3);
3739 const UINT_32 blkSizeLog2 = GetBlockSizeLog2(pIn->swizzleMode);
3740 const UINT_32 blkMask = (1 << blkSizeLog2) - 1;
3741 const UINT_32 pipeMask = (1 << m_pipesLog2) - 1;
3742 const UINT_32 bankMask = ((1 << GetBankXorBits(blkSizeLog2)) - 1) << (m_pipesLog2 + ColumnBits);
3743 const UINT_32 pipeBankXor = IsXor(pIn->swizzleMode) ?
3744 (((pIn->pipeBankXor & (pipeMask | bankMask)) << m_pipeInterleaveLog2) & blkMask) : 0;
3745
3746 if (localIn.numSamples > 1)
3747 {
3748 const ADDR_SW_PATINFO* pPatInfo = GetSwizzlePatternInfo(pIn->swizzleMode,
3749 pIn->resourceType,
3750 elemLog2,
3751 localIn.numSamples);
3752
3753 if (pPatInfo != NULL)
3754 {
3755 const UINT_32 pb = localOut.pitch / localOut.blockWidth;
3756 const UINT_32 yb = pIn->y / localOut.blockHeight;
3757 const UINT_32 xb = pIn->x / localOut.blockWidth;
3758 const UINT_64 blkIdx = yb * pb + xb;
3759
3760 ADDR_BIT_SETTING fullSwizzlePattern[20];
3761 GetSwizzlePatternFromPatternInfo(pPatInfo, fullSwizzlePattern);
3762
3763 const UINT_32 blkOffset =
3764 ComputeOffsetFromSwizzlePattern(reinterpret_cast<const UINT_64*>(fullSwizzlePattern),
3765 blkSizeLog2,
3766 pIn->x,
3767 pIn->y,
3768 pIn->slice,
3769 pIn->sample);
3770
3771 pOut->addr = (localOut.sliceSize * pIn->slice) +
3772 (blkIdx << blkSizeLog2) +
3773 (blkOffset ^ pipeBankXor);
3774 }
3775 else
3776 {
3777 ret = ADDR_INVALIDPARAMS;
3778 }
3779 }
3780 else
3781 {
3782 const UINT_32 rsrcIdx = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? 1 : 0;
3783 const UINT_32 swMode = static_cast<UINT_32>(pIn->swizzleMode);
3784 const UINT_32 eqIndex = m_equationLookupTable[rsrcIdx][swMode][elemLog2];
3785
3786 if (eqIndex != ADDR_INVALID_EQUATION_INDEX)
3787 {
3788 const BOOL_32 inTail = (mipInfo[pIn->mipId].mipTailOffset != 0) ? TRUE : FALSE;
3789 const BOOL_32 isThin = IsThin(pIn->resourceType, pIn->swizzleMode);
3790 const UINT_64 sliceSize = isThin ? localOut.sliceSize : (localOut.sliceSize * localOut.blockSlices);
3791 const UINT_32 sliceId = isThin ? pIn->slice : (pIn->slice / localOut.blockSlices);
3792 const UINT_32 x = inTail ? (pIn->x + mipInfo[pIn->mipId].mipTailCoordX) : pIn->x;
3793 const UINT_32 y = inTail ? (pIn->y + mipInfo[pIn->mipId].mipTailCoordY) : pIn->y;
3794 const UINT_32 z = inTail ? (pIn->slice + mipInfo[pIn->mipId].mipTailCoordZ) : pIn->slice;
3795 const UINT_32 pb = mipInfo[pIn->mipId].pitch / localOut.blockWidth;
3796 const UINT_32 yb = pIn->y / localOut.blockHeight;
3797 const UINT_32 xb = pIn->x / localOut.blockWidth;
3798 const UINT_64 blkIdx = yb * pb + xb;
3799 const UINT_32 blkOffset = ComputeOffsetFromEquation(&m_equationTable[eqIndex],
3800 x << elemLog2,
3801 y,
3802 z);
3803 pOut->addr = sliceSize * sliceId +
3804 mipInfo[pIn->mipId].macroBlockOffset +
3805 (blkIdx << blkSizeLog2) +
3806 (blkOffset ^ pipeBankXor);
3807 }
3808 else
3809 {
3810 ret = ADDR_INVALIDPARAMS;
3811 }
3812 }
3813 }
3814
3815 return ret;
3816 }
3817
3818 /**
3819 ************************************************************************************************************************
3820 * Gfx11Lib::HwlComputeMaxBaseAlignments
3821 *
3822 * @brief
3823 * Gets maximum alignments
3824 * @return
3825 * maximum alignments
3826 ************************************************************************************************************************
3827 */
HwlComputeMaxBaseAlignments() const3828 UINT_32 Gfx11Lib::HwlComputeMaxBaseAlignments() const
3829 {
3830 return Size256K;
3831 }
3832
3833 /**
3834 ************************************************************************************************************************
3835 * Gfx11Lib::HwlComputeMaxMetaBaseAlignments
3836 *
3837 * @brief
3838 * Gets maximum alignments for metadata
3839 * @return
3840 * maximum alignments for metadata
3841 ************************************************************************************************************************
3842 */
HwlComputeMaxMetaBaseAlignments() const3843 UINT_32 Gfx11Lib::HwlComputeMaxMetaBaseAlignments() const
3844 {
3845 Dim3d metaBlk;
3846
3847 // Max base alignment for Htile
3848 const AddrSwizzleMode ValidSwizzleModeForHtile[] =
3849 {
3850 ADDR_SW_64KB_Z_X,
3851 ADDR_SW_256KB_Z_X,
3852 };
3853
3854 UINT_32 maxBaseAlignHtile = 0;
3855
3856 for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForHtile) / sizeof(ValidSwizzleModeForHtile[0]); swIdx++)
3857 {
3858 for (UINT_32 bppLog2 = 0; bppLog2 < 3; bppLog2++)
3859 {
3860 for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)
3861 {
3862 const UINT_32 metaBlkSizeHtile = GetMetaBlkSize(Gfx11DataDepthStencil,
3863 ADDR_RSRC_TEX_2D,
3864 ValidSwizzleModeForHtile[swIdx],
3865 bppLog2,
3866 numFragLog2,
3867 TRUE,
3868 &metaBlk);
3869
3870 maxBaseAlignHtile = Max(maxBaseAlignHtile, metaBlkSizeHtile);
3871 }
3872 }
3873 }
3874
3875 // Max base alignment for 2D Dcc
3876 // swizzle mode support DCC...
3877 const AddrSwizzleMode ValidSwizzleModeForDcc2D[] =
3878 {
3879 ADDR_SW_64KB_R_X,
3880 ADDR_SW_256KB_R_X,
3881 };
3882
3883 UINT_32 maxBaseAlignDcc2D = 0;
3884
3885 for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc2D) / sizeof(ValidSwizzleModeForDcc2D[0]); swIdx++)
3886 {
3887 for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)
3888 {
3889 for (UINT_32 numFragLog2 = 0; numFragLog2 < 4; numFragLog2++)
3890 {
3891 const UINT_32 metaBlkSize2D = GetMetaBlkSize(Gfx11DataColor,
3892 ADDR_RSRC_TEX_2D,
3893 ValidSwizzleModeForDcc2D[swIdx],
3894 bppLog2,
3895 numFragLog2,
3896 TRUE,
3897 &metaBlk);
3898
3899 maxBaseAlignDcc2D = Max(maxBaseAlignDcc2D, metaBlkSize2D);
3900 }
3901 }
3902 }
3903
3904 // Max base alignment for 3D Dcc
3905 const AddrSwizzleMode ValidSwizzleModeForDcc3D[] =
3906 {
3907 ADDR_SW_64KB_S_X,
3908 ADDR_SW_64KB_D_X,
3909 ADDR_SW_64KB_R_X,
3910 ADDR_SW_256KB_S_X,
3911 ADDR_SW_256KB_D_X,
3912 ADDR_SW_256KB_R_X,
3913 };
3914
3915 UINT_32 maxBaseAlignDcc3D = 0;
3916
3917 for (UINT_32 swIdx = 0; swIdx < sizeof(ValidSwizzleModeForDcc3D) / sizeof(ValidSwizzleModeForDcc3D[0]); swIdx++)
3918 {
3919 for (UINT_32 bppLog2 = 0; bppLog2 < MaxNumOfBpp; bppLog2++)
3920 {
3921 const UINT_32 metaBlkSize3D = GetMetaBlkSize(Gfx11DataColor,
3922 ADDR_RSRC_TEX_3D,
3923 ValidSwizzleModeForDcc3D[swIdx],
3924 bppLog2,
3925 0,
3926 TRUE,
3927 &metaBlk);
3928
3929 maxBaseAlignDcc3D = Max(maxBaseAlignDcc3D, metaBlkSize3D);
3930 }
3931 }
3932
3933 return Max(maxBaseAlignHtile, Max(maxBaseAlignDcc2D, maxBaseAlignDcc3D));
3934 }
3935
3936 /**
3937 ************************************************************************************************************************
3938 * Gfx11Lib::GetMetaElementSizeLog2
3939 *
3940 * @brief
3941 * Gets meta data element size log2
3942 * @return
3943 * Meta data element size log2
3944 ************************************************************************************************************************
3945 */
GetMetaElementSizeLog2(Gfx11DataType dataType)3946 INT_32 Gfx11Lib::GetMetaElementSizeLog2(
3947 Gfx11DataType dataType) ///< Data surface type
3948 {
3949 INT_32 elemSizeLog2 = 0;
3950
3951 if (dataType == Gfx11DataColor)
3952 {
3953 elemSizeLog2 = 0;
3954 }
3955 else
3956 {
3957 ADDR_ASSERT(dataType == Gfx11DataDepthStencil);
3958 elemSizeLog2 = 2;
3959 }
3960
3961 return elemSizeLog2;
3962 }
3963
3964 /**
3965 ************************************************************************************************************************
3966 * Gfx11Lib::GetMetaCacheSizeLog2
3967 *
3968 * @brief
3969 * Gets meta data cache line size log2
3970 * @return
3971 * Meta data cache line size log2
3972 ************************************************************************************************************************
3973 */
GetMetaCacheSizeLog2(Gfx11DataType dataType)3974 INT_32 Gfx11Lib::GetMetaCacheSizeLog2(
3975 Gfx11DataType dataType) ///< Data surface type
3976 {
3977 INT_32 cacheSizeLog2 = 0;
3978
3979 if (dataType == Gfx11DataColor)
3980 {
3981 cacheSizeLog2 = 6;
3982 }
3983 else
3984 {
3985 ADDR_ASSERT(dataType == Gfx11DataDepthStencil);
3986 cacheSizeLog2 = 8;
3987 }
3988
3989 return cacheSizeLog2;
3990 }
3991
3992 /**
3993 ************************************************************************************************************************
3994 * Gfx11Lib::HwlComputeSurfaceInfoLinear
3995 *
3996 * @brief
3997 * Internal function to calculate alignment for linear surface
3998 *
3999 * @return
4000 * ADDR_E_RETURNCODE
4001 ************************************************************************************************************************
4002 */
HwlComputeSurfaceInfoLinear(const ADDR2_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR2_COMPUTE_SURFACE_INFO_OUTPUT * pOut) const4003 ADDR_E_RETURNCODE Gfx11Lib::HwlComputeSurfaceInfoLinear(
4004 const ADDR2_COMPUTE_SURFACE_INFO_INPUT* pIn, ///< [in] input structure
4005 ADDR2_COMPUTE_SURFACE_INFO_OUTPUT* pOut ///< [out] output structure
4006 ) const
4007 {
4008 ADDR_E_RETURNCODE returnCode = ADDR_OK;
4009
4010 if (IsTex1d(pIn->resourceType) && (pIn->height > 1))
4011 {
4012 returnCode = ADDR_INVALIDPARAMS;
4013 }
4014 else
4015 {
4016 const UINT_32 elementBytes = pIn->bpp >> 3;
4017 const UINT_32 pitchAlign = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? 1 : (256 / elementBytes);
4018 const UINT_32 mipDepth = (pIn->resourceType == ADDR_RSRC_TEX_3D) ? pIn->numSlices : 1;
4019 UINT_32 pitch = PowTwoAlign(pIn->width, pitchAlign);
4020 UINT_32 actualHeight = pIn->height;
4021 UINT_64 sliceSize = 0;
4022
4023 if (pIn->numMipLevels > 1)
4024 {
4025 for (INT_32 i = static_cast<INT_32>(pIn->numMipLevels) - 1; i >= 0; i--)
4026 {
4027 UINT_32 mipWidth, mipHeight;
4028
4029 GetMipSize(pIn->width, pIn->height, 1, i, &mipWidth, &mipHeight);
4030
4031 const UINT_32 mipActualWidth = PowTwoAlign(mipWidth, pitchAlign);
4032
4033 if (pOut->pMipInfo != NULL)
4034 {
4035 pOut->pMipInfo[i].pitch = mipActualWidth;
4036 pOut->pMipInfo[i].height = mipHeight;
4037 pOut->pMipInfo[i].depth = mipDepth;
4038 pOut->pMipInfo[i].offset = sliceSize;
4039 pOut->pMipInfo[i].mipTailOffset = 0;
4040 pOut->pMipInfo[i].macroBlockOffset = sliceSize;
4041 }
4042
4043 sliceSize += static_cast<UINT_64>(mipActualWidth) * mipHeight * elementBytes;
4044 }
4045 }
4046 else
4047 {
4048 returnCode = ApplyCustomizedPitchHeight(pIn, elementBytes, pitchAlign, &pitch, &actualHeight);
4049
4050 if (returnCode == ADDR_OK)
4051 {
4052 sliceSize = static_cast<UINT_64>(pitch) * actualHeight * elementBytes;
4053
4054 if (pOut->pMipInfo != NULL)
4055 {
4056 pOut->pMipInfo[0].pitch = pitch;
4057 pOut->pMipInfo[0].height = actualHeight;
4058 pOut->pMipInfo[0].depth = mipDepth;
4059 pOut->pMipInfo[0].offset = 0;
4060 pOut->pMipInfo[0].mipTailOffset = 0;
4061 pOut->pMipInfo[0].macroBlockOffset = 0;
4062 }
4063 }
4064 }
4065
4066 if (returnCode == ADDR_OK)
4067 {
4068 pOut->pitch = pitch;
4069 pOut->height = actualHeight;
4070 pOut->numSlices = pIn->numSlices;
4071 pOut->sliceSize = sliceSize;
4072 pOut->surfSize = sliceSize * pOut->numSlices;
4073 pOut->baseAlign = (pIn->swizzleMode == ADDR_SW_LINEAR_GENERAL) ? elementBytes : 256;
4074 pOut->blockWidth = pitchAlign;
4075 pOut->blockHeight = 1;
4076 pOut->blockSlices = 1;
4077
4078 // Following members are useless on GFX11
4079 pOut->mipChainPitch = 0;
4080 pOut->mipChainHeight = 0;
4081 pOut->mipChainSlice = 0;
4082 pOut->epitchIsHeight = FALSE;
4083
4084 // Post calculation validate
4085 ADDR_ASSERT(pOut->sliceSize > 0);
4086 }
4087 }
4088
4089 return returnCode;
4090 }
4091
4092 } // V2
4093 } // Addr
4094