Le 06/06/2011 23:54, Roland Scheidegger a écrit :
> Am 06.06.2011 23:18, schrieb Tormod Volden:
>> On Sun, Jun 5, 2011 at 1:14 AM, Benjamin Bellec wrote:
>>> So here is a v2 patch with a builtin GCC optimization which is the
>>> fastest (thx Matt to point me to this solution).
>>>
>>
>> From patch:
>> +       return (1 << (32 - __builtin_clz(x - 1)));
>>
>> I don't know if the use of gcc guarantees that int will always be 32
>> bit, otherwise maybe use sizeof(int)*8 instead of 32? Or even
>> sizeof(int)*CHAR_BIT for good measures. Although probably the robots
>> have taken over before this becomes necessary :)
>>
> 
> Hmm I think a lot more things will break if that's not 32bit.
> There's another problem though, gcc docs say this:
> 
> — Built-in Function: int __builtin_clz (unsigned int x)
> 
>     Returns the number of leading 0-bits in x, starting at the most
> significant bit position. If x is 0, the result is undefined.
> 
> Which means it's now undefined for x == 1 too - not handling x == 0
> correctly might not be much of a problem in practice, but the same
> certainly cannot be said for x == 1. So that should probably be
> 
> +#if defined(PIPE_CC_GCC)
> +   if (x <= 1)
> +       return 1;
> +   else
> +       return (1 << (32 - __builtin_clz(x - 1)));
> 
> 
> Also I believe this builtin requires gcc 3.4 - not sure though if the
> rest of the code compiles on older gcc.
> 
> Roland
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Here is the v4 patch.

Benjamin
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index 65a99fc..93ac012 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -493,17 +493,29 @@ util_logbase2(unsigned n)
 static INLINE unsigned
 util_next_power_of_two(unsigned x)
 {
-   unsigned i;
+#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION >= 340)
+   if (x <= 1)
+       return 1;
+   else
+       return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
+#else
+   unsigned val = x;
 
-   if (x == 0)
+   if (x <= 1)
       return 1;
 
-   --x;
-
-   for (i = 1; i < sizeof(unsigned) * 8; i <<= 1)
-      x |= x >> i;
-
-   return x + 1;
+   if (util_is_power_of_two(x))
+      return x;
+
+   val--;
+   val = (val >> 1) | val;
+   val = (val >> 2) | val;
+   val = (val >> 4) | val;
+   val = (val >> 8) | val;
+   val = (val >> 16) | val;
+   val++;
+   return val;
+#endif
 }
 
 
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to