之前在博文里面说过不能同时将一个resource的shader resource view和unordered 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 slot和input slot的resource还是一样的,不会随着清空。这就是为什么一个好的Directx10,11的习惯就是完成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或别没意义的东西。