diff options
| -rw-r--r-- | hello/main.c | 115 |
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 | ||
| 43 | static 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 | |||
| 56 | static 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 | |||
| 63 | static 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 | ||
| 103 | static 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. |
| 112 | static void d3d_create_depth_stencil_buffer_and_view(D3D* d3d) { | 132 | static 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 | |||
| 295 | static 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 | |||
| 308 | static 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 | ||
| 315 | static void d3d_populate_command_list(D3D* d3d) { | 316 | static 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 | ||
