DrawIndexedPrimitives takes 20 to 40 FPS to draw

Started by
27 comments, last by LemonBiscuit 10 years, 1 month ago

Hello,

I'm trying to display a terrain in my XNA game which is made of 512*512 vertices.

On my laptop, without the terrain, I have 60 FPS. When I display it, I'm running between 25 and 40 FPS.

I'm drawing 2 times the terrain: once for the camera, and once for the water reflection (I have an ocean).

I optimized a maximum my shaders, and I can tell you the lag doesn't come from here.

My draw function is only composed of this:


GraphicsDevice.DrawIndexedPrimitives(PrimitiveType.TriangleList, 0, 0, numberVertices, 0, numberIndices / 3);

I've seen a lot of people drawing million of faces in their game. I "only" have 512288 vertices to draw...

What could I do to optimize this function and get some more FPS?

Thank you!

Advertisement

I optimized a maximum my shaders, and I can tell you the lag doesn't come from here.

If that's an assumption I suggest you use a profiler like Intel GPA to check it.

No it's not an assumption, I tried removed them and the problem wasn't gone..

There are so many things that could be causing this. With the amount of code you've posted the best you're going to get are guesses, so here's a few to start with:

  • Try simpler shaders.
  • Try lower resolution textures.
  • Try drawing without your water reflection.
  • Are you reading anything back from the GPU? (Perhaps for that reflection?)
  • Check your vsync settings.
  • Are you using Sleep calls to control framerate?

It's highly unlikely that the DrawIndexedPrimitive call itself is the culprit. Instead, there's something running slow that the call depends on, or something that depends on the call and must wait for the call to fully finish before it can start, or something bad in your main loop that's being highlighted by the call. That's the kind of thing you need to look for.

Direct3D has need of instancing, but we do not. We have plenty of glVertexAttrib calls.

When you have trouble determining the root cause for why <x> is slowing your game down, you need to profile it. That is, using one of the various tools out there, get the numbers behind all the of the directx calls you are making to determine what exactly is at fault. I would recommend using the Intel Graphics Performance Analyzer (it's free) as mentioned above. I have just started using it and I can tell you it is amazing, once you capture a frame for analysis it displays all of the render calls based on which render target they are operating on. It lets you edit the shader code live, perform experiments such as swapping in a simple pixel shader, using 2x2 size input textures, it even lets you edit the current render states bound to each section of the pipeline.

I guess you're not culling anything?

No I'm not culling anything.

RnaodmBiT I used your profiler, and as nVidia's one it tells me DrawIndexedPrimitives is taking all the GPU ressources.

So I really don't know where it comes from...

Are you recreating and/or resending data between draw calls, rather than once up front?


RnaodmBiT I used your profiler, and as nVidia's one it tells me DrawIndexedPrimitives is taking all the GPU ressources.

I'm not sure about nVidia's tool, but Intel GPA should tell you whether or not the time is in the vertex shader or pixel shader. It should also let you perform experiments to see what happens if you swap things out with a 1x1 texture (to test if texture cache is the bottleneck), for instance. You might need an Intel GPU for some of the more advanced features to work.

You can also do this manually of course. For instance, replace your terrain pixel shader with a dummy one that just outputs a color. How does that affect your frame time?

All we can do on this forum is make wild guesses for you.

Can you post your vertex and pixel shaders?

512*512 is actually a lot of vertices. That translates to 262.144, which forces to use 32-bit indices.

Use instancing to draw four chunks of 256x256 verts (which allow to use 16-bit indices) in one call.

Furthermore, if your terrain vertices are generated in a random order, it could be that it's cache unfriendly.

Also, if you're updating your terrain vertices once per frame (and the buffer not created with the wrong flags, i.e. static vs dynamic) it could be causing the hit. When you remove the DrawPrimitive call you notice the performance goes up because the driver may be skipping your terrain vertex updates CPU->GPU entirely.

It could also be that when you put the DP call, your bad uploads cause the driver to stall (force the CPU wait for the GPU to complete)

Finally, you don't say that a car takes 100 km/h to arrive to destination, but rather that it took an hour.

Same here, measure your frames in time taken in milliseconds, no it in frames per second.

This topic is closed to new replies.

Advertisement