D3D12渲染技术之初始化流程

本文详细介绍了D3D12的初始化流程,包括创建窗体、创建ID3D12Device设备、创建Fence、检查设备MSAA支持、创建指令队列、交换链、描述符堆、渲染目标视图、深度/模板缓冲区及其视图,并设置了视口。通过这些步骤,为后续的D3D12图形编程打下基础。
摘要由CSDN通过智能技术生成

掌握了矩阵向量运算后,接下来我们要做的事情利用D3D12图形库API编程,也就是我们通常说的初始化D3D12,D3D12的初始化工作与以前的D3D9是完全不一样的,D3D12做了大幅的升级。但是每个D3D图形API都有自己的初始化流程,大家只要记住这个流程,学习起来就比较容易,就跟生产车架的流水线作业一样的原理,先做什么后做什么。其他的内容向里面添加就可以了,我们先聊聊D3D12的初始化流程,然后再编程实现。

D3D初始化

1、创建窗体
2、创建ID3D12Device设备
3、创建 ID3D12Fence用于查询descriptor 大小
4、检查设备是否支持4X MSAA
5、创建指令队列,指令列表和主指令列表。
6、创建交换链
7、创建描述符堆(descriptor heaps)
8、创建渲染目标视图。
9、创建深度/模板缓冲区及其关联的深度/模板视图。
10、设置视口

共分为10步,严格来说,第一步不属于D3D12初始化里面的内容,因为我们要显示D3D12中的内容,必须要要有窗体作为载体,在这里就把他们加进来了,我们下面就按照这10步去编写程序实现我们的D3D12的初始化工作。

  • 创建窗体
    窗体是一个载体,用于显示D3D12内容的,首先需要注册窗体类,把它们里面的参数填满,代码如下所示:
bool D3DApp::InitMainWindow()
{
    WNDCLASS wc;
    wc.style         = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc   = MainWndProc; 
    wc.cbClsExtra    = 0;
    wc.cbWndExtra    = 0;
    wc.hInstance     = mhAppInst;
    wc.hIcon         = LoadIcon(0, IDI_APPLICATION);
    wc.hCursor       = LoadCursor(0, IDC_ARROW);
    wc.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH);
    wc.lpszMenuName  = 0;
    wc.lpszClassName = L"MainWnd";

    if( !RegisterClass(&wc) )
    {
        MessageBox(0, L"RegisterClass Failed.", 0, 0);
        return false;
    }

    // Compute window rectangle dimensions based on requested client area dimensions.
    RECT R = { 0, 0, mClientWidth, mClientHeight };
    AdjustWindowRect(&R, WS_OVERLAPPEDWINDOW, false);
    int width  = R.right - R.left;
    int height = R.bottom - R.top;

    mhMainWnd = CreateWindow(L"MainWnd", mMainWndCaption.c_str(), 
        WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, 0, 0, mhAppInst, 0); 
    if( !mhMainWnd )
    {
        MessageBox(0, L"CreateWindow Failed.", 0, 0);
        return false;
    }

    ShowWindow(mhMainWnd, SW_SHOW);
    UpdateWindow(mhMainWnd);

    return true;
}

这个在DX9或者MFC中都会用到,这里就不介绍了,接下来开始进的入D3D12编程的正题了。

  • 创建ID3D12Device设备
    创建D3D12的设备,自然想到函数:D3D12CreateDevice,在D3D12中我们还需要做一件事情就是调用函数:CreateDXGIFactory1在这个函数中有DXGI字样,DXGI它是DirectX Graphics Infrastructure的缩写,DXGI 可以操控一些普通的图形功能,这其中包括全屏转换、枚举图形系统信息(比如显示适配器、显示器、被支持的显示模式(分辨率,刷新率等等)),它还定义了各种纹理格式(DXGI_FORMAT)。CreateDXGIFactory1就是DXGI下面的一个接口函数,可以枚举显示适配器。
    函数调用代码如下:
CreateDXGIFactory1(IID_PPV_ARGS(&mdxgiFactory))

其中 IID_PPV_ARGS 宏用来返回 COM 接口的 ID
接下来调用D3D12CreateDevice函数,代码实现如下:

HRESULT hardwareResult = D3D12CreateDevice(
        nullptr,             // default adapter
        D3D_FEATURE_LEVEL_11_0,
        IID_PPV_ARGS(&md3dDevice));


    if(FAILED(hardwareResult))
    {
        ComPtr<IDXGIAdapter> pWarpAdapter;
        ThrowIfFailed(mdxgiFactory->EnumWarpAdapter(IID_PPV_ARGS(&pWarpAdapter)));

        ThrowIfFailed(D3D12CreateDevice(
            pWarpAdapter.Get(),
            D3D_FEATURE_LEVEL_11_0,
            IID_PPV_ARGS(&md3dDevice)));
    }

if条件语句内部就是枚举适配器的代码,设备创建好了以后,下面就是创建Fence了。

  • 创建 ID3D12Fence
    接下来我们需要创建Fence对象用于CPU/GPU同步,另外,一旦我们开始使用描述符,我们将需要知道它们的大小, 描述符大小可能因GPU而异,因此我们需要查询此信息, 我们缓存描述符的大小,以便在我们需要它时可用于各种描述符类型,代码如下所示:
    ThrowIfFailed(md3dDevice->CreateFence(0, D3D12_FENCE_FLAG_NONE,
        IID_PPV_ARGS(&mFence)));

    mRtvDescriptorSize = md3dDevice->GetDescriptorHandleIncrementSize(D3D12_
  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
DirectX 12初始化流程包括以下几个步骤: 1. 创建ID3D12Device对象:通过调用D3D12CreateDevice函数创建ID3D12Device对象,这是DirectX 12中最重要的对象,代表了GPU的实例。 2. 创建ID3D12CommandQueue对象:通过ID3D12Device对象创建ID3D12CommandQueue对象,用于将命令列表提交给GPU执行。 3. 创建交换链:调用IDXGIFactory::CreateSwapChain()函数创建交换链,用于管理渲染目标的呈现和切换。 4. 创建渲染目标视图RTV:通过交换链获取渲染目标的纹理资源,并创建与其对应的渲染目标视图RTV。 5. 创建深度模板缓存视图DSV(可选):根据需要创建深度模板缓存视图DSV,用于深度测试和模板测试。 6. 创建常量缓存视图CBV(可选):根据需要创建常量缓存视图CBV,用于传递常量数据给着色器。 7. 创建顶点缓冲区VB和索引缓冲区IB(可选):根据需要创建顶点缓冲区VB和索引缓冲区IB,用于存储顶点和索引数据。 8. 创建着色器资源视图SRV(可选):根据需要创建着色器资源视图SRV,用于绑定纹理等资源。 9. 创建根签名:根据需要创建根签名,用于绑定常量缓存视图、着色器资源视图、采样器等资源。 10. 创建管道状态对象PSO:创建管道状态对象PSO,用于描述GPU渲染流水线的状态,包括着色器、根签名、渲染目标、深度模板缓存等状态信息。 11. 创建命令列表:创建命令列表,并通过ID3D12GraphicsCommandList::Close()函数关闭命令列表。 12. 提交命令列表:将命令列表提交给ID3D12CommandQueue对象,通过调用ID3D12CommandQueue::ExecuteCommandLists()函数实现。 13. 等待GPU执行完毕:通过ID3D12Fence对象等待GPU执行完毕,从而保证CPU和GPU的同步。 上述步骤是DirectX 12初始化流程的基本步骤,具体实现可以根据需要进行修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海洋_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值