mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-21 22:20:14 +01:00
d3d12: Attempt screen reset during context create
This will only work if all contexts have been destroyed. If the app attempts to re-create one context, while another outstanding context exists and is still in the removed state, then the screen is not recovered and the new context will fail to create. Reviewed-by: Bill Kristiansen <billkris@microsoft.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15002>
This commit is contained in:
parent
2d7eea08e2
commit
869a1a6066
5 changed files with 75 additions and 35 deletions
|
|
@ -2379,6 +2379,14 @@ struct pipe_context *
|
||||||
d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
d3d12_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
|
||||||
{
|
{
|
||||||
struct d3d12_screen *screen = d3d12_screen(pscreen);
|
struct d3d12_screen *screen = d3d12_screen(pscreen);
|
||||||
|
if (FAILED(screen->dev->GetDeviceRemovedReason())) {
|
||||||
|
/* Attempt recovery, but this may fail */
|
||||||
|
screen->deinit(screen);
|
||||||
|
if (!screen->init(screen)) {
|
||||||
|
debug_printf("D3D12: failed to reset screen\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct d3d12_context *ctx = CALLOC_STRUCT(d3d12_context);
|
struct d3d12_context *ctx = CALLOC_STRUCT(d3d12_context);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
|
|
|
||||||
|
|
@ -166,27 +166,23 @@ d3d12_destroy_dxcore_screen(struct pipe_screen *pscreen)
|
||||||
d3d12_destroy_screen(screen);
|
d3d12_destroy_screen(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pipe_screen *
|
static bool
|
||||||
d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid)
|
d3d12_init_dxcore_screen(struct d3d12_screen *dscreen)
|
||||||
{
|
{
|
||||||
struct d3d12_dxcore_screen *screen = CALLOC_STRUCT(d3d12_dxcore_screen);
|
struct d3d12_dxcore_screen *screen = d3d12_dxcore_screen(dscreen);
|
||||||
if (!screen)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
d3d12_init_screen_base(&screen->base, winsys);
|
|
||||||
screen->base.base.destroy = d3d12_destroy_dxcore_screen;
|
|
||||||
|
|
||||||
screen->factory = get_dxcore_factory();
|
screen->factory = get_dxcore_factory();
|
||||||
if (!screen->factory) {
|
if (!screen->factory)
|
||||||
d3d12_destroy_dxcore_screen(&screen->base.base);
|
return false;
|
||||||
return nullptr;
|
|
||||||
}
|
LUID *adapter_luid = &dscreen->adapter_luid;
|
||||||
|
if (adapter_luid->HighPart == 0 && adapter_luid->LowPart == 0)
|
||||||
|
adapter_luid = nullptr;
|
||||||
|
|
||||||
screen->adapter = choose_dxcore_adapter(screen->factory, adapter_luid);
|
screen->adapter = choose_dxcore_adapter(screen->factory, adapter_luid);
|
||||||
if (!screen->adapter) {
|
if (!screen->adapter) {
|
||||||
debug_printf("D3D12: no suitable adapter\n");
|
debug_printf("D3D12: no suitable adapter\n");
|
||||||
d3d12_destroy_dxcore_screen(&screen->base.base);
|
return false;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DXCoreHardwareID hardware_ids = {};
|
DXCoreHardwareID hardware_ids = {};
|
||||||
|
|
@ -200,8 +196,7 @@ d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid)
|
||||||
sizeof(screen->description),
|
sizeof(screen->description),
|
||||||
screen->description))) {
|
screen->description))) {
|
||||||
debug_printf("D3D12: failed to retrieve adapter description\n");
|
debug_printf("D3D12: failed to retrieve adapter description\n");
|
||||||
d3d12_destroy_dxcore_screen(&screen->base.base);
|
return false;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->base.vendor_id = hardware_ids.vendorID;
|
screen->base.vendor_id = hardware_ids.vendorID;
|
||||||
|
|
@ -211,6 +206,25 @@ d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid)
|
||||||
|
|
||||||
if (!d3d12_init_screen(&screen->base, screen->adapter)) {
|
if (!d3d12_init_screen(&screen->base, screen->adapter)) {
|
||||||
debug_printf("D3D12: failed to initialize DXCore screen\n");
|
debug_printf("D3D12: failed to initialize DXCore screen\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pipe_screen *
|
||||||
|
d3d12_create_dxcore_screen(struct sw_winsys *winsys, LUID *adapter_luid)
|
||||||
|
{
|
||||||
|
struct d3d12_dxcore_screen *screen = CALLOC_STRUCT(d3d12_dxcore_screen);
|
||||||
|
if (!screen)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
d3d12_init_screen_base(&screen->base, winsys, adapter_luid);
|
||||||
|
screen->base.base.destroy = d3d12_destroy_dxcore_screen;
|
||||||
|
screen->base.init = d3d12_init_dxcore_screen;
|
||||||
|
screen->base.deinit = d3d12_deinit_dxcore_screen;
|
||||||
|
|
||||||
|
if (!d3d12_init_dxcore_screen(&screen->base)) {
|
||||||
d3d12_destroy_dxcore_screen(&screen->base.base);
|
d3d12_destroy_dxcore_screen(&screen->base.base);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -147,34 +147,28 @@ d3d12_destroy_dxgi_screen(struct pipe_screen *pscreen)
|
||||||
d3d12_destroy_screen(screen);
|
d3d12_destroy_screen(screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct pipe_screen *
|
static bool
|
||||||
d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid)
|
d3d12_init_dxgi_screen(struct d3d12_screen *dscreen)
|
||||||
{
|
{
|
||||||
struct d3d12_dxgi_screen *screen = CALLOC_STRUCT(d3d12_dxgi_screen);
|
struct d3d12_dxgi_screen *screen = d3d12_dxgi_screen(dscreen);
|
||||||
if (!screen)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
d3d12_init_screen_base(&screen->base, winsys);
|
|
||||||
screen->base.base.destroy = d3d12_destroy_dxgi_screen;
|
|
||||||
|
|
||||||
screen->factory = get_dxgi_factory();
|
screen->factory = get_dxgi_factory();
|
||||||
if (!screen->factory) {
|
if (!screen->factory)
|
||||||
FREE(screen);
|
return false;
|
||||||
return nullptr;
|
|
||||||
}
|
LUID *adapter_luid = &dscreen->adapter_luid;
|
||||||
|
if (adapter_luid->HighPart == 0 && adapter_luid->LowPart == 0)
|
||||||
|
adapter_luid = nullptr;
|
||||||
|
|
||||||
screen->adapter = choose_dxgi_adapter(screen->factory, adapter_luid);
|
screen->adapter = choose_dxgi_adapter(screen->factory, adapter_luid);
|
||||||
if (!screen->adapter) {
|
if (!screen->adapter) {
|
||||||
debug_printf("D3D12: no suitable adapter\n");
|
debug_printf("D3D12: no suitable adapter\n");
|
||||||
d3d12_destroy_dxgi_screen(&screen->base.base);
|
return false;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DXGI_ADAPTER_DESC1 adapter_desc = {};
|
DXGI_ADAPTER_DESC1 adapter_desc = {};
|
||||||
if (FAILED(screen->adapter->GetDesc1(&adapter_desc))) {
|
if (FAILED(screen->adapter->GetDesc1(&adapter_desc))) {
|
||||||
debug_printf("D3D12: failed to retrieve adapter description\n");
|
debug_printf("D3D12: failed to retrieve adapter description\n");
|
||||||
d3d12_destroy_dxgi_screen(&screen->base.base);
|
return false;
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LARGE_INTEGER driver_version;
|
LARGE_INTEGER driver_version;
|
||||||
|
|
@ -193,6 +187,25 @@ d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid)
|
||||||
|
|
||||||
if (!d3d12_init_screen(&screen->base, screen->adapter)) {
|
if (!d3d12_init_screen(&screen->base, screen->adapter)) {
|
||||||
debug_printf("D3D12: failed to initialize DXGI screen\n");
|
debug_printf("D3D12: failed to initialize DXGI screen\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pipe_screen *
|
||||||
|
d3d12_create_dxgi_screen(struct sw_winsys *winsys, LUID *adapter_luid)
|
||||||
|
{
|
||||||
|
struct d3d12_dxgi_screen *screen = CALLOC_STRUCT(d3d12_dxgi_screen);
|
||||||
|
if (!screen)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
d3d12_init_screen_base(&screen->base, winsys, adapter_luid);
|
||||||
|
screen->base.base.destroy = d3d12_destroy_dxgi_screen;
|
||||||
|
screen->base.init = d3d12_init_dxgi_screen;
|
||||||
|
screen->base.deinit = d3d12_deinit_dxgi_screen;
|
||||||
|
|
||||||
|
if (!d3d12_init_dxgi_screen(&screen->base)) {
|
||||||
d3d12_destroy_dxgi_screen(&screen->base.base);
|
d3d12_destroy_dxgi_screen(&screen->base.base);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1098,11 +1098,13 @@ d3d12_init_null_rtv(struct d3d12_screen *screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys)
|
d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LUID *adapter_luid)
|
||||||
{
|
{
|
||||||
d3d12_debug = debug_get_option_d3d12_debug();
|
d3d12_debug = debug_get_option_d3d12_debug();
|
||||||
|
|
||||||
screen->winsys = winsys;
|
screen->winsys = winsys;
|
||||||
|
if (adapter_luid)
|
||||||
|
screen->adapter_luid = *adapter_luid;
|
||||||
mtx_init(&screen->descriptor_pool_mutex, mtx_plain);
|
mtx_init(&screen->descriptor_pool_mutex, mtx_plain);
|
||||||
mtx_init(&screen->submit_mutex, mtx_plain);
|
mtx_init(&screen->submit_mutex, mtx_plain);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,9 +64,12 @@ struct d3d12_memory_info {
|
||||||
struct d3d12_screen {
|
struct d3d12_screen {
|
||||||
struct pipe_screen base;
|
struct pipe_screen base;
|
||||||
struct sw_winsys *winsys;
|
struct sw_winsys *winsys;
|
||||||
|
LUID adapter_luid;
|
||||||
|
|
||||||
ID3D12Device3 *dev;
|
ID3D12Device3 *dev;
|
||||||
ID3D12CommandQueue *cmdqueue;
|
ID3D12CommandQueue *cmdqueue;
|
||||||
|
bool (*init)(struct d3d12_screen *screen);
|
||||||
|
void (*deinit)(struct d3d12_screen *screen);
|
||||||
void (*get_memory_info)(struct d3d12_screen *screen, struct d3d12_memory_info *output);
|
void (*get_memory_info)(struct d3d12_screen *screen, struct d3d12_memory_info *output);
|
||||||
|
|
||||||
mtx_t submit_mutex;
|
mtx_t submit_mutex;
|
||||||
|
|
@ -150,7 +153,7 @@ d3d12_dxcore_screen(struct d3d12_screen *screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys);
|
d3d12_init_screen_base(struct d3d12_screen *screen, struct sw_winsys *winsys, LUID *adapter_luid);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter);
|
d3d12_init_screen(struct d3d12_screen *screen, IUnknown *adapter);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue