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?


  • ROCKFISH_AndiROCKFISH_Andi Administrator Posts: 1,317
    Hmm, can't answer this easy question, asked our technical artist and he can't help you, either - sorry
  • PedalToTheMetalPedalToTheMetal Member Posts: 137
    edited July 2019
    Sorry then, guess it is one of those things that should be taken as "it just works" :) In fact both DX11 and some GPU drivers get really enigmatic at times, say I once tried a geometry shader for per-face normals. A simple GS that only does some vector cross-products and outputs a single triangle. The results were spectacular enough for me to never go GS again :smile: : while the performance loss from mangling the pipeline was slight on GTX660, the impact was pretty much murderous on both GTX1080 (a drop from above 250 to below 230 fps!) and integrated ATI (I use that 256MHz thing for accurate tests), where the framerate was halved. Reading a dedicated per-face normal buffer in the vertex shaders instead of the GS approach made things fast again, though even generating normals in pixel shaders using ddx()/ddy() was faster compared to the GS usage.
    Anyway, at least now we know that (at least on NV) there is no reason for alpha-less BlendStates...
Sign In or Register to comment.