我们现在需要创建深度/模板缓冲区。 如§4.1.5所述,深度缓冲区只是一个2D纹理,用于存储最近的可见对象的深度信息(如果使用模板(stencil),则也会存储模板信息)。 纹理是一种GPU资源,因此我们通过填写描述纹理资源的D3D12_RESOURCE_DESC结构,然后调用ID3D12Device :: CreateCommittedResource方法来创建一个。 D3D12_RESOURCE_DESC结构定义如下:

typedef struct D3D12_RESOURCE_DESC {
D3D12_RESOURCE_DIMENSION Dimension;
UINT64 Alignment;
UINT64 Width;
UINT Height;
UINT16 DepthOrArraySize;
UINT16 MipLevels;
DXGI_FORMAT Format;
DXGI_SAMPLE_DESC SampleDesc;
D3D12_TEXTURE_LAYOUT Layout;
D3D12_RESOURCE_MISC_FLAG MiscFlags;
} D3D12_RESOURCE_DESC;

1.Dimension:资源的维度,它是以下枚举类型之一:

enum D3D12_RESOURCE_DIMENSION
  {
    D3D12_RESOURCE_DIMENSION_UNKNOWN = 0,
    D3D12_RESOURCE_DIMENSION_BUFFER = 1,
    D3D12_RESOURCE_DIMENSION_TEXTURE1D = 2,
    D3D12_RESOURCE_DIMENSION_TEXTURE2D = 3,
    D3D12_RESOURCE_DIMENSION_TEXTURE3D = 4
  } D3D12_RESOURCE_DIMENSION;

2.Width:纹理的宽度,以纹素为单位。对于缓冲区资源,这是缓冲区中的字节数。

3.Height:纹理的高度,以纹素为单位。

4.DepthOrArraySize:纹理的纹理深度,或纹理数组大小(对于1D和2D纹理)。请注意,您不能拥有3D纹理的纹理数组。

5.MipLevels:mipmap级别的数量。有关纹理的第9章介绍了Mipmap。为了创建深度/模板缓冲区,我们的纹理只需要一个mipmap级别。
格式:DXGI_FORMAT枚举类型的成员,指定纹素的格式。对于深度/模板缓冲区,这需要是§4.1.5中所示的格式之一。

6.SampleDesc:多重采样和质量等级的数量;见§4.1.7和§4.1.8。回想一下,4X MSAA使用比屏幕分辨率大4倍的后缓冲和深度缓冲,以便存储每个子像素的颜色和深度/模板信息。因此,用于深度/模板缓冲区的多重采样设置必须与用于渲染目标的设置相匹配。

7.Layout:D3D12_TEXTURE_LAYOUT枚举类型的成员,指定纹理布局。目前,我们不必担心布局,可以指定D3D12_TEXTURE_LAYOUT_UNKNOWN

8.MiscFlags:杂项资源标志。对于深度/模板缓冲区资源,请指定D3D12_RESOURCE_MISC_DEPTH_STENCIL。

GPU资源存在于堆中,这些资源本质上是具有某些属性的GPU内存块。 ID3D12Device :: CreateCommittedResource方法将我们指定了属性的资源创建并提交给内存块:

HRESULT ID3D12Device::CreateCommittedResource(
const D3D12_HEAP_PROPERTIES *pHeapProperties,
D3D12_HEAP_MISC_FLAG HeapMiscFlags,
const D3D12_RESOURCE_DESC *pResourceDesc,
D3D12_RESOURCE_USAGE InitialResourceState,
const D3D12_CLEAR_VALUE *pOptimizedClearValue,
REFIID riidResource,
void **ppvResource); typedef struct D3D12_HEAP_PROPERTIES {
D3D12_HEAP_TYPE Type;
D3D12_CPU_PAGE_PROPERTIES CPUPageProperties;
D3D12_MEMORY_POOL MemoryPoolPreference;
UINT CreationNodeMask;
UINT VisibleNodeMask;
} D3D12_HEAP_PROPERTIES;

1.pHeapProperties:我们要将资源提交到的堆的属性。其中一些属性用于高级用法。目前,我们需要考虑的主要属性是D3D12_HEAP_TYPE,它可以是D3D12_HEAP_PROPERTIES枚举类型的以下成员之一:
  D3D12_HEAP_TYPE_DEFAULT:默认堆。这是我们提交的资源将只由GPU单独访问的地方。以深度/模板缓冲区为例:GPU读取和写入深度/模板缓冲区。 CPU永远不需要访问它,因此深度/模板缓冲区将被放置在默认堆中;
  D3D12_HEAP_TYPE_UPLOAD:上传堆。如果我们需要将数据从CPU上传到GPU,我们需要将资源提交到这里;
  D3D12_HEAP_TYPE_READBACK:回读堆(Read-back heap)。如果我们提交的资源需要被CPU读取,我们就将资源提交到这里;
  D3D12_HEAP_TYPE_CUSTOM:高级场景使用,请参阅MSDN文档以获取更多信息。

