Search code examples
graphicsdirectx-11compute-shader

DirectX11: Read stencil bit from compute shader


I am converting a full-screen effect to a compute shader so that I can take advantage of some features of compute that can't be done with fragment shaders. Right now, this full-screen effect uses stenciling to avoid writing to pixels which it should not affect, and I would like to mimic that behavior with my compute shader.

I know that I can write this info to a color channel somewhere, but I'm hoping to avoid that and instead just read the stencil bit directly in the compute shader. However, I can't find any way to bind a D24S8 buffer to a compute shader such that I can actually read the stencil bit. It seems to only provide the depth information.

Is there any way to do this? Google is failing me, because everyone calls it the depth/stencil buffer when talking about sampling depth values.


Solution

  • This is possible.

    1. Create your D24S8 depth buffer Texture with the typeless format DXGI_FORMAT_R24G8_TYPELESS.
    2. Create your DepthStencilView of the resource in Step 1 using the strongly typed format of DXGI_FORMAT_D24_UNORM_S8_UINT.
    3. Create a ShaderResourceView of the stencil buffer for binding to the Compute Shader using the strongly typed format of DXGI_FORMAT_X24_TYPELESS_G8_UINT.
    4. [Optional] Create a ShaderResourceView of the "depth" part of the resource using the strongly typed format DXGI_FORMAT_R24_UNORM_X8_TYPELESS.

    Make sure you declare your stencil SRV in HLSL to be Texture2D<uint2> so you can access the Green channel (G8) which is where the stencil data will come from.

    Note since Depth and Stencil are separate SRVs you'd need to declare two Texture2Ds in HLSL, one for each. eg:

    Texture2D<float> depthBuffer; // Red contains depth.
    Texture2D<uint2> stencilBuffer; // Green contains stencil. Red is unused.