1 /*============================================================================== 2 Copyright(c) 2017 Intel Corporation 3 4 Permission is hereby granted, free of charge, to any person obtaining a 5 copy of this software and associated documentation files(the "Software"), 6 to deal in the Software without restriction, including without limitation 7 the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 and / or sell copies of the Software, and to permit persons to whom the 9 Software is furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included 12 in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 OTHER DEALINGS IN THE SOFTWARE. 21 ============================================================================*/ 22 23 #ifndef __GFXMACRO_H__ 24 #define __GFXMACRO_H__ 25 26 #include <limits.h> 27 #include <string.h> // for memcpy 28 #include <stdint.h> 29 30 // ### __GFXMACRO_ASSERT ###################################################### 31 // Since an "always-callable" GFX_ASSERT/etc. is no longer really in-place, 32 // this file will define its own assert statement... 33 #if DBG 34 #define __GFXMACRO_ASSERT(Expression) \ 35 { \ 36 if(!(Expression)) \ 37 { \ 38 __debugbreak(); \ 39 } \ 40 } // __GFXMACRO_ASSERT ################## 41 #else // Release Build 42 #define __GFXMACRO_ASSERT(Expression) 43 #endif 44 45 46 //------------------------------------------------------------------------ 47 // Useful constants. 48 49 #define GFX_ZERO (0.0f) 50 #define GFX_HALF (0.5f) 51 #define GFX_PI ((float) 3.14159265358979323846) 52 #define GFX_SQR_ROOT_OF_TWO ((float) 1.41421356237309504880) 53 #define GFX_E ((float) 2.7182818284590452354) 54 55 //------------------------------------------------------------------------ 56 57 // !!! Many of these are macros (instead of functions) so 64-bit friendly (even on 32-bit builds)!!! 58 59 #define GFX_IS_ALIGNED(A, B) (((B) > 0) && (((A) % (B)) == 0)) 60 #define GFX_ALIGN(x, a) (((x) + ((a) - 1)) - (((x) + ((a) - 1)) & ((a) - 1))) // Alt implementation with bitwise not (~) has issue with uint32 align used with 64-bit value, since ~'ed value will remain 32-bit. 61 #define GFX_ALIGN_FLOOR(x, a) ((x) - ((x) & ((a) - 1))) 62 63 #define GFX_ALIGN_NP2(x, a) (((a) > 0) ? ((x) + (((a) - 1) - (((x) + ((a) - 1)) % (a)))) : (x)) 64 #define GFX_ALIGN_FLOOR_NP2(x, a) (((a) > 0) ? ((x) - ((x) % (a))) : (x)) 65 66 #define GFX_MASK(lo,hi) ((1UL << (hi)) | \ 67 ((1UL << (hi)) - \ 68 (1UL << (lo)))) 69 70 #define GFX_MASK_LARGE(lo,hi) (((uint64_t)1 << (hi)) | \ 71 (((uint64_t)1 << (hi)) - \ 72 ((uint64_t)1 << (lo)))) 73 74 #define GFX_IS_POWER_OF_2(a) (((a) > 0) && !((a) & ((a) - 1))) 75 76 #define GFX_SWAP_VAR(a,b,t) (t=a, a=b, b=t) 77 #define GFX_SWAP_VAR3(a,b,c,t) (t=a, a=b, b=c, c=t) 78 79 #define GFX_UF_ROUND(a) ((uint32_t) ((a) + 0.5F)) 80 #define GFX_F_ROUND(a) ((int32_t) ((a) + ((a) < 0 ? -0.5F : 0.5F))) 81 #define GFX_ABS(a) (((a) < 0) ? -(a) : (a)) 82 83 #define GFX_MIN(a,b) (((a) < (b)) ? (a) : (b)) 84 #define GFX_MAX(a,b) (((a) > (b)) ? (a) : (b)) 85 86 #define GFX_MIN3(a,b,c) (((a) < (b)) ? GFX_MIN((a), (c)) : GFX_MIN((b), (c))) 87 #define GFX_MAX3(a,b,c) (((a) > (b)) ? GFX_MAX((a), (c)) : GFX_MAX((b), (c))) 88 89 #define GFX_CEIL_DIV(a,b) (((b) > 0) ? (((a) + ((b) - 1)) / (b)) : (a)) 90 91 #define GFX_SQ(a) ((a) * (a)) 92 93 #define GFX_CLAMP_MIN_MAX(a,min,max) ((a) < (min) ? (min) : GFX_MIN ((a), (max))) 94 95 #define GFX_KB(k) ((k) * 1024) 96 #define GFX_MB(m) ((m) * 1024 * 1024) 97 98 //------------ Macros for setting and removing bits. 99 100 #define GFX_BIT(n) (1UL << (n)) 101 #define GFX_BIT_ON(a,bit) ((a) |= (bit)) 102 #define GFX_BIT_OFF(a,bit) ((a) &= ~(bit)) 103 #define GFX_IS_BIT_SET(a,bit) ((a) & (bit)) 104 105 //***************************************************************************** 106 // MACRO: GFX_BIT_RANGE 107 // PURPOSE: Calculates the number of bits between the startbit and the endbit 108 // and count is inclusive of both bits. The bits are 0 based. 109 //***************************************************************************** 110 #define GFX_BIT_RANGE(endbit, startbit) ((endbit)-(startbit)+1) 111 112 //------------ Macros for dealing with void pointers 113 114 #define GFX_VOID_PTR_INC(p,n) ((void *) ((char *)(p) + (n))) 115 #define GFX_VOID_PTR_DEC(p,n) ((void *) ((char *)(p) - (n))) 116 117 // While the difference of two pointers on a 64-bit machine can exceed 118 // 32-bits, it is mostly limited to 32-bits for the graphics driver. In 119 // order to avoid compilation warnings arising from assigning a 64-bit 120 // quantity to a 32-bit lvalue, we have two separate macros for obtaining 121 // pointer difference of two pointers. 122 123 #define GFX_VOID_PTR_DIFF(a,b) (int32_t) ((char *) (a) - (char *) (b)) 124 #define GFX_VOID_PTR_DIFF_LARGE(a,b) ((char *) (a) - (char *) (b)) 125 126 //------------ Bytes to page conversion 127 128 #define GFX_BYTES_TO_PAGES(b) (((b) + PAGE_SIZE - 1) / PAGE_SIZE) 129 #define GFX_PAGES_TO_BYTES(p) ((p) * PAGE_SIZE) 130 131 #define GFX_MEMSET(p,d,s) (memset(p, d, s)) 132 133 #if DBG 134 #define GFX_ULONG_CAST(x) \ 135 ( \ 136 ((x) <= 0xffffffff) ? \ 137 1 : __debugbreak(), \ 138 (uint32_t)(x) \ 139 ) 140 #else // Release Build 141 #define GFX_ULONG_CAST(x) ((uint32_t)(x)) 142 #endif 143 144 // Since hardware addresses are still 32 bits, we need a safe way 145 // to convert 64 bit pointers into 32 bit hardware addresses. 146 // ASSERT that the upper 32 bits are 0 before truncating address. 147 #define GFX_VOID_PTR_TO_ULONG(ptr) ((uint32_t)(ptr)) 148 149 150 //------------------------------------------------------------------------ 151 // FAST FLOAT-TO_LONG CONVERSION 152 // 153 // We can convert floats to integers quickly by adding a floating-point 154 // constant to an IEEE float so that the integer value of the IEEE float is 155 // found in the least significant bits of the sum. We add 2^23 + 2^22, and 156 // thus the number is represented in IEEE single-precision as 157 // 2^23*(1.1xxxxxxx), where the first 1 is the implied one, the second is 1 . 158 // 159 // This technique has several limitations: 160 // 1. It only works on values in the range [0,2^22-1]. 161 // 2. It is subject to the processor rounding mode, which we assume to be 162 // "round to nearest (even)". In this rounding mode, the conversion 163 // yields round(x), not floor(x) as called for in C. 164 // 165 // It can be made to work on negative values with a little fixed point 166 // trickery by: 167 // result = ((LONG) (result ^ 0x00800000) << 8) >> 8, 168 // 169 // However, when the result is masked to a byte or a short and directly 170 // assigned to the right type, no sign extension is required. 171 // 172 // The macros for -ve numbers since we use a constant of "1100" in binary 173 // representation. The msb 1 is force it to be the implicit bit. The next 174 // 1 is used for -ve numbers which will force other bits to be FFF.. 175 // 176 // which flips and then smears the sign bit into the rest of the number. The 177 // intermediate values must be signed, so we do an arithmetic (fill with sign 178 // bit) instead of logical shift. 179 // 180 // We approximate the floor operation by subtracting off 0.5 before doing the 181 // round. This would work perfectly except that the processor breaks ties in 182 // rounding be selecting the even value. Thus, we compute floor(1.0) as 183 // round(0.5) = 0! Not good -- the caller must be careful to use 184 // __GL_FLOAT_TO_LONG_TRUNC only in cases where he can live with this 185 // behavior. 186 187 #define GFX_FLOAT_TO_LONG_ROUND(ux,x,mask) \ 188 { \ 189 float fx; \ 190 \ 191 fx = x; \ 192 fx += 0x00C00000; \ 193 ux = mask & *(uint32_t *) &fx; \ 194 } 195 196 #define GFX_FLOAT_TO_LONG_TRUNC(ux,x,mask) \ 197 { \ 198 float fx; \ 199 \ 200 fx = x - GFX_HALF; \ 201 fx += 0x00C00000; \ 202 ux = mask & *(uint32_t *) &fx; \ 203 } 204 205 // Note: Double has 1 sign bit, 11 exponent and 52 mantissa bits. 206 // We need to add the following constant for fast conversion 207 // 208 // fx += (__LONG64) 0x18000000000000; 209 // 210 // This is done in a portable/decipherable manner through 211 // multiplications which are collapsed by the compiler at compile time. 212 213 #define GFX_DOUBLE_TO_LONG_ROUND(ux,x,mask) \ 214 { \ 215 double fx; \ 216 \ 217 fx = x; \ 218 fx += 24.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0 * 256; \ 219 ux = mask & *(uint32_t *) &fx; \ 220 } 221 222 #define GFX_DOUBLE_TO_LONG_TRUNC(ux,x,mask) \ 223 { \ 224 double fx; \ 225 \ 226 fx = x - GFX_HALF; \ 227 fx += 24.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0 * 256; \ 228 ux = mask & *(uint32_t *) &fx; \ 229 } 230 231 #if __DEFINE_PROTO || defined __GFX_MACRO_C__ 232 extern uint32_t GFX_LOG2 (uint32_t a); 233 extern uint32_t GFX_REAL_TO_UBYTE (float a); 234 extern int64_t GFX_POW2_SIZE (int64_t x); 235 extern uint32_t GFX_2_TO_POWER_OF (uint32_t w); 236 extern uint32_t GFX_MEMCPY_S(void *d, int dn, const void *s, int n); 237 extern void* GFX_MEMCPY_S_INC(void *d, int dn, const void *s, int n); 238 #endif // __DEFINE_PROTO 239 240 #ifndef __S_INLINE 241 #define __S_INLINE __inline 242 #endif 243 244 #if __DEFINE_MACRO || defined __GFX_MACRO_C__ 245 //------------------------------------------------------------------------ 246 GFX_LOG2(uint32_t a)247 __S_INLINE uint32_t GFX_LOG2 (uint32_t a) 248 { 249 long i = 1; 250 251 while ((a >> i) > 0) { 252 i++; 253 } 254 255 return (i - 1); 256 } 257 258 // Round-up to next power-of-2 GFX_POW2_SIZE(int64_t x)259 __S_INLINE int64_t GFX_POW2_SIZE (int64_t x) 260 { //-- Signed instead of unsigned since 64-bit is large enough that we don't need unsigned's range extension. 261 int64_t Pow2Size; 262 263 /* Algorithm: 264 If there are no bits lit beneath the highest bit lit (HBL), the value 265 is already a power-of-2 and needs no further rounding but if there are 266 additional bits lit beneath the highest, the next higher power-of-2 is 267 (1 << (HBL + 1)). To determine if there are bits lit beneath the HBL, 268 we will subtract 1 from the given value before scanning for the HBL, 269 and only if there are no lower bits lit will the subtraction reduce the 270 HBL but in both cases, (1 << (HBL + 1)) will then produce the 271 appropriately rounded-up (or not) power-of-2. 272 */ 273 274 if(x > 1) // <-- Since we bit-scan for (x - 1) and can't bit-scan zero. 275 { 276 #define MSB (sizeof(x) * CHAR_BIT - 1) 277 278 uint32_t HighBit; 279 280 { // HighBit = HighestBitLit(x - 1)... 281 #if defined(__GNUC__) || defined(__clang__) 282 { 283 HighBit = MSB - __builtin_clzll(x - 1); 284 } 285 #else // Windows 286 { 287 #ifdef __CT__ 288 { 289 _BitScanReverse64((DWORD *)&HighBit, x - 1); 290 } 291 #else // Break into separate Upper/Lower scans... 292 { 293 #define UDW_1 ((int64_t) _UI32_MAX + 1) // <-- UpperDW Value of 1 (i.e. 0x00000001`00000000). 294 295 if(x < UDW_1) 296 { 297 _BitScanReverse((DWORD *)&HighBit, GFX_ULONG_CAST(x - 1)); 298 } 299 else if(x > UDW_1) 300 { 301 _BitScanReverse((DWORD *)&HighBit, GFX_ULONG_CAST((x - 1) >> 32)); 302 HighBit += 32; 303 } 304 else 305 { 306 HighBit = 31; 307 } 308 309 #undef UDW_1 310 } 311 #endif 312 } 313 #endif 314 } 315 316 if(HighBit < (MSB - 1)) // <-- -1 since operating on signed type. 317 { 318 Pow2Size = (int64_t) 1 << (HighBit + 1); 319 } 320 else 321 { 322 __GFXMACRO_ASSERT(0); // Overflow! 323 Pow2Size = 0; 324 } 325 326 #undef MSB 327 } 328 else 329 { 330 Pow2Size = 1; 331 } 332 333 return(Pow2Size); 334 } // GFX_POW2_SIZE 335 336 // Find 2 to the power of w GFX_2_TO_POWER_OF(uint32_t w)337 __S_INLINE uint32_t GFX_2_TO_POWER_OF (uint32_t w) 338 { 339 __GFXMACRO_ASSERT(w < (sizeof(w) * CHAR_BIT)); // Assert no overflow. 340 341 return(1UL << w); 342 } 343 GFX_REAL_TO_UBYTE(float a)344 __S_INLINE uint32_t GFX_REAL_TO_UBYTE (float a) 345 { 346 uint32_t x; 347 GFX_FLOAT_TO_LONG_ROUND(x, a, 0xFF); 348 return x; 349 } 350 GFX_MEMCPY_S(void * d,int dn,const void * s,int n)351 __S_INLINE uint32_t GFX_MEMCPY_S(void *d, int dn, const void *s, int n) 352 { 353 uint32_t Error; 354 355 // Check for the size, overlapping, etc. 356 // Calling code responsibility to avoid overlap regions 357 __GFXMACRO_ASSERT(n >= 0); 358 __GFXMACRO_ASSERT( 359 (((char*) d >= (char*) s) && ((ULONG_PTR)((char*) d - (char*) s) >= (ULONG_PTR) n) ) || 360 (((char*) s >= (char*) d) && ((ULONG_PTR)((char*) s - (char*) d) >= (ULONG_PTR) n) )); 361 362 #ifndef _WIN32 363 Error = 0; 364 if(n <= dn) 365 { 366 memcpy(d, s, n); 367 } 368 else 369 { 370 Error = !Error; 371 } 372 #else 373 Error = (uint32_t) memcpy_s(d, dn, s, n); 374 #endif 375 376 __GFXMACRO_ASSERT(!Error); 377 return(Error); 378 } 379 GFX_MEMCPY_S_INC(void * d,int dn,const void * s,int n)380 __S_INLINE void* GFX_MEMCPY_S_INC(void *d, int dn, const void *s, int n) 381 { 382 GFX_MEMCPY_S(d, dn, s, n); 383 return GFX_VOID_PTR_INC(d, n); 384 } 385 GFX_GET_NONZERO_BIT_COUNT(uint32_t bitMask)386 __S_INLINE uint32_t GFX_GET_NONZERO_BIT_COUNT(uint32_t bitMask) 387 { 388 uint32_t bitCount = 0; 389 while(bitMask) 390 { 391 bitCount += bitMask & 0x1; 392 bitMask >>= 1; 393 } 394 395 return bitCount; 396 } 397 398 #endif 399 400 //#include <intrin.h> 401 402 // __readmsr should not be called for vGT cases, use __try __except to handle the 403 // exception and assign it with hard coded values 404 // isVGT flag will be set if it's being called from vGT. 405 406 407 #define GFX_READ_MSR(pHwDevExt, value, reg, retParam) \ 408 if(!gfx_read_msr((pHwDevExt), &(value), (reg))) return retParam; 409 #define GFX_WRITE_MSR(pHwDevExt, reg, value, retParam)\ 410 if(!gfx_write_msr((pHwDevExt), (value), (reg))) return retParam; 411 412 #define GFX_READ_MSR_GOTO_LABEL_ON_ERROR(pHwDevExt, value, reg, label) \ 413 if(!gfx_read_msr((pHwDevExt), &(value), (reg))) goto label; 414 415 #define GFX_WRITE_MSR_GOTO_LABEL_ON_ERROR(pHwDevExt, reg, value, label)\ 416 if(!gfx_write_msr((pHwDevExt), (value), (reg))) goto label; 417 #endif // __GFXMACRO_H__ 418