From 557c6dfb1813e05f259f479cc9b4ced9a7ed471b Mon Sep 17 00:00:00 2001
From: cosmonaut <[EMAIL REDACTED]>
Date: Wed, 25 Sep 2024 10:47:14 -0700
Subject: [PATCH] GPU: call SDL_SetError where appropriate
---
src/gpu/d3d11/SDL_gpu_d3d11.c | 164 ++++++++++++++++++++++----------
src/gpu/d3d12/SDL_gpu_d3d12.c | 155 ++++++++++++++++++++----------
src/gpu/metal/SDL_gpu_metal.m | 20 ++--
src/gpu/vulkan/SDL_gpu_vulkan.c | 115 ++++++++++------------
4 files changed, 281 insertions(+), 173 deletions(-)
diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c
index ccd55d6bb51e9..dad57cfa83fbc 100644
--- a/src/gpu/d3d11/SDL_gpu_d3d11.c
+++ b/src/gpu/d3d11/SDL_gpu_d3d11.c
@@ -108,17 +108,23 @@ static const GUID D3D_IID_DXGI_DEBUG_ALL = { 0xe48ae283, 0xda80, 0x490b, { 0x87,
// Macros
-#define ERROR_CHECK(msg) \
+#define ERROR_LOG(msg) \
if (FAILED(res)) { \
D3D11_INTERNAL_LogError(renderer->device, msg, res); \
}
-#define ERROR_CHECK_RETURN(msg, ret) \
+#define ERROR_LOG_RETURN(msg, ret) \
if (FAILED(res)) { \
D3D11_INTERNAL_LogError(renderer->device, msg, res); \
return ret; \
}
+#define ERROR_SET_RETURN(msg, ret) \
+ if (FAILED(res)) { \
+ D3D11_INTERNAL_SetError(renderer->device, msg, res); \
+ return ret; \
+ }
+
#define TRACK_RESOURCE(resource, type, array, count, capacity) \
Uint32 i; \
\
@@ -793,7 +799,7 @@ struct D3D11Renderer
// Logging
-static void D3D11_INTERNAL_LogError(
+static void D3D11_INTERNAL_SetError(
ID3D11Device1 *device,
const char *msg,
HRESULT res)
@@ -847,6 +853,60 @@ static void D3D11_INTERNAL_LogError(
SDL_LogError(SDL_LOG_CATEGORY_GPU, "%s! Error Code: %s " HRESULT_FMT, msg, wszMsgBuff, res);
}
+static void D3D11_INTERNAL_LogError(
+ ID3D11Device1 *device,
+ const char *msg,
+ HRESULT res)
+{
+#define MAX_ERROR_LEN 1024 // FIXME: Arbitrary!
+
+ // Buffer for text, ensure space for \0 terminator after buffer
+ char wszMsgBuff[MAX_ERROR_LEN + 1];
+ DWORD dwChars; // Number of chars returned.
+
+ if (res == DXGI_ERROR_DEVICE_REMOVED) {
+ res = ID3D11Device_GetDeviceRemovedReason(device);
+ }
+
+ // Try to get the message from the system errors.
+#ifdef _WIN32
+ dwChars = FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ res,
+ 0,
+ wszMsgBuff,
+ MAX_ERROR_LEN,
+ NULL);
+#else
+ // FIXME: Do we have error strings in dxvk-native? -flibit
+ dwChars = 0;
+#endif
+
+ // No message? Screw it, just post the code.
+ if (dwChars == 0) {
+ SDL_SetError("%s! Error Code: " HRESULT_FMT, msg, res);
+ return;
+ }
+
+ // Ensure valid range
+ dwChars = SDL_min(dwChars, MAX_ERROR_LEN);
+
+ // Trim whitespace from tail of message
+ while (dwChars > 0) {
+ if (wszMsgBuff[dwChars - 1] <= ' ') {
+ dwChars--;
+ } else {
+ break;
+ }
+ }
+
+ // Ensure null-terminated string
+ wszMsgBuff[dwChars] = '\0';
+
+ SDL_SetError("%s! Error Code: %s " HRESULT_FMT, msg, wszMsgBuff, res);
+}
+
// Helper Functions
static inline Uint32 D3D11_INTERNAL_CalcSubresource(
@@ -1288,7 +1348,7 @@ static ID3D11BlendState *D3D11_INTERNAL_FetchBlendState(
renderer->device,
&blendDesc,
&result);
- ERROR_CHECK_RETURN("Could not create blend state", NULL);
+ ERROR_LOG_RETURN("Could not create blend state", NULL);
return result;
}
@@ -1326,7 +1386,7 @@ static ID3D11DepthStencilState *D3D11_INTERNAL_FetchDepthStencilState(
renderer->device,
&dsDesc,
&result);
- ERROR_CHECK_RETURN("Could not create depth-stencil state", NULL);
+ ERROR_LOG_RETURN("Could not create depth-stencil state", NULL);
return result;
}
@@ -1357,7 +1417,7 @@ static ID3D11RasterizerState *D3D11_INTERNAL_FetchRasterizerState(
renderer->device,
&rasterizerDesc,
&result);
- ERROR_CHECK_RETURN("Could not create rasterizer state", NULL);
+ ERROR_LOG_RETURN("Could not create rasterizer state", NULL);
return result;
}
@@ -1426,7 +1486,7 @@ static ID3D11InputLayout *D3D11_INTERNAL_FetchInputLayout(
shaderByteLength,
&result);
if (FAILED(res)) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not create input layout! Error: " HRESULT_FMT, res);
+ SDL_SetError("Could not create input layout! Error: " HRESULT_FMT, res);
SDL_stack_free(elementDescs);
return NULL;
}
@@ -1516,7 +1576,7 @@ static SDL_GPUComputePipeline *D3D11_CreateComputePipeline(
NULL,
NULL);
if (shader == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create compute pipeline!");
+ SDL_SetError("Failed to create compute pipeline!");
return NULL;
}
@@ -1815,7 +1875,7 @@ static SDL_GPUSampler *D3D11_CreateSampler(
renderer->device,
&samplerDesc,
&samplerStateHandle);
- ERROR_CHECK_RETURN("Could not create sampler state", NULL);
+ ERROR_SET_RETURN("Could not create sampler state", NULL);
d3d11Sampler = (D3D11Sampler *)SDL_malloc(sizeof(D3D11Sampler));
d3d11Sampler->handle = samplerStateHandle;
@@ -1934,7 +1994,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
&desc2D,
initialData,
(ID3D11Texture2D **)&textureHandle);
- ERROR_CHECK_RETURN("Could not create Texture2D", NULL);
+ ERROR_LOG_RETURN("Could not create Texture2D", NULL);
// Create the SRV, if applicable
if (needsSRV) {
@@ -2002,7 +2062,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
&desc3D,
initialData,
(ID3D11Texture3D **)&textureHandle);
- ERROR_CHECK_RETURN("Could not create Texture3D", NULL);
+ ERROR_LOG_RETURN("Could not create Texture3D", NULL);
// Create the SRV, if applicable
if (needsSRV) {
@@ -2071,7 +2131,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
d3d11Texture->handle,
&dsvDesc,
&d3d11Texture->subresources[subresourceIndex].depthStencilTargetView);
- ERROR_CHECK_RETURN("Could not create DSV!", NULL);
+ ERROR_LOG_RETURN("Could not create DSV!", NULL);
} else if (isColorTarget) {
@@ -2103,7 +2163,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
d3d11Texture->handle,
&rtvDesc,
&d3d11Texture->subresources[subresourceIndex].colorTargetViews[depthIndex]);
- ERROR_CHECK_RETURN("Could not create RTV!", NULL);
+ ERROR_LOG_RETURN("Could not create RTV!", NULL);
}
}
@@ -2131,7 +2191,7 @@ static D3D11Texture *D3D11_INTERNAL_CreateTexture(
d3d11Texture->handle,
&uavDesc,
&d3d11Texture->subresources[subresourceIndex].uav);
- ERROR_CHECK_RETURN("Could not create UAV!", NULL);
+ ERROR_LOG_RETURN("Could not create UAV!", NULL);
}
}
}
@@ -2170,7 +2230,7 @@ static SDL_GPUTexture *D3D11_CreateTexture(
NULL);
if (texture == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create texture!");
+ SDL_SetError("Failed to create texture!");
return NULL;
}
@@ -2295,7 +2355,7 @@ static D3D11Buffer *D3D11_INTERNAL_CreateBuffer(
bufferDesc,
NULL,
&bufferHandle);
- ERROR_CHECK_RETURN("Could not create buffer", NULL);
+ ERROR_LOG_RETURN("Could not create buffer", NULL);
// Storage buffer
if (bufferDesc->MiscFlags & D3D11_RESOURCE_MISC_BUFFER_ALLOW_RAW_VIEWS) {
@@ -2315,7 +2375,7 @@ static D3D11Buffer *D3D11_INTERNAL_CreateBuffer(
&uav);
if (FAILED(res)) {
ID3D11Buffer_Release(bufferHandle);
- ERROR_CHECK_RETURN("Could not create UAV for buffer!", NULL);
+ ERROR_LOG_RETURN("Could not create UAV for buffer!", NULL);
}
// Create a SRV for the buffer
@@ -2334,7 +2394,7 @@ static D3D11Buffer *D3D11_INTERNAL_CreateBuffer(
&srv);
if (FAILED(res)) {
ID3D11Buffer_Release(bufferHandle);
- ERROR_CHECK_RETURN("Could not create SRV for buffer!", NULL);
+ ERROR_LOG_RETURN("Could not create SRV for buffer!", NULL);
}
}
@@ -2396,7 +2456,7 @@ static SDL_GPUBuffer *D3D11_CreateBuffer(
size);
if (buffer == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create buffer!");
+ SDL_SetError("Failed to create buffer!");
return NULL;
}
@@ -2434,7 +2494,7 @@ static D3D11UniformBuffer *D3D11_INTERNAL_CreateUniformBuffer(
&bufferDesc,
NULL,
&buffer);
- ERROR_CHECK_RETURN("Could not create uniform buffer", NULL)
+ ERROR_LOG_RETURN("Could not create uniform buffer", NULL)
uniformBuffer = SDL_malloc(sizeof(D3D11UniformBuffer));
uniformBuffer->buffer = buffer;
@@ -2737,7 +2797,7 @@ static void D3D11_UploadToBuffer(
&stagingBufferDesc,
&stagingBufferData,
&stagingBuffer);
- ERROR_CHECK_RETURN("Could not create staging buffer", )
+ ERROR_LOG_RETURN("Could not create staging buffer", )
// Copy from staging buffer to buffer
ID3D11DeviceContext1_CopySubresourceRegion(
@@ -2820,7 +2880,7 @@ static void D3D11_DownloadFromTexture(
&stagingDesc2D,
NULL,
(ID3D11Texture2D **)&textureDownload->stagingTexture);
- ERROR_CHECK_RETURN("Staging texture creation failed", )
+ ERROR_LOG_RETURN("Staging texture creation failed", )
} else {
stagingDesc3D.Width = source->w;
stagingDesc3D.Height = source->h;
@@ -2899,7 +2959,7 @@ static void D3D11_DownloadFromBuffer(
&stagingBufferDesc,
NULL,
&bufferDownload->stagingBuffer);
- ERROR_CHECK_RETURN("Could not create staging buffer", )
+ ERROR_LOG_RETURN("Could not create staging buffer", )
ID3D11DeviceContext1_CopySubresourceRegion1(
d3d11CommandBuffer->context,
@@ -3043,7 +3103,7 @@ static void D3D11_INTERNAL_AllocateCommandBuffers(
renderer->device,
0,
&commandBuffer->context);
- ERROR_CHECK("Could not create deferred context");
+ ERROR_LOG("Could not create deferred context");
// Initialize debug annotation support, if available
ID3D11DeviceContext_QueryInterface(
@@ -3114,7 +3174,7 @@ static bool D3D11_INTERNAL_CreateFence(
renderer->device,
&queryDesc,
&queryHandle);
- ERROR_CHECK_RETURN("Could not create query", 0);
+ ERROR_LOG_RETURN("Could not create query", 0);
fence = SDL_malloc(sizeof(D3D11Fence));
fence->handle = queryHandle;
@@ -3147,7 +3207,7 @@ static bool D3D11_INTERNAL_AcquireFence(
if (renderer->availableFenceCount == 0) {
if (!D3D11_INTERNAL_CreateFence(renderer)) {
SDL_UnlockMutex(renderer->fenceLock);
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create fence!");
+ SDL_SetError("Failed to create fence!");
return false;
}
}
@@ -3220,11 +3280,15 @@ static SDL_GPUCommandBuffer *D3D11_AcquireCommandBuffer(
SDL_zeroa(commandBuffer->computeWriteOnlyStorageTextureSubresources);
SDL_zeroa(commandBuffer->computeWriteOnlyStorageBuffers);
- D3D11_INTERNAL_AcquireFence(commandBuffer);
+ bool acquireFenceResult = D3D11_INTERNAL_AcquireFence(commandBuffer);
commandBuffer->autoReleaseFence = 1;
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
+ if (!acquireFenceResult) {
+ return NULL;
+ }
+
return (SDL_GPUCommandBuffer *)commandBuffer;
}
@@ -3344,7 +3408,7 @@ static void D3D11_INTERNAL_PushUniformData(
D3D11_MAP_WRITE_DISCARD,
0,
&subres);
- ERROR_CHECK_RETURN("Failed to map uniform buffer", )
+ ERROR_LOG_RETURN("Failed to map uniform buffer", )
d3d11UniformBuffer->mappedData = subres.pData;
}
@@ -4673,7 +4737,7 @@ static void D3D11_INTERNAL_MapAndCopyBufferDownload(
D3D11_MAP_READ,
0,
&subres);
- ERROR_CHECK_RETURN("Failed to map staging buffer", )
+ ERROR_LOG_RETURN("Failed to map staging buffer", )
SDL_memcpy(
((Uint8 *)transferBuffer->data) + bufferDownload->dstOffset,
@@ -4707,7 +4771,7 @@ static void D3D11_INTERNAL_MapAndCopyTextureDownload(
D3D11_MAP_READ,
0,
&subres);
- ERROR_CHECK_RETURN("Could not map staging texture", )
+ ERROR_LOG_RETURN("Could not map staging texture", )
for (depth = 0; depth < textureDownload->depth; depth += 1) {
dataPtrOffset = textureDownload->bufferOffset + (depth * textureDownload->bytesPerDepthSlice);
@@ -5009,7 +5073,7 @@ static bool D3D11_INTERNAL_InitializeSwapchainTexture(
0,
&D3D_IID_ID3D11Texture2D,
(void **)&swapchainTexture);
- ERROR_CHECK_RETURN("Could not get buffer from swapchain!", 0);
+ ERROR_LOG_RETURN("Could not get buffer from swapchain!", 0);
// Create the RTV for the swapchain
rtvDesc.Format = rtvFormat;
@@ -5109,7 +5173,7 @@ static bool D3D11_INTERNAL_CreateSwapchain(
(IUnknown *)renderer->device,
&swapchainDesc,
&swapchain);
- ERROR_CHECK_RETURN("Could not create swapchain", 0);
+ ERROR_LOG_RETURN("Could not create swapchain", 0);
/*
* The swapchain's parent is a separate factory from the factory that
@@ -5224,7 +5288,7 @@ static bool D3D11_INTERNAL_ResizeSwapchain(
height,
DXGI_FORMAT_UNKNOWN, // Keep the old format
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
- ERROR_CHECK_RETURN("Could not resize swapchain buffers", 0);
+ ERROR_LOG_RETURN("Could not resize swapchain buffers", 0);
// Create the texture object for the swapchain
return D3D11_INTERNAL_InitializeSwapchainTexture(
@@ -5264,7 +5328,7 @@ static bool D3D11_SupportsSwapchainComposition(
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Must claim window before querying swapchain composition support!");
+ SDL_SetError("Must claim window before querying swapchain composition support!");
return false;
}
@@ -5285,7 +5349,7 @@ static bool D3D11_SupportsSwapchainComposition(
return false;
}
} else {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "DXGI 1.4 not supported, cannot use composition other than SDL_GPU_SWAPCHAINCOMPOSITION_SDR!");
+ SDL_SetError("DXGI 1.4 not supported, cannot use composition other than SDL_GPU_SWAPCHAINCOMPOSITION_SDR!");
return false;
}
}
@@ -5340,7 +5404,7 @@ static bool D3D11_ClaimWindow(
return true;
} else {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not create swapchain, failed to claim window!");
+ SDL_SetError("Could not create swapchain, failed to claim window!");
SDL_free(windowData);
return false;
}
@@ -5439,7 +5503,7 @@ static SDL_GPUTexture *D3D11_AcquireSwapchainTexture(
windowData,
windowW,
windowH);
- ERROR_CHECK_RETURN("Could not resize swapchain", NULL);
+ ERROR_SET_RETURN("Could not resize swapchain", NULL);
}
if (windowData->inFlightFences[windowData->frameCounter] != NULL) {
@@ -5475,7 +5539,7 @@ static SDL_GPUTexture *D3D11_AcquireSwapchainTexture(
0,
&D3D_IID_ID3D11Texture2D,
(void **)&windowData->texture.handle);
- ERROR_CHECK_RETURN("Could not acquire swapchain!", NULL);
+ ERROR_SET_RETURN("Could not acquire swapchain!", NULL);
// Send the dimensions to the out parameters.
*w = windowW;
@@ -5506,7 +5570,7 @@ static SDL_GPUTextureFormat D3D11_GetSwapchainTextureFormat(
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Cannot get swapchain format, window has not been claimed!");
+ SDL_SetError("Cannot get swapchain format, window has not been claimed!");
return SDL_GPU_TEXTUREFORMAT_INVALID;
}
@@ -5523,17 +5587,17 @@ static bool D3D11_SetSwapchainParameters(
D3D11WindowData *windowData = D3D11_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Cannot set swapchain parameters on unclaimed window!");
+ SDL_SetError("Cannot set swapchain parameters on unclaimed window!");
return false;
}
if (!D3D11_SupportsSwapchainComposition(driverData, window, swapchainComposition)) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Swapchain composition not supported!");
+ SDL_SetError("Swapchain composition not supported!");
return false;
}
if (!D3D11_SupportsPresentMode(driverData, window, presentMode)) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Present mode not supported!");
+ SDL_SetError("Present mode not supported!");
return false;
}
@@ -5604,7 +5668,7 @@ static void D3D11_Submit(
d3d11CommandBuffer->context,
0,
&commandList);
- ERROR_CHECK("Could not finish command list recording!");
+ ERROR_LOG("Could not finish command list recording!");
// Submit the command list to the immediate context
ID3D11DeviceContext_ExecuteCommandList(
@@ -6145,7 +6209,7 @@ static SDL_GPUDevice *D3D11_CreateDevice(bool debugMode, bool preferLowPower, SD
// Load the DXGI library
renderer->dxgi_dll = SDL_LoadObject(DXGI_DLL);
if (renderer->dxgi_dll == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not find " DXGI_DLL);
+ SDL_SetError("Could not find " DXGI_DLL);
return NULL;
}
@@ -6154,7 +6218,7 @@ static SDL_GPUDevice *D3D11_CreateDevice(bool debugMode, bool preferLowPower, SD
renderer->dxgi_dll,
CREATE_DXGI_FACTORY1_FUNC);
if (CreateDxgiFactoryFunc == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not load function: " CREATE_DXGI_FACTORY1_FUNC);
+ SDL_SetError("Could not load function: " CREATE_DXGI_FACTORY1_FUNC);
return NULL;
}
@@ -6162,7 +6226,7 @@ static SDL_GPUDevice *D3D11_CreateDevice(bool debugMode, bool preferLowPower, SD
res = CreateDxgiFactoryFunc(
&D3D_IID_IDXGIFactory1,
(void **)&renderer->factory);
- ERROR_CHECK_RETURN("Could not create DXGIFactory", NULL);
+ ERROR_SET_RETURN("Could not create DXGIFactory", NULL);
// Check for flip-model discard support (supported on Windows 10+)
res = IDXGIFactory1_QueryInterface(
@@ -6222,7 +6286,7 @@ static SDL_GPUDevice *D3D11_CreateDevice(bool debugMode, bool preferLowPower, SD
// Load the D3D library
renderer->d3d11_dll = SDL_LoadObject(D3D11_DLL);
if (renderer->d3d11_dll == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not find " D3D11_DLL);
+ SDL_SetError("Could not find " D3D11_DLL);
return NULL;
}
@@ -6231,7 +6295,7 @@ static SDL_GPUDevice *D3D11_CreateDevice(bool debugMode, bool preferLowPower, SD
renderer->d3d11_dll,
D3D11_CREATE_DEVICE_FUNC);
if (D3D11CreateDeviceFunc == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not load function: " D3D11_CREATE_DEVICE_FUNC);
+ SDL_SetError("Could not load function: " D3D11_CREATE_DEVICE_FUNC);
return NULL;
}
@@ -6263,14 +6327,14 @@ static SDL_GPUDevice *D3D11_CreateDevice(bool debugMode, bool preferLowPower, SD
goto tryCreateDevice;
}
- ERROR_CHECK_RETURN("Could not create D3D11 device", NULL);
+ ERROR_SET_RETURN("Could not create D3D11 device", NULL);
// The actual device we want is the ID3D11Device1 interface...
res = ID3D11Device_QueryInterface(
d3d11Device,
&D3D_IID_ID3D11Device1,
(void **)&renderer->device);
- ERROR_CHECK_RETURN("Could not get ID3D11Device1 interface", NULL);
+ ERROR_SET_RETURN("Could not get ID3D11Device1 interface", NULL);
// Release the old device interface, we don't need it anymore
ID3D11Device_Release(d3d11Device);
diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c
index 902930149ff71..b9dfaafee583e 100644
--- a/src/gpu/d3d12/SDL_gpu_d3d12.c
+++ b/src/gpu/d3d12/SDL_gpu_d3d12.c
@@ -56,17 +56,23 @@
// Macros
-#define ERROR_CHECK(msg) \
+#define ERROR_LOG(msg) \
if (FAILED(res)) { \
D3D12_INTERNAL_LogError(renderer->device, msg, res); \
}
-#define ERROR_CHECK_RETURN(msg, ret) \
+#define ERROR_LOG_RETURN(msg, ret) \
if (FAILED(res)) { \
D3D12_INTERNAL_LogError(renderer->device, msg, res); \
return ret; \
}
+#define ERROR_SET_RETURN(msg, ret) \
+ if (FAILED(res)) { \
+ D3D12_INTERNAL_SetError(renderer->device, msg, res); \
+ return ret; \
+ }
+
// Defines
#if defined(_WIN32)
#if defined(SDL_PLATFORM_XBOXSERIES)
@@ -917,6 +923,57 @@ typedef HRESULT (D3DAPI* PFN_D3D12_XBOX_CREATE_DEVICE)(_In_opt_ IGraphicsUnknown
// Logging
+static void D3D12_INTERNAL_SetError(
+ ID3D12Device *device,
+ const char *msg,
+ HRESULT res)
+{
+ #define MAX_ERROR_LEN 1024 // FIXME: Arbitrary!
+
+ // Buffer for text, ensure space for \0 terminator after buffer
+ char wszMsgBuff[MAX_ERROR_LEN + 1];
+ DWORD dwChars; // Number of chars returned.
+
+ if (res == DXGI_ERROR_DEVICE_REMOVED) {
+ if (device) {
+ res = ID3D12Device_GetDeviceRemovedReason(device);
+ }
+ }
+
+ // Try to get the message from the system errors.
+ dwChars = FormatMessageA(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ res,
+ 0,
+ wszMsgBuff,
+ MAX_ERROR_LEN,
+ NULL);
+
+ // No message? Screw it, just post the code.
+ if (dwChars == 0) {
+ SDL_SetError("%s! Error Code: " HRESULT_FMT, msg, res);
+ return;
+ }
+
+ // Ensure valid range
+ dwChars = SDL_min(dwChars, MAX_ERROR_LEN);
+
+ // Trim whitespace from tail of message
+ while (dwChars > 0) {
+ if (wszMsgBuff[dwChars - 1] <= ' ') {
+ dwChars--;
+ } else {
+ break;
+ }
+ }
+
+ // Ensure null-terminated string
+ wszMsgBuff[dwChars] = '\0';
+
+ SDL_SetError("%s! Error Code: %s " HRESULT_FMT, msg, wszMsgBuff, res);
+}
+
static void
D3D12_INTERNAL_LogError(
ID3D12Device *device,
@@ -2100,7 +2157,7 @@ static D3D12GraphicsRootSignature *D3D12_INTERNAL_CreateGraphicsRootSignature(
if (FAILED(res)) {
if (errorBlob) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to create RootSignature");
+ SDL_SetError("Failed to create RootSignature");
ID3D10Blob_Release(errorBlob);
}
D3D12_INTERNAL_DestroyGraphicsRootSignature(d3d12GraphicsRootSignature);
@@ -2354,7 +2411,7 @@ static SDL_GPUComputePipeline *D3D12_CreateComputePipeline(
createinfo);
if (rootSignature == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not create root signature!");
+ SDL_SetError("Could not create root signature!");
SDL_free(bytecode);
return NULL;
}
@@ -2375,7 +2432,7 @@ static SDL_GPUComputePipeline *D3D12_CreateComputePipeline(
(void **)&pipelineState);
if (FAILED(res)) {
- D3D12_INTERNAL_LogError(renderer->device, "Could not create compute pipeline state", res);
+ D3D12_INTERNAL_SetError(renderer->device, "Could not create compute pipeline state", res);
SDL_free(bytecode);
return NULL;
}
@@ -2640,7 +2697,7 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline(
fragShader);
if (rootSignature == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Could not create root signature!");
+ SDL_SetError("Could not create root signature!");
D3D12_INTERNAL_DestroyGraphicsPipeline(pipeline);
return NULL;
}
@@ -2655,7 +2712,7 @@ static SDL_GPUGraphicsPipeline *D3D12_CreateGraphicsPipeline(
D3D_GUID(D3D_IID_ID3D12PipelineState),
(void **)&pipelineState);
if (FAILED(res)) {
- D3D12_INTERNAL_LogError(renderer->device, "Could not create graphics pipeline state", res);
+ D3D12_INTERNAL_SetError(renderer->device, "Could not create graphics pipeline state", res);
D3D12_INTERNAL_DestroyGraphicsPipeline(pipeline);
return NULL;
}
@@ -3160,7 +3217,7 @@ static D3D12Buffer *D3D12_INTERNAL_CreateBuffer(
}
heapFlags = D3D12_HEAP_FLAG_NONE;
} else {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized buffer type!");
+ SDL_SetError("Unrecognized buffer type!");
return NULL;
}
@@ -4111,7 +4168,7 @@ static D3D12UniformBuffer *D3D12_INTERNAL_AcquireUniformBufferFromPool(
0,
NULL,
(void **)&uniformBuffer->buffer->mapPointer);
- ERROR_CHECK_RETURN("Failed to map buffer pool!", NULL);
+ ERROR_LOG_RETURN("Failed to map buffer pool!", NULL);
D3D12_INTERNAL_TrackUniformBuffer(commandBuffer, uniformBuffer);
@@ -5991,7 +6048,7 @@ static bool D3D12_SupportsSwapchainComposition(
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Must claim window before querying swapchain composition support!");
+ SDL_SetError("Must claim window before querying swapchain composition support!");
return false;
}
@@ -6161,7 +6218,7 @@ static bool D3D12_INTERNAL_InitializeSwapchainTexture(
index,
D3D_GUID(D3D_IID_ID3D12Resource),
(void **)&swapchainTexture);
- ERROR_CHECK_RETURN("Could not get buffer from swapchain!", 0);
+ ERROR_LOG_RETURN("Could not get buffer from swapchain!", 0);
pTexture = (D3D12Texture *)SDL_calloc(1, sizeof(D3D12Texture));
if (!pTexture) {
@@ -6293,7 +6350,7 @@ static bool D3D12_INTERNAL_ResizeSwapchainIfNeeded(
h,
DXGI_FORMAT_UNKNOWN, // Keep the old format
renderer->supportsTearing ? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0);
- ERROR_CHECK_RETURN("Could not resize swapchain buffers", 0)
+ ERROR_LOG_RETURN("Could not resize swapchain buffers", 0)
// Create texture object for the swapchain
for (Uint32 i = 0; i < MAX_FRAMES_IN_FLIGHT; i += 1) {
@@ -6402,14 +6459,14 @@ static bool D3D12_INTERNAL_CreateSwapchain(
&fullscreenDesc,
NULL,
&swapchain);
- ERROR_CHECK_RETURN("Could not create swapchain", 0);
+ ERROR_LOG_RETURN("Could not create swapchain", 0);
res = IDXGISwapChain1_QueryInterface(
swapchain,
D3D_GUID(D3D_IID_IDXGISwapChain3),
(void **)&swapchain3);
IDXGISwapChain1_Release(swapchain);
- ERROR_CHECK_RETURN("Could not create IDXGISwapChain3", 0);
+ ERROR_LOG_RETURN("Could not create IDXGISwapChain3", 0);
if (swapchainComposition != SDL_GPU_SWAPCHAINCOMPOSITION_SDR) {
// Support already verified if we hit this block
@@ -6526,7 +6583,7 @@ static bool D3D12_ClaimWindow(
return true;
} else {
- SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Could not create swapchain, failed to claim window!");
+ SDL_SetError("Could not create swapchain, failed to claim window!");
SDL_free(windowData);
return false;
}
@@ -6585,17 +6642,17 @@ static bool D3D12_SetSwapchainParameters(
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Cannot set swapchain parameters on unclaimed window!");
+ SDL_SetError("Cannot set swapchain parameters on unclaimed window!");
return false;
}
if (!D3D12_SupportsSwapchainComposition(driverData, window, swapchainComposition)) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Swapchain composition not supported!");
+ SDL_SetError("Swapchain composition not supported!");
return false;
}
if (!D3D12_SupportsPresentMode(driverData, window, presentMode)) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Present mode not supported!");
+ SDL_SetError("Present mode not supported!");
return false;
}
@@ -6626,7 +6683,7 @@ static SDL_GPUTextureFormat D3D12_GetSwapchainTextureFormat(
D3D12WindowData *windowData = D3D12_INTERNAL_FetchWindowData(window);
if (windowData == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Cannot get swapchain format, window has not been claimed!");
+ SDL_SetError("Cannot get swapchain format, window has not been claimed!");
return SDL_GPU_TEXTUREFORMAT_INVALID;
}
@@ -6822,7 +6879,7 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
SDL_UnlockMutex(renderer->acquireCommandBufferLock);
if (commandBuffer == NULL) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire command buffer!");
+ SDL_SetError("Failed to acquire command buffer!");
return NULL;
}
@@ -6831,7 +6888,7 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
D3D12_INTERNAL_AcquireDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
if (!commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV]) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire descriptor heap!");
+ SDL_SetError("Failed to acquire descriptor heap!");
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
return NULL;
}
@@ -6840,7 +6897,7 @@ static SDL_GPUCommandBuffer *D3D12_AcquireCommandBuffer(
D3D12_INTERNAL_AcquireDescriptorHeapFromPool(commandBuffer, D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER);
if (!commandBuffer->gpuDescriptorHeaps[D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER]) {
- SDL_LogError(SDL_LOG_CATEGORY_GPU, "Failed to acquire descriptor heap!");
+ SDL_SetError("Failed to acquire descriptor heap!");
D3D12_INTERNAL_DestroyCommandBuffer(commandBuffer);
return NULL;
}
@@ -6909,7 +6966,7 @@ static SDL_GPUTexture *D3D12_AcquireSwapchainTexture(
res = D3D12_INTERNAL_ResizeSwapchainIfNeeded(
renderer,
windowData);
- ERROR_CHECK_RETURN("Could not resize swapcha
(Patch may be truncated, please check the link at the top of this post.)