DirectX12 绘制流程
一、Dx12绘制流程
一、重置上传
二、提交命令
1、前言
2、把后缓冲区的资源状态切换成Render Target
3、设置视口和裁剪区域
4、清空后缓存和深度缓存
5、输出的合并阶段
6、把后缓冲区切换成PRESENT状态
7、录入完成,提交命令
三、页面翻转
四、执行同步
五、全流程代码
六、效果展示
一、Dx12绘制流程
上一章说完了Dx12的初始化,接下来就是核心了,开始绘制画面。 这一阶段,就是CPU向GPU送任务,处理,如此往复即可,具体可以理解为如下几个步骤: 1、重置上传; 2、提交命令; 3、页面翻转; 4、等待同步;
一、重置上传
在每次渲染绘制之前,都要把上传相关的进行重置,当初用快递举例,但快递是接收到,快递壳子就丢掉了,但这里不是,只是重置而已,其目的就是为了避免删除后再创建这样的开销;
void cDx12Rendering::ResetCMDListAlloctor()
{
//重置上传
m_spCommandAllocator->Reset();
m_spGraphicsCommandList->Reset(m_spCommandAllocator.Get(), NULL);
}
二、提交命令
提交绘制任务是绘制的绝对核心,也是开放了很复杂的参数,用来“本地化”Dx12的通用方案,以期达到想要的渲染效果。 也因为任务的可定制化极高,这里将会涉及到动辄上千的代码,但暂时先采用最简单的绘制让我们有一个总体的印象,细节将会在后面的章节不断补充。 先,来绘制一个纯色背景吧。
void cDx12Rendering::SubmitDrawingTask()
{
//把后缓冲区的资源状态切换成Render Target
CD3DX12_RESOURCE_BARRIER ResourceBarrierPresent = CD3DX12_RESOURCE_BARRIER::Transition(
vecRTVBuffer[m_iCurrentSwapBuffIndex].Get(),
D3D12_RESOURCE_STATE_PRESENT,
D3D12_RESOURCE_STATE_RENDER_TARGET);
m_spGraphicsCommandList->ResourceBarrier(1, &ResourceBarrierPresent);
//设置视口和裁剪区域
m_spGraphicsCommandList->RSSetViewports(1, &m_dvViewprotInfo);
m_spGraphicsCommandList->RSSetScissorRects(1, &m_drViewprotRect);
//清空后缓存和深度缓存
m_spGraphicsCommandList->ClearRenderTargetView(
CD3DX12_CPU_DESCRIPTOR_HANDLE(
m_spRTVHeap->GetCPUDescriptorHandleForHeapStart(),
m_iCurrentSwapBuffIndex,
m_iRTVDescriptorSize),
DirectX::Colors::Blue,
0, nullptr);
m_spGraphicsCommandList->ClearDepthStencilView(
m_spDSVHeap->GetCPUDescriptorHandleForHeapStart(),
D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL,
1.f, 0, 0, NULL);
//输出的合并阶段
D3D12_CPU_DESCRIPTOR_HANDLE SwapBufferView = CD3DX12_CPU_DESCRIPTOR_HANDLE(
m_spRTVHeap->GetCPUDescriptorHandleForHeapStart(),
m_iCurrentSwapBuffIndex,
m_iRTVDescriptorSize);
D3D12_CPU_DESCRIPTOR_HANDLE DepthStencilView = m_spDSVHeap->GetCPUDescriptorHandleForHeapStart();
m_spGraphicsCommandList->OMSetRenderTargets(
1,
&SwapBufferView,
true,
&DepthStencilView);
//把后缓冲区切换成PRESENT状态
CD3DX12_RESOURCE_BARRIER ResourceBarrierPresentRenderTarget = CD3DX12_RESOURCE_BARRIER::Transition(
vecRTVBuffer[m_iCurrentSwapBuffIndex].Get(),
D3D12_RESOURCE_STATE_RENDER_TARGET,
D3D12_RESOURCE_STATE_PRESENT);
m_spGraphicsCommandList->ResourceBarrier(1, &ResourceBarrierPresentRenderTarget);
//录入完成,提交命令
m_spGraphicsCommandList->Close();
ID3D12CommandList* pCommandList[] = {
m_spGraphicsCommandList.Get() };
m_spCommandQueue