Anybody knows if it makes any difference at wich point you unmap a mapped VBO? It would be convenient for me to unmap it just before rendering it(as the sample code in the specs does) but then again if that’s perfectly all right how come the driver doesn’t unmap the buffer automagically if it’s mapped and it’s trying to source/sink data from/to it. I mean it would have to check whether it’s mapped anyway(to signal an error in case it is) so it wouldn’t be much overhead and it would be convenient in some cases. Also is it expensive to use the glGetBufferParameterivARB call to query buffer parameters? For example if I have say 100 buffers and I need to query is_mapped status once per frame(to unmap before rendering) would I see a big difference if I kept track of each object’s state myself? I wouldn’t want both the driver and my app do bookkeeping if it wouldn’t make a big difference.
For example if I have say 100 buffers and I need to query is_mapped status once per frame(to unmap before rendering) would I see a big difference if I kept track of each object’s state myself?
I think the idea with mapping is that you don’t keep a bunch of buffers mapped at once. In general, you should map a buffer when you need to fill it with data, and this unmap it afterwards.
Also, the reason why buffers aren’t unmapped when you use them is because the unmap function tells you whether or not the work you just did was invalid. That is, an unmap operation is not guarenteed to succeed. The driver is permitted to lose the changes you make to an mapped buffer if something forces this condition (an alt-tab, for example).
In the data structure I use to keep track of buffers, I keep a simple “is mapped” flag. When someone calls the accessor for the vertex data pointer, I map the buffer (if it isn’t mapped) and return it. When the buffer gets a prepareToDraw() notification from the renderer, I un-map the buffer if it’s mapped. This works pretty well.
I would recommend you not query buffer parameters, though; that’s likely to be significantly slower than just keeping a lightweight data structure per buffer mirroring the information you know about it.
(Actually, the “prepareToDraw()” notification isn’t the only way a buffer gets unmapped, but I won’t bore you with implementation details
jwatte: That’s more or less what I had in mind except in my case unmapping (the prepareToDraw call) will happen just before the glDrawElements call. I just hoped I wouldn’t have to mirror the VBO’s internal structure. How do you handle the possibility that unmapping may fail? Also would it be (a lot) better to use a mechanism that unmaps as soon as the work on the buffer is done instead of before rendering (although it would be severely inconvenient in my case)? Anyway thanks to both of you.
[This message has been edited by zen (edited 10-18-2003).]
Yes, un-mapping when you’re done changing the data is best, but there are many cases where this isn’t easy. I unmap lazily, because the same code has three different memory management paths (NV_VAR, ARB_VBO and plain system memory) and in the VAR case, I don’t want to copy into AGP unless it’s actually going to be rendered. (I also re-use the same chunk and avoid copying again on successive renders, unless the data hase been touched again – and I use fencing to allow for a fallback FIFO usage of AGP if we don’t have enough to fit an entire frame)
Regarding losing the buffer after it’s mapped: if you lose it, you can just avoid drawing that frame. The reason you lost it is probably that the user did a mode switch, so his monitor is likely to be trying to sync to video and not be displaying what you’re doing anyway.
Actually, there are even more gory details, because my internal rendering API separates the three cases of STATIC_DRAW, DYNAMIC_COPY and STREAM_DRAW into separate vertex buffer interfaces, but to make a long story short: what you’re thinking isn’t to different from what we’re doing, and that works fine.