Skip to main content
GameDev.net gamedev.net
🔒 Locked

[.net] MDX Sort-By-Texture Low FPS Gain

Started by Mace Mar 22, 2006 at 4:10 AM 4 replies 2.2k views
Original Post
Mace
Mace
Hey. I recently implemented a material/texture sorter for my application and was surprised to see how little it affected the actual performance. FPS Test -------- Non-sorted Ex1: 266 Ex2: 52 Sorted: Ex1: 289 Ex2: 57 Ex1: 126 textured cubes with 2 random materials Ex2: 730 textured cubes with 2 random materials -------- In more detail, what i do is that i group my meshes into 2 lists (since there are 2 materials in this example) and render each list separately with a SetTexture() state change between them. Does anyone know why? Also i would appreciate if someone posted an url with some MDX speed optimization tips because ive had a hard time finding one. Cheers /Johan
remigius
remigius
Quote:
Does anyone know why?


I'm no mind reader, but I guess you're doing this to optimize performance [wink]

Smart-ass comments aside, the low gain from this indicates your rendering is limited elsewhere. The frist thing to check would be if you're setting the stream source each time you need to draw a cube. SetStreamSource is a rather costly method to call, so if you're doing this for every cube that might explain the low performance. Since you're probably rendering the cube with the same vertices over and over, you only need to set the stream source and vertex formats once, before you start rendering.

Next up for optimization is typically batch submission. If you're drawing these cubes one at a time, the low performance may be caused by issuing too many DIP (DrawIndexPrimitive, which is also what Mesh.DrawSubset uses internally) calls per frame. You can use batching (more in this thread) or hardware instancing (more on this page) to reduce the number of DIP calls you make each frame.

And finally, you might want to make sure you created your mesh with MeshFlags.Managed. I got pretty low FPS rates when I simply used 0 for the MeshFlags parameter (which probably means the mesh is created in SystemMemory). Before you make any drastic changes to your code however, you might want to use PIX (more this page) to get a better idea what is causing the poor performance.

Hope this helps :)
RipTorn
RipTorn
~50 fps for rendering 700 cubes is quite low. How big are the cubes?

Monitor your memory usage in task manager, if it's not rock solid, you are probably getting a lot of gen1+ garbage collection, which kills real-time performance (especially on single core processors). I made a 'mega test' with approx 10k cubes in my own engine, initally (because of gen1+ GC) I was getting around 3fps, which is quite unacceptable. With three very minor changes (litterly a line or two each) I eliminated the GC problems and now it sits at 55fps. I tracked these down via the .net CLR profiler.
Mace
Mace
Great replies, thanks guys :)

Yeah, you know, i might have overlooked SetStreamSource and didnt take that into account. What i will do next is to sort my already sorted lists by mesh as well to minimise SetStreamSource calls. That should do the trick.

"RipTorn: ~50 fps for rendering 700 cubes is quite low. How big are the cubes?"
I agree, however its work in progress and i will remember to check my memory as you suggested. By the way, the cubes are just 1x1x1 units big so nothing impressive there :)

Also Remigius, i dont use DX Meshes because my code is structured like this:

SceneManager -> SceneNode -> Mesh -> SubMesh

SceneNode: contains properties such as transformation, rotation etc.
Mesh: Basically a collection of SubMeshes bundled into one "model"
SubMesh: Contains the actual vbuffer, indexbuffer, material reference etc.

Also since this program.. ah what the heck, engine, support implementations of other renderers such as OpenGL, i decided to keep the SubMesh a more abstract interface and keep the api specific calls within their respective implementations, such as a Direct3D Mesh.

Of course i could store a Mesh object within my DX implementation of SubMesh but im not familiar with the advantages of that since i just recently switched from OpenGL to MDX :)
remigius
remigius
Quote:
Of course i could store a Mesh object within my DX implementation of SubMesh but im not familiar with the advantages of that since i just recently switched from OpenGL to MDX :)


Always nice to hear [wink]

I don't think there is a real performance advantage in using DX Mesh objects. It's more a matter of convenience, since working with Mesh objects yields somewhat 'cleaner' code and they contain various useful utility functions for intersection, loading/saving, generating tangent space etc. It is however a bit more difficult to set up batching or instancing when you're using Mesh objects.
janoside
janoside
Quote:
Also i would appreciate if someone posted an url with some MDX speed optimization tips because ive had a hard time finding one.


Not specific, to MDX, but very useful information about DX (scroll to the bottom of the page for the good stuff).
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/Accurately_Profiling_Direct3D_API_Calls.asp

Quote:
Quote:

Of course i could store a Mesh object within my DX implementation of SubMesh but im not familiar with the advantages of that since i just recently switched from OpenGL to MDX :)




Always nice to hear


Agreed.

[Edited by - janoside on March 22, 2006 8:43:18 AM]
-janoside [Firestorm Engine]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.