Agreed. This STATIC,DYNAMIC,STREAM business is confusing. <etc>
I’m sure people said something similar about not being able to directly manage texture objects too. Where are those people now? They don’t have a problem because it ultimately isn’t a problem. Even D3D is moving in that direction.
I don’t want to have to translate what I want before I call the API. i.e. I want video memory therefore I have to use STATIC_DRAW.
Would you prefer an API that changes every time the hardware goes through some kind of alteration? What happens if there is no video memory, if there is some other kind of scheme involved instead? Is PCIe memory the same as AGP memory, or, due to the increased bandwidth, would you consider it more acceptable? It’s better to let the driver decide such things.
More importantly, you believe that STATIC_DRAW gives you video memory. You believe this due to empherical data based on the performance characteristics of drivers (nVidia drivers; nothing has been said about how ATi cards handle this) today. What about the next driver release that might decide to dump them to AGP? What about the driver release that puts DYNAMIC_DRAW textures into video ram?
Perhaps what I should really be asking for is STREAM_DRAW but I’m not entirely sure what that is even after reading the spec.
Even if the spec is unclear, the nVidia document is very clear: n-draw-to-n-uploads. A buffer that is frequently uploaded to, typically once per use. This changes frequently enough that sync issues may crop up and the driver may want to double-buffer stuff, or orphan the buffer when you respecify it. Dynamic is less frequent than stream.
Remember, these hints aren’t simple, “Put me in X-RAM,” things; they are hints about the expected user behavior. They tell the driver how you intend to use the buffer so that it can make this usage pattern more optimal for you. It’s important for a proper abstraction to know what it is you intend to do with the memory.
The only real question is when you switch from one to the other. How many uploads per second does it take when you should use DYNAMIC rather than STATIC, and how many does it take to use STREAM rather than DYNAMIC?
Perhaps the problem is that I’m coming from having used the VAR extension which did it the right way imo.
VAR is very clearly not the right way to do it, for any number of reasons. Besides its horrible usage hint mechanism (the fact that nVidia had to tell you which hints to use to get specific memory should be a clue that it’s a bad hint mechanism), there’s the fact that the application is poking directly at driver-side memory, which is never a good thing except under specific conditions.
Say you want 30Mb of video memory and say your target card will only give you 29Mb of video memory.
You’re thinking like an opponent of driver-managed textures again. Equally importantly, you’re allocating 30MB of space. With 64-byte vertices, that’s almost 500,000 vertices all in one VBO. This is not a good idea right from the start. Huge VBO’s are a bad idea, precisely due to problems like this. I hope you’re not treating VBO like VAR, where you allocate a big block and manage it yourself.
Equally importantly, the amount of video memory available to you is not fixed; it varies depending on texture needs. You have two systems competing for the same resource. And remember, you can’t texture from AGP, but you can read vertices from there. So, ultimately, textures are more important. The more video memory you take up with VBO’s (if the driver doesn’t page them out to AGP), the fewer resident textures you can have and the greater the likelihood that, in real-world situations (as opposed to a demo), you’ll start trashing your textures. This is why you want the driver to manage your VBO’s.
On reflection it may be that in the case of a card with 29Mb available as video memory for vbos and 30Mb requested that the driver would internally split the buffer into 29Mb video & 1Mb AGP but with no mechansim to find out, how do we know?
VBO’s almost certainly cannot be split internally. One more reason not to treat VBO like VAR.
You have two choices. One, you can poke at the system and hope that it gives you what you think you want, and hope that it doesn’t change in another driver revision. Or two, you can trust the driver to know what’s best for you in real-world situations, and if you find yourself with a piece of AGP memory, just accept it as being better overall for you. Oh, and telling your users to set up their AGP apature better isn’t a bad idea either.
VBO is at the exact right place for an abstraction of vertex arrays. It’s general enough to cover all kinds of memory, and it allows the driver to manage the memory properly (moving from video to AGP and back when needed). Meanwhile, it allows the user to inform the driver of how he intends to use the memory. Not even texture object lets you do that.