From 1fe3f99f4fc906379ac0cf0465880fac01fb8ba7 Mon Sep 17 00:00:00 2001 From: Rajveer Malviya Date: Thu, 6 Jul 2023 08:44:22 +0530 Subject: [PATCH] fix `WGPUInstanceEnumerateAdapterOptions`, `wgpuSwapChainGetCurrentTextureView` & `wgpuDevicePopErrorScope` (#276) --- examples/triangle/main.c | 31 +++++++++++++++++++++++++++++++ ffi/wgpu.h | 2 +- src/lib.rs | 34 ++++++++++++++++++++++------------ 3 files changed, 54 insertions(+), 13 deletions(-) diff --git a/examples/triangle/main.c b/examples/triangle/main.c index e983d526..d5539fd6 100644 --- a/examples/triangle/main.c +++ b/examples/triangle/main.c @@ -4,6 +4,7 @@ #include #include #include +#include #if defined(WGPU_TARGET_MACOS) #include @@ -31,6 +32,7 @@ struct demo { WGPUDevice device; WGPUSwapChainDescriptor config; WGPUSwapChain swapchain; + bool skip_curr_frame; }; static void handle_request_adapter(WGPURequestAdapterStatus status, @@ -88,6 +90,27 @@ static void handle_glfw_framebuffer_size(GLFWwindow *window, int width, wgpuDeviceCreateSwapChain(demo->device, demo->surface, &demo->config); assert(demo->swapchain); } +static void handle_curr_texture_error(WGPUErrorType type, char const *message, + void *userdata) { + if (type == WGPUErrorType_NoError) + return; + + printf(LOG_PREFIX " curr_texture_error type=%#.8x message=%s\n", type, + message); + + struct demo *demo = userdata; + + if (strstr(message, "Surface timed out") != NULL) { + demo->skip_curr_frame = true; + return; + } else if (strstr(message, "Surface is outdated") != NULL) { + demo->skip_curr_frame = true; + return; + } else if (strstr(message, "Surface was lost") != NULL) { + demo->skip_curr_frame = true; + return; + } +} int main(int argc, char *argv[]) { UNUSED(argc) @@ -295,10 +318,18 @@ int main(int argc, char *argv[]) { ASSERT_CHECK(demo.swapchain); while (!glfwWindowShouldClose(window)) { + demo.skip_curr_frame = false; glfwPollEvents(); + wgpuDevicePushErrorScope(demo.device, WGPUErrorFilter_Validation); WGPUTextureView next_texture = wgpuSwapChainGetCurrentTextureView(demo.swapchain); + wgpuDevicePopErrorScope(demo.device, handle_curr_texture_error, &demo); + if (demo.skip_curr_frame) { + if (next_texture) + wgpuTextureViewRelease(next_texture); + continue; + } assert(next_texture); WGPUCommandEncoder command_encoder = wgpuDeviceCreateCommandEncoder( diff --git a/ffi/wgpu.h b/ffi/wgpu.h index 46e73615..b4032680 100644 --- a/ffi/wgpu.h +++ b/ffi/wgpu.h @@ -179,7 +179,7 @@ typedef struct WGPUSwapChainDescriptorExtras { } WGPUSwapChainDescriptorExtras; typedef struct WGPUInstanceEnumerateAdapterOptions { - WGPUChainedStruct chain; + WGPUChainedStruct const * nextInChain; WGPUInstanceBackendFlags backends; } WGPUInstanceEnumerateAdapterOptions; diff --git a/src/lib.rs b/src/lib.rs index f1a7810f..c0761c8a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2574,20 +2574,27 @@ pub unsafe extern "C" fn wgpuDevicePopErrorScope( let mut error_sink = device.error_sink.lock(); let scope = error_sink.scopes.pop().unwrap(); - if let Some(error) = scope.error { - let typ = match error { - crate::Error::OutOfMemory { .. } => native::WGPUErrorType_OutOfMemory, - crate::Error::Validation { .. } => native::WGPUErrorType_Validation, - // We handle device lost error early in ErrorSinkRaw::handle_error - // so we should never get device lost error here. - crate::Error::DeviceLost { .. } => unreachable!(), - }; + match scope.error { + Some(error) => { + let typ = match error { + crate::Error::OutOfMemory { .. } => native::WGPUErrorType_OutOfMemory, + crate::Error::Validation { .. } => native::WGPUErrorType_Validation, + // We handle device lost error early in ErrorSinkRaw::handle_error + // so we should never get device lost error here. + crate::Error::DeviceLost { .. } => unreachable!(), + }; - let msg = CString::new(error.to_string()).unwrap(); - unsafe { - callback(typ, msg.as_ptr(), userdata); + let msg = CString::new(error.to_string()).unwrap(); + unsafe { + callback(typ, msg.as_ptr(), userdata); + }; } - } + None => { + unsafe { + callback(native::WGPUErrorType_NoError, std::ptr::null(), userdata); + }; + } + }; } #[no_mangle] @@ -3689,6 +3696,9 @@ pub unsafe extern "C" fn wgpuSwapChainGetCurrentTextureView( })) } _ => { + if let Some(texture_id) = result.texture_id { + gfx_select!(texture_id => context.texture_drop(texture_id, false)); + } handle_error( context, error_sink,