4.3 初始化Direct3D
- 用D3D12CreateDevice函数创建ID3D12Device接口实例
- 创建一个ID3D12Fence对象,并查询描述符大小
- 检测用户设备对4X MSAA质量级别的支持情况
- 依次创建命令队列、命令列表分配器和主命令列表
- 描述并创建交换链
- 创建应用程序所需的描述符堆
- 调整后台缓冲区的大小,并为其创建渲染目标视图
- 创建深度缓冲区以及与之关联的深度视图
- 设置视口和裁剪矩形
4.3.1 创建设备
初始化D3D必须先创建D3D12设备(代表3D图形硬件或者软件模拟的图形硬件)。D3D12设备可以检测系统环境对功能的支持情况,也能创建其他D3D接口对象。
HRESULT WINAPI D3D12CreateDevice(
IUnknown* pAdapter,
//指定创建设备时采用的主显示适配器,设nullptr时表示用主显示适配器
D3D_FEATURE_LEVEL MinimunFeatureLevel,
//程序需要硬件支持的最低功能级别,不支持会创建失败,建议用D3D11的特性
REFIID riid,//创建的ID3D12Device的COM ID
void** ppDevice//返回创建好的D3D12设备
);
4.3.2 创建围栏并获取描述符大小
创建好设备之后就可以为CPU和GPU的同步而创建围栏了。使用描述符需要了解它们的大小,然而其在不同GPU平台上大同小异,需要查询相关信息。可以将描述符大小缓存起来,需要时直接引用
ThrowIfFailed(md3dDevice->CreateFence(
0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&mFence)));
mRtvDescriptorSize = md3dDevice->GetDescriptorHandleIncrementSize(
D3D12_DESCRIPTOR_HEAP_TYPE_RTV);
mRtvDescriptorSize = md3dDevice->GetDescriptorHandleIncrementSize(
D3D12_DESCRIPTOR_HEAP_TYPE_DSV);
mCbvSrvUavDescriptorSize = md3dDevice->GetDescriptorHandleIncrementSize(
D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
4.3.3 检测对4X MSAA质量级别的支持情况
4x就够用好用,要额外加上对质量级别的检测
D3D12_FEATURE_DATA_MULTISAMPLE_QUALITY_LEVELS msQualityLevels;
msQualityLevels.Format = mBackBufferFormat;
msQualityLevels.SampleCount = 4;
msQualityLevels.Flags = D3D12_MULTISAMPLE_QUALITY_LEVELS_FLAG_NONE;
msQualityLevels.NumQualityLevels = 0;
ThrowIfFailed(md3dDevice->CheckFeatureSupport(
D3D12_FEATURE_MULTISAMPLE_QUALITY_LEVELS,
&msQualityLevels,
sizeof(msQualityLevels)));
m4xMsaaQuality = msQualityLevels.NumQualityLevels;
assert(m4xMsaaQuality > 0 && "Unexpected MSAA quality level.");
4.3.4 创建命令队列和命令列表
void D3DApp::CreateCommandObjects()
{
D3D12_COMMAND_QUEUE_DESC queueDesc = {};
queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
ThrowIfFailed(md3dDevice->CreateCommandQueue(
&queueDesc,IID_PPV_ARGS(&mCommandQueue)));
ThrowIfFailed(md3dDevice->CreateCommandAllocator(
D3D12_COMMAND_LIST_TYPE_DIRECT,
IID_PPV_ARGS(mDirectCmdListAlloc.GetAddressOf())));
ThrowIfFailed(md3dDevice->CreateCommandList(
0,
D3D12_COMMAND_LIST_TYPE_DIRECT,
mDirectCmdListAlloc.Get(), //关联命令分配器
nullptr, //初始化流水线状态对象
IID_PPV_ARGS(mCommandList.GetAddressOf())));
//先将命令列表关闭。因为第一次引用它时要重置,在调用重置方法前需要关闭
mCommandList->Close();
}
太多了,不想写了,下次一定