Directx11的warning:Resource View Is Already Bound To An OutputSlot

之前在博文里面说过不能同时将一个resourceshader resource viewunordered access view绑定到pipeline。本来想说这种sb行为估计也没人会犯错。但是今天才发现防不胜防,当系统一大起来,算法复杂起来,就会不经意的犯这种错误了。

首先看看SDK对同时绑定两个view时(先用CSSetUnorderedAccessView绑定到output slot,再用CSSetShaderResourceView绑定到input slot)系统会做的反应的解释:

ID3D11DeviceContext::CSSetShaderResources 

If an overlapping resource view is already bound to an output slot, such as a render target, then the method will fill the destination shader resource slot with NULL.

接着要说明的是即使调用了ID3D11DeviceContext::Dispatch(),之前被绑定到output slotinput slotresource还是一样的,不会随着清空。这就是为什么一个好的Directx1011的习惯就是完成DirectCompute计算后,就调用CSSetShaderResource()CSSetUnorderedAccessView()来给所有的register绑定一个空的resource。如下

ID3D11UnorderedAccessView* g_NULLUAV;

ID3D11ShaderResourceView *g_NULLSRV;

UINT g_NULLInt=0;

m_pContext->CSSetShaderResource(0,1,&g_NULLSRV);

m_pContext->CSSetShaderResource(2,1,&g_NULLSRV);

……

m_pContext->CSSetUnorderedAccessView(0,1,&g_NULLUAV,&gInitCout);

……

 

    来看看今天我们遇到的非常隐蔽的bug,让我们非常痛苦,还要感谢一个师弟在一堆复杂数值计算中一行行debug下来,才让我发现了这个bug。不懂下面变量代表什么没关系,只是看看我们上面指出的错误是如何在代码中隐蔽的出现。。

UINT uavInitCount=0;

m_pContext->CSSetShaderResources(0,1,&m_pParticleSRV);

m_pContext->CSSetUnorderedAccessViews(0,1,&m_pParticleDensityUAV,&uavInitCount);

m_pContext->CSSetShader(m_pDensitySimpleCS,NULL,0);

m_pContext->Dispatch(m_cbOfFluidCSType.iParticleNum/threadGroupSize_X,1,1);

 

m_pContext->CSSetShaderResources(3,1,&m_pParticleDensitySRV);

m_pContext->CSSetUnorderedAccessViews(0,1,&m_pParticleForceUAV,&uavInitCount);

m_pContext->CSSetShader(m_pForceSimpleCS,NULL,0);

m_pContext->Dispatch(m_cbOfFluidCSType.iParticleNum/threadGroupSize_X,1,1);

 

看出来了没,调用了m_pContext->CSSetShaderResources(3,1,&m_pParticleDensitySRV);前,在上面已经调用了m_pContext->CSSetUnorderedAccessViews(0,1,&m_pParticleDensityUAV,&uavInitCount);也就是按照SDK的说法,pParticleDensity这个resource会不知不觉的被清0。这个bug让我们纠结了很久。

所以我们可以想到了,写Directx10,11的另外一个好的习惯是在要绑定多个resource时,先调用CSSetUnorderedAccessView(),再调用CSSetShaderResource()。否则如果先调用CSSetShaderResource(),绑定的resource如果之前已经被CSSetUnorderedAccessView()绑定到output slot了,很不幸我们之前的计算结果会被清零,读出一堆0或别没意义的东西。

你可能感兴趣的:(D3d11)