旁注:应将资源放在默认堆中以获得最佳性能。 仅在需要相应功能时才使用上传或回读堆。
2.HeapMiscFlags:有关我们要将资源提交到的堆的其他标志。这通常是D3D12_HEAP_MISC_NONE。
3.pResourceDesc:指向描述我们要创建的资源的D3D12_RESOURCE_DESC实例的指针。
4.InitialResourceState:回顾§4.2.3资源具有当前使用状态。使用此参数可在创建资源时设置资源的初始状态。对于深度/模板缓冲区,初始状态将为D3D12_RESOURCE_USAGE_INITIAL,然后我们将要将其转换为D3D12_RESOURCE_USAGE_DEPTH,以便它可以作为深度/模板缓冲区绑定到管道。
5.pOptimizedClearValue:指向D3D12_CLEAR_VALUE对象的指针,该对象描述清除资源的优化值。与优化的清除值匹配的清除呼叫可能比与优化的清除值不匹配的清除呼叫更快。也可以为此值指定Null,以不指定优化的清除值。

struct D3D12_CLEAR_VALUE
{
DXGI_FORMAT Format;
union {
FLOAT Color[ ];
D3D12_DEPTH_STENCIL_VALUE DepthStencil;
};
}D3D12_CLEAR_VALUE;

6.riidResource:我们想要获取指针的ID3D12Resource接口的COM ID。
7.ppvResource:返回指向ID3D12Resource的指针,该ID3D12Resource表示新创建的资源。

此外,在使用深度/模板缓冲区之前,我们必须创建一个关联的深度/模板视图以绑定到管道。 这与创建渲染目标视图类似。 下面的代码示例显示了我们如何创建深度/模板纹理及其相应的深度/模板视图:

// Create the depth/stencil buffer and view.
D3D12_RESOURCE_DESC depthStencilDesc;
depthStencilDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;
depthStencilDesc.Alignment = ;
depthStencilDesc.Width = mClientWidth;
depthStencilDesc.Height = mClientHeight;
depthStencilDesc.DepthOrArraySize = ;
depthStencilDesc.MipLevels = ;
depthStencilDesc.Format = mDepthStencilFormat;
depthStencilDesc.SampleDesc.Count = m4xMsaaState ? : ;
depthStencilDesc.SampleDesc.Quality = m4xMsaaState ? (m4xMsaaQuality - ) : ;
depthStencilDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
depthStencilDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; D3D12_CLEAR_VALUE optClear;
optClear.Format = mDepthStencilFormat;
optClear.DepthStencil.Depth = 1.0f;
optClear.DepthStencil.Stencil = ;
ThrowIfFailed(md3dDevice->CreateCommittedResource(
&CD3DX12_HEAP_PROPERTIES(D3D12_HEAP_TYPE_DEFAULT),
D3D12_HEAP_FLAG_NONE,
&depthStencilDesc,
D3D12_RESOURCE_STATE_COMMON,
&optClear,
IID_PPV_ARGS(mDepthStencilBuffer.GetAddressOf())));
// Create descriptor to mip level 0 of entire resource using the
// format of the resource.
md3dDevice->CreateDepthStencilView(
mDepthStencilBuffer.Get(),
nullptr,
DepthStencilView()); // Transition the resource from its initial state to be used as a depth buffer.
mCommandList->ResourceBarrier(
,
&CD3DX12_RESOURCE_BARRIER::Transition(
mDepthStencilBuffer.Get(),
D3D12_RESOURCE_STATE_COMMON,
D3D12_RESOURCE_STATE_DEPTH_WRITE));
Note that we use the CD3DX12_HEAP_PROPERTIES helper constructor to create the heap properties structure, which is implemented like so:
explicit CD3DX12_HEAP_PROPERTIES(
D3D12_HEAP_TYPE type,
UINT creationNodeMask = ,
UINT nodeMask = )
{
Type = type;
CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
CreationNodeMask = creationNodeMask;
VisibleNodeMask = nodeMask;
}

CreateDepthStencilView的第二个参数是指向D3D12_DEPTH_STENCIL_VIEW_DESC的指针。 除此之外,该结构描述了资源中元素的数据类型(格式)。 如果资源是使用类型化格式(即非无类型)创建的,则此参数可以为null,这表示创建此资源的第一个mipmap级别的视图(深度/模板缓冲区仅使用一个mipmap级别创建 )使用创建资源的格式。 (Mipmap在第9章中讨论。)因为我们指定了深度/模板缓冲区的类型,所以我们为此参数指定null。

