• FEATURED

View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# Is this code to calculate the datasize of an ARGB8 texture?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

7 replies to this topic

### #1jor1980  Members

Posted 20 April 2014 - 11:13 AM

Hi I need to calculate the dataSize of ARGB8 textures with mipmaps.

I made this routine but ti don´t know if is there a minimum size for the mimaps, so I don´t know if it s right

	size=width*height*4;
mipWidth=width;
mipHeight=height;

if(mipMaps!=0){
for(int i=0;i<mipMaps;i++){
mipWidth/=2;
mipHeight/=2;
if(mipHeight<1)
mipHeight=1;
if(mipWidth<1)
mipWidth=1;
tempSize=mipWidth*mipHeight*4;
size+=tempSize;
}
}


### #2haegarr  Members

Posted 20 April 2014 - 02:17 PM

A full MIP map chain ends with the 1x1 texel texture inclusive. But when being used on a GPU, a MIP map chain just needs to be complete, and that may be before the 1x1 texture is reached. So it depends on how the MIP map level limits are chosen.

Your code snippet seems me correct as long as the variable mipMaps doesn't cause the 1x1 texture be considered several times. I.e. the value of mipMaps should be

0 <= mipMaps <= ld( max( width, height ) )

Alternatively also breaking the loop just behind "size+=tempSize;" like so

if (mipHeight==1 && mipWidth==1) break;

would work in this sense.

EDIT: Just for clarification: The ld(x) function in the formula above means the "logarithm dualis", i.e. the logarithm to base 2.

ld( x ) := log2( x )

In case that it isn't available in your favorite math lib, it can be computed by using any other logarithmic function when dividing by the same logarithm of the base. To compute ld when e.g. the natural logarithm or the decimal logarithm is available, this would look like

log2( x ) = loge( x ) / loge( 2 )

log2( x ) = log10( x ) / log10( 2 )

You perhaps want to round to the nearest integer to avoid floating point problems.

Edited by haegarr, 21 April 2014 - 06:41 AM.

### #3jor1980  Members

Posted 21 April 2014 - 03:14 AM

Is that "A full MIP map chain ends with the 1x1 texel texture inclusive" also applied to other texture formats like dxt5 or dxt1?

### #4haegarr  Members

Posted 21 April 2014 - 04:16 AM

Is that "A full MIP map chain ends with the 1x1 texel texture inclusive" also applied to other texture formats like dxt5 or dxt1?

DXTn is an encoding of texture data. Due to its block nature the last MIP level that fills in the entire block is 4x4 texels. However, with doing some padding one can get down to 1x1 again. Searching for the problem brings e.g. this thread to light, where Evil Steve answers your question in post #5.

Of course, the code snippet in the OP does not consider compression but raw texture data. When considering compression, you should use the mipMaps <= ld( max( width, height ) ) formula instead of the conditional break, and you need to restrict mipHeight and mipWidth to the respective block's edge length instead of 1, and you need to multiply the resulting size with the compression ratio (depending on the compression scheme and sometimes the texel format, but fortunately a fix rate therein).

### #5jor1980  Members

Posted 22 April 2014 - 08:34 AM

This is the code I implemented, I thinks it is right but I post it to be reviewed.

	switch(textureFormat){

case DXT5:
size=width*height;
mipWidth=width;
mipHeight=height;

if(mipMaps!=0){
for(int i=0;i<mipMaps;i++){
mipWidth=mipWidth/2;
mipHeight=mipHeight/2;
blockWidth=mipWidth;
blockHeight=mipHeight;
if(mipHeight<1){
mipHeight=1;
blockHeight=4;
}
if(mipWidth<1){
mipWidth=1;
blockWidth=4;
}
tempSize=blockHeight*blockWidth;
if(tempSize<16)
tempSize=16;
size+=tempSize;
if (mipHeight==1 && mipWidth==1) break;//A full MIP map chain ends with the 1x1 texel texture inclusive
}
}
return size;

case DXT3:
size=width*height;
mipWidth=width;
mipHeight=height;

if(mipMaps!=0){
for(int i=0;i<mipMaps;i++){
mipWidth=mipWidth/2;
mipHeight=mipHeight/2;
blockWidth=mipWidth;
blockHeight=mipHeight;
if(mipHeight<1){
mipHeight=1;
blockHeight=4;
}
if(mipWidth<1){
mipWidth=1;
blockWidth=4;
}
tempSize=blockHeight*blockWidth;
if(tempSize<16)
tempSize=16;
size+=tempSize;
if (mipHeight==1 && mipWidth==1) break;//A full MIP map chain ends with the 1x1 texel texture inclusive
}
}
return size;

case DXT1:
size=(width*height)/2;
mipWidth=width;
mipHeight=height;

if(mipMaps!=0){
for(int i=0;i<mipMaps;i++){
mipWidth=mipWidth/2;
mipHeight=mipHeight/2;
blockWidth=mipWidth;
blockHeight=mipHeight;
if(mipHeight<1){
mipHeight=1;
blockHeight=4;
}
if(mipWidth<1){
mipWidth=1;
blockWidth=4;
}
tempSize=(blockHeight*blockWidth)/2;
if(tempSize<8)
tempSize=8;
size+=tempSize;
if (mipHeight==1 && mipWidth==1) break;//A full MIP map chain ends with the 1x1 texel texture inclusive
}
}
return size;

case ABGR8:
size=width*height*4;
mipWidth=width;
mipHeight=height;

if(mipMaps!=0){
for(int i=0;i<mipMaps;i++){
mipWidth/=2;
mipHeight/=2;
if(mipHeight<1)
mipHeight=1;
if(mipWidth<1)
mipWidth=1;
tempSize=mipWidth*mipHeight*4;
size+=tempSize;
if (mipHeight==1 && mipWidth==1) break;//A full MIP map chain ends with the 1x1 texel texture inclusive
}
}
return size;

case Luminance8:
size=width*height;
mipHeight=height;
mipWidth=width;

if(mipMaps!=0){
for(int i=0;i< mipMaps;i++){
mipWidth/=2;
mipHeight/=2;
if(mipHeight<1)
mipHeight=1;
if(mipWidth<1)
mipWidth=1;
tempSize=mipHeight*mipWidth;
size+=tempSize;
if (mipHeight==1 && mipWidth==1) break;//A full MIP map chain ends with the 1x1 texel texture inclusive
}
}
return size;


### #6haegarr  Members

Posted 22 April 2014 - 10:40 AM

The code snippet above seems me correct (although I would take advantage of the similarity of all 5 calculations and make a parametrizable solution from them; and those additional checks that tempSize has a minimum value seems me not necessary).

### #7jor1980  Members

Posted 22 April 2014 - 03:07 PM

Yes you are right the checks for tempSize is not necessary

### #8Hodgman  Moderators

Posted 22 April 2014 - 04:29 PM

What are you using the routine for?
If it's for measuring how much VRAM you're using, then it's only a lower-bound estimate due to pitch/padding ;)

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.