首页 > 代码库 > D3D11笔记——Resource基本概念
D3D11笔记——Resource基本概念
D3D11中的Resource主要可以分为Buffers和Textures两类。Resource可以被绑定到渲染管线的特定阶段,有些绑定是直接的(比如ID3D11DeviceContext::IASetVertexBuffers就直接把一定数量的Vertex Buffers绑定到管线的Input Assembler阶段),也有的绑定(比如想让Pixel Shader读一个Texture中的内容)必须是间接的,即以Resource View为中间层进行绑定。
D3D11中对Resource View的使用只有四种情况,其他的Resource都可以直接绑定。四种使用Resource View的情况如下:
1. Render Target,即把内容渲染到的地方。在初始化D3D11的时候一般都会由DXGISwapChain准备Backbuffers,为其创建一个(或多个)Render Target View,再用ID3D11DeviceContext::OMSetRenderTargets把这些Buffers绑定到管线的末端。此外,在渲染到纹理的时候往往会设置别的Render Target。对应的资源视图是RenderTargetView(RTV)。
2. Depth Stencil,也就是深度/模板缓存。同样是在初始化D3D11的时候会用到。对应的资源视图是DepthStencilView(DSV)。
3. Shader Resource,指会被着色器访问的一些外部资源,比如纹理(Textures)。对应的资源视图是ShaderResourceView(SRV)。
4. Unordered Access,和Shader Resource相似,但是它不光能被着色器读,还能被着色器写入,所以更加灵活一些。不过它只能绑定于Pixel Shader或Compute Shader。对应的资源视图是UnorderedAccessView(UAV)。
不管是在创建什么类型的Resource前,都要填充一个DESC结构体(比如要创建Buffer时要填充一个D3D11_BUFFER_DESC),它是用来描述要创建的Resource的性质的。不同类型的Resource用到的DESC可能不同,但其中会有一些共有的成员:
1. Usage,它用来描述Resource将会被如何使用。可选的值包括:
a. D3D11_USAGE_DEFAULT:GPU对这个Resource能读能写,但CPU就和它绝缘了。
b. D3D11_USAGE_DYNAMIC:顾名思义,dynamic指这个Resource是能够动态更新的(by CPU)。它表示只允许CPU写入它、GPU读取它。
c. D3D11_USAGE_IMMUTABLE:表示这个Resource创建过后就不再发生变化,并且只允许GPU读取它。
d. D3D11_USAGE_STAGING:CPU、GPU都拥有对它的读/写权,从这个角度上说是四种usage中最强的一种。
然而,并不是说Usage越“强”就越好。比如用了Immutable,那么D3D就知道只有GPU会读这个Resource的内容,于是可以放心地做一些相关的优化(比方说,把Resource的内容放在显存中),访问起来也就可能比Dynamic等更快。
2. CPUAccessFlags,用来描述CPU会如何访问这个Resource。严格地说,通过这个字段向D3D提供的信息和Usage提供的信息并不是正交的,但我们还是应该保持它和Usage字段的一致性。显然,它至多有四种取值:不读不写/只读不写/只写不读/读写,其中读对应D3D11_CPU_ACCESS_READ,写对应D3D11_CPU_ACCESS_WRITE,可以用位运算“|”同时选择这两个,0则表示不读不写。
3. BindFlags,表示这个Resource以后会被如何绑定到渲染管线。比如想创建一个Vertex Buffer,那么BindFlags就应该是D3D11_BIND_VERTEX_BUFFER。值得注意的是BindFlags的取值同样是可以按位或起来的,比如我想先把这块Buffer作为管线的Stream Output阶段的输出,再在下一次渲染中作为Input Assembler阶段的输入,那么就应该用D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT。
4. Misc,意为Miscellaneous Flags,即一些杂项。先不管,要用到的时候再分别介绍。
此外,创建Resource的时候还会要求一个D3D11_SUBRESOURCE_DATA类型的pInitData字段,表示的是用来初始化该Resource的数据。这个参数可以传入一个空指针,表示不进行初始化(有时初始化是必须的,比如Usage用的是Immutable,那么Resource一旦创建完毕就没有修改的机会了)。D3D11_SUBRESOURCE_DATA中的pSysMem是数据指针,另外两个字段分别指行宽和层宽,只在创建2D和3D纹理的时候有用。
D3D11笔记——Resource基本概念