【D3D12学习手记】4.3.8 Create the Depth/Stencil Buffer and View的更多相关文章

  1. 【D3D12学习手记】The Command Queue and Command Lists

    GPU有一个命令队列,CPU通过Direct3D API将命令提交到队列里来使用命令列表(command lists),如下图.当一套命令(a set of commands)已经被提交到命令队列,他 ...

  2. 【D3D12学习手记】4.1.6 Resources and Descriptors

    在渲染过程中,GPU将写资源(resources)(例如,后缓冲区,深度/模板缓冲区),读资源(例如,描述表面外观的纹理,存储场景中几何体3D位置的缓冲区).在我们发出绘图命令之前,我们需要将资源绑定 ...

  3. 【D3D12学习手记】The Swap Chain and Page Flipping

    为了避免动画中的闪烁,最好将整个动画帧绘制到称为后台缓冲区的屏幕外纹理(off-screen texture)中.一旦整个场景被绘制到给定动画帧的后缓冲区,它就作为一个完整的帧呈现给屏幕;以这种方式, ...

  4. 【D3D12学习手记】CPU/GPU Synchronization

    由于有两个并行运行的处理器(CPU和GPU),会出现许多同步问题.假设我们有一些资源R存储了我们希望绘制的某些几何体的位置. 此外,假设CPU更新R的数据以存储位置p1,然后将引用R的绘图命令C添加到 ...

  5. ROS学习手记 - 2.1: Create and Build ROS Package 生成包(Python)

    ROS学习手记 - 2.1: Create and Build ROS Package 生成包(Python) 时隔1年,再回来总结这个问题,因为它是ros+python开发中,太常用的一个操作,需要 ...

  6. Linux.NET学习手记(7)

    前一篇中,我们简单的讲述了下如何在Linux.NET中部署第一个ASP.NET MVC 5.0的程序.而目前微软已经提出OWIN并致力于发展VNext,接下来系列中,我们将会向OWIN方向转战. 早在 ...

  7. Linux.NET学习手记(8)

    上一回合中,我们讲解了Linux.NET面对OWIN需要做出的准备,以及介绍了如何将两个支持OWIN协议的框架:SignalR以及NancyFX以OwinHost的方式部署到Linux.NET当中.这 ...

  8. 关于《Linux.NET学习手记(8)》的补充说明

    早前的一两天<Linux.NET学习手记(8)>发布了,这一篇主要是讲述OWIN框架与OwinHost之间如何根据OWIN协议进行通信构成一套完整的系统.文中我们还直接学习如何直接操作OW ...

  9. EF框架学习手记

    转载: [ASP.NET MVC]: - EF框架学习手记 1.EF(Entity Framework)实体框架EF是ADO.NET中的一组支持开发面向数据的软件应用程序的技术,是微软的一个ORM框架 ...

随机推荐

  1. 22_6mybatis中的缓存

    1.mybatis中的延时加载 问题:在一对多中,当我们有一个用户,它有100个账户. 在查询用户的时候,要不要把关联的账户查出来? 在查询账户的时候,要不要把关联的用户查出来? 在查询用户时,用户下 ...

  2. python+Appium自动化:记录遇到的坑

    1.打开 uiautomatorviewer同步的的时候突然报错 Error while obtaining UI hierarchy XML file: com.android.ddmlib.Syn ...

  3. Mybatis XML配置(转载)

    原文地址:https://www.w3cschool.cn/mybatis/f4uw1ilx.html Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它 ...

  4. Myeclipse中左边的项目目录没了

    切换一下Perspective, java, resource都有项目窗口 具体的 Window->Open Perspective 如果项目窗口被关了的话 windows->show v ...

  5. springboot打包后静态资源webapp文件夹无法打包进去

    1.如下图的目录结构 webapp 文件夹和resources 文件夹同级.使用mvn clean install 打包过后项目启动访问,静态资源页面404. 2.原因,springboot 打包时候 ...

  6. linux中强大的编辑工具vim

    先来个图镇贴 vim是一个模式编辑器.由三种主要模式比较常用: 1.命令(Normal)模式:默认模式,移动光标,剪切/粘贴文本 2.插入(Insert)或编辑模式:修改文本 3.扩展命令(exten ...

  7. WCF错误:由于目标计算机积极拒绝,无法连接;127.0.0.1:3456

    问题描述 最近Windows打完补丁,原来部署在本机的WCF无法连接:出现如下WCF错误:由于目标计算机积极拒绝,无法连接:127.0.0.1:3456 解决方案 检查一下本机的服务:NetTcpAc ...

  8. What is a Digital Signature? 理解数字签名与数字证书

    What is a Digital Signature?An introduction to Digital Signatures, by David Youd Bob (Bob's public k ...

  9. yii项目连接多个数据库时, MySQL报错No such file or directory

    服务器错误 yii\db\Exception SQLSTATE[HY000] [2002] No such file or directory ###'xxx是项目根目录' #0 xxx/vendor ...

  10. [Docker]Harbor部署私有镜像仓库

    Harbor部署私有镜像仓库 认识: Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器. 部署环境: CentOS7 Python2.7.5 Docker CE ...