Jump to content
  • Advertisement
Sign in to follow this  
eltharynd

Depth stencil state issue

This topic is 2116 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I was trying to understand why my Depth stencil isn't working and i ended up changing all the code to copy/paste MSDN's...

and still it's not working... I really have no idea why...

	ID3D11Texture2D* depthStencilTexture;

	D3D11_TEXTURE2D_DESC depthTexDesc;
	ZeroMemory (&depthTexDesc, sizeof(D3D11_TEXTURE2D_DESC));
	depthTexDesc.Width = set->mapSettings["SCREEN_WIDTH"];
	depthTexDesc.Height = set->mapSettings["SCREEN_HEIGHT"];
	depthTexDesc.MipLevels = 1;
	depthTexDesc.ArraySize = 1;
	depthTexDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthTexDesc.SampleDesc.Count = 1;
	depthTexDesc.SampleDesc.Quality = 0;
	depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
	depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	depthTexDesc.CPUAccessFlags = 0;
	depthTexDesc.MiscFlags = 0;

	mDevice->CreateTexture2D(&depthTexDesc, NULL, &depthStencilTexture);

	D3D11_DEPTH_STENCIL_DESC dsDesc;

	// Depth test parameters
	dsDesc.DepthEnable = true;
	dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	dsDesc.DepthFunc = D3D11_COMPARISON_ALWAYS;//LESS

	// Stencil test parameters
	dsDesc.StencilEnable = true;
	dsDesc.StencilReadMask = 0xFF;
	dsDesc.StencilWriteMask = 0xFF;

	// Stencil operations if pixel is front-facing
	dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; //INCR
	dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// Stencil operations if pixel is back-facing
	dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; //DECR
	dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// Create depth stencil state
	mDevice->CreateDepthStencilState(&dsDesc, &mDepthStencilState);

	mDeviceContext->OMSetDepthStencilState(mDepthStencilState, 1);
	
	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
	ZeroMemory (&depthStencilViewDesc, sizeof(depthStencilViewDesc));
	depthStencilViewDesc.Format = depthTexDesc.Format;
	depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	depthStencilViewDesc.Texture2D.MipSlice = 0;

	mDevice->CreateDepthStencilView(depthStencilTexture, &mDepthDesc, &mDepthStencilView);

any ideas anyone? it's hard to understand with the pictures but it seems like it's testing the opposite way it should... i try to reverse it in the depth stencil description with no luck.... the highermost cube is the last beeing rendered

Share this post


Link to post
Share on other sites
Advertisement

Hi eltharynd!

If you don't need the stencil test, you probably want to disable it.

dsDesc.StencilEnabled = false;

In this case, you can put full precision into the depth value by using a full float for it:

depthTexDesc.Format = DXGI_FORMAT_D32_FLOAT;

 
Currently, your depth testing function permits all fragments to be written. Instead, let only fragments through that have a smaller depth value.

dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;

 
It might be just due to copy-pasting into the browser, but did you use the correct depth stencil view description, when creating the depth stencil view? (2nd argument changed)

mDevice->CreateDepthStencilView(depthStencilTexture, &depthStencilViewDesc, &mDepthStencilView);

I guess you did, but for completeness I'm just saying it: You bound your depth buffer like so, right?

ID3D11RenderTargetView* rtvs[] = { mRenderTargetView_Backbuffer };
ImmediateContext->OMSetRenderTargets(1, rtvs, mDepthStencilView);

Do you clear the depth stencil view before drawing?

mImmediateContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH, 1, 0);

Also, were all your resources successfully created? (That is, they are not NULL?)

Best, Tsus

Share this post


Link to post
Share on other sites

- dsDesc.DepthFunc needs to be D3D11_COMPARISON_LESS.

- make sure you have set the correct culling mode in the rasterizer state (seems alright).

- make sure you bind the depth-stencil surface with OMSetRenderTargets().

dsDesc.StencilEnable can be set to false, unless you have some reason to use stencil-ops.

- enable the debug-layer.

Edited by eppo

Share this post


Link to post
Share on other sites

thanks everyone for the replies.... 

 

dsDesc.DepthFunc was less before i changed everything then i forgot to put it back :/

 

Tsus you were right i was giving the wrong depth stencil view description ( although it probably was due to the copy paste as you said)

 

i tried to change the format 

 

i was already using OMsetblablabla()

 

 

the current code is this

