(转载请注明出处)

请叫我挖坑狂魔_(:3」∠)_


微软前几天发布了Win10的开发工具,希望使用的童鞋可以加入windows insider计划 进行下载.

下面是我的环境:

  • Windows 10 Technical Preview Build 10041
  • Visual Studio 2015 CTP 6
  • Visual Studio Tools for Windows 10

当然,使用的是虚拟机.

D3D12文档可以在官方文档里面进行查看,里面有编程向导与API文档. 不过, 这个文档也是初步的, 可能链接会失效.

初始化:

初始化COM组件和创建窗口就不再累述,直接杀入主题:
和D3D11类似, 使用D3D12CreateDevice创建D3D12设备,目前,函数声明如下:

HRESULT WINAPI D3D12CreateDevice(IDXGIAdapter* pAdapter,D3D_DRIVER_TYPE DriverType,D3D12_CREATE_DEVICE_FLAG Flags,D3D_FEATURE_LEVEL MinimumFeatureLevel,UINT SDKVersion,REFIID riid,void** ppDevice );

第一个是显卡适配器, 可以枚举, 可以为nullptr,
第二个是驱动类型, 我这里是虚拟机, 所以选择WARP
第三个是创建flag(没有RGBA支持,也就是说不能链接D2D?)
第四个是特性等级, 现在还没有12的等级,所以选择11.1
第五个是SDK版本, 使用宏D3D12_SDK_VERSION即可
第五个第六个也就很熟悉了, 假如只是用MSC编译, 可以使用宏
IID_PPV_ARGS,不过对于GCC等编译器还是手写吧:

        D3D12_CREATE_DEVICE_FLAG flags = D3D12_CREATE_DEVICE_NONE;
#ifdef _DEBUGflags |= D3D12_CREATE_DEVICE_DEBUG;
#endifhr = ::D3D12CreateDevice(nullptr,D3D_DRIVER_TYPE_WARP,flags,D3D_FEATURE_LEVEL_11_1,D3D12_SDK_VERSION,IID_ID3D12Device,reinterpret_cast<void**>(&m_pd3dDevice));

不知道是不是bug还是没有实现还是什么原因,不能像D3D11那样利用d3d设备获取dxgi设备, 再balabala创建交换链。 所以这里利用CreateDXGIFactory2创建Dxgi工厂

        hr = ::CreateDXGIFactory2(0,IID_IDXGIFactory2, reinterpret_cast<void**>(&m_pDxgiFactory));

再使用IDXGIFactory2::CreateSwapChainForHwnd为窗口创建交换链, 需要注意的是第一个参数,用过D3D11的童鞋可能习惯性地传个D3D12设备指针,不过这是错误的,调用可能没问题, 但是呈现时会出错,第一个参数应该传一个ID3D12CommandQueue指针,所以我们还应该创建一个D3D12的命令队列, 官方给的向导里面可以获取一个默认的队列,但是发现现在这个接口被移除了,只能直接创建了:

    // 创建命令队列if (SUCCEEDED(hr)) {D3D12_COMMAND_QUEUE_DESC desc = {D3D12_COMMAND_LIST_TYPE_DIRECT,0,D3D12_COMMAND_QUEUE_NONE,0};hr = m_pd3dDevice->CreateCommandQueue(&desc,IID_ID3D12CommandQueue,reinterpret_cast<void**>(&m_pCmdQueue));}// 创建交换链if (SUCCEEDED(hr)) {RECT rect = { 0 };  ::GetClientRect(m_hwnd, &rect);// 交换链信息DXGI_SWAP_CHAIN_DESC1 swapChainDesc = { 0 };m_uBufferWidth = swapChainDesc.Width = rect.right - rect.left;m_uBufferHeight = swapChainDesc.Height = rect.bottom - rect.top;swapChainDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;swapChainDesc.Stereo = FALSE;swapChainDesc.SampleDesc.Count = 1;swapChainDesc.SampleDesc.Quality = 0;swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;swapChainDesc.BufferCount = 2;swapChainDesc.Scaling = DXGI_SCALING_STRETCH;swapChainDesc.Flags = 0;// 一般桌面应用程序swapChainDesc.AlphaMode = DXGI_ALPHA_MODE_UNSPECIFIED;swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;// 利用窗口句柄创建交换链hr = m_pDxgiFactory->CreateSwapChainForHwnd(m_pCmdQueue,m_hwnd,&swapChainDesc,nullptr,nullptr,&m_pSwapChain);}

