核心概念:什么是 HRESULT? (The Why)#
从技术上讲,HRESULT 是一个 32位整数(long),它是 COM (Component Object Model) 组件的标准返回值。DirectX 是基于 COM 构建的,所以沿用了这一标准。
HRESULT 是与图形硬件沟通的第一道防线,它是 API 调用的“心跳报告”。
在 D3D12 中,几乎所有的 API 调用(创建设备、分配内存、编译着色器)都会返回一个 HRESULT。如果你忽略它,你就是在蒙眼狂奔。
HRESULT 是一个变量类型(C++中的 long),它是 Windows 编程中用来记录函数执行结果(包括错误类型、成功状态)的标准载体。
在 DirectX 12 和 Windows COM 编程中,它不仅记录“出错了”,还记录“错哪了”甚至“成功了但有些小状况”。
在 C++ 的头文件定义中,它其实就是一个 32 位的整数: typedef long HRESULT;所以,当你看到 HRESULT hr = … 时,你本质上是在存一个数字。 但是,这个数字并不是随机生成的,它像一个“比特位地图”。
2. 它的内部结构(为什么它是 32 位的?)#
虽然它只是一个整数,但它的 32 个二进制位(bit)被划分成了三个特定的区域。这就好比身份证号码,每一段数字都有特定含义。
我们通常用 16 进制来看它,比如常见的失败代码 0x80070057:
0= 成功 (Success)1= 失败 (Fail)- 这就是为什么所有的错误代码(如
0x8...)开头都是 8(二进制1000...),因为第 31 位是 1。
- 比如
0x007代表 Win32 API,0x87A代表 DXGI (DirectX Graphics Infrastructure)。
- 比如
5代表 "Access Denied" (拒绝访问),57代表 "Invalid Argument" (参数无效)。
GUID : 它本质上是一个 128位 (16字节) 的超大整数, 是每一个组件的“身份证”
实现代码:#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), (void**)(ppType)
1)device 的类型是 ID3D12Device*(指向设备的指针)。
2)ppType (也就是 &device) 的类型是 ID3D12Device**(指向指针的指针)。
3)*(ppType) 解引用一次,变成了 ID3D12Device*。
4)**(ppType) 再解引用一次,变成了 ID3D12Device (类型本身)。
结论:__uuidof 直接去查“你传入的这个变量所属的类型”的身份证号。 如果你传的是 device,它就自动填 ID3D12Device 的 GUID。你根本没有机会填错*/
实质: Fence 本质上就是一个所有的 CPU 和 GPU 都能访问的 64位整数 (UINT64)
ps:这个方法是强制刷新命令队列,cpu会一直对单帧的绘制进行等待;后面用到了其他的方法,叫做双缓冲或三缓冲,意思是在提交了第一帧的命令之后,CPU不会傻等,而是去填写第二帧与第三帧命令,此时只有当第一帧还没有绘制完时,CPU才会等待
- 你不能直接问“支持 MSAA 吗?”
- 你必须精确地问:“对于 R8G8B8A8 这种颜色格式,做 4倍 采样,你支不支持?”
- 如果你换了颜色格式(比如
DXGI_FORMAT_R16G16B16A16_FLOATHDR格式),你得重新问一次,因为显卡可能支持普通颜色的 MSAA,但不支持 HDR 颜色的 MSAA。
CPU 使用命令列表(List)作为工具,将指令数据写死在分配器(Allocator)提供的内存上,最后将整块内存的引用交给队列(Queue)去执行
交换链本质就是观众在看A黑板而这时候你在写B黑板,之后在把B黑板调换位置,观众永远能看见完整画面
关于为什么每次使用comptr类型变量都要调用Get()方法:
在 Windows 中,你不能直接说“给我个窗口”。你必须先填写一张详细的“申请表”,定义这个窗口的行为和长相:WNDCLASS wc;
D3D12_RESOURCE_STATE_PRESENT 是 CPU、GPU 渲染核心、显示控制器三者之间的一个契约。
它保证了当屏幕读取数据时,数据是完整的、可读的且不再被修改的。如果你不切换到这个状态直接 Present,Debug Layer 会直接报错,而在真机上,你可能会看到花屏、闪烁或者显卡驱动崩溃。
首先沿着镜面的对称轴(镜面Local Space的x轴(应该是吧?))再创建一个一样的模型,接着根据对称轴创建镜像矩阵,将光照方向也镜像,这个光照将用于镜像物体的渲染
之后我们需要在RenderItem结构体中添加layer成员变量,用于控制渲染过程使用的不同的passconstant : 在BuildRenderItems()中赋予属性,在Draw()中进行调用
原文:DX12



















