Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm programming a two-pass effect in DirectX 11 (SharpDX). It's supposed to write the depth to a texture in the first pass and then use that texture to extract data on the second one in the pixel shader.

What I get is a white screen, with nothing but the interface and I don't know why nothing is being printed. What could be the problem? I would say I should get at least something from the Depth Texture.

This is how I'm setting the depth texture values:

this.depthBuffer = new Texture2D(device, new Texture2DDescription()
        {
            Format = Format.R32_Typeless,
            ArraySize = 1,
            MipLevels = 1,
            Width = (int)host.ActualWidth,
            Height = (int)host.ActualHeight,
            SampleDescription = new SampleDescription(1, 0),
            Usage = ResourceUsage.Default,
            BindFlags = BindFlags.DepthStencil | BindFlags.ShaderResource,
            CpuAccessFlags = CpuAccessFlags.None,
            OptionFlags = ResourceOptionFlags.None,
        });

this.depthBufferShaderResourceView = new ShaderResourceView(this.device, this.depthBuffer, new ShaderResourceViewDescription()
        {
            Format = Format.R32_Float,
            Dimension = ShaderResourceViewDimension.Texture2D,
            Texture2D = new ShaderResourceViewDescription.Texture2DResource()
            {
                MipLevels = 1,
                MostDetailedMip = 0,
            }
        });
var depthStencilDesc = new DepthStencilStateDescription()
        {
            DepthComparison = Comparison.LessEqual,
            DepthWriteMask = global::SharpDX.Direct3D11.DepthWriteMask.All,
            IsDepthEnabled = true,
        };

And here is how I sample the depth in the .fx file:

int3 posTex = int3(input.p.xy, 0);
float depthPixel = DepthTexture.Load(posTex);
float4 color = float4(depthPixel, depthPixel , depthPixel, 1.0f );
return color;

And here the way I'm now setting the Depth Buffer stencil view as a Render Target in 2 passes. In the first I try to set the depthstencilview as a target. In the second pass I'm trying to set teh depth texture as a shader resource to read from it.

this.device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(this.vertexBuffer, LinesVertex.SizeInBytes, 0));

// PASS 0
this.device.ImmediateContext.OutputMerger.SetTargets(depthBufferStencilView);
this.device.ImmediateContext.ClearDepthStencilView(this.depthBufferStencilView,     DepthStencilClearFlags.Depth | DepthStencilClearFlags.Stencil, 1.0f, 0);
this.technique.GetPassByIndex(0).Apply(this.device.ImmediateContext);
this.device.ImmediateContext.DrawIndexed(this.geometry.Indices.Length, 0, 0);

// PASS 1
this.device.ImmediateContext.OutputMerger.ResetTargets(); // unbinding the depthStencilView

this.device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(this.vertexBuffer, LinesVertex.SizeInBytes, 0));
this.depthStencilShaderResourceVariable = effect.GetVariableByName("DepthTexture").AsShaderResource();
this.depthStencilShaderResourceVariable.SetResource(this.depthBufferShaderResourceView);
this.technique.GetPassByIndex(1).Apply(this.device.ImmediateContext);
this.device.ImmediateContext.DrawIndexed(this.geometry.Indices.Length, 0, 0);

Finally, this is how I set the two passes in the .fx file:

technique11 RenderMyTechnique
{
pass P0
{   

SetDepthStencilState( DSSDepthLessEqual, 0 );
SetVertexShader     ( CompileShader( vs_4_0, VShader() ) );
    SetHullShader       ( NULL );
    SetDomainShader     ( NULL );        
    SetGeometryShader   ( NULL  );
SetPixelShader      ( NULL );
}

pass P1
{
SetDepthStencilState( DSSDepthLessEqual, 0 );
SetVertexShader     ( CompileShader( vs_4_0, VShader() ) );
    SetHullShader       ( NULL );
    SetDomainShader     ( NULL );        
    SetGeometryShader   ( CompileShader( gs_4_0, GShader() ) );
SetPixelShader      ( CompileShader( ps_4_0, PShader() ) );
}
}
share|improve this question
    
Obvious question: Are you actually writing to the depth buffer for sure? –  Sean Middleditch Nov 14 '13 at 18:13
    
how can I be sure? I thought it was just always done. –  c4sh Nov 14 '13 at 18:20
    
@c4sh You also have to create a DepthStencilView of the buffer (using the D32_FLOAT format) and pass it in your SetRenderTargets call. –  Nathan Reed Nov 14 '13 at 18:23
    
@c4sh: You also have to make sure that DepthWrite is turned on in your DepthStencilState bound to the context when rendering when you render your scene. I don't recall if it's set by default, but it might not be. –  Sean Middleditch Nov 14 '13 at 18:35
    
Following the comments I passed the DepthStencilView to my SetRenderTargets call and set a DepthStencilState with IsDepthEnabled as true (added the DepthStencilStateDescription in the question. (see changes in question) So I realized I'm now getting always a 1.0f because I'm clearing the DepthBuffer to 1.0f. So I'm not writing on it, the thing is I don't know why I'm not writing to it..? @NathanReed @SeanMiddleditch –  c4sh Nov 15 '13 at 15:01
add comment

1 Answer

up vote 1 down vote accepted

My guess would be that you've bound the texture for reading and writing at the same time (i.e. it's the current depth buffer). DX11 won't let you do that (the debug runtime should give you an error message about it).

Also note that it decides what the current depth buffer is at the time you bind the shader resource, and not at draw call time so you want to bind the correct set of render targets before binding any shader resources.

There are three solutions:

  1. Unbind the depth buffer while reading from it in a shader. This assumes you don't need depth testing.
  2. Copy the depth buffer at some point, and read from the copy. This is clearly the slowest option.
  3. Bind the depth buffer as read only. This won't work on 10.0 or 10.1 hardware.
share|improve this answer
    
I would take the third approach as I need it to be fast and I really need the depth buffer. The problem is, I don't know how to bind the depth buffer as read only. I'm binding it like this: this.depthStencilShaderResourceVariable = effect.GetVariableByName("DepthTexture").AsShaderResource(); this.depthStencilShaderResourceVariable.SetResource(this.depthBufferShaderResour‌​ceView); I don't know if you mean this types of resource usage: sharpdx.org/documentation/api/… But didn't see anything useful in them. –  c4sh Nov 15 '13 at 16:46
    
You need to pass D3D11_DSV_READ_ONLY_DEPTH to CreateDepthStencilView() to get a read-only view. For SharpDX I think that's done by calling sharpdx.org/documentation/api/… and setting the Description up appropriately. –  Adam Nov 15 '13 at 20:09
    
This leaves it just with 0s. So the depth buffer was cleared to 1.0 but it's as if I was writing zeroes on it! –  c4sh Nov 18 '13 at 10:37
    
As no one else is gonna answer this and the problem for me is not solved, I would accept the answer I got as a thanks giving for its usefulness, though it didn't lead me to a solution. –  c4sh Nov 22 '13 at 10:15
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.