diff --git a/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp b/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp index 8f10e5273f7..d0e1c7b9435 100644 --- a/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_dxcore_screen.cpp @@ -143,6 +143,29 @@ dxcore_get_memory_info(struct d3d12_screen *screen, struct d3d12_memory_info *ou output->usage = local_info.currentUsage + nonlocal_info.currentUsage; } +static void +d3d12_deinit_dxcore_screen(struct d3d12_screen *dscreen) +{ + d3d12_deinit_screen(dscreen); + struct d3d12_dxcore_screen *screen = d3d12_dxcore_screen(dscreen); + if (screen->adapter) { + screen->adapter->Release(); + screen->adapter = nullptr; + } + if (screen->factory) { + screen->factory->Release(); + screen->factory = nullptr; + } +} + +static void +d3d12_destroy_dxcore_screen(struct pipe_screen *pscreen) +{ + struct d3d12_screen *screen = d3d12_screen(pscreen); + d3d12_deinit_dxcore_screen(screen); + d3d12_destroy_screen(screen); +} + struct pipe_screen * d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid) { @@ -150,16 +173,19 @@ d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid) if (!screen) return nullptr; + d3d12_init_screen_base(&screen->base, winsys); + screen->base.base.destroy = d3d12_destroy_dxcore_screen; + screen->factory = get_dxcore_factory(); if (!screen->factory) { - FREE(screen); + d3d12_destroy_dxcore_screen(&screen->base.base); return nullptr; } screen->adapter = choose_dxcore_adapter(screen->factory, adapter_luid); if (!screen->adapter) { debug_printf("D3D12: no suitable adapter\n"); - FREE(screen); + d3d12_destroy_dxcore_screen(&screen->base.base); return nullptr; } @@ -174,7 +200,7 @@ d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid) sizeof(screen->description), screen->description))) { debug_printf("D3D12: failed to retrieve adapter description\n"); - FREE(screen); + d3d12_destroy_dxcore_screen(&screen->base.base); return nullptr; } @@ -183,9 +209,9 @@ d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid) screen->base.base.get_name = dxcore_get_name; screen->base.get_memory_info = dxcore_get_memory_info; - if (!d3d12_init_screen(&screen->base, winsys, screen->adapter)) { + if (!d3d12_init_screen(&screen->base, screen->adapter)) { debug_printf("D3D12: failed to initialize DXCore screen\n"); - FREE(screen); + d3d12_destroy_dxcore_screen(&screen->base.base); return nullptr; } diff --git a/src/gallium/drivers/d3d12/d3d12_dxgi_screen.cpp b/src/gallium/drivers/d3d12/d3d12_dxgi_screen.cpp index 344adb638bd..ff9987c2b5e 100644 --- a/src/gallium/drivers/d3d12/d3d12_dxgi_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_dxgi_screen.cpp @@ -124,6 +124,29 @@ dxgi_get_memory_info(struct d3d12_screen *screen, struct d3d12_memory_info *outp output->usage = local_info.CurrentUsage + nonlocal_info.CurrentUsage; } +static void +d3d12_deinit_dxgi_screen(struct d3d12_screen *dscreen) +{ + d3d12_deinit_screen(dscreen); + struct d3d12_dxgi_screen *screen = d3d12_dxgi_screen(dscreen); + if (screen->adapter) { + screen->adapter->Release(); + screen->adapter = nullptr; + } + if (screen->factory) { + screen->factory->Release(); + screen->factory = nullptr; + } +} + +static void +d3d12_destroy_dxgi_screen(struct pipe_screen *pscreen) +{ + struct d3d12_screen *screen = d3d12_screen(pscreen); + d3d12_deinit_dxgi_screen(screen); + d3d12_destroy_screen(screen); +} + struct pipe_screen * d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid) { @@ -131,6 +154,9 @@ d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid) if (!screen) return nullptr; + d3d12_init_screen_base(&screen->base, winsys); + screen->base.base.destroy = d3d12_destroy_dxgi_screen; + screen->factory = get_dxgi_factory(); if (!screen->factory) { FREE(screen); @@ -140,14 +166,14 @@ d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid) screen->adapter = choose_dxgi_adapter(screen->factory, adapter_luid); if (!screen->adapter) { debug_printf("D3D12: no suitable adapter\n"); - FREE(screen); + d3d12_destroy_dxgi_screen(&screen->base.base); return nullptr; } DXGI_ADAPTER_DESC1 adapter_desc = {}; if (FAILED(screen->adapter->GetDesc1(&adapter_desc))) { debug_printf("D3D12: failed to retrieve adapter description\n"); - FREE(screen); + d3d12_destroy_dxgi_screen(&screen->base.base); return nullptr; } @@ -165,9 +191,9 @@ d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid) screen->base.base.get_name = dxgi_get_name; screen->base.get_memory_info = dxgi_get_memory_info; - if (!d3d12_init_screen(&screen->base, winsys, screen->adapter)) { + if (!d3d12_init_screen(&screen->base, screen->adapter)) { debug_printf("D3D12: failed to initialize DXGI screen\n"); - FREE(screen); + d3d12_destroy_dxgi_screen(&screen->base.base); return nullptr; } diff --git a/src/gallium/drivers/d3d12/d3d12_residency.cpp b/src/gallium/drivers/d3d12/d3d12_residency.cpp index 75654c5b610..b3b0934e7ee 100644 --- a/src/gallium/drivers/d3d12/d3d12_residency.cpp +++ b/src/gallium/drivers/d3d12/d3d12_residency.cpp @@ -249,3 +249,12 @@ d3d12_init_residency(struct d3d12_screen *screen) return true; } + +void +d3d12_deinit_residency(struct d3d12_screen *screen) +{ + if (screen->residency_fence) { + screen->residency_fence->Release(); + screen->residency_fence = nullptr; + } +} diff --git a/src/gallium/drivers/d3d12/d3d12_residency.h b/src/gallium/drivers/d3d12/d3d12_residency.h index af84e65e682..2413aaedaca 100644 --- a/src/gallium/drivers/d3d12/d3d12_residency.h +++ b/src/gallium/drivers/d3d12/d3d12_residency.h @@ -31,3 +31,6 @@ d3d12_process_batch_residency(struct d3d12_screen *screen, struct d3d12_batch *b bool d3d12_init_residency(struct d3d12_screen *screen); + +void +d3d12_deinit_residency(struct d3d12_screen *screen); diff --git a/src/gallium/drivers/d3d12/d3d12_screen.cpp b/src/gallium/drivers/d3d12/d3d12_screen.cpp index 8b6896d7d97..60f4681eb2d 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.cpp +++ b/src/gallium/drivers/d3d12/d3d12_screen.cpp @@ -694,18 +694,56 @@ d3d12_is_format_supported(struct pipe_screen *pscreen, return true; } -static void -d3d12_destroy_screen(struct pipe_screen *pscreen) +void +d3d12_deinit_screen(struct d3d12_screen *screen) +{ + if (screen->rtv_pool) { + d3d12_descriptor_pool_free(screen->rtv_pool); + screen->rtv_pool = nullptr; + } + if (screen->dsv_pool) { + d3d12_descriptor_pool_free(screen->dsv_pool); + screen->dsv_pool = nullptr; + } + if (screen->view_pool) { + d3d12_descriptor_pool_free(screen->view_pool); + screen->view_pool = nullptr; + } + if (screen->readback_slab_bufmgr) { + screen->readback_slab_bufmgr->destroy(screen->readback_slab_bufmgr); + screen->readback_slab_bufmgr = nullptr; + } + if (screen->slab_bufmgr) { + screen->slab_bufmgr->destroy(screen->slab_bufmgr); + screen->slab_bufmgr = nullptr; + } + if (screen->cache_bufmgr) { + screen->cache_bufmgr->destroy(screen->cache_bufmgr); + screen->cache_bufmgr = nullptr; + } + if (screen->bufmgr) { + screen->bufmgr->destroy(screen->bufmgr); + screen->bufmgr = nullptr; + } + d3d12_deinit_residency(screen); + if (screen->fence) { + screen->fence->Release(); + screen->fence = nullptr; + } + if (screen->cmdqueue) { + screen->cmdqueue->Release(); + screen->cmdqueue = nullptr; + } + if (screen->dev) { + screen->dev->Release(); + screen->dev = nullptr; + } +} + +void +d3d12_destroy_screen(struct d3d12_screen *screen) { - struct d3d12_screen *screen = d3d12_screen(pscreen); slab_destroy_parent(&screen->transfer_pool); - d3d12_descriptor_pool_free(screen->rtv_pool); - d3d12_descriptor_pool_free(screen->dsv_pool); - d3d12_descriptor_pool_free(screen->view_pool); - screen->readback_slab_bufmgr->destroy(screen->readback_slab_bufmgr); - screen->slab_bufmgr->destroy(screen->slab_bufmgr); - screen->cache_bufmgr->destroy(screen->cache_bufmgr); - screen->bufmgr->destroy(screen->bufmgr); mtx_destroy(&screen->submit_mutex); mtx_destroy(&screen->descriptor_pool_mutex); FREE(screen); @@ -788,8 +826,10 @@ static void enable_d3d12_debug_layer() { ID3D12Debug *debug = get_debug_interface(); - if (debug) + if (debug) { debug->EnableDebugLayer(); + debug->Release(); + } } static void @@ -797,9 +837,13 @@ enable_gpu_validation() { ID3D12Debug *debug = get_debug_interface(); ID3D12Debug3 *debug3; - if (debug && - SUCCEEDED(debug->QueryInterface(IID_PPV_ARGS(&debug3)))) - debug3->SetEnableGPUBasedValidation(true); + if (debug) { + if (SUCCEEDED(debug->QueryInterface(IID_PPV_ARGS(&debug3)))) { + debug3->SetEnableGPUBasedValidation(true); + debug3->Release(); + } + debug->Release(); + } } static ID3D12Device3 * @@ -1053,8 +1097,8 @@ d3d12_init_null_rtv(struct d3d12_screen *screen) screen->dev->CreateRenderTargetView(NULL, &rtv, screen->null_rtv.cpu_handle); } -bool -d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknown *adapter) +void +d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys) { d3d12_debug = debug_get_option_d3d12_debug(); @@ -1072,7 +1116,12 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow screen->base.get_compiler_options = d3d12_get_compiler_options; screen->base.context_create = d3d12_context_create; screen->base.flush_frontbuffer = d3d12_flush_frontbuffer; - screen->base.destroy = d3d12_destroy_screen; +} + +bool +d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter) +{ + assert(screen->base.destroy != nullptr); #ifndef DEBUG if (d3d12_debug & D3D12_DEBUG_DEBUG_LAYER) @@ -1086,7 +1135,7 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow if (!screen->dev) { debug_printf("D3D12: failed to create device\n"); - goto failed; + return false; } ID3D12InfoQueue *info_queue; @@ -1107,37 +1156,38 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow NewFilter.DenyList.pIDList = msg_ids; info_queue->PushStorageFilter(&NewFilter); + info_queue->Release(); } if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS, &screen->opts, sizeof(screen->opts)))) { debug_printf("D3D12: failed to get device options\n"); - goto failed; + return false; } if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1, &screen->opts1, sizeof(screen->opts1)))) { debug_printf("D3D12: failed to get device options\n"); - goto failed; + return false; } if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2, &screen->opts2, sizeof(screen->opts2)))) { debug_printf("D3D12: failed to get device options\n"); - goto failed; + return false; } if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &screen->opts3, sizeof(screen->opts3)))) { debug_printf("D3D12: failed to get device options\n"); - goto failed; + return false; } if (FAILED(screen->dev->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &screen->opts4, sizeof(screen->opts4)))) { debug_printf("D3D12: failed to get device options\n"); - goto failed; + return false; } screen->architecture.NodeIndex = 0; @@ -1145,7 +1195,7 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow &screen->architecture, sizeof(screen->architecture)))) { debug_printf("D3D12: failed to get device architecture\n"); - goto failed; + return false; } D3D12_FEATURE_DATA_FEATURE_LEVELS feature_levels; @@ -1161,7 +1211,7 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow &feature_levels, sizeof(feature_levels)))) { debug_printf("D3D12: failed to get device feature levels\n"); - goto failed; + return false; } screen->max_feature_level = feature_levels.MaxSupportedFeatureLevel; @@ -1175,19 +1225,19 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow if (SUCCEEDED(screen->dev->QueryInterface(&device9))) { if (FAILED(device9->CreateCommandQueue1(&queue_desc, OpenGLOn12CreatorID, IID_PPV_ARGS(&screen->cmdqueue)))) - goto failed; + return false; device9->Release(); } else { if (FAILED(screen->dev->CreateCommandQueue(&queue_desc, IID_PPV_ARGS(&screen->cmdqueue)))) - goto failed; + return false; } if (FAILED(screen->dev->CreateFence(0, D3D12_FENCE_FLAG_NONE, IID_PPV_ARGS(&screen->fence)))) - goto failed; + return false; if (!d3d12_init_residency(screen)) - goto failed; + return false; UINT64 timestamp_freq; if (FAILED(screen->cmdqueue->GetTimestampFrequency(×tamp_freq))) @@ -1203,16 +1253,27 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow desc.usage = (pb_usage_flags)(PB_USAGE_CPU_WRITE | PB_USAGE_GPU_READ); screen->bufmgr = d3d12_bufmgr_create(screen); + if (!screen->bufmgr) + return false; + screen->cache_bufmgr = pb_cache_manager_create(screen->bufmgr, 0xfffff, 2, 0, 512 * 1024 * 1024); + if (!screen->cache_bufmgr) + return false; + screen->slab_bufmgr = pb_slab_range_manager_create(screen->cache_bufmgr, 16, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, &desc); + if (!screen->slab_bufmgr) + return false; + desc.usage = (pb_usage_flags)(PB_USAGE_CPU_READ_WRITE | PB_USAGE_GPU_WRITE); screen->readback_slab_bufmgr = pb_slab_range_manager_create(screen->cache_bufmgr, 16, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, D3D12_DEFAULT_RESOURCE_PLACEMENT_ALIGNMENT, &desc); + if (!screen->readback_slab_bufmgr) + return false; screen->rtv_pool = d3d12_descriptor_pool_new(screen, D3D12_DESCRIPTOR_HEAP_TYPE_RTV, @@ -1223,6 +1284,8 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow screen->view_pool = d3d12_descriptor_pool_new(screen, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV, 1024); + if (!screen->rtv_pool || !screen->dsv_pool || !screen->view_pool) + return false; d3d12_init_null_srvs(screen); d3d12_init_null_uavs(screen); @@ -1252,7 +1315,4 @@ d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknow screen->nir_options.lower_doubles_options = (nir_lower_doubles_options)~0; return true; - -failed: - return false; } diff --git a/src/gallium/drivers/d3d12/d3d12_screen.h b/src/gallium/drivers/d3d12/d3d12_screen.h index a97e7360b33..9cf012fd861 100644 --- a/src/gallium/drivers/d3d12/d3d12_screen.h +++ b/src/gallium/drivers/d3d12/d3d12_screen.h @@ -149,7 +149,16 @@ d3d12_dxcore_screen(struct d3d12_screen *screen) return (struct d3d12_dxcore_screen *)screen; } +void +d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys); + bool -d3d12_init_screen(struct d3d12_screen *screen, struct sw_winsys *winsys, IUnknown *adapter); +d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter); + +void +d3d12_deinit_screen(struct d3d12_screen *screen); + +void +d3d12_destroy_screen(struct d3d12_screen *screen); #endif