D3D12中中显然的就是命令列表ID3D12CommandList, 其中一个实现是ID3D12GraphicsCommandList , 和Direct2D中的命令列表类似,不过可以重置.
这个图像命令列表的特点就是用来记录DrawCall, 完了就关闭, 然后高效重现.

为了创建图像命令列表, 我们需要创建一个命令分配器, 因为可以指定分配器的类型, 不然可以向D2D那样由设备上下文直接创建命令列表, 使用ID3D12Device::CreateCommandQueue:

    // 创建命令队列if (SUCCEEDED(hr)) {D3D12_COMMAND_QUEUE_DESC desc = {D3D12_COMMAND_LIST_TYPE_DIRECT,0,D3D12_COMMAND_QUEUE_NONE,0};hr = m_pd3dDevice->CreateCommandQueue(&desc,IID_ID3D12CommandQueue,reinterpret_cast<void**>(&m_pCmdQueue));}

这样创建一个D3D12_COMMAND_LIST_TYPE_DIRECT类型的分配器,这个是可以创建GPU可执行的命令列表.

现在终于可以创建一个图像命令列表ID3D12Device::CreateCommandList了:

    // 创建图像命令列表if (SUCCEEDED(hr)) {hr = m_pd3dDevice->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT,m_pCmdAllocator,nullptr,IID_ID3D12GraphicsCommandList,reinterpret_cast<void**>(&m_pGfxCmdList));}

这个图像命令列表就和D3D11的设备上下文一样可以执(ji)行(lu)具体渲染命令:


D3D11中, 我们可以从交换链中获取一个2D纹理, 但是D3D12中就没有2D纹理, 取代的是可以代表资源的ID3D12Resource接口, 直接获取就行了:

    // 获取缓冲区if (SUCCEEDED(hr)) {hr = m_pSwapChain->GetBuffer(0, IID_ID3D12Resource,reinterpret_cast<void**>(&m_pTargetBuffer));}

同样地, D3D11中, 可以使用设备创建RTV
(ID3D11Device::CreateRenderTargetView),

在D3D12中, 所有的资源都被绑定到”descriptor”标识符上面,还有descriptor tables, descriptor heaps, root signature什么的,详见资源绑定. 这里主要是descriptor 和 descriptor heap,主要区别, 前者是单个后者是连续.
因为(目前)没有ID3D12Device::CreateDescriptor, 所以使用ID3D12Device::CreateDescriptorHeap代替, 创建一个就好了, 以后有相同资源需要绑定, 可以创建一个descriptor heap一起使用.

    // 创建RTV描述符if (SUCCEEDED(hr)) {D3D12_DESCRIPTOR_HEAP_DESC desc = {D3D12_RTV_DESCRIPTOR_HEAP,1,D3D12_DESCRIPTOR_HEAP_NONE,0};hr = m_pd3dDevice->CreateDescriptorHeap(&desc, IID_ID3D12DescriptorHeap,reinterpret_cast<void**>(&m_pRTVDescriptor));}// 创建RTVif (SUCCEEDED(hr)) {m_pd3dDevice->CreateRenderTargetView(m_pTargetBuffer,nullptr,m_pRTVDescriptor->GetCPUDescriptorHandleForHeapStart());}

D3D11类似, 创建RTV, 不过没有专用的接口了, 用这个描述符就好了, 从这里和上面可以看出, D3D12没有了一大堆接口, 泛化了.


D3D11 中, 清屏很简单:

  1. 为当前设备上下文在OM阶段设置RTV
  2. 清理RTV

D3D12中:

  1. 为某图像命令列表在RS阶段设置RTV
  2. 为该命令列表对于资源(呈现缓存)设置Barrier表明从”用于呈现”变为”用于渲染对象”
  3. 清除RTV
  4. 设置Barrier, 变回来
  5. 关闭本命令列表
  6. 加入命令队列并执行

可以看出多了几步, 其实就多了两步: 设置资源Barrier过去, 设置Barrier回来. (因为D3D12对多线程渲染做了很多?) 资源Barrier就是为了处理资源的多个访问.

对于命令列表, 如果不再使用可以重置.
这部分代码就不放上来了, 可以看所附带的实例代码: 下载地址


下面就是成果图


已知问题

从输出窗口可以看出错误:

这个错误有机会再说吧_(:3」∠)_


代码下载地址在上面, 不要漏掉了

