Sign in to follow this  
sirob

2 Sprites, Resource Locking, and cache repercussions.

Recommended Posts

sirob    1181
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,

Share this post


Link to post
Share on other sites
jollyjeffers    1570
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

Share this post


Link to post
Share on other sites
sirob    1181
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 :).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this