release dx12 objects on exit

This commit is contained in:
jacob 2025-06-06 17:31:36 -05:00
parent d0ec962123
commit 50ca2387fa
4 changed files with 174 additions and 127 deletions

1
.gitignore vendored
View File

@ -7,6 +7,7 @@
*.pdb *.pdb
*.exe *.exe
.vs/* .vs/*
.vscode/*
unused/ unused/
build/ build/

View File

@ -355,6 +355,7 @@ void app_entry_point(struct string args_str)
struct sys_lock lock = sys_mutex_lock_e(&G.exit_callbacks_mutex); struct sys_lock lock = sys_mutex_lock_e(&G.exit_callbacks_mutex);
/* Start callback threads */ /* Start callback threads */
/* TODO: Create these threads when the callbacks are initially registered and have them wait on exit */
{ {
__profscope(app_start_exit_callbacks); __profscope(app_start_exit_callbacks);
for (struct exit_callback *callback = G.exit_callbacks_head; callback; callback = callback->next) { for (struct exit_callback *callback = G.exit_callbacks_head; callback; callback = callback->next) {

View File

@ -6,6 +6,7 @@
#include "memory.h" #include "memory.h"
#include "string.h" #include "string.h"
#include "scratch.h" #include "scratch.h"
#include "app.h"
#pragma warning(push, 0) #pragma warning(push, 0)
# define UNICODE # define UNICODE
@ -68,13 +69,21 @@ GLOBAL struct {
struct dx12_handle_entry *first_free_handle_entry; struct dx12_handle_entry *first_free_handle_entry;
u64 num_handle_entries_reserved; u64 num_handle_entries_reserved;
/* Device */
ID3D12Device *device;
/* Swapchain */ /* Swapchain */
u32 swapchain_frame_index;
ID3D12CommandQueue *swapchain_cq;
IDXGISwapChain3 *swapchain;
} G = ZI, DEBUG_ALIAS(G, G_gpu_dx12); } G = ZI, DEBUG_ALIAS(G, G_gpu_dx12);
/* ========================== * /* ========================== *
* Startup * Startup
* ========================== */ * ========================== */
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown);
struct gpu_startup_receipt gpu_startup(struct sys_window *window) struct gpu_startup_receipt gpu_startup(struct sys_window *window)
{ {
struct temp_arena scratch = scratch_begin_no_conflict(); struct temp_arena scratch = scratch_begin_no_conflict();
@ -84,17 +93,31 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
G.handle_entries_mutex = sys_mutex_alloc(); G.handle_entries_mutex = sys_mutex_alloc();
G.handle_entries_arena = arena_alloc(GIGABYTE(64)); G.handle_entries_arena = arena_alloc(GIGABYTE(64));
/* Create debug controller */ /* Initialize dx12 */
{
/* Enable debug layer */
u32 dxgi_factory_flags = 0; u32 dxgi_factory_flags = 0;
#if DX12_DEBUG #if DX12_DEBUG
ID3D12Debug *debug_controller = NULL;
{ {
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller); ID3D12Debug *debug_controller0 = NULL;
hr = D3D12GetDebugInterface(&IID_ID3D12Debug, (void **)&debug_controller0);
if (!SUCCEEDED(hr)) { if (!SUCCEEDED(hr)) {
sys_panic(LIT("Failed to create D3D12 debug controller")); sys_panic(LIT("Failed to create ID3D12Debug0"));
} }
ID3D12Debug_EnableDebugLayer(debug_controller);
ID3D12Debug_Release(debug_controller); ID3D12Debug1 *debug_controller1 = NULL;
hr = ID3D12Debug_QueryInterface(debug_controller0, &IID_ID3D12Debug1, (void **)&debug_controller1);
if (!SUCCEEDED(hr)) {
sys_panic(LIT("Failed to create ID3D12Debug1"));
}
ID3D12Debug_EnableDebugLayer(debug_controller0);
/* FIXME: Enable this */
//ID3D12Debug1_SetEnableGPUBasedValidation(debug_controller1, true);
ID3D12Debug_Release(debug_controller1);
ID3D12Debug_Release(debug_controller0);
dxgi_factory_flags |= DXGI_CREATE_FACTORY_DEBUG; dxgi_factory_flags |= DXGI_CREATE_FACTORY_DEBUG;
} }
#endif #endif
@ -156,7 +179,7 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
} }
#if DX12_DEBUG #if DX12_DEBUG
/* D3D12 Debug break */ /* Enable D3D12 Debug break */
{ {
ID3D12InfoQueue *info = NULL; ID3D12InfoQueue *info = NULL;
hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info); hr = ID3D12Device_QueryInterface(device, &IID_ID3D12InfoQueue, (void **)&info);
@ -168,7 +191,7 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
ID3D12InfoQueue_Release(info); ID3D12InfoQueue_Release(info);
} }
/* DXGI Debug break */ /* Enable DXGI Debug break */
{ {
IDXGIInfoQueue *dxgi_info = NULL; IDXGIInfoQueue *dxgi_info = NULL;
hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info); hr = DXGIGetDebugInterface1(0, &IID_IDXGIInfoQueue, (void **)&dxgi_info);
@ -181,16 +204,16 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
} }
#endif #endif
/* Create command queue */ /* Create direct command queue */
ID3D12CommandQueue *cq = NULL; ID3D12CommandQueue *swapchain_cq = NULL;
{ {
D3D12_COMMAND_QUEUE_DESC desc = ZI; D3D12_COMMAND_QUEUE_DESC desc = ZI;
desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE; desc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT; desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&cq); hr = ID3D12Device_CreateCommandQueue(device, &desc, &IID_ID3D12CommandQueue, (void **)&swapchain_cq);
if (!SUCCEEDED(hr)) { if (!SUCCEEDED(hr)) {
sys_panic(LIT("Failed to create command queue")); sys_panic(LIT("Failed to create swapchain command queue"));
} }
} }
@ -212,7 +235,7 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
/* Create swapchain1 */ /* Create swapchain1 */
IDXGISwapChain1 *swapchain1 = NULL; IDXGISwapChain1 *swapchain1 = NULL;
hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)cq, hwnd, &desc, NULL, NULL, &swapchain1); hr = IDXGIFactory2_CreateSwapChainForHwnd(factory, (IUnknown *)swapchain_cq, hwnd, &desc, NULL, NULL, &swapchain1);
if (!SUCCEEDED(hr)) { if (!SUCCEEDED(hr)) {
sys_panic(LIT("Failed to create IDXGISwapChain1")); sys_panic(LIT("Failed to create IDXGISwapChain1"));
} }
@ -226,18 +249,39 @@ struct gpu_startup_receipt gpu_startup(struct sys_window *window)
/* Disable Alt+Enter changing monitor resolution to match window size */ /* Disable Alt+Enter changing monitor resolution to match window size */
IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER); IDXGIFactory_MakeWindowAssociation(factory, hwnd, DXGI_MWA_NO_ALT_ENTER);
/* Get initial frame index */
swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain); swapchain_frame_index = IDXGISwapChain3_GetCurrentBackBufferIndex(swapchain);
(UNUSED)swapchain_frame_index;
IDXGISwapChain1_Release(swapchain1); IDXGISwapChain1_Release(swapchain1);
} }
G.device = device;
G.swapchain_frame_index = swapchain_frame_index;
G.swapchain_cq = swapchain_cq;
G.swapchain = swapchain;
IDXGIFactory6_Release(factory); IDXGIFactory6_Release(factory);
}
app_register_exit_callback(gpu_shutdown);
scratch_end(scratch); scratch_end(scratch);
struct gpu_startup_receipt res = ZI; struct gpu_startup_receipt res = ZI;
return res; return res;
} }
INTERNAL APP_EXIT_CALLBACK_FUNC_DEF(gpu_shutdown)
{
#if DX12_DEBUG
/* Release objects to make live object reporting less noisy */
{
ID3D12Device_Release(G.device);
ID3D12CommandQueue_Release(G.swapchain_cq);
IDXGISwapChain3_Release(G.swapchain);
}
#endif
}
/* ========================== * /* ========================== *
* Handle * Handle
* ========================== */ * ========================== */

View File

@ -2076,6 +2076,7 @@ INTERNAL void user_update(void)
{ {
__profscope(render); __profscope(render);
struct rect user_viewport = RECT_FROM_V2(V2(0, 0), G.user_size); struct rect user_viewport = RECT_FROM_V2(V2(0, 0), G.user_size);
struct rect backbuffer_viewport = RECT_FROM_V2(V2(0, 0), G.screen_size); struct rect backbuffer_viewport = RECT_FROM_V2(V2(0, 0), G.screen_size);
struct v2i32 user_resolution = v2_round_to_int(user_viewport.size); struct v2i32 user_resolution = v2_round_to_int(user_viewport.size);