When are Images in video memory?

BlitzMax Forums/BlitzMax Beginners Area/When are Images in video memory?

Gabriel(Posted 2005) [#1]
Are they using video memory when I load/create them or only when i actually draw them? I'd test but.. well.. there doesn't seem to be a command to report vid mem usage.


ImaginaryHuman(Posted 2005) [#2]
When you use CreateImage() or LoadImage() or, I think there's also something like bglTextureFromPixmap() or something like that .. .When you use those, what you're doing is `uploading` an image into videoram. They then sit there in video ram for as long as the OpenGL context is present, or until you delete them. In some cases if you don't have enough video ram to hold all of the images that you are trying to use at once, it may spool some of the lesser used ones off to main memory and swap back and forth to try and accomodate you, which of course produces slowdown.

When you use DrawImage you are just taking the pixels from one location in video ram, pushing it through the OpenGL pipeline and squirting it out the other end usually into the backbuffer, which is also in video ram. I would say the front buffer is also in video ram, although in window mode I'm not sure how that exactly works.

If your hardware doesn't support any implimentation of OpenGL routines, ie it's just sitting there as a basic display device and not much else, you might have an OpenGL driver which does everything in software. In that case you might find that the images are `uploaded` from main memory TO main memory. The OpenGL system will then likely run at the same speed using DrawPixmap() as it does using DrawImage(), because both are using the CPU. In most cases your hardware and driver and OpenGL implimentation will support using the hardware to do stuff, in which case DrawImage is a lot faster.

At the moment we don't have functionality to get the address in video ram of the OpenGL buffer or images. Btw Images are the same thing as `textures` - ie uploaded graphics stored in video ram. OpenGL can only USE graphics that are considered `uploaded`, ie usually in video ram. It isn't usually able to work with graphics in main memory. You can transfer the backbuffer to/from main memory but it uses the CPU and is generally slow. Only when the image is stored in video ram can OpenGL use it to draw to/from. Pixmaps are a BlitzMax-invented object, which is alluded to in the OpenGL documentation, to provide `offline` CPU-based handling of graphics data that isn't `active` in the OpenGL system. Because OpenGL *manages* the textures/images, BlitzMax currently doesn't very well know what it's doing with it. Once Max asks OpenGL to do something, it's kind of like passing the baton. OpenGL then does its thing, or tries to, and returns to BlitzMax.

So at the moment we don't really have a way to get that memory address, and it may change every time you do a Flip. You can `lock` an image, which basically means download it to main memory, work on it as a pixmap, and then re-upload it. It would be GREAT to be able to get a lock on the backbuffer, plus get the actual memory address of the locked graphic. I don't think we currently have access to that.

I had been thinking that you could draw a small image to the backbuffer, like just an 8x8 image. Then you could get the base address of video ram and do a `search` through all of video ram trying to find the image data. Then if you find it, you might have the base address of the backbuffer. But I'm sure the memory may move a lot and is unpredictable, plus I don't really know what format the data is stored in.


Gabriel(Posted 2005) [#3]
Hmm ok, thanks for that. I'm just noticing odd memory fluctuations when objects are hidden and shown, after they've been loaded. I can't really follow why hiding and unhiding an image would make any difference to system memory if it's in video memory already.


GW(Posted 2005) [#4]
Im pretty sure that when a new image is created or loaded, it is not resident in video memory until it is first called to draw.
Even with plenty of video memory available, there is always a performance hit when you drawimage() the first time (from moving from main memory to video memory).


ImaginaryHuman(Posted 2005) [#5]
Umm, I don't think it does that. Looking at the code for LoadImage and such, they actually upload the image to the graphics card as a texture.

However, when you SWITCH between two different textures, you might notice a performance decrease because it has to `bind` the texture in order to select it. It's extra overhead so maybe that's what you're seeing. When you thereafter use that same image, without switching to another image, it would render faster. I don't think it has anything to do with what memory it's located in.

I also wonder if the fluctuating main memory that Sybixsus mentioned is just because OpenGL is writing something to it.


GW(Posted 2005) [#6]
As an example, take a huge image, something like 5k by 5k, break it up into tiles, 512x512 or so, write some code to draw all the tiles each loop, and some functions to scroll around the entire image. you will notice that as each new tile comes into view for the first time, there will be a performance hit for each one (as its moved into vidmem). but (assuming you have plenty of vidmem) once they have all been shown once, everything will be smooth. This works for BB3D as well as BMax using both drivers.

BTW: there was a thread a few months back about having to do a 360^ RenderWorld() in b3d at the beginning of a 3d game before the main loop just for this reason. Otherwise the player will experience lots of choppyness the first time looking around.


ImaginaryHuman(Posted 2005) [#7]
Some kind of caching problem?