Window Creation & DirectX 12 Initialization
All good projects must start somewhere. Before we can begin working on portals, a window needs to be created, and DirectX 12 needs to be initialized. For this, I heavily utilized Jeremiah's tutorial on DirectX 12: https://www.3dgep.com/learning-directx-12-1/. This is the code so far. There is a lot of code here! With almost 800 lines of code, the final result!? (drum roll)
There is a lot moving components within DirectX 12 in order to initialize it. Way more than DirectX 11! In order to initialize DX12 we first we needed to get the adapter, then create a device, then create a command queue, then create a swap chain, then create a descriptor heap for retender target views, then create render target views, then create command allocator per back buffer, then create a command list, then create a fence... Phew! Once all of that is done we can finally run our game loop.
The render loop contains the most important logic in understanding how DX12 is being used. The render loop first clears the render target view with the clear color, executes the command list for the current back buffer, and presents the back buffer to the screen. The commands in DX12 are dispatched without blocking. Thus, it is possible we could keep calling the render function and return back at the same back buffer before the command list we populated in the previous call has been fully executed. To ensure that the previous commands in the command list are executed we use a fence. The fence is essentially an object that can be enqueued in the command queue. When the queue reaches that fence object, it will signal it. We can then wait on that signal with a Windows event. This a is a diagram of the render loop provided by Jeremiah:
This example shows a double-buffered implementation. For M back buffers, main, on frame N, would wait for fence value N - (M - 1). My implementation currently uses triple buffering but can be changed variably.
An example of performing GPU synchronization (Jeremiah) |
This example shows a double-buffered implementation. For M back buffers, main, on frame N, would wait for fence value N - (M - 1). My implementation currently uses triple buffering but can be changed variably.
In addition to the window create and basic DX12 initialization, my window implementation currently supports variable refresh rate, and the ability to turn on and off vsync.
In the future, I will reorganize the code by encapsulating the window and DX12 in separate classes and files.
Comments
Post a Comment