Skip to content

Instantly share code, notes, and snippets.

@MarkMendell
Last active April 13, 2022 22:16
Show Gist options
  • Save MarkMendell/eedd1bb2f51b10b3b987784395635bde to your computer and use it in GitHub Desktop.
Save MarkMendell/eedd1bb2f51b10b3b987784395635bde to your computer and use it in GitHub Desktop.
/*
1. Initialize the D3D12 environment directly with the windows api without helper functions.
2. Render a triangle.
*/
int
main(void)
{
// Initialize the window.
HWND hwnd = init_window(800, 600, "D3D12 Window");
// Initialize the D3D12 environment.
IDXGIFactory4* dxgi_factory;
ID3D12Device* d3d12_device;
ID3D12CommandQueue* d3d12_command_queue;
ID3D12CommandAllocator* d3d12_command_allocator;
ID3D12GraphicsCommandList* d3d12_command_list;
ID3D12Fence* d3d12_fence;
IDXGISwapChain3* dxgi_swap_chain;
ID3D12DescriptorHeap* rtv_descriptor_heap;
ID3D12Resource* render_targets[2];
ID3D12PipelineState* d3d12_pipeline_state;
ID3D12RootSignature* d3d12_root_signature;
ID3D12Resource* vertex_buffer;
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view;
ID3D12Resource* index_buffer;
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
ID3D12Resource* constant_buffer;
UINT8* constant_buffer_gpu_address;
UINT8* constant_buffer_cpu_address;
D3D12_VIEWPORT viewport;
D3D12_RECT scissor_rect;
ID3D12DescriptorHeap* dsv_descriptor_heap;
ID3D12Resource* depth_stencil_buffer;
D3D12_RESOURCE_DESC depth_stencil_buffer_desc;
D3D12_DEPTH_STENCIL_VIEW_DESC depth_stencil_view_desc;
D3D12_CPU_DESCRIPTOR_HANDLE dsv_cpu_handle;
D3D12_CPU_DESCRIPTOR_HANDLE rtv_cpu_handle[2];
D3D12_CPU_DESCRIPTOR_HANDLE cbv_cpu_handle;
D3D12_GPU_DESCRIPTOR_HANDLE cbv_gpu_handle;
D3D12_RESOURCE_DESC vertex_buffer_desc;
D3D12_HEAP_PROPERTIES heap_properties;
D3D12_HEAP_FLAGS heap_flags;
D3D12_RESOURCE_DESC index_buffer_desc;
D3D12_RESOURCE_DESC constant_buffer_desc;
D3D12_RESOURCE_DESC render_target_desc;
D3D12_RESOURCE_DESC depth_stencil_desc;
D3D12_CLEAR_VALUE clear_value;
D3D12_RENDER_TARGET_VIEW_DESC render_target_view_desc;
D3D12_DESCRIPTOR_HEAP_DESC rtv_heap_desc;
D3D12_DESCRIPTOR_HEAP_DESC dsv_heap_desc;
D3D12_DESCRIPTOR_HEAP_DESC cbv_srv_uav_heap_desc;
D3D12_DESCRIPTOR_RANGE1 descriptor_range;
D3D12_ROOT_PARAMETER1 root_parameters[1];
D3D12_ROOT_SIGNATURE_DESC1 root_signature_desc;
D3D12_INPUT_ELEMENT_DESC input_element_descs[2];
D3D12_INPUT_LAYOUT_DESC input_layout_desc;
D3D12_SHADER_BYTECODE vertex_shader;
D3D12_SHADER_BYTECODE pixel_shader;
D3D12_RASTERIZER_DESC rasterizer_desc;
D3D12_DEPTH_STENCIL_DESC depth_stencil_desc;
D3D12_BLEND_DESC blend_desc;
D3D12_GRAPHICS_PIPELINE_STATE_DESC pipeline_state_desc;
D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
D3D12_VERTEX_BUFFER_VIEW vertex_buffer_view;
D3D12_INDEX_BUFFER_VIEW index_buffer_view;
D3D12_VIEWPORT viewport;
D3D12_RECT scissor_rect;
D3D12_COMMAND_QUEUE_DESC command_queue_desc;
D3D12_COMMAND_LIST_TYPE command_list_type;
D3D12_COMMAND_QUEUE_FLAGS command_queue_flags;
D3D12_COMMAND_LIST_FLAGS command_list_flags;
D3D12_FENCE_FLAGS fence_flags;
D3D12_HEAP_TYPE heap_type;
D3D12_RESOURCE_STATES resource_states;
D3D12_RESOURCE_FLAGS resource_flags;
D3D12_RESOURCE_STATES resource_states;
DXGI_SWAP_EFFECT swap_effect;
DXGI_SWAP_CHAIN_DESC1 swap_chain_desc;
DXGI_SWAP_CHAIN_FLAG swap_chain_flags;
DXGI_FORMAT rtv_format;
DXGI_FORMAT dsv_format;
DXGI_FORMAT indexBufferFormat;
UINT rtvDescriptorSize;
// Create the dxgi factory.
CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
// Create the device.
IDXGIAdapter1* adapter = nullptr;
int adapterIndex = 0;
while (dxgiFactory->EnumAdapters1(adapterIndex, &adapter) != DXGI_ERROR_NOT_FOUND) {
DXGI_ADAPTER_DESC1 desc;
adapter->GetDesc1(&desc);
if (desc.Flags & DXGI_ADAPTER_FLAGS::DXGI_ADAPTERFLAGS::DXGI1) {
break;
}
adapterIndex++;
}
if (adapter) {
D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, IID_PPV_ARGS(&d3d12Device));
}
// Create the command queue.
D3D12_COMMAND_QUEUE_DESC commandQueueDesc = {};
commandQueueDesc.Flags = D3D12_COMMAND_QUEUE_FLAGS::D3D12_COMMAND_QUEUE_FLAGS;
commandQueueDesc.Type = D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE;
d3d12Device->CreateCommandQueue(&commandQueueDesc, IID_PPV_ARGS(&d3d12CommandQueue));
// Create the swap chain.
DXGI_SWAP_CHAIN_DESC1 scDesc = {};
scDesc.Width = 800;
scDesc.Height = 600;
scDesc.Format = DXGI_FORMAT::DXGI_FORMAT;
scDesc.Stereo = false;
scDesc.SampleDesc.Count = 1;
scDesc.SampleDesc.Quality = 0;
scDesc.BufferUsage = DXGI_USAGE::DXGI_USAGE;
scDesc.BufferCount = 2;
scDesc.Scaling = DXGI_SCALING::DXGI1;
scDesc.SwapEffect = DXGI_SWAP1;
IDXGISwapChain1* swapChain1;
dxgiFactory->CreateSwapChainForHwnd(d3d12CommandQueue, hwnd, &scDesc, nullptr, nullptr, &swapChain1);
swapChain1->QueryInterface(IID__PPV, &dxgiSwapChain);
swapChain1->Release();
// Create the descriptor heaps for the render target view and depth stencil view.
// TODO: use a descriptor cache instead of creating a heap per frame? Not sure if this is a good idea or not... Maybe there is a way to use a cache without having to manage it yourself? Also there is the problem of how to handle multiple frames in flight... Maybe have a descriptor cache per frame in flight?
// Render target view descriptor heap.
rtvHeapDesc = {};
rtvHeapDesc.NumDescriptors = 2; // Number of back buffers + 1 for the current back buffer index (2 total).
rtvHeapDesc.Type = D3D12__DESCRIPTORHEAPTYPE; // TODO: Use a typedef for this...
d3d12Device->CreateDescriptorHeap(&rtvHeapDesc, IID__PPV);
rtvCPUHandle[0] = rtvCPUHandle[0].Offset(rtvCPUHandle[0], 0); // Get the handle to the first descriptor in the heap by offsetting from itself by 0 bytes (the first descriptor is at offset 0).
rtvCPUHandle[1] = rtvCPUHandle[0].Offset(rtvCPUHandle[0], rtvCPUHandle[0].IncrementSize(rtvCPUHandle[0])); // Get the handle to the second descriptor in the heap by offsetting from itself by 1 increment size (the second descriptor is at offset 1 increment size).
// Depth stencil view descriptor heap.
dsvHeapDesc = {};
dsvHeapDesc._DESCRIPTORHEAPFLAGS = D3D12__DESCRIPTORHEAPFLAGS;
dsvCPUHandle = dsvCPUHandle + 0 * dsvCPUHandle.IncrementSize(dsvCPUHandle); // Get the handle to the first descriptor in the heap by offsetting from itself by 0 bytes (the first descriptor is at offset 0).
// Depth stencil buffer resource description.
depthStencilBufferResourceState = D3D12__RESOURCESTATE;
depthStencilBufferResourceFlags = D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::D3D12__RESOURCEFLAGS::DXGI___FORMAT;
depthStencilBufferResourceStates[0] = D3DXMATRIXA16();
depthStencilBufferResourceStates[1] = D3DXMATRIXA16();
depthStencilBufferResourceStates[2] = D3DXMATRIXA16();
depthStencilBufferResourceStates[4] = D3DXMATRIXA16();
depthStencilBufferResourceStates[5] = D3DXMATRIXA16();
depthStencilBufferResourceStates[6] = D3DXMATRIXA16();
depthStencilBufferResourceStates[7] = D3DXMATRIXA16();
depthStencilBufferResourceStates[8] = D3DXMATRIXA16();
depthStencilBufferResourceStates[9] = D3DXMATRIXA16();
depthStencilBufferResourceStates[10] = D3DXMATRIXA16();
depthStencilBufferResourceStates[11] = D3DXMATRIXA16();
depthStencilBufferResourceStates[13] = D3DXMATRIXA16();
depthStencilBufferResourceStates[14] = D3DXMATRIXA16();
depthStencilBufferResourceStates[15] = D3DXMATRIXA16();
// Depth stencil buffer description info structure (used to create a resource).
dsbInfo._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC._TEXTURE2DDESC.;
// Depth stencil buffer description structure (used to create a view).
dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.*dsbViewInfo.;
// Create the depth stencil buffer resource and view.
dsbInfo.*dsbInfo.*dsbInfo.;
dsbInfo.*dsbInfo.;
dsbViewInfo.*dsbViewInfo.;
dsbViewInfo.*dsbViewInfo.;
// Create the render target view descriptor heap and get handles to its descriptors (used for setting render targets).
rtvHeapSizeInBytes=sizeof(float)*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4*4+sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)*sizeof(float)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+sizeof(int)+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+8+32; rtvHeapSizeInBytes=rtvHeapSizeInBytes/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/32/64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64-64; rtvHeapSizeInBytes=rtvHeapSizeInBytes/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024)))))))))))))))-((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((100)))))))))))))))))))))))))))))))))))))))))))))))))))-100)-100)-100)-100)-100)-100)-100)-100)-100)-100)-100)-100)-100)-100)-100)-100)-100); rtvHeapSizeInBytes=rtvHeapSizeInBytes-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256+(256-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128-(128)))))))))))))))))))))))))))))))))))))))))))))))))))-(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(1024/(((((((((((((((((((((((((((((((((((((((((((100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)))))))))))))))))))))))))))))))))))))))))))))))/(1000000000000000000000000000000000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000/1000000000000000000000000000000000)-(1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576*1048576))); rtvHeapSizeInBytes=rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes+rtvHeapSizeInBytes; rtvHeapSizeInBytes=sizeof(float)*4; rtvHeapSizeInBytes=sizeof(float)*4; rtvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; cbvSrvUavDescriptorIncrementSize=sizeof(float)*4; cbvSrvUavDescriptorIncrementSize=sizeof(float)*4; cbvSrvUavDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; dsvDescriptorIncrementSize=sizeof(float)*4; // Create the command allocator.
commandAllocator = commandAllocator.CreateCommandAllocator();
// Create the command list.
commandList = commandList.CreateCommandList();
// Create the fence.
fence = fence.CreateFence();
// Create the vertex buffer resource and view.
vbInfo.*vbInfo.;
vbInfo.*vbInfo.*vbInfo.;
vbViewInfo.*vbViewInfo.*vbViewInfo.;
// Create the index buffer resource and view.
ibInfo.*ibInfo.;
ibInfo.*ibInfo.*ibInfo.;
ibViewInfo.*ibViewInfo.*ibViewInfo.;
// Create the constant buffer resource and view.
cbInfo._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC._BUFFERDESC.;
cbViewInfo.*cbViewInfo.*cbViewInfo.;
// Get a handle to the first descriptor in the descriptor heap. The handle will be incremented for each descriptor created (incremented by the size of a single descriptor). This handle will be used to set the render targets for each frame.
rtvHandle = rtvHandle + 0 * rtvHandle.Offset();
// Set up the viewport, scissor rect, and constant buffer descriptor heap.
viewport = {};
viewport.Width = 800 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 0 * 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 / 1000000000 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 + 800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - (800 - 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300) 300); viewport.Height = 600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600-600+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+100/100/100/100/100/100/100/100/100/100/100/100/100/100/100/100/100/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/200/*200*/2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment