Each core is now a pencil

Drawing is done by recording commands to a ID3D12GraphicsCommandList. No real work is done until the command list is set to a queue to be executed.

Record commands

Reset and Close - DB

To re-use a command list start with running ID3D12GraphicsCommandList::Reset() on it. This can be done after the ExecuteCommandList() has been called. To submit command lists for execution they need to be closed. To close a command list use ID3D12GraphicsCommandList::Close().

Clear the screen

To clear a rendertarget use ID3D12GraphicsCommandList::ClearRenderTargetView(). The rendertarget should be in state D3D12_RESOURCE_STATE_RENDER_TARGET for this command. To clear depth or stencil target use ID3D12GraphicsCommandList::ClearDepthStencilView(). The depth target should be in state D3D12_RESOURCE_STATE_DEPTH_WRITE.

Select RenderTarget

Select the target to render to with ID3D12GraphicsCommandList::OMSetRenderTargets(). It is possible to give an array of descriptors to render targets and a descriptor to any depth/stencil target. Set the viewports with ID3D12GraphicsCommandList::RSSetViewports() and the scissor rectangles with ID3D12GraphicsCommandList::RSSetScissorRects()

Select state

Set the rootsignature with ID3D12GraphicsCommandList::SetGraphicsRootSignature(). Set the PSO to use with the ID3D12GraphicsCommandList::SetPipelineState() function.

Bind shader data

The data in the root signature that are used by the shaders are set by root signature slot with these functions. One need to use the correct function depending on what data is in that rootparameter one is setting.

Root Constants: Use SetGraphicsRoot32BitConstant() to set a single value and SetGraphicsRoot32BitConstants() to set a group of them.

Root Descriptors: Depending on the type of descriptor SetGraphicsRootConstantBufferView(), SetGraphicsRootShaderResourceView() or SetGraphicsRootUnorderedAccessView() is used. Each one takes the GPU virtual address of the resource.

Descriptors tables: To set a table use SetGraphicsRootDescriptorTable() and send in the GPU descriptor handle of the first descriptor in the table.


To set the vertex buffers and index buffer to use call ID3D12GraphicsCommandList::IASetVertexBuffers() and ID3D12GraphicsCommandList::IASetIndexBuffer().


Select the typ of primitive to render with ID3D12GraphicsCommandList::IASetPrimitiveTopology().


There are two functions used to draw things, ID3D12GraphicsCommandList::DrawInstanced() and ID3D12GraphicsCommandList::DrawIndexedInstanced().


The ID3D12GraphicsCommandList::ExecuteBundle can only be used on a direct command list and the argument must be a bundle list. The bundle will inherit all the state from the bundle and the things that change in the bundle will affect the rest of the command list.


BeginQuery, EndQuery and ResolveQueryData






Frequency of use

Render Loop


foreach batch:


foreach draw:

set root parameters

set vertex/index buffer



Command Lists are send to the command queue by using ID3D12CommandQueue::ExecuteCommandLists(). Try to batch up as many commandlists as possible in the same call. The caller need to ensure that the GPU is not using any of submitted command lists from a previous execution.

Swap and show

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