Calculating exact VRAM size of image...

Blitz3D Forums/Blitz3D Programming/Calculating exact VRAM size of image...

big10p(Posted 2005) [#1]
I have images of arbitrary size and I need to calculate the exact amount of VRAM they will occupy when loaded. My tests using AvailVidMem() show that it's not simply a case of "width*height*bitdepth".

I thought that maybe the image width/height were being taken to the nearest ^2 for some reason (like textures) but this doesn't seem to be the case. However, I'm pretty sure there's some ^2 related sizing going on - I just can't seem to nail it down.

Ideas, anyone?

P.S. For reasons I won't bore you with, I can't do the "check VRAM, load image, check VRAM again" method to find the size.


Banshee(Posted 2005) [#2]
I dont think it's *bitdepth in vram

I migt be wrong here, it's midnight and i'm tired but my over heated over tired over stressed brain is saying that it's 4 bytes per pixel, RGBA. Ask me again in the morning and i'll probably deny ever saying that.


octothorpe(Posted 2005) [#3]
To elaborate on what Becky was saying:

AvailVidMem() returns the "total bytes of available free video memory", but "width*height*bitdepth" gives you a number of bits. There are 8 bits in a byte.


big10p(Posted 2005) [#4]
Yeah, sorry, I know this - I should really have put "width*height*4" because I'm working in a 32-bit graphics mode.

That cleared up, my question still stands. Anyone?


octothorpe(Posted 2005) [#5]
Bore us. Why can't you "check VRAM, load image, check VRAM again"? That's what I'd do!


big10p(Posted 2005) [#6]
Bore us.

OK. :)

My images can potentially be fairly large. If there's not enough physical VRAM left to load such an image, it seems blitz/DX loads the image into AGP(GART) mem or maybe even plain system mem - I'm not sure which. Either way, AvailVidMem() doesn't change when this happens.


Hotcakes(Posted 2005) [#7]
width*height*4 regardless of what bit depth screen res you are using, because Blitz works on 32bit images internally.

The power of 2 rounding can't really be calculated; it happens at a sort of gfx card/drivers/directx/blitz/phase of the moon-based type of occurance. Your image -may- be rounded up to the next power of 2 on width and/or height. It depends.

But, basically, if you can't fit the image in your entire vidmem (not just what's currently available, as what's in use can be paged out - and remember that the screen itself takes up a total size of screenwidth*screenheight*4*2 (for double buffers) - that automatically chews up your vidmem the second you make a call to Graphics()), you're screwed. I'm of the impression that vidmem cannot store 'part' of an image. However if the image does fit into total vidmem, but not into available vidmem, an older pic will get paged out and the new one loaded in, which 1) causes severe slowdown due to the AGP bus and 2) doesn't really affect the availvidmem command much, as it's mostly the same as before... obviously, it's not going to return a negative value...

For compatibility reasons, your image should not be larger than the dimensions of your screen anyway (another directx/gfx card/drivers/number of flies from 1000 camels-related issue), although Blitz is -supposed- to handle it intelligently behind the scenes. It probably does, but... you know... sometimes something happens that makes you feel unsure...


Mustang(Posted 2005) [#8]
Don't forget the mipmaps... check my formulas:

http://www.blitzbasic.co.nz/Community/posts.php?topic=24157&hl=DXTC

[last post]


Neochrome(Posted 2005) [#9]
something like this?

oldmem% = TotalVidMem() - AvailVidMem()
img% =LoadImage("screen_practice_setup.jpg")
newmem% = (TotalVidMem() - AvailVidMem())

usemem% = newmem - oldmem
;PlaySound music

Print oldmem%

Print newmem%

Print "used image mem:" + usemem%




big10p(Posted 2005) [#10]
width*height*4 regardless of what bit depth screen res you are using, because Blitz works on 32bit images internally.

Funny, I was under the impression all images are automatically converted to match the bitdepth of the graphics mode. I'll test this tomorrow.

The power of 2 rounding can't really be calculated; it happens at a sort of gfx card/drivers/directx/blitz/phase of the moon-based type of occurance. Your image -may- be rounded up to the next power of 2 on width and/or height. It depends.

Yes, unfortunately, this seems to be the case, from my testing. :(

Further testing today gave funny results: my GF2 machine seems to refuse to load any image with a width > 4096 directly into VRAM, even if there is enough space. However, my older GeForce256 machine has no problem with loading such images directly into VRAM. Probably a driver issue, though.

For compatibility reasons, your image should not be larger than the dimensions of your screen anyway (another directx/gfx card/drivers/number of flies from 1000 camels-related issue), although Blitz is -supposed- to handle it intelligently behind the scenes. It probably does, but... you know... sometimes something happens that makes you feel unsure...

In my experience, there's no problem with images bigger than the screen, as long as you dont try and display the whole thing - using DrawImageRect to display sections works fine.

Don't forget the mipmaps... check my formulas:

I'm talking 2D images here, Mustang. Mip-maps don't come into it. ;)

Neochrome: As I explained above, I can't use that kind of method.


Hotcakes(Posted 2005) [#11]
Funny, I was under the impression all images are automatically converted to match the bitdepth of the graphics mode. I'll test this tomorrow.

You know what... I think you may be right... that would explain why ReadPixels can be innacurate on a loaded image in 16 bit mode... obviously... maybe it was Max that did it the way I said... can't remember.

In my experience, there's no problem with images bigger than the screen, as long as you dont try and display the whole thing

In my experience, there's been no problem regardless. Of course, I have tested on a whole 3 machines. =] The OpenGL renderer in BlitzPlus has definate problems with it though (causes occasional crashes on End). Of course that doesn't apply here.

Neochrome, as mentioned previously, that does not take into account which images have been swapped out of vidmem - if an image is swapped out availvidmem will go up OR down depending on the size of the newer image.


ozak(Posted 2005) [#12]
You can't really predict the size a bitmap will take in vidmem as internal card memory alignment etc. kan eat some.
And as mentioned, conversion might occur in other layers such as DX and OpenGL

The best thing to do is to load the texture and check the vidmem again. Actually the vidmem is probably directly returned from DirectX in Blitz3D and the docs says it's not all that reliable :)


Shifty Geezer(Posted 2005) [#13]
It'll likely vary between GPU hardwares as well. I doubt there's a formula for calculating VRAM usage. However if you go with with (Nearest ^2 to fit width)*(nearest ^2 to fit height)*4 you should get a worst-case scenario that works for all cards. Using ^2 sized textures/images is a lot more efficient for some hardwares and is needed for fastest texture scaling too. I've taken to using square textures like 128x128 or 256x256 and for smaller irregular size images crop to the appropriate size by resizing the texture UVs. eg. A 54x38 button image will be saved as a 64x64 .png, applied to a relative 54:38 sprite, and the texture coords stretched to show only the 54x38 pixels of the texture. This ensures fastest results on all hardwares.


big10p(Posted 2005) [#14]
OK, it looks like I'm simply going to have to estimate the size using width*height*4.

However if you go with with (Nearest ^2 to fit width)*(nearest ^2 to fit height)*4

That would be another option, Shifty, but I think doing it this way is more likely to produce wildly inaccurate results (on my machines, at least), compared to the formula above. Dunno, I'll have a think.

Thanks for all input, folks!