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/////////////////////////////////////////////////////////////////////////////////////////////////// 52static const UINT_32 MicroTileWidth = 8; ///< Micro tile width, for 1D and 2D tiling 53static const UINT_32 MicroTileHeight = 8; ///< Micro tile height, for 1D and 2D tiling 54static const UINT_32 ThickTileThickness = 4; ///< Micro tile thickness, for THICK modes 55static const UINT_32 XThickTileThickness = 8; ///< Extra thick tiling thickness 56static const UINT_32 PowerSaveTileBytes = 64; ///< Nuber of bytes per tile for power save 64 57static const UINT_32 CmaskCacheBits = 1024; ///< Number of bits for CMASK cache 58static const UINT_32 CmaskElemBits = 4; ///< Number of bits for CMASK element 59static const UINT_32 HtileCacheBits = 16384; ///< Number of bits for HTILE cache 512*32 60 61static const UINT_32 MicroTilePixels = MicroTileWidth * MicroTileHeight; 62 63static const INT_32 TileIndexInvalid = TILEINDEX_INVALID; 64static const INT_32 TileIndexLinearGeneral = TILEINDEX_LINEAR_GENERAL; 65static 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*/ 82enum 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*/ 100enum 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*/ 120union 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*/ 262static 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*/ 285static 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*/ 300static 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*/ 315static 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*/ 334static 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*/ 353static 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*/ 368static 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*/ 383static 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*/ 398static 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*/ 413static 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*/ 444static 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*/ 472static 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*/ 511static 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*/ 529static 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*/ 547static 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