UpdateSubresource and data size

Started by
3 comments, last by hdxpete 11 years, 5 months ago
Hello,

Like everyone i'm looking to speed up my draw code as much as possible. I am currently using DirectX 11 on windows 8. I've ran my code through various profilers, and it seems to two functions i have which are taking up the most time are

UpdateSubresource
and
DrawIndexed

I am not worried about the DrawIndexed one because i know all objects in the scene which are being draw should be in the scene. im doing object culling using a visibility test before either of these two functions gets called.

so looking at the UpdateSubresource call it seems to come from me updating vertex shader resources. I reviewed my code and right now where i have 1 generic vertex shader resource type. (i.e. one struct that contains all values for all my shaders) i could divide it up into two different types of vertex shader resources. one that is 256bytes long and one that is approx 800 bytes long.

my question is, how many objects would i have to draw with the 256 byte shader data size in order to get a benefit? say i was drawing 100 objects (right now all use 800 bytes of data) or 80k total data sent to the graphics card. if i use the 256byte version for 50 objects, i go down to 52k sent to the graphics card. now a savings of 30k data is nice, but should i really worry about it, if im only drawing 100 objects in my scene?

thanks
Advertisement
Maybe you should look into ID3D11DeviceContext::DrawIndexedInstanced to minimize the draw calls, in case you are drawing the same object multiple times. This will also reduce the amount of constant buffer updates you do.

The amount of data you describe (kilobytes) for updating constant buffers every frame is rather meaningless with the current generation of the hardware. However, if you are somehow stalling your pipeline, then even smallest amount of data may have a dramatic effect. I have copied well over one megabyte of data per frame to the GPU for over a decade and I can still reach 100-200 fps easily.

It is good idea to split your constant buffer data up to some point so that you can really keep some data constant for at least some time. View, Projection matrices for example don't change typically during the frame so they could well be in one constant buffer.

Cheers!
Hello,

There are times when we are drawing the same object multiple times. however it is a legacy program we are porting from opengl to directx so the code isnt structured enough to "group" an instance like that. but we are already referencing the same vertex buffer id so if it happens 3 objects drawn in a row all use the same vertex data then the only thing updated is the vertex data buffer and then the objects are drawn. ill look into more though. thank you.
UpdateResource can be slow if you're using it to repeatedly update the same resource. If you're not going to use lots of constant buffers, you should consider making the constant buffer using D3D11_USAGE_DYNAMIC and mapping it with D3D11_MAP_DISCARD. It may allow the driver to better optimize things for your use case.

Splitting up your constant buffers so that you update them as little as possible is pretty much always a good thing to do. It's hard to put a number on it though, since it depends a lot on your code, your driver, and your hardware. But it's definitely a good place to start optimizing.
MJP,

That did seem to have a minor effect on speeding things up. Thank you very much. really appreciate it. I was having trouble using map before turns out i wasnt creating the buffer properly for map. so i was using Updatesubresource instead.

This topic is closed to new replies.

Advertisement