瀏覽代碼

Improved error information when renderer creation fails

On Android, if you create a window with SDL_WINDOW_OPENGL, you can't create a Vulkan surface. The error message has been improved to reflect this, and the error is propagated back up to the application.

Also added warn level logging if the renderer couldn't be created.
Sam Lantinga 3 天之前
父節點
當前提交
3316dde0c2
共有 3 個文件被更改,包括 16 次插入3 次删除
  1. 10 1
      src/render/SDL_render.c
  2. 0 1
      src/render/vulkan/SDL_render_vulkan.c
  3. 6 1
      src/video/android/SDL_androidvulkan.c

+ 10 - 1
src/render/SDL_render.c

@@ -1096,6 +1096,7 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
             goto error;
             goto error;
         }
         }
     } else {
     } else {
+        char *driver_error = NULL;
         bool rc = false;
         bool rc = false;
         if (!driver_name) {
         if (!driver_name) {
             driver_name = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
             driver_name = SDL_GetHint(SDL_HINT_RENDER_DRIVER);
@@ -1110,10 +1111,13 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
                 for (int i = 0; render_drivers[i]; i++) {
                 for (int i = 0; render_drivers[i]; i++) {
                     const SDL_RenderDriver *driver = render_drivers[i];
                     const SDL_RenderDriver *driver = render_drivers[i];
                     if ((driver_attempt_len == SDL_strlen(driver->name)) && (SDL_strncasecmp(driver->name, driver_attempt, driver_attempt_len) == 0)) {
                     if ((driver_attempt_len == SDL_strlen(driver->name)) && (SDL_strncasecmp(driver->name, driver_attempt, driver_attempt_len) == 0)) {
+                        SDL_free(driver_error);
                         rc = driver->CreateRenderer(renderer, window, props);
                         rc = driver->CreateRenderer(renderer, window, props);
                         if (rc) {
                         if (rc) {
                             break;
                             break;
                         }
                         }
+                        driver_error = SDL_strdup(SDL_GetError());
+                        SDL_LogWarn(SDL_LOG_CATEGORY_RENDER, "Couldn't create renderer %s: %s\n", driver->name, driver_error);
                         SDL_DestroyRendererWithoutFreeing(renderer);
                         SDL_DestroyRendererWithoutFreeing(renderer);
                         SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct.
                         SDL_zerop(renderer); // make sure we don't leave function pointers from a previous CreateRenderer() in this struct.
                     }
                     }
@@ -1137,7 +1141,12 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
             SDL_DebugLogBackend("render", renderer->name);
             SDL_DebugLogBackend("render", renderer->name);
         } else {
         } else {
             if (driver_name) {
             if (driver_name) {
-                SDL_SetError("%s not available", driver_name);
+                if (driver_error) {
+                    SDL_SetError("%s", driver_error);
+                    SDL_free(driver_error);
+                } else {
+                    SDL_SetError("%s not available", driver_name);
+                }
             } else {
             } else {
                 SDL_SetError("Couldn't find matching render driver");
                 SDL_SetError("Couldn't find matching render driver");
             }
             }

+ 0 - 1
src/render/vulkan/SDL_render_vulkan.c

@@ -1812,7 +1812,6 @@ static VkResult VULKAN_CreateDeviceResources(SDL_Renderer *renderer, SDL_Propert
     } else {
     } else {
         if (!SDL_Vulkan_CreateSurface(renderer->window, rendererData->instance, NULL, &rendererData->surface)) {
         if (!SDL_Vulkan_CreateSurface(renderer->window, rendererData->instance, NULL, &rendererData->surface)) {
             VULKAN_DestroyAll(renderer);
             VULKAN_DestroyAll(renderer);
-            SET_ERROR_MESSAGE("Vulkan_CreateSurface() failed");
             return VK_ERROR_UNKNOWN;
             return VK_ERROR_UNKNOWN;
         }
         }
     }
     }

+ 6 - 1
src/video/android/SDL_androidvulkan.c

@@ -145,6 +145,7 @@ bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
         return SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
         return SDL_SetError(VK_KHR_ANDROID_SURFACE_EXTENSION_NAME
                             " extension is not enabled in the Vulkan instance.");
                             " extension is not enabled in the Vulkan instance.");
     }
     }
+
     SDL_zero(createInfo);
     SDL_zero(createInfo);
     createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
     createInfo.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
     createInfo.pNext = NULL;
     createInfo.pNext = NULL;
@@ -152,7 +153,11 @@ bool Android_Vulkan_CreateSurface(SDL_VideoDevice *_this,
     createInfo.window = windowData->native_window;
     createInfo.window = windowData->native_window;
     result = vkCreateAndroidSurfaceKHR(instance, &createInfo, allocator, surface);
     result = vkCreateAndroidSurfaceKHR(instance, &createInfo, allocator, surface);
     if (result != VK_SUCCESS) {
     if (result != VK_SUCCESS) {
-        return SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
+        if (result == VK_ERROR_NATIVE_WINDOW_IN_USE_KHR) {
+            return SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s, was the window created with SDL_WINDOW_VULKAN?", SDL_Vulkan_GetResultString(result));
+        } else {
+            return SDL_SetError("vkCreateAndroidSurfaceKHR failed: %s", SDL_Vulkan_GetResultString(result));
+        }
     }
     }
     return true;
     return true;
 }
 }