Reputation: 3567
So from looking around at examples and tutorials, it seems the most common method of placing buffers in the pipeline is, every model object gets it's own vertex buffer, and then after the buffers are filled, they lock, set the buffers, unlock, set shaders, draw, and rinse/repeat for every models individual buffer. seems to me that all that locking and unlocking would slow things down a bit.
So i'm wondering if maybe the model objects could instead aggregate all their vertices into 1 big array, all the indices in a big array, create 1 large buffer, lock once, set buffers once, unlock, and then switch out shaders and draw as many polygons as required with those shaders, and just work your way along the buffer drawing and switching shaders like before, instead of having to lock and drop more vertices in the pipeline every time before you draw.
Would this be any more efficient, or do you think the overhead from all the bookkeeping involved,(for example, from index a to index b, use this shader), would just make this more work than it's worth?
also, if i have missed a concept of d3d here, please inform me. ( i'm new)
due to massive misunderstanding, anywhere where i refered to locking and unlocking, was actually supposed to just be calling IASetVertexBuffer/IASetIndexBuffer. The "revised" question is more or less:
Does stuffing the vertices for all the models in the scene into one single buffer, and simply calling IASetVertexBuffer once improve perforamance at all?
Upvotes: 1
Views: 510
Reputation: 473387
So from looking around at examples and tutorials
Stop. Most "examples and tutorials" for anything are not intended to show best performance practices. Unless they are specifically about best performance practices. They're trying to show in the clearest and cleanest way how to perform task X. Optimization is an entirely other issue. Optimized code is a lit less clear and clean than unoptimal code; thus, many optimizations would get in the way of the tutorial's stated purpose.
So never assume that just because a tutorial does it some way, that's the fastest way to do something. It is simply one way to do it.
then after the buffers are filled, they lock, set the buffers, unlock, set shaders, draw, and rinse/repeat for every models individual buffer.
Locking and unlocking is for modifying the buffer. If you're not modifying it... why are you locking it? And if you are modifying it, then you're doing some form of buffer streaming, which requires special handling in order to make it efficient.
If you're doing streaming, then that's a different question you should ask (ie: how to do high-performance vertex streaming).
That isn't to say that putting the data for multiple objects in one buffer isn't a good idea. But if it is, the reason for it has less to do with locking and unlocking and more to do with the possibility of drawing multiple objects with a single draw call.
Upvotes: 3
Reputation: 67380
In general the fewer locks the better, every lock has to be an in-sync transfer between system memory and graphics card memory that stalls your GPU. The more you can batch these transfers together the better.
An even better improvement however is to leave buffers that don't change alone. You won't always need to reload bench #1221 every. single. frame. It never changes (*). So load your static art at the beginning and just draw it as needed. And before you think of culling half the bench away in preprocessing, think twice about the cost of locking a buffer just to get rid of a few vertices when your GPU already knows how to do basic culling at lightning speeds.
(*) assuming it doesn't change of course :)
Upvotes: 1