1 /* 2 ************************************************************************************************************************ 3 * 4 * Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. 5 * SPDX-License-Identifier: MIT 6 * 7 ***********************************************************************************************************************/ 8 9 10 /** 11 ************************************************************************************************************************ 12 * @file addrlib3.h 13 * @brief Contains the Addr::V3::Lib class definition. 14 ************************************************************************************************************************ 15 */ 16 17 #ifndef __ADDR3_LIB3_H__ 18 #define __ADDR3_LIB3_H__ 19 20 #include "addrlib.h" 21 22 namespace Addr 23 { 24 namespace V3 25 { 26 27 constexpr UINT_32 Size256 = 256u; 28 constexpr UINT_32 Size4K = 4 * 1024; 29 constexpr UINT_32 Size64K = 64 * 1024; 30 constexpr UINT_32 Size256K = 256 * 1024; 31 32 struct ADDR3_COORD 33 { 34 INT_32 x; 35 INT_32 y; 36 INT_32 z; 37 }; 38 39 // The HW address library utilizes an "addr_params" structure that is GPU-specific; therefore, we use a "void" pointer 40 // here to allow the HWL's to interpret this pointer with the appropriate structure. 41 // To reduce the frequency of conversion between the "ADDR3_COMPUTE_SURFACE_INFO_INPUT" structure and the "addr_params" 42 // structure, we create this super-structure to tie the two structures together. 43 struct ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT 44 { 45 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pSurfInfo; 46 void* pvAddrParams; 47 }; 48 49 /** 50 ************************************************************************************************************************ 51 * @brief Bit setting for swizzle pattern 52 ************************************************************************************************************************ 53 */ 54 union ADDR_BIT_SETTING 55 { 56 struct 57 { 58 UINT_16 x; 59 UINT_16 y; 60 UINT_16 z; 61 UINT_16 s; 62 }; 63 UINT_64 value; 64 }; 65 66 /** 67 ************************************************************************************************************************ 68 * @brief Flags for SwizzleModeTable 69 ************************************************************************************************************************ 70 */ 71 union SwizzleModeFlags 72 { 73 struct 74 { 75 // Swizzle mode 76 UINT_32 isLinear : 1; // Linear 77 UINT_32 is2d : 1; // 2d mode 78 UINT_32 is3d : 1; // 3d mode 79 80 // Block size 81 UINT_32 is256b : 1; // Block size is 256B 82 UINT_32 is4kb : 1; // Block size is 4KB 83 UINT_32 is64kb : 1; // Block size is 64KB 84 UINT_32 is256kb : 1; // Block size is 256KB 85 86 UINT_32 reserved : 25; // Reserved bits 87 }; 88 89 UINT_32 u32All; 90 }; 91 92 const UINT_32 Log2Size256 = 8u; 93 94 const UINT_32 Log2Size256K = 18u; 95 96 /** 97 ************************************************************************************************************************ 98 * @brief Swizzle pattern information 99 ************************************************************************************************************************ 100 */ 101 // Accessed by index representing the logbase2 of (8bpp/16bpp/32bpp/64bpp/128bpp) 102 // contains the indices which map to 2D arrays SW_PATTERN_NIBBLE[1-4] which contain sections of an index equation. 103 struct ADDR_SW_PATINFO 104 { 105 UINT_8 nibble1Idx; 106 UINT_8 nibble2Idx; 107 UINT_8 nibble3Idx; 108 UINT_8 nibble4Idx; 109 }; 110 111 /** 112 ************************************************************************************************************************ 113 * InitBit 114 * 115 * @brief 116 * Initialize bit setting value via a return value 117 ************************************************************************************************************************ 118 */ 119 #define InitBit(c, index) (1ull << ((c << 4) + index)) 120 121 const UINT_64 X0 = InitBit(0, 0); 122 const UINT_64 X1 = InitBit(0, 1); 123 const UINT_64 X2 = InitBit(0, 2); 124 const UINT_64 X3 = InitBit(0, 3); 125 const UINT_64 X4 = InitBit(0, 4); 126 const UINT_64 X5 = InitBit(0, 5); 127 const UINT_64 X6 = InitBit(0, 6); 128 const UINT_64 X7 = InitBit(0, 7); 129 const UINT_64 X8 = InitBit(0, 8); 130 131 const UINT_64 Y0 = InitBit(1, 0); 132 const UINT_64 Y1 = InitBit(1, 1); 133 const UINT_64 Y2 = InitBit(1, 2); 134 const UINT_64 Y3 = InitBit(1, 3); 135 const UINT_64 Y4 = InitBit(1, 4); 136 const UINT_64 Y5 = InitBit(1, 5); 137 const UINT_64 Y6 = InitBit(1, 6); 138 const UINT_64 Y7 = InitBit(1, 7); 139 const UINT_64 Y8 = InitBit(1, 8); 140 141 const UINT_64 Z0 = InitBit(2, 0); 142 const UINT_64 Z1 = InitBit(2, 1); 143 const UINT_64 Z2 = InitBit(2, 2); 144 const UINT_64 Z3 = InitBit(2, 3); 145 const UINT_64 Z4 = InitBit(2, 4); 146 const UINT_64 Z5 = InitBit(2, 5); 147 148 const UINT_64 S0 = InitBit(3, 0); 149 const UINT_64 S1 = InitBit(3, 1); 150 const UINT_64 S2 = InitBit(3, 2); 151 152 /** 153 ************************************************************************************************************************ 154 * @brief Bit setting for swizzle pattern 155 ************************************************************************************************************************ 156 */ 157 158 /** 159 ************************************************************************************************************************ 160 * @brief This class contains asic independent address lib functionalities 161 ************************************************************************************************************************ 162 */ 163 class Lib : public Addr::Lib 164 { 165 public: 166 virtual ~Lib(); 167 168 static Lib* GetLib( 169 ADDR_HANDLE hLib); 170 171 // 172 // Interface stubs 173 // 174 175 // For data surface 176 ADDR_E_RETURNCODE ComputeSurfaceInfo( 177 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, 178 ADDR3_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; 179 180 ADDR_E_RETURNCODE GetPossibleSwizzleModes( 181 const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn, 182 ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT* pOut) const; 183 184 ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoord( 185 const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, 186 ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const; 187 188 // Misc 189 ADDR_E_RETURNCODE ComputePipeBankXor( 190 const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn, 191 ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT* pOut); 192 193 ADDR_E_RETURNCODE ComputeNonBlockCompressedView( 194 const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn, 195 ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT* pOut); 196 197 ADDR_E_RETURNCODE ComputeSubResourceOffsetForSwizzlePattern( 198 const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, 199 ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut); 200 201 ADDR_E_RETURNCODE ComputeSlicePipeBankXor( 202 const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, 203 ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut); 204 205 protected: 206 Lib(); // Constructor is protected 207 Lib(const Client* pClient); 208 209 UINT_32 m_pipesLog2; ///< Number of pipe per shader engine Log2 210 UINT_32 m_pipeInterleaveLog2; ///< Log2 of pipe interleave bytes 211 212 SwizzleModeFlags m_swizzleModeTable[ADDR3_MAX_TYPE]; ///< Swizzle mode table 213 214 // Number of unique MSAA sample rates (1/2/4/8) 215 static const UINT_32 MaxMsaaRateLog2 = 4; 216 // Max number of bpp (8bpp/16bpp/32bpp/64bpp/128bpp) 217 static const UINT_32 MaxElementBytesLog2 = 5; 218 219 // Number of equation entries in the table 220 UINT_32 m_numEquations; 221 222 // Swizzle equation lookup table according to swizzle mode, MSAA sample rate and bpp. This does not include linear. 223 UINT_32 m_equationLookupTable[ADDR3_MAX_TYPE - 1][MaxMsaaRateLog2][MaxElementBytesLog2]; 224 225 // Block dimension lookup table according to swizzle mode, MSAA sample rate and bpp. This includes linear. 226 ADDR_EXTENT3D m_blockDimensionTable[ADDR3_MAX_TYPE][MaxMsaaRateLog2][MaxElementBytesLog2]; 227 228 virtual ADDR_E_RETURNCODE HwlComputeStereoInfo( 229 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, 230 UINT_32* pAlignY, 231 UINT_32* pRightXor) const = 0; 232 SetEquationTableEntry(Addr3SwizzleMode swMode,UINT_32 msaaLog2,UINT_32 elementBytesLog2,UINT_32 value)233 void SetEquationTableEntry( 234 Addr3SwizzleMode swMode, 235 UINT_32 msaaLog2, 236 UINT_32 elementBytesLog2, 237 UINT_32 value) 238 { 239 // m_equationLookupTable doesn't include linear, so we must exclude linear when calling this function. 240 ADDR_ASSERT(swMode != ADDR3_LINEAR); 241 m_equationLookupTable[swMode - 1][msaaLog2][elementBytesLog2] = value; 242 } 243 GetEquationTableEntry(Addr3SwizzleMode swMode,UINT_32 msaaLog2,UINT_32 elementBytesLog2)244 const UINT_32 GetEquationTableEntry( 245 Addr3SwizzleMode swMode, 246 UINT_32 msaaLog2, 247 UINT_32 elementBytesLog2) const 248 { 249 UINT_32 res = ADDR_INVALID_EQUATION_INDEX; 250 // m_equationLookupTable doesn't include linear 251 if (swMode != ADDR3_LINEAR) 252 { 253 res = m_equationLookupTable[swMode - 1][msaaLog2][elementBytesLog2]; 254 } 255 256 return res; 257 } 258 GetBlockDimensionTableEntry(Addr3SwizzleMode swMode,UINT_32 msaaLog2,UINT_32 elementBytesLog2)259 const ADDR_EXTENT3D GetBlockDimensionTableEntry( 260 Addr3SwizzleMode swMode, 261 UINT_32 msaaLog2, 262 UINT_32 elementBytesLog2) const 263 { 264 return m_blockDimensionTable[swMode][msaaLog2][elementBytesLog2]; 265 } 266 Valid3DMipSliceIdConstraint(UINT_32 numSlices,UINT_32 mipId,UINT_32 slice)267 static BOOL_32 Valid3DMipSliceIdConstraint( 268 UINT_32 numSlices, 269 UINT_32 mipId, 270 UINT_32 slice) 271 { 272 return (Max((numSlices >> mipId), 1u) > slice); 273 } 274 275 UINT_32 GetBlockSize( 276 Addr3SwizzleMode swizzleMode, 277 BOOL_32 forPitch = FALSE) const; 278 279 UINT_32 GetBlockSizeLog2( 280 Addr3SwizzleMode swizzleMode, 281 BOOL_32 forPitch = FALSE) const; 282 IsValidSwMode(Addr3SwizzleMode swizzleMode)283 BOOL_32 IsValidSwMode(Addr3SwizzleMode swizzleMode) const 284 { 285 return (m_swizzleModeTable[swizzleMode].u32All != 0); 286 } 287 IsLinear(Addr3SwizzleMode swizzleMode)288 UINT_32 IsLinear(Addr3SwizzleMode swizzleMode) const 289 { 290 return m_swizzleModeTable[swizzleMode].isLinear; 291 } 292 293 // Checking block size IsBlock256b(Addr3SwizzleMode swizzleMode)294 BOOL_32 IsBlock256b(Addr3SwizzleMode swizzleMode) const 295 { 296 return m_swizzleModeTable[swizzleMode].is256b; 297 } 298 299 // Checking block size IsBlock4kb(Addr3SwizzleMode swizzleMode)300 BOOL_32 IsBlock4kb(Addr3SwizzleMode swizzleMode) const 301 { 302 return m_swizzleModeTable[swizzleMode].is4kb; 303 } 304 305 // Checking block size IsBlock64kb(Addr3SwizzleMode swizzleMode)306 BOOL_32 IsBlock64kb(Addr3SwizzleMode swizzleMode) const 307 { 308 return m_swizzleModeTable[swizzleMode].is64kb; 309 } 310 311 // Checking block size IsBlock256kb(Addr3SwizzleMode swizzleMode)312 BOOL_32 IsBlock256kb(Addr3SwizzleMode swizzleMode) const 313 { 314 return m_swizzleModeTable[swizzleMode].is256kb; 315 } 316 Is2dSwizzle(Addr3SwizzleMode swizzleMode)317 BOOL_32 Is2dSwizzle(Addr3SwizzleMode swizzleMode) const 318 { 319 return m_swizzleModeTable[swizzleMode].is2d; 320 } 321 Is3dSwizzle(Addr3SwizzleMode swizzleMode)322 BOOL_32 Is3dSwizzle(Addr3SwizzleMode swizzleMode) const 323 { 324 return m_swizzleModeTable[swizzleMode].is3d; 325 } 326 327 // miptail is applied to only larger block size (4kb, 64kb, 256kb), so there is no miptail in linear and 328 // 256b_2d addressing since they are both 256b block. SupportsMipTail(Addr3SwizzleMode swizzleMode)329 BOOL_32 SupportsMipTail(Addr3SwizzleMode swizzleMode) const 330 { 331 return GetBlockSize(swizzleMode) > 256u; 332 } 333 334 // The max alignment is tied to the swizzle mode and since the largest swizzle mode is 256kb, so the maximal 335 // alignment is also 256kb. HwlComputeMaxBaseAlignments()336 virtual UINT_32 HwlComputeMaxBaseAlignments() const { return Size256K; } 337 338 virtual ADDR_E_RETURNCODE HwlGetPossibleSwizzleModes( 339 const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn, 340 ADDR3_GET_POSSIBLE_SWIZZLE_MODE_OUTPUT* pOut) const = 0; 341 HwlInitGlobalParams(const ADDR_CREATE_INPUT * pCreateIn)342 virtual BOOL_32 HwlInitGlobalParams(const ADDR_CREATE_INPUT* pCreateIn) 343 { 344 ADDR_NOT_IMPLEMENTED(); 345 // Although GFX12 addressing should be consistent regardless of the configuration, we still need to 346 // call some initialization for member variables. 347 return TRUE; 348 } 349 HwlComputeMaxMetaBaseAlignments()350 virtual UINT_32 HwlComputeMaxMetaBaseAlignments() const { return 0; } 351 HwlComputeSurfaceInfo(const ADDR3_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR3_COMPUTE_SURFACE_INFO_OUTPUT * pOut)352 virtual ADDR_E_RETURNCODE HwlComputeSurfaceInfo( 353 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, 354 ADDR3_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const 355 { 356 ADDR_NOT_IMPLEMENTED(); 357 return ADDR_NOTSUPPORTED; 358 } 359 HwlComputePipeBankXor(const ADDR3_COMPUTE_PIPEBANKXOR_INPUT * pIn,ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT * pOut)360 virtual ADDR_E_RETURNCODE HwlComputePipeBankXor( 361 const ADDR3_COMPUTE_PIPEBANKXOR_INPUT* pIn, 362 ADDR3_COMPUTE_PIPEBANKXOR_OUTPUT* pOut) const 363 { 364 ADDR_NOT_IMPLEMENTED(); 365 return ADDR_NOTSUPPORTED; 366 } 367 368 VOID ComputeBlockDimensionForSurf( 369 const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, 370 ADDR_EXTENT3D* pExtent) const; 371 372 ADDR_EXTENT3D GetMipTailDim( 373 const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, 374 const ADDR_EXTENT3D& blockDims) const; 375 376 ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordLinear( 377 const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, 378 ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const; 379 380 virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordLinear( 381 const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, 382 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pSurfInfoIn, 383 ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const = 0; 384 385 ADDR_E_RETURNCODE ComputeSurfaceAddrFromCoordTiled( 386 const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, 387 ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const; 388 HwlComputeSurfaceAddrFromCoordTiled(const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT * pIn,ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT * pOut)389 virtual ADDR_E_RETURNCODE HwlComputeSurfaceAddrFromCoordTiled( 390 const ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_INPUT* pIn, 391 ADDR3_COMPUTE_SURFACE_ADDRFROMCOORD_OUTPUT* pOut) const 392 { 393 ADDR_NOT_IMPLEMENTED(); 394 return ADDR_NOTIMPLEMENTED; 395 } 396 HwlComputeNonBlockCompressedView(const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT * pIn,ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT * pOut)397 virtual ADDR_E_RETURNCODE HwlComputeNonBlockCompressedView( 398 const ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_INPUT* pIn, 399 ADDR3_COMPUTE_NONBLOCKCOMPRESSEDVIEW_OUTPUT* pOut) const 400 { 401 ADDR_NOT_IMPLEMENTED(); 402 return ADDR_NOTSUPPORTED; 403 } 404 HwlComputeSubResourceOffsetForSwizzlePattern(const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT * pIn,ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT * pOut)405 virtual VOID HwlComputeSubResourceOffsetForSwizzlePattern( 406 const ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_INPUT* pIn, 407 ADDR3_COMPUTE_SUBRESOURCE_OFFSET_FORSWIZZLEPATTERN_OUTPUT* pOut) const 408 { 409 ADDR_NOT_IMPLEMENTED(); 410 } 411 HwlComputeSlicePipeBankXor(const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT * pIn,ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT * pOut)412 virtual ADDR_E_RETURNCODE HwlComputeSlicePipeBankXor( 413 const ADDR3_COMPUTE_SLICE_PIPEBANKXOR_INPUT* pIn, 414 ADDR3_COMPUTE_SLICE_PIPEBANKXOR_OUTPUT* pOut) const 415 { 416 ADDR_NOT_IMPLEMENTED(); 417 return ADDR_NOTSUPPORTED; 418 } 419 HwlGetEquationIndex(const ADDR3_COMPUTE_SURFACE_INFO_INPUT * pIn)420 virtual UINT_32 HwlGetEquationIndex( 421 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn) const 422 { 423 ADDR_NOT_IMPLEMENTED(); 424 return ADDR_INVALID_EQUATION_INDEX; 425 } 426 SetEquationIndex(const ADDR3_COMPUTE_SURFACE_INFO_INPUT * pIn,ADDR3_COMPUTE_SURFACE_INFO_OUTPUT * pOut)427 void SetEquationIndex( 428 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, 429 ADDR3_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const 430 { 431 UINT_32 equationIdx = HwlGetEquationIndex(pIn); 432 433 if (pOut->pMipInfo != NULL) 434 { 435 for (UINT_32 i = 0; i < pIn->numMipLevels; i++) 436 { 437 pOut->pMipInfo[i].equationIndex = equationIdx; 438 } 439 } 440 } 441 442 ADDR_E_RETURNCODE ApplyCustomizedPitchHeight( 443 const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn, 444 ADDR3_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; 445 446 BOOL_32 UseCustomHeight(const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn) const; 447 BOOL_32 UseCustomPitch(const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn) const; 448 BOOL_32 CanTrimLinearPadding(const ADDR3_COMPUTE_SURFACE_INFO_INPUT* pIn) const; 449 450 virtual VOID HwlCalcBlockSize( 451 const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, 452 ADDR_EXTENT3D* pExtent) const = 0; 453 454 virtual ADDR_EXTENT3D HwlGetMipInTailMaxSize( 455 const ADDR3_COMPUTE_SURFACE_INFO_PARAMS_INPUT* pIn, 456 const ADDR_EXTENT3D& blockDims) const = 0; 457 458 virtual BOOL_32 HwlValidateNonSwModeParams(const ADDR3_GET_POSSIBLE_SWIZZLE_MODE_INPUT* pIn) const = 0; 459 460 private: 461 // Disallow the copy constructor 462 Lib(const Lib& a); 463 464 // Disallow the assignment operator 465 Lib& operator=(const Lib& a); 466 467 void Init(); 468 469 VOID ComputeQbStereoInfo(ADDR3_COMPUTE_SURFACE_INFO_OUTPUT* pOut) const; 470 }; 471 472 } // V3 473 } // Addr 474 475 #endif