Adam's Lair Forum

game development and casual madness
It is currently 2019/09/17, 15:20

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: 2013/07/09, 13:31 
Novice Member
Novice Member

Joined: 2013/07/08, 21:47
Posts: 13
Role: Professional
Hey, ran into a problem yesterday to do with batching of vertices, where when drawing a series of sprites that make up a skeletal animation the first sprite wasn't being drawn. It turned out that it was because we were reusing the same vertex array to send the verts for each part of the skeleton. While the batcher copies the array if a batch already exists, it just uses a reference to the original array to create the batch if it doesn't, so when we changed that array it destroyed that information.

We are going to change it now to send the vertices for the entire skeleton in one call to AddVertices, but I was just wondering if there was any particular reason why you don't copy the first set of vertices? It seems like a fairly easy trap to fall into and the cause is a little difficult to identify.


Top
 Profile  
 
PostPosted: 2013/07/09, 16:26 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2073
Location: Germany
Role: Professional
Short version: You aren't supposed to re-use vertex data arrays within the same frame. If you submitted an array, don't submit it again (within the same frame).

Long version: That your data is copied in some cases and isn't in others is not done to allow re-using vertex data, it's simply necessary for internal batching behavior and thus a measure to improve performance. Cloning all incoming data would negatively impact rendering performance for no significant reason.

If you know exactly how many vertices a single object will need for rendering, the recommended implementation allocates a suitable array once, but re-writes and re-submits it every frame.

Don't do the following:
Code:
if (this.vertices == null) this.vertices = new VertexC1P3T2[4];
this.vertices[0] = ...
this.vertices[1] = ...
...
this.vertices[3] = ...
device.AddVertices(this.vertices, ...);

this.vertices[0] = ...
this.vertices[1] = ...
...
this.vertices[3] = ...
device.AddVertices(this.vertices, ...);

Instead, do the following:
Code:
if (this.vertices == null) this.vertices = new VertexC1P3T2[8];
this.vertices[0] = ...
this.vertices[1] = ...
...
this.vertices[7] = ...
device.AddVertices(this.vertices, ...);

Or, if you really want to, the following:
Code:
if (this.vertices == null) this.vertices = new VertexC1P3T2[4];
this.vertices[0] = ...
this.vertices[1] = ...
...
this.vertices[3] = ...
device.AddVertices(this.vertices, ...);

if (this.vertices2 == null) this.vertices2 = new VertexC1P3T2[4];
this.vertices2[0] = ...
this.vertices2[1] = ...
...
this.vertices2[3] = ...
device.AddVertices(this.vertices2, ...);

The last approach isn't recommended, though. It's always better to have one big array than a lot of small ones. AddVertices also allows you to specify the number of vertices that are actually to be displayed, so you can allocate a large buffer array and use a valid portion of it. This comes in especially handy when dealing with a dynamic number of vertices.

FlaxenFlash wrote:
It seems like a fairly easy trap to fall into and the cause is a little difficult to identify.

Yes. That is actually a problem, but I don't want to sacrifice performance by doing a runtime check for multi-submissions or always cloning the incoming vertex array. If you have any suggestions other than that - I'm all ears :)

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
PostPosted: 2013/07/09, 20:33 
Novice Member
Novice Member

Joined: 2013/07/08, 21:47
Posts: 13
Role: Professional
Yeah, I understand your reasoning, we've gone with the second method you suggested.
I'm maybe not familiar enough with how the batching works to really understand the potential bottle necks, but won't most of the vertices get copied anyway or do the batches tend to be small? I'm just sort of surprised that the impact would be that large.
Also is it the copying of the values itself or the memory allocation that you are worried about? If it was the memory then potentially you could reuse the batch arrays from the previous frame and just copy the data into those. Though I suppose that would only make sense if there was some temporal consistency to the size of your batches. If it isn't the memory then nothing really springs to mind unfortunately.


Top
 Profile  
 
PostPosted: 2013/07/10, 09:47 
Site Admin
Site Admin
User avatar

Joined: 2013/05/11, 22:30
Posts: 2073
Location: Germany
Role: Professional
FlaxenFlash wrote:
I'm maybe not familiar enough with how the batching works to really understand the potential bottle necks, but won't most of the vertices get copied anyway or do the batches tend to be small? I'm just sort of surprised that the impact would be that large.


It really depends and it is impossible to make a global statement that will always hold true. My assumption is: There are cases where the performance impact of "always copying" would be large enough. At the same time, the usability gain from doing so would be relatively small - so I'm facing kind of a bad cost-benefit-ratio here - probably. On the other hand, you might be correct that it doesn't really matter in most cases. Can't really say something for sure until I've done some profiling.

I'll look into that. Subscribe to the following issue in case you want to stay up-to-date: https://code.google.com/p/duality/issues/detail?id=42

_________________
Blog | GitHub | Twitter (@Adams_Lair)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group