DX11 easy, but very obscure question
Guys, I need help as this really makes me once too curious. Was recently messing with BlendStates in D3D11, and a thing did catch my eye. Normally whenever you do forward rendering, you do not really care about the alpha channel that much - so a logical step is creating a blend state that masks it's writes out altogether as while having 16 or even 32 bit per channel rendertargets this will save a lot of traffic. So, I created a dedicated "default" blend state to replace the DX11's one for the main pass of my engine - and let the science begin. A pretty strange science, must I say.
The core of the setup looks like this: although much stuff is happening around, the part under question is just an R32G32B32A32 rendertarget written by pixel shaders and read back by compute shaders that do not rely on the alpha channel, so far it is very straightforward (and yes, I used 32 instead of 16 to make the traffic higher for this test, although 16bpc is usually sufficient for a nice image). The rendertarget is cleared every frame with the alpha value of 1.0, the shaders also return 1.0 as the alpha component. Now, the results:
- masking out the red, green or blue channel writes gives some minor yet notable framerate gain as expected, compared to both the default and the custom blend states.
- masking two of the above channels roughly doubles the gain, again no miracle.
- BUT(!) - masking out the alpha writes (channel write mask becomes 0x7 this way) gives virtually nothing compared to the DX11's default blend state, especially after the drastic effects of disabling R, G or B!
What is going on?! Does the system somehow "see" I do not use the channel, and disables it on iit's own? Or it "sees" the the pixel shaders always write the same channel value the preceding ClearRenderTargetView() call supplied and doesn't trigger the memory write? Or am I missing something else?
The core of the setup looks like this: although much stuff is happening around, the part under question is just an R32G32B32A32 rendertarget written by pixel shaders and read back by compute shaders that do not rely on the alpha channel, so far it is very straightforward (and yes, I used 32 instead of 16 to make the traffic higher for this test, although 16bpc is usually sufficient for a nice image). The rendertarget is cleared every frame with the alpha value of 1.0, the shaders also return 1.0 as the alpha component. Now, the results:
- masking out the red, green or blue channel writes gives some minor yet notable framerate gain as expected, compared to both the default and the custom blend states.
- masking two of the above channels roughly doubles the gain, again no miracle.
- BUT(!) - masking out the alpha writes (channel write mask becomes 0x7 this way) gives virtually nothing compared to the DX11's default blend state, especially after the drastic effects of disabling R, G or B!
What is going on?! Does the system somehow "see" I do not use the channel, and disables it on iit's own? Or it "sees" the the pixel shaders always write the same channel value the preceding ClearRenderTargetView() call supplied and doesn't trigger the memory write? Or am I missing something else?
0
Comments
Anyway, at least now we know that (at least on NV) there is no reason for alpha-less BlendStates...