Direct3D 12 尝鲜: 基本呈现相关推荐

  1. Direct3D 12 尝鲜(五): SDK 更新

    (转载请注明出处) 又是一个月, 微软在Build2015中公布了不少关于Win10的新闻, 又在N卡公布的支持DX12显卡中看到了我的垃圾显卡(GT640M LE)居然在支持范围,高高兴兴地直接换物 ...

  2. Direct3D 12 尝鲜(二): Fence

    (转载请注明出处) 正如上节末尾所说, 出现了运行时错误: D3D12 ERROR: ID3D12CommandAllocator::Reset: A command allocator is bei ...

  3. 首台android手机号码,国内首批手机Android 12尝鲜列表已公布,华为与荣耀不在名单之上...

    今天凌晨,谷歌在 I/O 2021大会上正式发布Android 12操作系统,并且开放了Android 12 Beta 1的下载链接,除了可支持谷歌Pixel机型以外,国内的众多手机品牌也在首次尝鲜名 ...

  4. PHP 8.0 源码编译安装 JIT 尝鲜

    女主宣言 今天小编为大家分享一篇最简化的 PHP 8 源码编译安装方法.PHP 8.0 Alpha 1 已经在2020年6月25号发布了,今天带领大家快速尝鲜 PHP 8.0 的新特性 JIT.希望能 ...

  5. 尝鲜Ubuntu Server 12.04 LTS

    作为一个尝试远离Windows的Linux初学者,一直都比较关注对初学者来说比较简单的Ubuntu Server. 4月中旬之后有几次都需要装DB服务器,因为希望能够使用最新版本,所以就一直在等Ubu ...

  6. 鸿蒙系统支持名单,12月支持鸿蒙系统的机型名单!想尝鲜的可以注意了!

    来看看你的手机支持HarmonyOS(鸿蒙操作系统)吗?注意:12月18日开放Beta测试版,有想尝鲜的及时申请哦! 以下是华为鸿蒙操作系统2.0版支持的设备清单! HarmonyOS(鸿蒙操作系统) ...

  7. Debian 12 Bookworm 尝鲜记

    前几天在网上看到 Debian 12 的开发代号定下来了,是 Bookworm,好奇地去清华源看了一看,结果看到了这个: 我目瞪狗呆(0-0),Debian 12 不是预计在 2023 年中期发布吗? ...

  8. 鸿蒙系统开发者公测,公测尝鲜开启!华为Mate40/P40开始和安卓渐行渐远

    目前华为官方发布公告,华为EMUI的微博等相关官方媒体账号全部更名为HarmonyOS,这也意味着HarmonyOS将会成为华为在软件系统层面的重心,彻底替代基于Android的华为EMUI. 至于那 ...

  9. 前端每周清单第 49 期:Webpack 4 Beta 尝鲜,React Windowing 与 setState 分析

    前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点:分为新闻热点.开发教程.工程实践.深度阅读.开源项目.巅峰人生等栏目.欢迎关注[前端之巅]微信公众号(ID: fron ...

最新文章

  1. poj3159(差分约束)
  2. mybatis 一二事(1) - 简单介绍
  3. Golang Study 三 map的顺序输出
  4. python多项分式求和计算_python实现利用留数定理分解分式多项式
  5. 思科表示视频资源将在2022年占据所有互联网流量的82%
  6. Perl 数字与字符串运算符之区别
  7. java sbt二叉树,Treap——堆和二叉树的完美结合,性价比极值的搜索树
  8. PIFA-平面倒F天线[搬运]
  9. linux搭建ntp发包教程,linux 搭建本地ntp服务器
  10. 版式设计怎么做对比?有哪些形式!
  11. java-练习题-黄金分割点
  12. 世链投研|链游操作指南之MIR4
  13. 有关计算机专业的对联,有趣的电脑对联(微软亚洲研究院自然语言计算组研发)...
  14. 播放视频时过滤播霸浏览器
  15. [BUUCTF-pwn] zer0ptts_2020_protrude
  16. 性能测试报告包括哪些内容?模板范文哪里找?看这里
  17. height:100vh
  18. Unsupervised Domain Adaptation via Structurally Regularized Deep Clustering-CVPR2020
  19. Java泛型方法的定义
  20. strncpy()函数用法及其详解

热门文章

  1. Graph Neural Networks: A Review of Methods and Applications(图神经网络:方法与应用综述)
  2. app css+html 仿微信我的二维码、个人二维码
  3. 按键精灵_字符点阵制作
  4. Ubuntu安装re2c和ninja
  5. 1.7.1 容器类数据-列表
  6. 【30天从入门到放弃】我的机器学习之路 4
  7. Win10 localhost无法打开的解决方法(亲测)
  8. ios客户端开源的项目
  9. 论流氓软件,以及其解决方法。
  10. 简单快速删除流氓软件(包括注册表)