-
Notifications
You must be signed in to change notification settings - Fork 4
Robust GPU error recovery [Windows] #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: stable
Are you sure you want to change the base?
Changes from 6 commits
223e2b8
b63b8f5
8a3b5fa
33f73bf
be4ad33
c014061
b4f1412
d2b88a9
1af162e
c7c3d66
3066a96
6473bde
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| #include "error.h" | ||
|
|
||
| #include "tlocal.h" | ||
|
|
||
| static TLOCAL MTY_Queue *Q = NULL; | ||
|
|
||
| void error_local_init(void) | ||
| { | ||
| error_local_clear(); | ||
|
|
||
| Q = MTY_QueueCreate(10, sizeof(MTY_Error)); | ||
dvijayak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
|
|
||
| void error_local_clear(void) | ||
| { | ||
| MTY_QueueDestroy(&Q); | ||
| } | ||
|
|
||
|
|
||
| bool error_local_get_next_error(MTY_Error *error) | ||
| { | ||
| if (!Q) | ||
| return false; | ||
|
|
||
| MTY_Error *buf = NULL; | ||
|
|
||
| bool rc = MTY_QueueGetOutputBuffer(Q, 0, (void **) &buf, NULL); | ||
| if (rc) { | ||
| *error = *buf; | ||
| MTY_QueuePop(Q); | ||
| } | ||
|
|
||
| return rc; | ||
| } | ||
|
|
||
| void error_local_push_error(MTY_Error error) | ||
| { | ||
| if (!Q) | ||
| return; | ||
|
|
||
| MTY_Error *buf = MTY_QueueGetInputBuffer(Q); | ||
| if (buf) { | ||
| *buf = error; | ||
| MTY_QueuePush(Q, sizeof(MTY_Error)); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| #pragma once | ||
|
|
||
| #include "matoya.h" | ||
|
|
||
| void error_local_init(void); | ||
| void error_local_clear(void); | ||
|
|
||
| bool error_local_get_next_error(MTY_Error *error); | ||
| void error_local_push_error(MTY_Error error); |
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All changes in this file implement a more robust GPU error handling. This portion concerns the main graphics context state. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,8 +12,11 @@ GFX_CTX_PROTOTYPES(_d3d11_) | |
| #include "gfx/sync.h" | ||
| #include "dxgi-sync.h" | ||
|
|
||
| #include "d3d11-error.h" | ||
|
|
||
| #define DXGI_FATAL(e) ( \ | ||
| (e) == DXGI_ERROR_DEVICE_REMOVED || \ | ||
| (e) == DXGI_ERROR_DRIVER_INTERNAL_ERROR || \ | ||
| (e) == DXGI_ERROR_DEVICE_HUNG || \ | ||
| (e) == DXGI_ERROR_DEVICE_RESET \ | ||
| ) | ||
|
|
@@ -187,12 +190,21 @@ static bool d3d11_ctx_init(struct d3d11_ctx *ctx) | |
| if (device2) | ||
| IDXGIDevice2_Release(device2); | ||
|
|
||
| if (e != S_OK) | ||
| if (e != S_OK) { | ||
| d3d11_push_local_error(e); | ||
| d3d11_ctx_free(ctx); | ||
| } | ||
|
|
||
| return e == S_OK; | ||
| } | ||
|
|
||
| int32_t mty_d3d11_error_handler_default(int32_t e1, int32_t e2, void *opaque) | ||
| { | ||
| e1; e2; opaque; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We usually put each of these on a different line |
||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| struct gfx_ctx *mty_d3d11_ctx_create(void *native_window, bool vsync) | ||
| { | ||
| struct d3d11_ctx *ctx = MTY_Alloc(1, sizeof(struct d3d11_ctx)); | ||
|
|
@@ -263,6 +275,8 @@ static void d3d11_ctx_refresh(struct d3d11_ctx *ctx) | |
|
|
||
| if (DXGI_FATAL(e)) { | ||
| MTY_Log("'IDXGISwapChain2_ResizeBuffers' failed with HRESULT 0x%X", e); | ||
| d3d11_push_local_error(e); | ||
|
|
||
| d3d11_ctx_free(ctx); | ||
| d3d11_ctx_init(ctx); | ||
| } | ||
|
|
@@ -273,6 +287,7 @@ MTY_Surface *mty_d3d11_ctx_get_surface(struct gfx_ctx *gfx_ctx) | |
| { | ||
| struct d3d11_ctx *ctx = (struct d3d11_ctx *) gfx_ctx; | ||
|
|
||
| HRESULT e = S_OK; | ||
| ID3D11Resource *resource = NULL; | ||
|
|
||
| if (!ctx->swap_chain2) | ||
|
|
@@ -281,22 +296,28 @@ MTY_Surface *mty_d3d11_ctx_get_surface(struct gfx_ctx *gfx_ctx) | |
| if (!ctx->back_buffer) { | ||
| d3d11_ctx_refresh(ctx); | ||
|
|
||
| HRESULT e = IDXGISwapChain2_GetBuffer(ctx->swap_chain2, 0, &IID_ID3D11Resource, &resource); | ||
| e = IDXGISwapChain2_GetBuffer(ctx->swap_chain2, 0, &IID_ID3D11Resource, &resource); | ||
| if (e != S_OK) { | ||
| MTY_Log("'IDXGISwapChain2_GetBuffer' failed with HRESULT 0x%X", e); | ||
| goto except; | ||
| } | ||
|
|
||
| e = ID3D11Device_CreateRenderTargetView(ctx->device, resource, NULL, &ctx->back_buffer); | ||
| if (e != S_OK) | ||
| if (e != S_OK) { | ||
| MTY_Log("'ID3D11Device_CreateRenderTargetView' failed with HRESULT 0x%X", e); | ||
| goto except; | ||
| } | ||
| } | ||
|
|
||
| except: | ||
|
|
||
| if (resource) | ||
| ID3D11Resource_Release(resource); | ||
|
|
||
| if (e != S_OK) | ||
| d3d11_push_local_error(e); | ||
|
|
||
|
|
||
| return (MTY_Surface *) ctx->back_buffer; | ||
| } | ||
|
|
||
|
|
@@ -335,13 +356,17 @@ void mty_d3d11_ctx_present(struct gfx_ctx *gfx_ctx) | |
|
|
||
| if (DXGI_FATAL(e)) { | ||
| MTY_Log("'IDXGISwapChain2_Present' failed with HRESULT 0x%X", e); | ||
| d3d11_push_local_error(e); | ||
|
|
||
| d3d11_ctx_free(ctx); | ||
| d3d11_ctx_init(ctx); | ||
|
|
||
| } else { | ||
| DWORD we = WaitForSingleObjectEx(ctx->waitable, D3D11_CTX_WAIT, TRUE); | ||
| if (we != WAIT_OBJECT_0) | ||
| if (we != WAIT_OBJECT_0) { | ||
| MTY_Log("'WaitForSingleObjectEx' failed with error 0x%X", we); | ||
| d3d11_push_local_error(e); | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #pragma once | ||
|
|
||
| #include "matoya.h" | ||
|
|
||
| #include "error.h" | ||
|
|
||
| static MTY_Error d3d11_map_error(int32_t e) | ||
| { | ||
| switch (e) { | ||
| case DXGI_ERROR_DEVICE_REMOVED: | ||
| case DXGI_ERROR_DRIVER_INTERNAL_ERROR: | ||
| return MTY_ERROR_GFX_DEVICE_REMOVED; | ||
|
|
||
| case DXGI_ERROR_DEVICE_HUNG: | ||
| case DXGI_ERROR_DEVICE_RESET: | ||
| return MTY_ERROR_GFX_ERROR; | ||
|
|
||
| case DXGI_STATUS_OCCLUDED: | ||
| return MTY_ERROR_GFX_INVISIBLE_CONTENT; | ||
|
|
||
| case DXGI_STATUS_UNOCCLUDED: | ||
| return MTY_ERROR_GFX_REVISIBLE_CONTENT; | ||
|
|
||
| default: | ||
| return MTY_ERROR_OK; | ||
| } | ||
| } | ||
|
|
||
| #define d3d11_push_local_error(e) error_local_push_error(d3d11_map_error(e)) |
|
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All changes in this file implement a more robust GPU error handling. This portion concerns state pertaining to rendering UI. |
Uh oh!
There was an error while loading. Please reload this page.