The Beauty of DirectX 11 (2) --- Resource View & Vertex Buffer

The Beauty of DirectX 11 (2) --- Resource View & Vertex Buffer

作者:clayman

仅供个人学习使用,请勿转载,勿用于任何商业用途。

 

 

CPU Access Flag(D3D11_CPU_ACCESS_FLAG)

         这是一个位标记,在指定usage flage之后,进一步说明是否允许cpu访问某块资源(其实个人觉得这个枚举稍微有些多余)。这个标记必须配合usage使用,比如只有dynamicstagin资源能设置为D3D11_CPU_ACCESS_WRITE。如果一块资源不需要被CPU访问,那么必须把值设置为0.

 

Bind Flags

         指定资源可以绑定到pipeline的哪些位置。这同样是一个位标记,因此可以组合起来,允许资源绑定到流水线的多个位置。

D3D11_BIND_FLAG {

  D3D11_BIND_VERTEX_BUFFER,

  D3D11_BIND_INDEX_BUFFER,

  D3D11_BIND_CONSTANT_BUFFER,

  D3D11_BIND_SHADER_RESOURCE,

  D3D11_BIND_STREAM_OUTPUT,

  D3D11_BIND_RENDER_TARGET,

  D3D11_BIND_DEPTH_STENCIL,

  D3D11_BIND_UNORDERED_ACCESS

}

         整个管线只有8种类型的位置可以绑定资源,分别对应D3D11_BIND_FLAG中的一个值。Vertex/index buffer表示资源可以作为input assembler阶段的输入数据;render targetdepth stencil表示资源可以接收output merger阶段的数据;stream out表示可以接收来自于pipeline生成的几何数据。这几个枚举分别对应着管线中的一个可绑定点。Constant buffer, shader resourceunorderer access则都可以作为可编程阶段的输入数据。后面会讨论三者之间的区别。

 

         此外Miscellaneous Flags中的枚举值,用来指定一些特别的用途,大部分值都不经常用到,不再仔细介绍,详见文档。唯一值得一提的是D3D11_RESOURCE_MISC_GDI_COMPATIBLE,这个值允许创建与GDI兼容的资源,对于需要用GDI创建文字的程序可能会用到。

   

Resource View

         有两种方法把资源绑定到pipeline,如前所述的8种绑定点中,有一半可以直接绑定资源,分别是vertex/index/const/stream buffer;其他4种类型则必须通过Resource ViewRV)绑定。Resource View是在DirectX10时代引入的概念,它实际上是连接resoucepipeline绑定点之间的一种适配器对象,作用类似翻译。同一种资源可以对应多个不同的RV,允许它被绑定到不同的pipline阶段。

 

resource type

         有四种不同类型的RV,分别对应着pipeline中的4个可绑定位置:

Render target view (ID3D11RenderTargetView)

Depth stencil view (ID3D11DepthStencilView)

Shader resource view (ID3D11ShaderResourceView)

Unordered access view (ID3D11UnorderedAccessView)

 

         第一种就是常见的render target,大家应该很熟悉,没有太多可说的。DSVRTV的区别在于为了优化性能,可以选择DSV是否可写。不可写的DSV资源既可以绑定为depth stencil bufferdepth stencil test,又能*同时*绑定为SRV使用。SRV其实和之前DX中纹理的作用几乎一样。UVA则稍微有些特别,和SRV类似,UVA也可以为某个shader阶段提供数据,不仅如此,它还允许在同一个shader阶段,同时读取和写入数据,并且能把数据写入到资源的任意位置,灵活性非常高,但只能在pixel shadercompute shader中使用。

 

Resource View Creation

         创建RV的模式和创建资源的模式类似,也通过ID3DDevice的成员函数完成,每个Create函数接收3个参数,第一个是RV所依赖的资源;第三个是所创建的RV对象。第二个参数则是每个类型都不同的一个属性结构,SDK中对这些结构有详细描述,这里不再重复。

 

 

Resource in Detail

Buffer Resource

         BR是一维的线性内存块,虽然有多种不同的buffer配置选项,但内部数据都是基本的线性布局。Bufferbyte为单位,大小等于每个元素大小乘元素个数,与普通数组类似。接下来将详细介绍每一种buffer

 

Vertex Buffer

         VB最基本的用途就是保存几何体顶点数据,是一系列格式相同的顶点的集合。当然,也可以把顶点的不同元素分离到不同VB中,比如位置信息储存在vb1,纹理和法线信息储存在vb2,根据渲染时的需要选择使用合适的buffer,也就是常说的multi-stream。此外,VB也可以用来实现instancing rendering(注:后文将把instance翻译为副本,而不是常见的实体,这样更容易理解),比如用一块或几块vb保存per-vertex data,也就是普通的顶点数据,再用额外的vb来提供per-instance data,比如每个模型副本的world matrixcolor等等,这样便可一次渲染大量图形,减少CPU负载。后面还会详细介绍与instancing rendering相关的内容。

 

         VB主要用于Input Assembler阶段给整个流水线提供顶点数据,也可以用于stream out阶段接收生成的顶点,以便后续渲染使用。

 

         创建VB时,必须使用D3D11_BIND_VERTEX_BUFFER以及可选的D3D11_BIND_STREAM_OUTPUT枚举。再根据程序预期的用途,选择合适的usagee.g对于静态资源(静态模型,地形数据),使用D3D11_USAGE_IMMUTABLE枚举,并且使用D3D11_SUBRESOURCE_DATA参数初始化资源;对需要频繁修改的资源使用D3D11_USAGE_DYNAMIC以及D3D11_CPU_ACCESS_WRITE枚举;对于需要作为stream output输出目标的资源,使用D3D11_USAGE_DEFAULTVB不需要RV就可以绑定到管线。

 

ID3D11Device* pDevice =  0;
ID3DBuffer* CreateVertexBuffer( uint size,  bool dynamic,  bool streamout, D3D11_SUBRESOURCE_DATA* pData)
{
    D3D11_BUFFER_DESC desc;
    desc.ByteWidth = size;
    desc.MiscFlags =  0;
    desc.StructureByteStride =  0;

     if(streamout)
        desc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_STREAM_OUTPUT;
else
        desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;

     if(dynamic)
    {
        desc.Usage = D3D11_USAGE_DYNAMIC;
        desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE
}
else
{
    desc.Usage = D3D11_USAGE_IMMUTABLE;
    desc.CPUAccessFlags =  0;
}

ID3DBuffer* pBuffer =  0;
HRESULT hr = pDevice->CreateBuffer(&desc,pData,&pBuffer);
if(FAILED(hr))
{
     return  0;
}
return pBuffer;
}

 

 

Index buffer

         Index buffer的基本操作都与vertex buuffer基本类似,详细请参考sdk文档。

 

 

-------------------------------------to be continue----------------------------------

 

本文以及未来文章中的代码都未经编译测试

关于DirectX 11 pipeline流程图,参考 这里

你可能感兴趣的:(The Beauty of DirectX 11 (2) --- Resource View & Vertex Buffer)