Startup

Gentlemen, start your engines!

Here are the steps to take to setup DirectX 12 with the things needed to clear the screen only.

The Device

Enable the debug layer

DirectX12 does the minimal of parameter checking it can when running. For development one can enable a debug layer that does more checks of the parameters and state to make it more easy to find bug. To enable get the layer with D3D12GetDebugInterface () and enable it with ID3D12Debug::EnableDebugLayer(). To make sense of all the objects in the logs use ID3D12Object::SetName() to set a helpful name on the important objects.

Enumerate adapters

To get a list of the devices use CreateDXGIFactory1() and then call IDXGIFactory::EnumAdapters() on it.

Create the device

Create the device using D3D12CreateDevice(). Use the NULL as pAdapter to use the default adapter.

The Buffer

Create a render target view (RTV) descriptor heap

Fill in a D3D12_DESCRIPTOR_HEAP_DESC() with type D3D12_DESCRIPTOR_HEAP_TYPE_RTV then use it to call ID3D12Device::CreateDescriptorHeap().

Create the swap chain

The swap chain is the back buffers in DX12. To create it fill in a DXGI_SWAP_CHAIN_DESC structure and then call IDXGIFactory::CreateSwapChain().

Create a descriptor to each render target

Use ID3D12Device::CreateRenderTargetView.

The Commands

Create the command queue

Use ID3D12Device::CreateCommandQueue() to create a direct command queue. The three types of queues are Direct, Compute and Copy. Each type in this list can handle commands from the lower types also. So a Compute queue can also use copy command lists but it can't use Direct command lists.

    • Direct: 3D rendering commands.

    • Compute: Compute on the GPU is possible with this queue.

    • Copy: Can handle command buffers for copying.

Create a command allocator

Create the command allocator with ID3D12Device::CreateCommandAllocator(). The allocator manage the memory for commands list and it's type must match the type of the command list being created. A allocator can only be associated with one currently recording command list at a time. To reclaim the memory of a allocator call ID3D12CommandAllocator::Reset(). It should only be done when the GPU is no longer executing any commands list associated with the allocator.

Create Command lists

To create a Command List use ID3D12Device::CreateCommandList(). It needs the type of command list to create, a allocator used to manage the memory for the list and a initial PSO. The PSO can be NULL if you plan to set it later. Commands can then be recorded to the list using the ID3D12GraphicsCommandList interface. When all commands are given use Close() on the list. With Reset() a command list can be re-used.

Clear and show

Clear the screen

Pseudocode to clear the screen.

CommandList->Reset(...);

commandList->ResourceBarrier(RenderTarget, STATE_RENDERTARGET);

commandList->ClearRenderTargetView(...);

commandList->ResourceBarrier(RenderTarget, STATE_PRESENT);

commandList->Close();

Executing the Command List

Command Lists are send to the command queue by using the ID3D12CommandQueue::ExecuteCommandLists() function. The caller need to ensure that the GPU is not using any of submitted command lists from a previous execution.

Swap and show the frame

To show the frame call IDXGISwapChain::Present().

Reference