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