1 /* 2 * Copyright 2014 Advanced Micro Devices, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS 17 * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 * USE OR OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * The above copyright notice and this permission notice (including the 23 * next paragraph) shall be included in all copies or substantial portions 24 * of the Software. 25 */ 26 27 /** 28 *************************************************************************************************** 29 * @file addrcommon.h 30 * @brief Contains the helper function and constants 31 *************************************************************************************************** 32 */ 33 34 #ifndef __ADDR_COMMON_H__ 35 #define __ADDR_COMMON_H__ 36 37 #include "addrinterface.h" 38 39 40 // ADDR_LNX_KERNEL_BUILD is for internal build 41 // Moved from addrinterface.h so __KERNEL__ is not needed any more 42 #if ADDR_LNX_KERNEL_BUILD // || (defined(__GNUC__) && defined(__KERNEL__)) 43 #include "lnx_common_defs.h" // ported from cmmqs 44 #elif !defined(__APPLE__) 45 #include <stdlib.h> 46 #include <string.h> 47 #endif 48 49 /////////////////////////////////////////////////////////////////////////////////////////////////// 50 // Common constants 51 /////////////////////////////////////////////////////////////////////////////////////////////////// 52 static const UINT_32 MicroTileWidth = 8; ///< Micro tile width, for 1D and 2D tiling 53 static const UINT_32 MicroTileHeight = 8; ///< Micro tile height, for 1D and 2D tiling 54 static const UINT_32 ThickTileThickness = 4; ///< Micro tile thickness, for THICK modes 55 static const UINT_32 XThickTileThickness = 8; ///< Extra thick tiling thickness 56 static const UINT_32 PowerSaveTileBytes = 64; ///< Nuber of bytes per tile for power save 64 57 static const UINT_32 CmaskCacheBits = 1024; ///< Number of bits for CMASK cache 58 static const UINT_32 CmaskElemBits = 4; ///< Number of bits for CMASK element 59 static const UINT_32 HtileCacheBits = 16384; ///< Number of bits for HTILE cache 512*32 60 61 static const UINT_32 MicroTilePixels = MicroTileWidth * MicroTileHeight; 62 63 static const INT_32 TileIndexInvalid = TILEINDEX_INVALID; 64 static const INT_32 TileIndexLinearGeneral = TILEINDEX_LINEAR_GENERAL; 65 static const INT_32 TileIndexNoMacroIndex = -3; 66 67 /////////////////////////////////////////////////////////////////////////////////////////////////// 68 // Common macros 69 /////////////////////////////////////////////////////////////////////////////////////////////////// 70 #define BITS_PER_BYTE 8 71 #define BITS_TO_BYTES(x) ( ((x) + (BITS_PER_BYTE-1)) / BITS_PER_BYTE ) 72 #define BYTES_TO_BITS(x) ( (x) * BITS_PER_BYTE ) 73 74 /// Helper macros to select a single bit from an int (undefined later in section) 75 #define _BIT(v,b) (((v) >> (b) ) & 1) 76 77 /** 78 *************************************************************************************************** 79 * @brief Enums to identify AddrLib type 80 *************************************************************************************************** 81 */ 82 enum AddrLibClass 83 { 84 BASE_ADDRLIB = 0x0, 85 R600_ADDRLIB = 0x6, 86 R800_ADDRLIB = 0x8, 87 SI_ADDRLIB = 0xa, 88 CI_ADDRLIB = 0xb, 89 }; 90 91 /** 92 *************************************************************************************************** 93 * AddrChipFamily 94 * 95 * @brief 96 * Neutral enums that specifies chip family. 97 * 98 *************************************************************************************************** 99 */ 100 enum AddrChipFamily 101 { 102 ADDR_CHIP_FAMILY_IVLD, ///< Invalid family 103 ADDR_CHIP_FAMILY_R6XX, 104 ADDR_CHIP_FAMILY_R7XX, 105 ADDR_CHIP_FAMILY_R8XX, 106 ADDR_CHIP_FAMILY_NI, 107 ADDR_CHIP_FAMILY_SI, 108 ADDR_CHIP_FAMILY_CI, 109 ADDR_CHIP_FAMILY_VI, 110 }; 111 112 /** 113 *************************************************************************************************** 114 * ADDR_CONFIG_FLAGS 115 * 116 * @brief 117 * This structure is used to set addr configuration flags. 118 *************************************************************************************************** 119 */ 120 union ADDR_CONFIG_FLAGS 121 { 122 struct 123 { 124 /// Clients do not need to set these flags except forceLinearAligned. 125 /// There flags are set up by AddrLib inside thru AddrInitGlobalParamsFromRegister 126 UINT_32 optimalBankSwap : 1; ///< New bank tiling for RV770 only 127 UINT_32 noCubeMipSlicesPad : 1; ///< Disables faces padding for cubemap mipmaps 128 UINT_32 fillSizeFields : 1; ///< If clients fill size fields in all input and 129 /// output structure 130 UINT_32 ignoreTileInfo : 1; ///< Don't use tile info structure 131 UINT_32 useTileIndex : 1; ///< Make tileIndex field in input valid 132 UINT_32 useCombinedSwizzle : 1; ///< Use combined swizzle 133 UINT_32 checkLast2DLevel : 1; ///< Check the last 2D mip sub level 134 UINT_32 useHtileSliceAlign : 1; ///< Do htile single slice alignment 135 UINT_32 degradeBaseLevel : 1; ///< Degrade to 1D modes automatically for base level 136 UINT_32 allowLargeThickTile : 1; ///< Allow 64*thickness*bytesPerPixel > rowSize 137 UINT_32 reserved : 22; ///< Reserved bits for future use 138 }; 139 140 UINT_32 value; 141 }; 142 143 /////////////////////////////////////////////////////////////////////////////////////////////////// 144 // Platform specific debug break defines 145 /////////////////////////////////////////////////////////////////////////////////////////////////// 146 #if DEBUG 147 #if defined(__GNUC__) 148 #define ADDR_DBG_BREAK() 149 #elif defined(__APPLE__) 150 #define ADDR_DBG_BREAK() { IOPanic("");} 151 #else 152 #define ADDR_DBG_BREAK() { __debugbreak(); } 153 #endif 154 #else 155 #define ADDR_DBG_BREAK() 156 #endif 157 /////////////////////////////////////////////////////////////////////////////////////////////////// 158 159 /////////////////////////////////////////////////////////////////////////////////////////////////// 160 // Debug assertions used in AddrLib 161 /////////////////////////////////////////////////////////////////////////////////////////////////// 162 #if DEBUG 163 #define ADDR_ASSERT(__e) if ( !((__e) ? TRUE : FALSE)) { ADDR_DBG_BREAK(); } 164 #define ADDR_ASSERT_ALWAYS() ADDR_DBG_BREAK() 165 #define ADDR_UNHANDLED_CASE() ADDR_ASSERT(!"Unhandled case") 166 #define ADDR_NOT_IMPLEMENTED() ADDR_ASSERT(!"Not implemented"); 167 #else //DEBUG 168 #define ADDR_ASSERT(__e) 169 #define ADDR_ASSERT_ALWAYS() 170 #define ADDR_UNHANDLED_CASE() 171 #define ADDR_NOT_IMPLEMENTED() 172 #endif //DEBUG 173 /////////////////////////////////////////////////////////////////////////////////////////////////// 174 175 /////////////////////////////////////////////////////////////////////////////////////////////////// 176 // Debug print macro from legacy address library 177 /////////////////////////////////////////////////////////////////////////////////////////////////// 178 #if DEBUG 179 180 #define ADDR_PRNT(a) AddrObject::DebugPrint a 181 182 /// @brief Macro for reporting informational messages 183 /// @ingroup util 184 /// 185 /// This macro optionally prints an informational message to stdout. 186 /// The first parameter is a condition -- if it is true, nothing is done. 187 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments, 188 /// starting with a string. This is passed to printf() or an equivalent 189 /// in order to format the informational message. For example, 190 /// ADDR_INFO(0, ("test %d",3) ); prints out "test 3". 191 /// 192 #define ADDR_INFO(cond, a) \ 193 { if (!(cond)) { ADDR_PRNT(a); } } 194 195 196 /// @brief Macro for reporting error warning messages 197 /// @ingroup util 198 /// 199 /// This macro optionally prints an error warning message to stdout, 200 /// followed by the file name and line number where the macro was called. 201 /// The first parameter is a condition -- if it is true, nothing is done. 202 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments, 203 /// starting with a string. This is passed to printf() or an equivalent 204 /// in order to format the informational message. For example, 205 /// ADDR_WARN(0, ("test %d",3) ); prints out "test 3" followed by 206 /// a second line with the file name and line number. 207 /// 208 #define ADDR_WARN(cond, a) \ 209 { if (!(cond)) \ 210 { ADDR_PRNT(a); \ 211 ADDR_PRNT((" WARNING in file %s, line %d\n", __FILE__, __LINE__)); \ 212 } } 213 214 215 /// @brief Macro for reporting fatal error conditions 216 /// @ingroup util 217 /// 218 /// This macro optionally stops execution of the current routine 219 /// after printing an error warning message to stdout, 220 /// followed by the file name and line number where the macro was called. 221 /// The first parameter is a condition -- if it is true, nothing is done. 222 /// The second pararmeter MUST be a parenthesis-enclosed list of arguments, 223 /// starting with a string. This is passed to printf() or an equivalent 224 /// in order to format the informational message. For example, 225 /// ADDR_EXIT(0, ("test %d",3) ); prints out "test 3" followed by 226 /// a second line with the file name and line number, then stops execution. 227 /// 228 #define ADDR_EXIT(cond, a) \ 229 { if (!(cond)) \ 230 { ADDR_PRNT(a); ADDR_DBG_BREAK();\ 231 } } 232 233 #else // DEBUG 234 235 #define ADDRDPF 1 ? (void)0 : (void) 236 237 #define ADDR_PRNT(a) 238 239 #define ADDR_DBG_BREAK() 240 241 #define ADDR_INFO(cond, a) 242 243 #define ADDR_WARN(cond, a) 244 245 #define ADDR_EXIT(cond, a) 246 247 #endif // DEBUG 248 /////////////////////////////////////////////////////////////////////////////////////////////////// 249 250 /////////////////////////////////////////////////////////////////////////////////////////////////// 251 // Misc helper functions 252 //////////////////////////////////////////////////////////////////////////////////////////////////// 253 254 /** 255 *************************************************************************************************** 256 * AddrXorReduce 257 * 258 * @brief 259 * Xor the right-side numberOfBits bits of x. 260 *************************************************************************************************** 261 */ 262 static inline UINT_32 XorReduce( 263 UINT_32 x, 264 UINT_32 numberOfBits) 265 { 266 UINT_32 i; 267 UINT_32 result = x & 1; 268 269 for (i=1; i<numberOfBits; i++) 270 { 271 result ^= ((x>>i) & 1); 272 } 273 274 return result; 275 } 276 277 /** 278 *************************************************************************************************** 279 * IsPow2 280 * 281 * @brief 282 * Check if the size (UINT_32) is pow 2 283 *************************************************************************************************** 284 */ 285 static inline UINT_32 IsPow2( 286 UINT_32 dim) ///< [in] dimension of miplevel 287 { 288 ADDR_ASSERT(dim > 0); 289 return !(dim & (dim - 1)); 290 } 291 292 /** 293 *************************************************************************************************** 294 * IsPow2 295 * 296 * @brief 297 * Check if the size (UINT_64) is pow 2 298 *************************************************************************************************** 299 */ 300 static inline UINT_64 IsPow2( 301 UINT_64 dim) ///< [in] dimension of miplevel 302 { 303 ADDR_ASSERT(dim > 0); 304 return !(dim & (dim - 1)); 305 } 306 307 /** 308 *************************************************************************************************** 309 * ByteAlign 310 * 311 * @brief 312 * Align UINT_32 "x" to "align" alignment, "align" should be power of 2 313 *************************************************************************************************** 314 */ 315 static inline UINT_32 PowTwoAlign( 316 UINT_32 x, 317 UINT_32 align) 318 { 319 // 320 // Assert that x is a power of two. 321 // 322 ADDR_ASSERT(IsPow2(align)); 323 return (x + (align - 1)) & (~(align - 1)); 324 } 325 326 /** 327 *************************************************************************************************** 328 * ByteAlign 329 * 330 * @brief 331 * Align UINT_64 "x" to "align" alignment, "align" should be power of 2 332 *************************************************************************************************** 333 */ 334 static inline UINT_64 PowTwoAlign( 335 UINT_64 x, 336 UINT_64 align) 337 { 338 // 339 // Assert that x is a power of two. 340 // 341 ADDR_ASSERT(IsPow2(align)); 342 return (x + (align - 1)) & (~(align - 1)); 343 } 344 345 /** 346 *************************************************************************************************** 347 * Min 348 * 349 * @brief 350 * Get the min value between two unsigned values 351 *************************************************************************************************** 352 */ 353 static inline UINT_32 Min( 354 UINT_32 value1, 355 UINT_32 value2) 356 { 357 return ((value1 < (value2)) ? (value1) : value2); 358 } 359 360 /** 361 *************************************************************************************************** 362 * Min 363 * 364 * @brief 365 * Get the min value between two signed values 366 *************************************************************************************************** 367 */ 368 static inline INT_32 Min( 369 INT_32 value1, 370 INT_32 value2) 371 { 372 return ((value1 < (value2)) ? (value1) : value2); 373 } 374 375 /** 376 *************************************************************************************************** 377 * Max 378 * 379 * @brief 380 * Get the max value between two unsigned values 381 *************************************************************************************************** 382 */ 383 static inline UINT_32 Max( 384 UINT_32 value1, 385 UINT_32 value2) 386 { 387 return ((value1 > (value2)) ? (value1) : value2); 388 } 389 390 /** 391 *************************************************************************************************** 392 * Max 393 * 394 * @brief 395 * Get the max value between two signed values 396 *************************************************************************************************** 397 */ 398 static inline INT_32 Max( 399 INT_32 value1, 400 INT_32 value2) 401 { 402 return ((value1 > (value2)) ? (value1) : value2); 403 } 404 405 /** 406 *************************************************************************************************** 407 * NextPow2 408 * 409 * @brief 410 * Compute the mipmap's next level dim size 411 *************************************************************************************************** 412 */ 413 static inline UINT_32 NextPow2( 414 UINT_32 dim) ///< [in] dimension of miplevel 415 { 416 UINT_32 newDim; 417 418 newDim = 1; 419 420 if (dim > 0x7fffffff) 421 { 422 ADDR_ASSERT_ALWAYS(); 423 newDim = 0x80000000; 424 } 425 else 426 { 427 while (newDim < dim) 428 { 429 newDim <<= 1; 430 } 431 } 432 433 return newDim; 434 } 435 436 /** 437 *************************************************************************************************** 438 * Log2 439 * 440 * @brief 441 * Compute log of base 2 442 *************************************************************************************************** 443 */ 444 static inline UINT_32 Log2( 445 UINT_32 x) ///< [in] the value should calculate log based 2 446 { 447 UINT_32 y; 448 449 // 450 // Assert that x is a power of two. 451 // 452 ADDR_ASSERT(IsPow2(x)); 453 454 y = 0; 455 while (x > 1) 456 { 457 x >>= 1; 458 y++; 459 } 460 461 return y; 462 } 463 464 /** 465 *************************************************************************************************** 466 * QLog2 467 * 468 * @brief 469 * Compute log of base 2 quickly (<= 16) 470 *************************************************************************************************** 471 */ 472 static inline UINT_32 QLog2( 473 UINT_32 x) ///< [in] the value should calculate log based 2 474 { 475 ADDR_ASSERT(x <= 16); 476 477 UINT_32 y = 0; 478 479 switch (x) 480 { 481 case 1: 482 y = 0; 483 break; 484 case 2: 485 y = 1; 486 break; 487 case 4: 488 y = 2; 489 break; 490 case 8: 491 y = 3; 492 break; 493 case 16: 494 y = 4; 495 break; 496 default: 497 ADDR_ASSERT_ALWAYS(); 498 } 499 500 return y; 501 } 502 503 /** 504 *************************************************************************************************** 505 * SafeAssign 506 * 507 * @brief 508 * NULL pointer safe assignment 509 *************************************************************************************************** 510 */ 511 static inline VOID SafeAssign( 512 UINT_32* pLVal, ///< [in] Pointer to left val 513 UINT_32 rVal) ///< [in] Right value 514 { 515 if (pLVal) 516 { 517 *pLVal = rVal; 518 } 519 } 520 521 /** 522 *************************************************************************************************** 523 * SafeAssign 524 * 525 * @brief 526 * NULL pointer safe assignment for 64bit values 527 *************************************************************************************************** 528 */ 529 static inline VOID SafeAssign( 530 UINT_64* pLVal, ///< [in] Pointer to left val 531 UINT_64 rVal) ///< [in] Right value 532 { 533 if (pLVal) 534 { 535 *pLVal = rVal; 536 } 537 } 538 539 /** 540 *************************************************************************************************** 541 * SafeAssign 542 * 543 * @brief 544 * NULL pointer safe assignment for AddrTileMode 545 *************************************************************************************************** 546 */ 547 static inline VOID SafeAssign( 548 AddrTileMode* pLVal, ///< [in] Pointer to left val 549 AddrTileMode rVal) ///< [in] Right value 550 { 551 if (pLVal) 552 { 553 *pLVal = rVal; 554 } 555 } 556 557 #endif // __ADDR_COMMON_H__ 558 559