(转载请注明出处)
首先得修正一个错误, 前一节说到了Fence中用到帧编号, 这个帧编号应该(?)要大于0, 所以初始化为1就好了, 否则(这一节中)第二次渲染会出一点小错误.(╯‵□′)╯︵┴─┴
在第一节有提到资源绑定, 一般的descriptor, 还有就是一个特殊的Root Signatures, 微软提到
The root signature defines what resources are bound to the graphics pipeline. A root signature is configured by the app and links command lists to the resources the shaders require. Currently, there is one graphics and one compute root signature per app.
就是说这个Root Signature是被绑定到图像渲染管线上的资源, 我们可以利用D3D12SerializeRootSignature先序列化一个Root Signature, 将创建的ID3DBlob(其实就是ID3D10Blob的马甲) 传给ID3D12Device::CreateRootSignature用来创建RootSignature.
不像Descriptor那样可以创建连续的多个, 只能单个创建. 说完Root Signature就进入这次的主题, Pipeline State Object(PSO), 这也是与D3D11的重大差别之一, 在官方的博客中提到, 在D3D11中, 渲染管线每个阶段都可以独立控制, 很方便, 但是也造成了性能的浪费, 驱动需要提供实时Get/Set:
在D3D12中, 通过将这些糅合成一个不可再变的PSO, 不过有提到:
Which PSO is in use can still be changed dynamically, but to do so the hardware only needs to copy the minimal amount of pre-computed state directly to the hardware registers, rather than computing the hardware state on the fly.
不过就认为不可变也不为过, 有点类似于以前的固定管线, 不过这个可以多创建几个PSO, 常见的几种组合够用了:
可以使用ID3D12Device::CreateGraphicsPipelineState来创建一个PSO, 最后两个参数REFIID, void**什么的就不说了, 说一下第一个参数D3D12_GRAPHICS_PIPELINE_STATE_DESC, (╯‵□′)╯︵┴─┴, 这个东西好大, 在x86下, 都有500+字节:
typedef struct D3D12_GRAPHICS_PIPELINE_STATE_DESC {
ID3D12RootSignature *pRootSignature;
D3D12_SHADER_BYTECODE VS;
D3D12_SHADER_BYTECODE PS;
D3D12_SHADER_BYTECODE DS;
D3D12_SHADER_BYTECODE HS;
D3D12_SHADER_BYTECODE