ID3D11Texture2D* depthStencilTexture;

	D3D11_TEXTURE2D_DESC depthTexDesc;
	ZeroMemory (&depthTexDesc, sizeof(D3D11_TEXTURE2D_DESC));
	depthTexDesc.Width = set->mapSettings["SCREEN_WIDTH"];
	depthTexDesc.Height = set->mapSettings["SCREEN_HEIGHT"];
	depthTexDesc.MipLevels = 1;
	depthTexDesc.ArraySize = 1;
	depthTexDesc.Format = DXGI_FORMAT_D32_FLOAT;
	depthTexDesc.SampleDesc.Count = 1;
	depthTexDesc.SampleDesc.Quality = 0;
	depthTexDesc.Usage = D3D11_USAGE_DEFAULT;
	depthTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	depthTexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE | D3D11_CPU_ACCESS_READ;
	depthTexDesc.MiscFlags = 0;

	mDevice->CreateTexture2D(&depthTexDesc, NULL, &depthStencilTexture);

	D3D11_DEPTH_STENCIL_DESC dsDesc;

	// Depth test parameters
	dsDesc.DepthEnable = true;
	dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
	dsDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;//LESS

	// Stencil test parameters
	dsDesc.StencilEnable = false;
	dsDesc.StencilReadMask = 0xFF;
	dsDesc.StencilWriteMask = 0xFF;

	// Stencil operations if pixel is front-facing
	dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; //INCR
	dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// Stencil operations if pixel is back-facing
	dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR; //DECR
	dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; //KEEP
	dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

	// Create depth stencil state
	mDevice->CreateDepthStencilState(&dsDesc, &mDepthStencilState);

	mDeviceContext->OMSetDepthStencilState(mDepthStencilState, 1);
	
	D3D11_DEPTH_STENCIL_VIEW_DESC depthStencilViewDesc;
	ZeroMemory (&depthStencilViewDesc, sizeof(depthStencilViewDesc));
	depthStencilViewDesc.Format = depthTexDesc.Format;
	depthStencilViewDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
	depthStencilViewDesc.Texture2D.MipSlice = 0;

	mDevice->CreateDepthStencilView(depthStencilTexture, &depthStencilViewDesc, &mDepthStencilView);

and later i pass them at the OM

mDeviceContext->OMSetRenderTargets(1, &mTargetView, mDepthStencilView);

and of course before every frame i call

void Engine::ClearTargetView()
{
mDeviceContext->ClearRenderTargetView(mTargetView, D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f));
mDeviceContext->ClearDepthStencilView(mDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0 );
}

note that for some reason

 

if i set depthTexDesc.CPUAccessFlags = 0;

nothing shows on the screen.....

if i set it to cpu access read and write i can see my models but i get the same error with the depth test....

 

i don't think the cpu ever tries to access the depth buffer to be honest.. 

I am really lost at this point...

Share this post


Link to post
Share on other sites

PS... i think it's irrelevant but i didn't set the resterizer yet....

it should not matter since it uses a default one.. right?

Share this post


Link to post
Share on other sites

Hi eltharynd,

Usually, CPU access flags are not required for the depth buffer.

Try to turn on the debug layer, as eppo suggested. D3D will most probably tell you what is wrong. The behavior you described sounds like invalid parameters. Pass the flag D3D11_CREATE_DEVICE_DEBUG into the Flags parameter of the D3D11CreateDevice call.

Could you check that all your mDevice->Create... methods return S_OK?
If not, the debug layer will tell you in the Output window of visual studio, why the Create-method failed.
(If you run in Debug mode with F5, not Ctrl+F5.)

Clearing structs with ZeroMemory is a good practice (in my eyes). Could you do it for the depth stencil desc, too? (Just to be safe.)

ZeroMemory (&dsDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));


Also, you have some copy paste error when clearing the depth stencil view desc. It should go:

ZeroMemory (&depthStencilViewDesc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC));



Just to be safe, set a rasterizer state. Whenever you move code around, you don't want to depend on states of some previous code block.

D3D11_RASTERIZER_DESC rsDesc;
ZeroMemory(&rsDesc, sizeof(D3D11_RASTERIZER_DESC));
rsDesc.CullMode = D3D11_CULL_BACK;
rsDesc.DepthBias = 0;
rsDesc.DepthBiasClamp = 0;
rsDesc.FillMode = D3D11_FILL_SOLID;
rsDesc.AntialiasedLineEnable = false;
rsDesc.DepthClipEnable = true;
rsDesc.FrontCounterClockwise = true;
rsDesc.MultisampleEnable = true;
rsDesc.ScissorEnable = false;
rsDesc.SlopeScaledDepthBias = 0;
if (FAILED(mDevice->CreateRasterizerState(&rsDesc, &mRsBackfaceCulling))) return false;


Then, later:

mDeviceContext->RSSetState(mRsBackfaceCulling);


And don't worry. You'll figure it out.

Best, Tsus
 

Share this post


Link to post
Share on other sites

ok so if i set CPU access flags to write/read i get E_INVALIDARG

so i set them back to 0 and i get everything S_OK but then nothing is rendered...

Share this post


Link to post
Share on other sites

Ok. So, with all resources being successfully created and no errors in the output window during draw calls, it's time to use a graphics debugger like PIX.
PIX is contained in the DxSDK and allows you to capture the draw calls and states for a frame (every time you hit F12).
When clicking on a draw call in the list presented to you in PIX, the vertices of the triangles are shown before and after transformation.
If you do a right click on the rendering output you can debug individual pixels and see, why fragments were discarded.

Also, you can dig into the states bound at a draw call.
Hopefully, this sheds some light on the matter.

Share this post


Link to post
Share on other sites

ok so if i set CPU access flags to write/read i get E_INVALIDARG

so i set them back to 0 and i get everything S_OK but then nothing is rendered...
 

 

If you want to use a resource with cpu access, you need to set the usage to D3D11_USAGE_DYNAMIC instead of D3D11_USAGE_DEFAULT. Did you do that?

Edited by Juliean

Share this post


Link to post
Share on other sites

i tried both actually cause i really have no clues about what's wrong... 

anyway now i tried to run PIX (even tho im not 100% sure about how to use it but i get this results:

 

b3yi.png

 

so if i understand this correctly my mesh is there as i can see from RGB channel but if i change to depth channel everything is blacked out.... so what could this mean?

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!