From 3d47877bb43b99a26800c607988ee293a4247f25 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Mon, 21 Oct 2024 00:19:05 -0700
Subject: [PATCH] Added SDL_EVENT_RENDER_DEVICE_LOST
This is sent when the device is lost and can't be recovered.
Also fixed the vulkan renderer so it returns errors appropriately and will log and break if debug mode is enabled.
---
include/SDL3/SDL_events.h | 1 +
src/render/direct3d11/SDL_render_d3d11.c | 75 +++---
src/render/direct3d12/SDL_render_d3d12.c | 76 +++---
src/render/vulkan/SDL_render_vulkan.c | 319 ++++++++++++++---------
src/test/SDL_test_common.c | 7 +-
5 files changed, 266 insertions(+), 212 deletions(-)
diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h
index 7de278551bc9e..399e0feb96284 100644
--- a/include/SDL3/SDL_events.h
+++ b/include/SDL3/SDL_events.h
@@ -228,6 +228,7 @@ typedef enum SDL_EventType
/* Render events */
SDL_EVENT_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
SDL_EVENT_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
+ SDL_EVENT_RENDER_DEVICE_LOST, /**< The device has been lost and can't be recovered. */
/* Reserved events for private platforms */
SDL_EVENT_PRIVATE0 = 0x4000,
diff --git a/src/render/direct3d11/SDL_render_d3d11.c b/src/render/direct3d11/SDL_render_d3d11.c
index f75bf02e3c7f5..c14346ff3f5f3 100644
--- a/src/render/direct3d11/SDL_render_d3d11.c
+++ b/src/render/direct3d11/SDL_render_d3d11.c
@@ -307,10 +307,9 @@ static void D3D11_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static void D3D11_ReleaseAll(SDL_Renderer *renderer)
{
D3D11_RenderData *data = (D3D11_RenderData *)renderer->internal;
- SDL_Texture *texture = NULL;
// Release all textures
- for (texture = renderer->textures; texture; texture = texture->next) {
+ for (SDL_Texture *texture = renderer->textures; texture; texture = texture->next) {
D3D11_DestroyTexture(renderer, texture);
}
@@ -982,39 +981,6 @@ static void D3D11_ReleaseMainRenderTargetView(SDL_Renderer *renderer)
SAFE_RELEASE(data->mainRenderTargetView);
}
-static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer *renderer);
-
-static HRESULT D3D11_HandleDeviceLost(SDL_Renderer *renderer)
-{
- HRESULT result = S_OK;
-
- D3D11_ReleaseAll(renderer);
-
- result = D3D11_CreateDeviceResources(renderer);
- if (FAILED(result)) {
- // D3D11_CreateDeviceResources will set the SDL error
- D3D11_ReleaseAll(renderer);
- return result;
- }
-
- result = D3D11_UpdateForWindowSizeChange(renderer);
- if (FAILED(result)) {
- // D3D11_UpdateForWindowSizeChange will set the SDL error
- D3D11_ReleaseAll(renderer);
- return result;
- }
-
- // Let the application know that the device has been reset
- {
- SDL_Event event;
- event.type = SDL_EVENT_RENDER_DEVICE_RESET;
- event.common.timestamp = 0;
- SDL_PushEvent(&event);
- }
-
- return S_OK;
-}
-
// Initialize all resources that change when the window's size changes.
static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
{
@@ -1045,15 +1011,7 @@ static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
w, h,
DXGI_FORMAT_UNKNOWN,
0);
- if (result == DXGI_ERROR_DEVICE_REMOVED) {
- // If the device was removed for any reason, a new device and swap chain will need to be created.
- D3D11_HandleDeviceLost(renderer);
-
- /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
- * and correctly set up the new device.
- */
- goto done;
- } else if (FAILED(result)) {
+ if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::ResizeBuffers"), result);
goto done;
}
@@ -1110,6 +1068,29 @@ static HRESULT D3D11_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
return result;
}
+static bool D3D11_HandleDeviceLost(SDL_Renderer *renderer)
+{
+ bool recovered = false;
+
+ D3D11_ReleaseAll(renderer);
+
+ if (SUCCEEDED(D3D11_CreateDeviceResources(renderer)) &&
+ SUCCEEDED(D3D11_CreateWindowSizeDependentResources(renderer))) {
+ recovered = true;
+ } else {
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Renderer couldn't recover from device lost: %s\n", SDL_GetError());
+ D3D11_ReleaseAll(renderer);
+ }
+
+ // Let the application know that the device has been reset or lost
+ SDL_Event event;
+ event.type = recovered ? SDL_EVENT_RENDER_DEVICE_RESET : SDL_EVENT_RENDER_DEVICE_LOST;
+ event.common.timestamp = 0;
+ SDL_PushEvent(&event);
+
+ return recovered;
+}
+
// This method is called when the window's size changes.
static HRESULT D3D11_UpdateForWindowSizeChange(SDL_Renderer *renderer)
{
@@ -1164,6 +1145,10 @@ static bool D3D11_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
D3D11_TEXTURE2D_DESC textureDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
+ if (!rendererData->d3dDevice) {
+ return SDL_SetError("Device lost and couldn't be recovered");
+ }
+
if (textureFormat == DXGI_FORMAT_UNKNOWN) {
return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified",
__FUNCTION__, texture->format);
@@ -2644,7 +2629,7 @@ static bool D3D11_RenderPresent(SDL_Renderer *renderer)
* must recreate all device resources.
*/
if (result == DXGI_ERROR_DEVICE_REMOVED) {
- if (SUCCEEDED(D3D11_HandleDeviceLost(renderer))) {
+ if (D3D11_HandleDeviceLost(renderer)) {
SDL_SetError("Present failed, device lost");
} else {
// Recovering from device lost failed, error is already set
diff --git a/src/render/direct3d12/SDL_render_d3d12.c b/src/render/direct3d12/SDL_render_d3d12.c
index 42a02f5e9a858..55114335048cd 100644
--- a/src/render/direct3d12/SDL_render_d3d12.c
+++ b/src/render/direct3d12/SDL_render_d3d12.c
@@ -374,14 +374,13 @@ static void D3D12_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
static void D3D12_ReleaseAll(SDL_Renderer *renderer)
{
D3D12_RenderData *data = (D3D12_RenderData *)renderer->internal;
- SDL_Texture *texture = NULL;
SDL_PropertiesID props = SDL_GetRendererProperties(renderer);
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_D3D12_DEVICE_POINTER, NULL);
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_D3D12_COMMAND_QUEUE_POINTER, NULL);
// Release all textures
- for (texture = renderer->textures; texture; texture = texture->next) {
+ for (SDL_Texture *texture = renderer->textures; texture; texture = texture->next) {
D3D12_DestroyTexture(renderer, texture);
}
@@ -1326,40 +1325,6 @@ static HRESULT D3D12_CreateSwapChain(SDL_Renderer *renderer, int w, int h)
}
#endif
-static HRESULT D3D12_UpdateForWindowSizeChange(SDL_Renderer *renderer);
-
-HRESULT
-D3D12_HandleDeviceLost(SDL_Renderer *renderer)
-{
- HRESULT result = S_OK;
-
- D3D12_ReleaseAll(renderer);
-
- result = D3D12_CreateDeviceResources(renderer);
- if (FAILED(result)) {
- // D3D12_CreateDeviceResources will set the SDL error
- D3D12_ReleaseAll(renderer);
- return result;
- }
-
- result = D3D12_UpdateForWindowSizeChange(renderer);
- if (FAILED(result)) {
- // D3D12_UpdateForWindowSizeChange will set the SDL error
- D3D12_ReleaseAll(renderer);
- return result;
- }
-
- // Let the application know that the device has been reset
- {
- SDL_Event event;
- event.type = SDL_EVENT_RENDER_DEVICE_RESET;
- event.common.timestamp = 0;
- SDL_PushEvent(&event);
- }
-
- return S_OK;
-}
-
// Initialize all resources that change when the window's size changes.
static HRESULT D3D12_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
{
@@ -1398,15 +1363,7 @@ static HRESULT D3D12_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
w, h,
DXGI_FORMAT_UNKNOWN,
data->swapFlags);
- if (result == DXGI_ERROR_DEVICE_REMOVED) {
- // If the device was removed for any reason, a new device and swap chain will need to be created.
- D3D12_HandleDeviceLost(renderer);
-
- /* Everything is set up now. Do not continue execution of this method. HandleDeviceLost will reenter this method
- * and correctly set up the new device.
- */
- goto done;
- } else if (FAILED(result)) {
+ if (FAILED(result)) {
WIN_SetErrorFromHRESULT(SDL_COMPOSE_ERROR("IDXGISwapChain::ResizeBuffers"), result);
goto done;
}
@@ -1486,6 +1443,29 @@ static HRESULT D3D12_CreateWindowSizeDependentResources(SDL_Renderer *renderer)
return result;
}
+static bool D3D12_HandleDeviceLost(SDL_Renderer *renderer)
+{
+ bool recovered = false;
+
+ D3D12_ReleaseAll(renderer);
+
+ if (SUCCEEDED(D3D12_CreateDeviceResources(renderer)) &&
+ SUCCEEDED(D3D12_CreateWindowSizeDependentResources(renderer))) {
+ recovered = true;
+ } else {
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Renderer couldn't recover from device lost: %s\n", SDL_GetError());
+ D3D12_ReleaseAll(renderer);
+ }
+
+ // Let the application know that the device has been reset or lost
+ SDL_Event event;
+ event.type = recovered ? SDL_EVENT_RENDER_DEVICE_RESET : SDL_EVENT_RENDER_DEVICE_LOST;
+ event.common.timestamp = 0;
+ SDL_PushEvent(&event);
+
+ return recovered;
+}
+
// This method is called when the window's size changes.
static HRESULT D3D12_UpdateForWindowSizeChange(SDL_Renderer *renderer)
{
@@ -1568,6 +1548,10 @@ static bool D3D12_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture, SD
D3D12_HEAP_PROPERTIES heapProps;
D3D12_SHADER_RESOURCE_VIEW_DESC resourceViewDesc;
+ if (!rendererData->d3dDevice) {
+ return SDL_SetError("Device lost and couldn't be recovered");
+ }
+
if (textureFormat == DXGI_FORMAT_UNKNOWN) {
return SDL_SetError("%s, An unsupported SDL pixel format (0x%x) was specified", __FUNCTION__, texture->format);
}
@@ -3147,7 +3131,7 @@ static bool D3D12_RenderPresent(SDL_Renderer *renderer)
* must recreate all device resources.
*/
if (result == DXGI_ERROR_DEVICE_REMOVED) {
- if (SUCCEEDED(D3D12_HandleDeviceLost(renderer))) {
+ if (D3D12_HandleDeviceLost(renderer)) {
SDL_SetError("Present failed, device lost");
} else {
// Recovering from device lost failed, error is already set
diff --git a/src/render/vulkan/SDL_render_vulkan.c b/src/render/vulkan/SDL_render_vulkan.c
index 12dc13b275cee..d99bf8cbed038 100644
--- a/src/render/vulkan/SDL_render_vulkan.c
+++ b/src/render/vulkan/SDL_render_vulkan.c
@@ -39,6 +39,20 @@
#include "../../video/SDL_pixels_c.h"
#include "SDL_shaders_vulkan.h"
+#define SET_ERROR_CODE(message, rc) \
+ if (SDL_GetHintBoolean(SDL_HINT_RENDER_VULKAN_DEBUG, false)) { \
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s: %s\n", message, SDL_Vulkan_GetResultString(rc)); \
+ SDL_TriggerBreakpoint(); \
+ } \
+ SDL_SetError("%s: %s", message, SDL_Vulkan_GetResultString(rc)) \
+
+#define SET_ERROR_MESSAGE(message) \
+ if (SDL_GetHintBoolean(SDL_HINT_RENDER_VULKAN_DEBUG, false)) { \
+ SDL_LogError(SDL_LOG_CATEGORY_RENDER, "%s\n", message); \
+ SDL_TriggerBreakpoint(); \
+ } \
+ SDL_SetError("%s", message) \
+
#define VULKAN_FUNCTIONS() \
VULKAN_DEVICE_FUNCTION(vkAcquireNextImageKHR) \
VULKAN_DEVICE_FUNCTION(vkAllocateCommandBuffers) \
@@ -304,6 +318,7 @@ typedef struct
VkSurfaceFormatKHR *surfaceFormats;
bool recreateSwapchain;
int vsync;
+ SDL_PropertiesID create_props;
VkFramebuffer *framebuffers;
VkRenderPass renderPasses[VULKAN_RENDERPASS_COUNT];
@@ -474,6 +489,11 @@ static void VULKAN_DestroyAll(SDL_Renderer *renderer)
return;
}
+ // Release all textures
+ for (SDL_Texture *texture = renderer->textures; texture; texture = texture->next) {
+ VULKAN_DestroyTexture(renderer, texture);
+ }
+
if (rendererData->waitDestStageMasks) {
SDL_free(rendererData->waitDestStageMasks);
rendererData->waitDestStageMasks = NULL;
@@ -489,6 +509,7 @@ static void VULKAN_DestroyAll(SDL_Renderer *renderer)
if (rendererData->surfaceFormats != NULL) {
SDL_free(rendererData->surfaceFormats);
rendererData->surfaceFormats = NULL;
+ rendererData->surfaceFormatsAllocatedCount = 0;
}
if (rendererData->swapchainImages != NULL) {
SDL_free(rendererData->swapchainImages);
@@ -564,12 +585,14 @@ static void VULKAN_DestroyAll(SDL_Renderer *renderer)
SDL_free(rendererData->renderingFinishedSemaphores);
rendererData->renderingFinishedSemaphores = NULL;
}
+ if (rendererData->commandBuffers) {
+ vkFreeCommandBuffers(rendererData->device, rendererData->commandPool, rendererData->swapchainImageCount, rendererData->commandBuffers);
+ SDL_free(rendererData->commandBuffers);
+ rendererData->commandBuffers = NULL;
+ rendererData->currentCommandBuffer = VK_NULL_HANDLE;
+ rendererData->currentCommandBufferIndex = 0;
+ }
if (rendererData->commandPool) {
- if (rendererData->commandBuffers) {
- vkFreeCommandBuffers(rendererData->device, rendererData->commandPool, rendererData->swapchainImageCount, rendererData->commandBuffers);
- SDL_free(rendererData->commandBuffers);
- rendererData->commandBuffers = NULL;
- }
vkDestroyCommandPool(rendererData->device, rendererData->commandPool, NULL);
rendererData->commandPool = VK_NULL_HANDLE;
}
@@ -584,7 +607,9 @@ static void VULKAN_DestroyAll(SDL_Renderer *renderer)
SDL_free(rendererData->descriptorPools[i]);
}
SDL_free(rendererData->descriptorPools);
+ rendererData->descriptorPools = NULL;
SDL_free(rendererData->numDescriptorPools);
+ rendererData->numDescriptorPools = NULL;
}
for (uint32_t i = 0; i < NUM_SHADERS; i++) {
if (rendererData->vertexShaderModules[i] != VK_NULL_HANDLE) {
@@ -608,6 +633,7 @@ static void VULKAN_DestroyAll(SDL_Renderer *renderer)
vkDestroyPipeline(rendererData->device, rendererData->pipelineStates[i].pipeline, NULL);
}
SDL_free(rendererData->pipelineStates);
+ rendererData->pipelineStates = NULL;
rendererData->pipelineStateCount = 0;
if (rendererData->currentUploadBuffer) {
@@ -618,7 +644,9 @@ static void VULKAN_DestroyAll(SDL_Renderer *renderer)
SDL_free(rendererData->uploadBuffers[i]);
}
SDL_free(rendererData->uploadBuffers);
+ rendererData->uploadBuffers = NULL;
SDL_free(rendererData->currentUploadBuffer);
+ rendererData->currentUploadBuffer = NULL;
}
if (rendererData->constantBuffers) {
@@ -630,8 +658,9 @@ static void VULKAN_DestroyAll(SDL_Renderer *renderer)
SDL_free(rendererData->constantBuffers[i]);
}
SDL_free(rendererData->constantBuffers);
- SDL_free(rendererData->numConstantBuffers);
rendererData->constantBuffers = NULL;
+ SDL_free(rendererData->numConstantBuffers);
+ rendererData->numConstantBuffers = NULL;
}
if (rendererData->device != VK_NULL_HANDLE && !rendererData->device_external) {
@@ -670,7 +699,7 @@ static VkResult VULKAN_AllocateBuffer(VULKAN_RenderData *rendererData, VkDeviceS
bufferCreateInfo.usage = usage;
result = vkCreateBuffer(rendererData->device, &bufferCreateInfo, NULL, &bufferOut->buffer);
if (result != VK_SUCCESS) {
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateBuffer(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkCreateBuffer()", result);
return result;
}
@@ -678,14 +707,13 @@ static VkResult VULKAN_AllocateBuffer(VULKAN_RenderData *rendererData, VkDeviceS
vkGetBufferMemoryRequirements(rendererData->device, bufferOut->buffer, &memoryRequirements);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetBufferMemoryRequirements(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkGetBufferMemoryRequirements()", result);
return result;
}
uint32_t memoryTypeIndex = 0;
if (!VULKAN_FindMemoryTypeIndex(rendererData, memoryRequirements.memoryTypeBits, requiredMemoryProps, desiredMemoryProps, &memoryTypeIndex)) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_FindMemoryTypeIndex failed.\n");
return VK_ERROR_UNKNOWN;
}
@@ -696,20 +724,20 @@ static VkResult VULKAN_AllocateBuffer(VULKAN_RenderData *rendererData, VkDeviceS
result = vkAllocateMemory(rendererData->device, &memoryAllocateInfo, NULL, &bufferOut->deviceMemory);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkAllocateMemory(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkAllocateMemory()", result);
return result;
}
result = vkBindBufferMemory(rendererData->device, bufferOut->buffer, bufferOut->deviceMemory, 0);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkBindBufferMemory(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkBindBufferMemory()", result);
return result;
}
result = vkMapMemory(rendererData->device, bufferOut->deviceMemory, 0, size, 0, &bufferOut->mappedBufferPtr);
if (result != VK_SUCCESS) {
VULKAN_DestroyBuffer(rendererData, bufferOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkMapMemory(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkMapMemory()", result);
return result;
}
bufferOut->size = size;
@@ -770,7 +798,7 @@ static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, SDL_Proper
result = vkCreateImage(rendererData->device, &imageCreateInfo, NULL, &imageOut->image);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateImage(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkCreateImage()", result);
return result;
}
@@ -778,14 +806,13 @@ static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, SDL_Proper
vkGetImageMemoryRequirements(rendererData->device, imageOut->image, &memoryRequirements);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetImageMemoryRequirements(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkGetImageMemoryRequirements()", result);
return result;
}
uint32_t memoryTypeIndex = 0;
if (!VULKAN_FindMemoryTypeIndex(rendererData, memoryRequirements.memoryTypeBits, 0, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, &memoryTypeIndex)) {
VULKAN_DestroyImage(rendererData, imageOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_FindMemoryTypeIndex failed.\n");
return VK_ERROR_UNKNOWN;
}
@@ -796,13 +823,13 @@ static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, SDL_Proper
result = vkAllocateMemory(rendererData->device, &memoryAllocateInfo, NULL, &imageOut->deviceMemory);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkAllocateMemory(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkAllocateMemory()", result);
return result;
}
result = vkBindImageMemory(rendererData->device, imageOut->image, imageOut->deviceMemory, 0);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkBindImageMemory(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkBindImageMemory()", result);
return result;
}
} else {
@@ -831,7 +858,7 @@ static VkResult VULKAN_AllocateImage(VULKAN_RenderData *rendererData, SDL_Proper
result = vkCreateImageView(rendererData->device, &imageViewCreateInfo, NULL, &imageOut->imageView);
if (result != VK_SUCCESS) {
VULKAN_DestroyImage(rendererData, imageOut);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateImageView(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkCreateImageView()", result);
return result;
}
@@ -880,9 +907,8 @@ static VkResult VULKAN_AcquireNextSwapchainImage(SDL_Renderer *renderer)
return result;
} else if(result == VK_SUBOPTIMAL_KHR) {
// Suboptimal, but we can contiue
- }
- else if (result != VK_SUCCESS) {
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkAcquireNextImageKHR(): %s\n", SDL_Vulkan_GetResultString(result));
+ } else if (result != VK_SUCCESS) {
+ SET_ERROR_CODE("vkAcquireNextImageKHR()", result);
return result;
}
rendererData->currentImageAvailableSemaphore = rendererData->imageAvailableSemaphores[rendererData->currentCommandBufferIndex];
@@ -1258,11 +1284,14 @@ static VULKAN_PipelineState *VULKAN_CreatePipelineState(SDL_Renderer *renderer,
result = vkCreateGraphicsPipelines(rendererData->device, VK_NULL_HANDLE, 1, &pipelineCreateInfo, NULL, &pipeline);
if (result != VK_SUCCESS) {
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkCreateGraphicsPipelines(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkCreateGraphicsPipelines()", result);
return NULL;
}
pipelineStates = (VULKAN_PipelineState *)SDL_realloc(rendererData->pipelineStates, (rendererData->pipelineStateCount + 1) * sizeof(*pipelineStates));
+ if (!pipelineStates) {
+ return NULL;
+ }
pipelineStates[rendererData->pipelineStateCount].shader = shader;
pipelineStates[rendererData->pipelineStateCount].blendMode = blendMode;
pipelineStates[rendererData->pipelineStateCount].topology = topology;
@@ -1303,7 +1332,7 @@ static bool VULKAN_FindMemoryTypeIndex(VULKAN_RenderData *rendererData, uint32_t
}
if (memoryTypeIndex >= rendererData->physicalDeviceMemoryProperties.memoryTypeCount) {
- SDL_SetError("[Vulkan] Unable to find memory type for allocation");
+ SET_ERROR_MESSAGE("Unable to find memory type for allocation");
return false;
}
*memoryTypeIndexOut = memoryTypeIndex;
@@ -1323,7 +1352,6 @@ static VkResult VULKAN_CreateVertexBuffer(VULKAN_RenderData *rendererData, size_
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
&rendererData->vertexBuffers[vbidx]);
if (result != VK_SUCCESS) {
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "VULKAN_AllocateBuffer(): %s\n", SDL_Vulkan_GetResultString(result));
return result;
}
return result;
@@ -1332,12 +1360,11 @@ static VkResult VULKAN_CreateVertexBuffer(VULKAN_RenderData *rendererData, size_
static bool VULKAN_LoadGlobalFunctions(VULKAN_RenderData *rendererData)
{
#define VULKAN_DEVICE_FUNCTION(name)
-#define VULKAN_GLOBAL_FUNCTION(name) \
- name = (PFN_##name)rendererData->vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \
- if (!name) { \
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, \
- "vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed\n"); \
- return false; \
+#define VULKAN_GLOBAL_FUNCTION(name) \
+ name = (PFN_##name)rendererData->vkGetInstanceProcAddr(VK_NULL_HANDLE, #name); \
+ if (!name) { \
+ SET_ERROR_MESSAGE("vkGetInstanceProcAddr(VK_NULL_HANDLE, \"" #name "\") failed"); \
+ return false; \
}
#define VULKAN_INSTANCE_FUNCTION(name)
#define VULKAN_OPTIONAL_INSTANCE_FUNCTION(name)
@@ -1359,9 +1386,8 @@ static bool VULKAN_LoadInstanceFunctions(VULKAN_RenderData *rendererData)
#define VULKAN_INSTANCE_FUNCTION(name) \
name = (PFN_##name)rendererData->vkGetInstanceProcAddr(rendererData->instance, #name); \
if (!name) { \
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, \
- "vkGetInstanceProcAddr(instance, \"" #name "\") failed\n"); \
- return false; \
+ SET_ERROR_MESSAGE("vkGetInstanceProcAddr(instance, \"" #name "\") failed"); \
+ return false; \
}
#define VULKAN_OPTIONAL_INSTANCE_FUNCTION(name) \
name = (PFN_##name)rendererData->vkGetInstanceProcAddr(rendererData->instance, #name);
@@ -1379,11 +1405,10 @@ static bool VULKAN_LoadInstanceFunctions(VULKAN_RenderData *rendererData)
static bool VULKAN_LoadDeviceFunctions(VULKAN_RenderData *rendererData)
{
-#define VULKAN_DEVICE_FUNCTION(name) \
- name = (PFN_##name)vkGetDeviceProcAddr(rendererData->device, #name); \
- if (!name) { \
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, \
- "vkGetDeviceProcAddr(device, \"" #name "\") failed\n"); \
+#define VULKAN_DEVICE_FUNCTION(name) \
+ name = (PFN_##name)vkGetDeviceProcAddr(rendererData->device, #name); \
+ if (!name) { \
+ SET_ERROR_MESSAGE("vkGetDeviceProcAddr(device, \"" #name "\") failed"); \
return false; \
}
#define VULKAN_GLOBAL_FUNCTION(name)
@@ -1413,18 +1438,18 @@ static VkResult VULKAN_FindPhysicalDevice(VULKAN_RenderData *rendererData)
result = vkEnumeratePhysicalDevices(rendererData->instance, &physicalDeviceCount, NULL);
if (result != VK_SUCCESS) {
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumeratePhysicalDevices(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkEnumeratePhysicalDevices()", result);
return result;
}
if (physicalDeviceCount == 0) {
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumeratePhysicalDevices(): no physical devices\n");
+ SET_ERROR_MESSAGE("vkEnumeratePhysicalDevices(): no physical devices");
return VK_ERROR_UNKNOWN;
}
physicalDevices = (VkPhysicalDevice *)SDL_malloc(sizeof(VkPhysicalDevice) * physicalDeviceCount);
result = vkEnumeratePhysicalDevices(rendererData->instance, &physicalDeviceCount, physicalDevices);
if (result != VK_SUCCESS) {
SDL_free(physicalDevices);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER,"vkEnumeratePhysicalDevices(): %s\n",SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkEnumeratePhysicalDevices()", result);
return result;
}
rendererData->physicalDevice = NULL;
@@ -1475,7 +1500,7 @@ static VkResult VULKAN_FindPhysicalDevice(VULKAN_RenderData *rendererData)
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkGetPhysicalDeviceSurfaceSupportKHR(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkGetPhysicalDeviceSurfaceSupportKHR()", result);
return VK_ERROR_UNKNOWN;
}
if (supported) {
@@ -1497,7 +1522,7 @@ static VkResult VULKAN_FindPhysicalDevice(VULKAN_RenderData *rendererData)
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateDeviceExtensionProperties(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkEnumerateDeviceExtensionProperties()", result);
return VK_ERROR_UNKNOWN;
}
if (deviceExtensionCount == 0) {
@@ -1518,7 +1543,7 @@ static VkResult VULKAN_FindPhysicalDevice(VULKAN_RenderData *rendererData)
SDL_free(physicalDevices);
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "vkEnumerateDeviceExtensionProperties(): %s\n", SDL_Vulkan_GetResultString(result));
+ SET_ERROR_CODE("vkEnumerateDeviceExtensionProperties()", result);
return result;
}
for (i = 0; i < deviceExtensionCount; i++) {
@@ -1537,7 +1562,7 @@ static VkResult VULKAN_FindPhysicalDevice(VULKAN_RenderData *rendererData)
SDL_free(queueFamiliesProperties);
SDL_free(deviceExtensions);
if (!rendererData->physicalDevice) {
- SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Vulkan: no viable physical devices found");
+ SET_ERROR_MESSAGE("No viable physical devices found");
return VK_ERROR_UNKNOWN;
}
return VK_SUCCESS;
@@ -1551,7 +1576,7 @@ static VkResult VULKAN_GetSurfaceFormats(VULKAN_RenderData *rendererData)
NULL);
if (result != VK_SUCCESS) {
rendererData->surfaceFormatsCount = 0;
- SDL_LogError(SDL_LOG_CATEGORY_RENDER,
(Patch may be truncated, please check the link at the top of this post.)