aboutsummaryrefslogtreecommitdiff
path: root/hello/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'hello/main.c')
-rw-r--r--hello/main.c115
1 files changed, 65 insertions, 50 deletions
diff --git a/hello/main.c b/hello/main.c
index 1f0b4ed..309a8c9 100644
--- a/hello/main.c
+++ b/hello/main.c
@@ -40,6 +40,34 @@ typedef struct D3D {
40 UINT cbv_descriptor_size; 40 UINT cbv_descriptor_size;
41} D3D; 41} D3D;
42 42
43static D3D12_CPU_DESCRIPTOR_HANDLE d3d_get_current_back_buffer_view(const D3D* d3d) {
44 assert(d3d);
45 assert(d3d->pSwapChain);
46 assert(d3d->pRtvHeap);
47 assert(d3d->rtv_descriptor_size > 0);
48 D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
49 d3d->pRtvHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(d3d->pRtvHeap, &rtv_handle);
50 return CD3DX12_CPU_DESCRIPTOR_HANDLE(
51 rtv_handle,
52 d3d->pSwapChain->lpVtbl->GetCurrentBackBufferIndex(d3d->pSwapChain),
53 d3d->rtv_descriptor_size);
54}
55
56static ID3D12Resource* d3d_get_current_back_buffer(const D3D* d3d) {
57 assert(d3d);
58 assert(d3d->pSwapChain);
59 assert(d3d->pSwapChainBuffer);
60 return d3d->pSwapChainBuffer[d3d->pSwapChain->lpVtbl->GetCurrentBackBufferIndex(d3d->pSwapChain)];
61}
62
63static D3D12_CPU_DESCRIPTOR_HANDLE d3d_get_depth_stencil_view(D3D* d3d) {
64 assert(d3d);
65 assert(d3d->pDsvHeap);
66 D3D12_CPU_DESCRIPTOR_HANDLE handle;
67 d3d->pDsvHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(d3d->pDsvHeap, &handle);
68 return handle;
69}
70
43/// Creates the application's swap chain. 71/// Creates the application's swap chain.
44/// 72///
45/// This method can be called multiple times to re-create the swap chain. 73/// This method can be called multiple times to re-create the swap chain.
@@ -100,14 +128,6 @@ static void d3d_create_swap_chain_buffer_render_target_views(D3D* d3d) {
100 } 128 }
101} 129}
102 130
103static D3D12_CPU_DESCRIPTOR_HANDLE d3d_get_depth_stencil_view(D3D* d3d) {
104 assert(d3d);
105 assert(d3d->pDsvHeap);
106 D3D12_CPU_DESCRIPTOR_HANDLE handle;
107 d3d->pDsvHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(d3d->pDsvHeap, &handle);
108 return handle;
109}
110
111/// Creates a depth/stencil buffer and its view. 131/// Creates a depth/stencil buffer and its view.
112static void d3d_create_depth_stencil_buffer_and_view(D3D* d3d) { 132static void d3d_create_depth_stencil_buffer_and_view(D3D* d3d) {
113 assert(d3d); 133 assert(d3d);
@@ -195,10 +215,10 @@ static void d3d_init(D3D* d3d, Window* pWindow, const D3DSettings* pSettings) {
195 d3d->settings = *pSettings; 215 d3d->settings = *pSettings;
196 216
197 UINT dxgiFactoryFlags = 0; 217 UINT dxgiFactoryFlags = 0;
198#ifdef DEBUG 218#ifndef NDEBUG
199 ID3D12Debug* debug = 0; 219 ID3D12Debug* pDebug = NULL;
200 D3D12GetDebugInterface(&IID_ID3D12Debug, (&debug)); 220 TrapIfFailed(D3D12GetDebugInterface(&IID_ID3D12Debug, (&pDebug)));
201 debug->EnableDebugLayer(); 221 pDebug->lpVtbl->EnableDebugLayer(pDebug);
202 dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG; 222 dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
203#endif 223#endif
204 TrapIfFailed(CreateDXGIFactory2( 224 TrapIfFailed(CreateDXGIFactory2(
@@ -249,7 +269,7 @@ static void d3d_init(D3D* d3d, Window* pWindow, const D3DSettings* pSettings) {
249 /*nodeMask=*/0, 269 /*nodeMask=*/0,
250 queue_desc.Type, 270 queue_desc.Type,
251 d3d->pCommandAllocator, 271 d3d->pCommandAllocator,
252 /*pInitialState=*/0, // Pipeline state. 272 /*pInitialState=*/NULL, // Pipeline state.
253 &IID_ID3D12CommandList, 273 &IID_ID3D12CommandList,
254 &d3d->pCommandList)); 274 &d3d->pCommandList));
255 275
@@ -272,7 +292,7 @@ static void d3d_init(D3D* d3d, Window* pWindow, const D3DSettings* pSettings) {
272 &IID_ID3D12Fence, 292 &IID_ID3D12Fence,
273 &d3d->pFence)); 293 &d3d->pFence));
274 294
275 if ((d3d->fence_event = CreateEvent(0, FALSE, FALSE, 0)) == 0) { 295 if ((d3d->fence_event = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
276 TrapIfFailed(HRESULT_FROM_WIN32(GetLastError())); 296 TrapIfFailed(HRESULT_FROM_WIN32(GetLastError()));
277 } 297 }
278} 298}
@@ -290,26 +310,7 @@ void d3d_destroy(D3D* d3d) {
290 SafeRelease(d3d->pFence); 310 SafeRelease(d3d->pFence);
291 SafeRelease(d3d->pDevice); 311 SafeRelease(d3d->pDevice);
292 SafeRelease(d3d->pDxgiFactory); 312 SafeRelease(d3d->pDxgiFactory);
293} 313 CloseHandle(d3d->fence_event);
294
295static D3D12_CPU_DESCRIPTOR_HANDLE d3d_get_current_back_buffer_view(const D3D* d3d) {
296 assert(d3d);
297 assert(d3d->pSwapChain);
298 assert(d3d->pRtvHeap);
299 assert(d3d->rtv_descriptor_size > 0);
300 D3D12_CPU_DESCRIPTOR_HANDLE rtv_handle;
301 d3d->pRtvHeap->lpVtbl->GetCPUDescriptorHandleForHeapStart(d3d->pRtvHeap, &rtv_handle);
302 return CD3DX12_CPU_DESCRIPTOR_HANDLE(
303 rtv_handle,
304 d3d->pSwapChain->lpVtbl->GetCurrentBackBufferIndex(d3d->pSwapChain),
305 d3d->rtv_descriptor_size);
306}
307
308static ID3D12Resource* d3d_get_current_back_buffer(const D3D* d3d) {
309 assert(d3d);
310 assert(d3d->pSwapChain);
311 assert(d3d->pSwapChainBuffer);
312 return d3d->pSwapChainBuffer[d3d->pSwapChain->lpVtbl->GetCurrentBackBufferIndex(d3d->pSwapChain)];
313} 314}
314 315
315static void d3d_populate_command_list(D3D* d3d) { 316static void d3d_populate_command_list(D3D* d3d) {
@@ -339,14 +340,21 @@ static void d3d_populate_command_list(D3D* d3d) {
339 TrapIfFailed(d3d->pCommandList->lpVtbl->Reset( 340 TrapIfFailed(d3d->pCommandList->lpVtbl->Reset(
340 d3d->pCommandList, 341 d3d->pCommandList,
341 d3d->pCommandAllocator, 342 d3d->pCommandAllocator,
342 /*pInitialState=*/0)); 343 /*pInitialState=*/NULL));
343 344
344 // Indicate that we intend to use the back buffer as a render target. 345 // Indicate that we intend to use the back buffer as a render target and
345 const D3D12_RESOURCE_BARRIER render_barrier = CD3DX12_RESOURCE_BARRIER_Transition( 346 // depth/stencil for writing.
346 d3d_get_current_back_buffer(d3d), 347 const D3D12_RESOURCE_BARRIER render_barriers[] = {
347 D3D12_RESOURCE_STATE_PRESENT, 348 CD3DX12_RESOURCE_BARRIER_Transition(
348 D3D12_RESOURCE_STATE_RENDER_TARGET); 349 d3d_get_current_back_buffer(d3d),
349 d3d->pCommandList->lpVtbl->ResourceBarrier(d3d->pCommandList, 1, &render_barrier); 350 D3D12_RESOURCE_STATE_PRESENT,
351 D3D12_RESOURCE_STATE_RENDER_TARGET),
352 CD3DX12_RESOURCE_BARRIER_Transition(
353 d3d->pDepthStencilBuffer,
354 D3D12_RESOURCE_STATE_PRESENT,
355 D3D12_RESOURCE_STATE_DEPTH_WRITE)
356 };
357 d3d->pCommandList->lpVtbl->ResourceBarrier(d3d->pCommandList, COUNTOF(render_barriers), render_barriers);
350 358
351 // Record commands. 359 // Record commands.
352 const float clear_colour[] = { 0.0f, 0.502f, 0.494f, 0.0f }; 360 const float clear_colour[] = { 0.0f, 0.502f, 0.494f, 0.0f };
@@ -366,12 +374,19 @@ static void d3d_populate_command_list(D3D* d3d) {
366 0, // Number of rectangles in the following array. 374 0, // Number of rectangles in the following array.
367 0); // No rectangles; clear the entire resource view. 375 0); // No rectangles; clear the entire resource view.
368 376
369 // Indicate that we now intend to use the back buffer to present. 377 // Indicate that we now intend to use the back buffer and depth/stencil
370 const D3D12_RESOURCE_BARRIER present_barrier = CD3DX12_RESOURCE_BARRIER_Transition( 378 // buffer to present.
371 d3d_get_current_back_buffer(d3d), 379 const D3D12_RESOURCE_BARRIER present_barriers[] = {
372 D3D12_RESOURCE_STATE_RENDER_TARGET, 380 CD3DX12_RESOURCE_BARRIER_Transition(
373 D3D12_RESOURCE_STATE_PRESENT); 381 d3d_get_current_back_buffer(d3d),
374 d3d->pCommandList->lpVtbl->ResourceBarrier(d3d->pCommandList, 1, &present_barrier); 382 D3D12_RESOURCE_STATE_RENDER_TARGET,
383 D3D12_RESOURCE_STATE_PRESENT),
384 CD3DX12_RESOURCE_BARRIER_Transition(
385 d3d->pDepthStencilBuffer,
386 D3D12_RESOURCE_STATE_DEPTH_WRITE,
387 D3D12_RESOURCE_STATE_PRESENT)
388 };
389 d3d->pCommandList->lpVtbl->ResourceBarrier(d3d->pCommandList, COUNTOF(present_barriers), present_barriers);
375 390
376 // A command list must be closed before it can be executed. 391 // A command list must be closed before it can be executed.
377 TrapIfFailed(d3d->pCommandList->lpVtbl->Close(d3d->pCommandList)); 392 TrapIfFailed(d3d->pCommandList->lpVtbl->Close(d3d->pCommandList));
@@ -385,8 +400,8 @@ static void d3d_wait_for_previous_frame(D3D* d3d) {
385 // Advance the fence value to mark commands up to this fence point. 400 // Advance the fence value to mark commands up to this fence point.
386 d3d->fence_value++; 401 d3d->fence_value++;
387 402
388 // The command queue will signal the new fence value when all commands 403 // The command queue will signal the new fence value when all commands up to
389 // up to this point have finished execution. 404 // this point have finished execution.
390 TrapIfFailed(d3d->pCommandQueue->lpVtbl->Signal( 405 TrapIfFailed(d3d->pCommandQueue->lpVtbl->Signal(
391 d3d->pCommandQueue, d3d->pFence, d3d->fence_value)); 406 d3d->pCommandQueue, d3d->pFence, d3d->fence_value));
392 407