2 Sprites, Resource Locking, and cache repercussions.

Started by
1 comment, last by sirob 17 years, 11 months ago
Hi everyone, This question has been bugging me for a while, so I thought I'd look for anyone who might have some more info. I'm working on my particle system code, and have encountered an issue with drawing Additive and non-Additive particles. My design has led me to believe that using 2 Sprite interfaces would be the best solution, providing both sorting by material, and easy visibility checks. This would mean I would need to have 2 Sprite interfaces, which are both ready for drawing (between the Begin and End calls), at the same time. I would also have to be drawing to both intermittently. What I am unsure of, is when the Sprite interface actually locks the GPU resources and updates them. If the resources are locked at Sprite.Begin, with each call to Sprite.Draw actually modifying the locked resource, using 2 at the same time would cause writing to two sections at the same time, which would (I assume) hurt caching performance. On the other hand, if the Sprite interface performs the lock and copy all in the Flush/End call, this wouldn't matter. I'm not sure what kind of repercussions to expect from this type of use. If the loss of caching is a non-issue, I'd gladly just ignore it and go on with my design. I've heard a lot of people recommend to not use more than 1 Sprite interface for your entire application. I always assumed this was due to better batching. In my case, since the two types of particles use different renderstates, batching the two into one call is not a possibility. I realize this is a bit specific, and might not seem like a big issue, but I'd like to make sure this is a good approach. Since I've heard a lot of talk against using 2 Sprite interfaces at once, I want to make sure I'm on top of all the reasons people said that, before going against such frequent advice :). Thanks for reading,
Sirob Yes.» - status: Work-O-Rama.
Advertisement
I dont honestly know what the difference would be - and I dont think anyone else will either [headshake]

Once you get into the realm of cache coherance/utilization you also quickly get into the realm of application-specific results, or worse - hardware specific results. There are so many factors involved (even simply down to the number of drawing calls and their frequency/pattern) that it becomes difficult to extra a general case.

As an educated guesstimate, the performance wouldn't be too bad by adding an additional sprite. The logic behind using a single sprite and batching is more of a "use one, not 100's or 1000's". The difference between 1,2 or 3 sprites will probably be negligable by comparison to using 100's or 1000's.

Conclusion - not very helpful, but you're best of trying it and seeing what happens [smile]

Quote:Original post by sirob
What I am unsure of, is when the Sprite interface actually locks the GPU resources and updates them. If the resources are locked at Sprite.Begin, with each call to Sprite.Draw actually modifying the locked resource, using 2 at the same time would cause writing to two sections at the same time, which would (I assume) hurt caching performance.
On the other hand, if the Sprite interface performs the lock and copy all in the Flush/End call, this wouldn't matter.
PIX is your friend here.

Sprite (and other D3DX classes) all have to use the core D3D calls "under the bonnet" (or "hood" if you're American?), thus running a call-stream capture will reveal exactly whats happening, and when. I dont know the MDX equivalents, but D3DPERF_BeginEvent()/D3DPERF_EndEvent() and D3DPERF_SetMarker() are extremely useful here. You can inject markers/grouping around calls making it trivial to identify which D3D calls are made by corresponding D3DX code...


As a related/final note, you can use the same PIX techniques (exported to CSV->Excel) to compare your two approaches. Set up a few test cases and then run a full stream capture with the same test data on each method. PIX will be able to tell you which has less API-related overhead and can give you some basic timing information. Its not necessarily a benchmark/proof, but it should give you important insight into the real differences between methods.

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Ahhhh, cool, thanks Jack.

I knew PIX showed you the calls for the Sprite interface, but didn't know you could expand those and see what each of them does internally. Was quite the learning experience.

At any rate, as far as I could tell, Sprite doesn't lock anything at all until the End() or Flush() calls, so I'd say I'm safe with using two instances.

Thanks again for the help :).
Sirob Yes.» - status: Work-O-Rama.

This topic is closed to new replies.

Advertisement