Preamble.

OpenGL glTexImage2D function works only with the images, whose width & height is the power of two (some extensions however make it possible to work with almost arbitrary sizes). That's why the image loader (e.g. TGA) have to check the size of a texture.

The originally proposed way, with some modifications, is:

`inline bool IsPower2( UINT32 value )`

{

if (0x8000000 < value) return false; // check top limit - prevents infinite looping

UINT32 pow2 = 1;

while( pow2 < value )

pow2 <<= 1;

return ( pow2 == value );

}

Code.

There is however a faster solution (sadly not mine). The idea is based on two simple facts:

1) if x is power of two it's binary representation has only one bit = 1, namely the bit in the position log2( x ) - 1.

2) x is power of two if and only if 0 == x & (x - 1).

For example:

x = 4 = 0100, x - 1 = 3 = 0011. 4 & 3 = 0100 & 0011 = 0000.

x = 5 = 0101, x - 1 = 4 = 0100. 5 & 4 = 0101 & 0100 = 0100,

etc.

`inline bool IsPowerOfTwo( const unsigned x ) // Beware: this does not work for 0.`

{

return 0 == (x & (x - 1));

}

This algo is superb: no loops, platform independence, it accepts any integer of any size (32, 64 etc).

VC++ generates for this function the swiftest inline code (just two op-codes):

` lea eax, DWORD PTR [edx-1] // x in edx, eax = x - 1`

test eax, edx // now result is in ZF

Later I've noticed, that this code does not work properly for x = 0 (obviously, 0 is not a power of two). So, my improvement was:

`inline bool IsPowerOfTwoStrict( const unsigned x ) // 0 is not a power of 2`

{

return x && !(x & (x - 1));

}

Fortunately for extra condition the VC2008 generates only two additional op-codes (bare minimum):

` test edx, edx // is x == 0 ?`

je some_label // jump if zero

lea eax, DWORD PTR [edx-1]

test eax, edx

OK, guys, I fully aware that an optimization of rarely used code is usually a waste of time. So, consider these exercises only as a sort of self training.

From the other side, this function can be moved in the general purpose library, thus it should be optimal.

Below is a garbage, that I've produced in attempts to find the best solution. It can be curious. In particular, I exploited x86 instruction: BSF (Bit Scan Forward) and BSR (reverse).

`// GeUtility.h`

//------------------------------------------------------------------------------

// Check whether the integer is power of 2

//------------------------------------------------------------------------------

inline bool IsPower2( const unsigned int x )

{

return x && !(x & (x - 1));

}

/*******************************************************************************

#ifdef GAME_ENGINE_USE_ASM_X86

inline

__declspec( naked ) // suppress compiler from prolog & epilog code generation

bool

__cdecl

IsPower2(

UINT32 value

)

{

__asm

{

//

// prolog

//

push ebp

mov ebp, esp

push ebx

push ecx

//

// body

//

mov eax, value

bsr ecx, eax // find leftmost (L) nonzero bit

jz END // if value = 0 then return (eax = value = 0)

bsf ebx, eax // find rightmost (R) nonzero bit

cmp ebx, ecx // if L == R then value is power of 2

sete al // if L == R eax = 1 otherwise eax = 0

END:

//

// epilog

//

pop ecx

pop ebx

mov esp, ebp

pop ebp

ret // return - result in AL

}

}

//

// "in_uint32_value" must be local value of type "UINT32"

// "out_bool_result" must be local value of type "bool"

//

#define IS_POWER_TWO( in_uint32_value, out_bool_result ) \

__asm push eax \

__asm push ecx \

__asm xor eax, eax \

__asm mov out_bool_result, al \

__asm bsr ecx, in_uint32_value \

__asm jz end \

__asm bsf eax, in_uint32_value \

__asm cmp eax, ecx \

__asm sete out_bool_result \

__asm end: \

__asm pop ecx \

__asm pop eax \

// inline bool IsPower2( UINT32 value )

// {

// bool result;

// __asm {

// xor ecx, ecx

// mov eax, value

// xor edx, edx

// bsr ecx, eax // find the first 1 from the right, so in ecx is exponent

// bts edx, ecx // edx = pow of 2

// cmp edx, eax

// sete result // result = 1 if edx == eax

// }

// return result;

// }

#else // !GAME_ENGINE_USE_ASM_X86

inline bool IsPower2( UINT32 value )

{

if (0x8000000 < value) return false; // check top limit

UINT32 pow2 = 1;

while( pow2 < value )

pow2 <<= 1;

return ( pow2 == value );

}

inline void IS_POWER_TWO( UINT32 in_value, bool & out_bool_result )

{

out_bool_result = IsPower2( in_value );

};

#endif

*******************************************************************************/