I wrote about some applications of DirectX9 a long time ago, and now DirectX12 has become popular. After writing a few DirectX12 test codes, write a brief introduction to the basic concepts, environment setup, and programming process of DirectX12.
Programming environment
Unlike DirectX9, in DirectX12 development, Microsoft directly integrates the DirectX SDK that needs to be downloaded separately into the Windows SDK. Due to the network characteristics of Visual Studio, in addition to downloading and installing the Windows SDK separately, you can directly use the Visual Studio Installer to select the version of the Windows SDK that needs to be installed. I am using the Visual Studio 2022 Community version. Similarly, because my target machine is my own machine, which is Windows version 10.1.19044, I chose SDK version 10.1.19041.0.
.
After selecting installation, it will be automatically installed and the corresponding SDK path will be registered in the environment variable, avoiding the need to manually configure DirectX's environment variables to include the corresponding header files and libraries in the DirectX 9 era.
Additionally, DirectX only supports C++ Develop. In addition, all DirectX series are interfaces designed based on the COM architecture. Therefore, in addition to requiring developers to possess C++ In addition to programming skills, it is also necessary to master the basic skills of COM transformation.
After installing the Windows SDK, you can create a C in Visual Studio+ Desktop program now. In addition to the default addition of Windows. h and related Windows 32 libraries to Visual Studio, additional configuration is required for the libraries D3d12. h, D3d12. DLL, and dxgi. lib used during compilation.
.
Afterwards, you can use the corresponding header files of d3d12. h and dxgi to call the corresponding APIs.
Programming process
From the highest perspective. The entire process and previous versions of DirectX, even with GDI/GDI+ The programming process is similar and can be divided into four parts, but DirectX12 abstracts many concepts for operation based on the characteristics of modern GPUs.
- initialization
- load resources
- Loop rendering
- Destroy Object
Next, let's introduce in detail what tasks need to be completed in each stage and what objects are needed.
Initialize
- The first step is to execute the rendering graphics card by creating an IDXGIFactory object to select a graphics card object that can be used for rendering. The interface is IDXGIAdapter.
- Create a rendering device object ID3D12Device on the selected graphics card object using D3D12CreateDevice. This object can be seen as an abstract interface for rendering hardware in a real graphics card.
- After obtaining the ID3D12Device interface, it is necessary to create a communication channel with it. In DirectX, this object is called a command queue. That is the ID3D12CommandQueue interface. After the creation is completed, all rendering operations will be sent to the rendering hardware through a command queue.
- Next, you will need to prepare the target for rendering. Two concepts need to be noted here. SwapChain and window. For the DirectX programming architecture, in order to avoid screen tearing, a dual buffering strategy is adopted, so the rendered related resources are placed in SwapChain for alternating operations. When to truly switch between Front Buffer and Back Buffer is controlled by DWM and the application itself according to different scenarios. Therefore, when creating a buffer for the rendering target, the actual created SwapChain is actually the Create SwapChainForHwnd. Here we will design the concepts of window and flip. According to the traditional display resource management mode. DWM will manage and combine the drawn content according to Window. But in reality, there will also be a new DirectComposition mode that does not require a real window handle to manage. For simplicity, a window handle is used here to bind the created rendering target, IDXGISwapChain, to a window handle and associate it with CommandQueue.
- Next, we need to create some rendering resources for the rendering device ID3D12Device, which can be referred to as a Descriptor in DirectX. The collection can become a Descriptor Heap. When rendering, the operating object cannot directly manipulate the Buffer in SwapChain. In DirectX, it is necessary to create the corresponding RenderTargetView in SwapChain to perform the operation, that is, Create RenderTargetView.
- Finally, it is necessary to create the ID3D12CommandAllocator interface through CreatCommandAllocator. It represents the management of all Command related resources that require operation.
After completing the above steps, the abstract interface of the rendered hardware resources is ready. Next, we need to allocate the resources used for rendering, many of which are related to the objects used in GPU rendering.