xref: /aosp_15_r20/external/gmmlib/Source/inc/common/gfxmacro.h (revision 35ffd701415c9e32e53136d61a677a8d0a8fc4a5)
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