DX12学习笔记(龙书)(小点6:用描述符将常量缓冲区绑定到渲染流水线上)

在4.1.6中,我们介绍了如何建立一个描述符堆。并通过GetCPUDescriptorHandleForHeapStart方法来获得描述符堆的第一个描述符的句柄。
在4.3.7中,我们学到如何为交换链中的缓冲区创建一个PTV。
首先在交换链中GetBuffer获得缓冲区地址,然后调用md3dDevice的CreateRenderTargetView函数,传入buffer地址和描述符堆地址。

在6.6.4中,我们要把常量缓冲区绑定到渲染流水线上。
首先,这种描述符要放在D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV类信息所建的描述符堆里。这种堆内可以混合储存常量缓冲区描述符、着色器资源描述符和无序访问描述符。

  1. 创建描述符堆。
D3D13_DESCRIPTOR_HEAP_DESC cbvHeapDesc;
cbvHeapDesc.NumDescriptors=1;
cbvHeapDesc.Type=D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
cbvHeapDesc.Flags=D3D13_DESCRIPTOR_HEAP_FLAG_SHADER_VIDIBLE;//这个Flags很重要。这个和其他描述符堆不一样。
cbvHeapDesc.NodeMask=0;

ComPtr<ID3D12DescriptorHeap> mCbvHeap;
md4dDevice->CreateDescriptorHeap(&cbvHeapDesc),IID_PPV_ARGS(&mCbvHeap);
  1. 创建常量缓存区视图。用的是CreateConstantBufferView(),这个函数有两个参数,一个是结构地址(其中包含了资源位置),一个是堆地址。
struct ObjectConstants
{DirectX::XMFLOAT4X4 WorldViewProj = MathHelper::Identity4x4();}

上面是需要储存的数据。

我们建立一个可以储存很多个上述内容的常量缓存区。

在
std::unique_ptr<UploadBuffer<ObjectConstants>> mObjectCB =nullptr;
mObjectCB=std::make_unique<uploadBuffer<ObjectConstants>>
(md3dDevice.Get(),n,true);

UINT mElementByteSize=d3dUtil::CalcConstantBufferByteSize(sizeof(ObjectConstants))

//获得缓冲区的起始地址
D3D12_GPU_VIRTUAL_ADDRESS cbAddress=mObjectCB->Resource()->GetGPUVirtualAddress();

//偏移到常量缓冲区中绘制第i个物体所需要的常量数据
int boxCBufIndex=i;
cbAddress += boxCBufferIndex*objCBByteSize;

//这个desc描述的是绑定到HLSL常量缓冲区结构体的常量缓冲区资源子集。
D3D13_CONSTANT_BUFFER_VIEW_DESC cbvDesc;
cbvDesc.BufferLocation=cbAddress; 
cbvDesc.SizeInBytes=d3dUtil::CalcConstantBufferByteSize(sizeof(ObjectConstants));

md3dDevice->CreateConstantsBufferView(&cbvDesc,mCbvHeap->GetCPUDescriptorHandleForHeapStart();
)

重点来啦。当我们说我们把着色器需要的资源绑定到渲染流水线上时,其实不同类型的资源会被绑定到特点的寄存器槽(register slot)上,以供着色器程序访问。
比如说,前文代码中的【顶点着色器】和【像素着色器】需要的是一个绑定到寄存器【b0】的常量缓冲区。
寄存器槽就是向着色器传递资源的手段,register表示寄存器传递的资源类型。可以是t->着色器资源视图,s_>采样器,u_无序访问视图以及b_常量缓冲区视图。

Texture2D gDiffuseMap :register(t0);表示将纹理资源绑定到纹理寄存器槽0
所以我们之前看到的这个,将常量缓冲区资源绑定到缓冲区(cbuffer)寄存槽0,其实以及是绑定了的。
cbuffer cbPerObject:register(b0){/
float4x4 gworld;
float4x4 gTexTransform;
}

接下来有一个新的东西:
在执行绘制命令之前,应用程序将绑定到渲染流水线上的资源,映射到对应的输入寄存器。这个是根签名进行定义的。下一小点来看根签名。

你可能感兴趣的:(DX12学习笔记(龙书)(小点6:用描述符将常量缓冲区绑定到渲染流水线上))