SDL: GPU: Forward D3D12 validation warnings to the SDL log

From dc5a2ddfd05dc11c1dd45015a0681d9eed63e7d0 Mon Sep 17 00:00:00 2001
From: Lucas Murray <[EMAIL REDACTED]>
Date: Sun, 1 Dec 2024 17:17:30 +1100
Subject: [PATCH] GPU: Forward D3D12 validation warnings to the SDL log

---
 src/gpu/d3d12/SDL_gpu_d3d12.c | 119 ++++++++++++++++++++++++++++++++--
 1 file changed, 114 insertions(+), 5 deletions(-)

diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c
index 3a2e4f5aa3079..1a17a65b9f91f 100644
--- a/src/gpu/d3d12/SDL_gpu_d3d12.c
+++ b/src/gpu/d3d12/SDL_gpu_d3d12.c
@@ -168,6 +168,7 @@ static const IID D3D_IID_ID3D12CommandSignature = { 0xc36a797c, 0xec80, 0x4f0a,
 static const IID D3D_IID_ID3D12PipelineState = { 0x765a30f3, 0xf624, 0x4c6f, { 0xa8, 0x28, 0xac, 0xe9, 0x48, 0x62, 0x24, 0x45 } };
 static const IID D3D_IID_ID3D12Debug = { 0x344488b7, 0x6846, 0x474b, { 0xb9, 0x89, 0xf0, 0x27, 0x44, 0x82, 0x45, 0xe0 } };
 static const IID D3D_IID_ID3D12InfoQueue = { 0x0742a90b, 0xc387, 0x483f, { 0xb9, 0x46, 0x30, 0xa7, 0xe4, 0xe6, 0x14, 0x58 } };
+static const IID D3D_IID_ID3D12InfoQueue1 = { 0x2852dd88, 0xb484, 0x4c0c, { 0xb6, 0xb1, 0x67, 0x16, 0x85, 0x00, 0xe6, 0x00 } };
 
 // Enums
 
@@ -8167,11 +8168,6 @@ static bool D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *rende
         infoQueue,
         &filter);
 
-    ID3D12InfoQueue_SetBreakOnSeverity(
-        infoQueue,
-        D3D12_MESSAGE_SEVERITY_ERROR,
-        true);
-
     ID3D12InfoQueue_SetBreakOnSeverity(
         infoQueue,
         D3D12_MESSAGE_SEVERITY_CORRUPTION,
@@ -8181,6 +8177,118 @@ static bool D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(D3D12Renderer *rende
 
     return true;
 }
+
+static void WINAPI D3D12_INTERNAL_OnD3D12DebugInfoMsg(
+    D3D12_MESSAGE_CATEGORY category, 
+    D3D12_MESSAGE_SEVERITY severity, 
+    D3D12_MESSAGE_ID id, 
+    LPCSTR description, 
+    void *context)
+{
+    char *catStr;
+    char *sevStr;
+
+    switch (category) {
+    case D3D12_MESSAGE_CATEGORY_APPLICATION_DEFINED:
+        catStr = "APPLICATION_DEFINED";
+        break;
+    case D3D12_MESSAGE_CATEGORY_MISCELLANEOUS:
+        catStr = "MISCELLANEOUS";
+        break;
+    case D3D12_MESSAGE_CATEGORY_INITIALIZATION:
+        catStr = "INITIALIZATION";
+        break;
+    case D3D12_MESSAGE_CATEGORY_CLEANUP:
+        catStr = "CLEANUP";
+        break;
+    case D3D12_MESSAGE_CATEGORY_COMPILATION:
+        catStr = "COMPILATION";
+        break;
+    case D3D12_MESSAGE_CATEGORY_STATE_CREATION:
+        catStr = "STATE_CREATION";
+        break;
+    case D3D12_MESSAGE_CATEGORY_STATE_SETTING:
+        catStr = "STATE_SETTING";
+        break;
+    case D3D12_MESSAGE_CATEGORY_STATE_GETTING:
+        catStr = "STATE_GETTING";
+        break;
+    case D3D12_MESSAGE_CATEGORY_RESOURCE_MANIPULATION:
+        catStr = "RESOURCE_MANIPULATION";
+        break;
+    case D3D12_MESSAGE_CATEGORY_EXECUTION:
+        catStr = "EXECUTION";
+        break;
+    case D3D12_MESSAGE_CATEGORY_SHADER:
+        catStr = "SHADER";
+        break;
+    default:
+        catStr = "UNKNOWN";
+        break;
+    }
+
+    switch (severity) {
+    case D3D12_MESSAGE_SEVERITY_CORRUPTION:
+        sevStr = "CORRUPTION";
+        break;
+    case D3D12_MESSAGE_SEVERITY_ERROR:
+        sevStr = "ERROR";
+        break;
+    case D3D12_MESSAGE_SEVERITY_WARNING:
+        sevStr = "WARNING";
+        break;
+    case D3D12_MESSAGE_SEVERITY_INFO:
+        sevStr = "INFO";
+        break;
+    case D3D12_MESSAGE_SEVERITY_MESSAGE:
+        sevStr = "MESSAGE";
+        break;
+    default:
+        sevStr = "UNKNOWN";
+        break;
+    }
+
+    if (severity <= D3D12_MESSAGE_SEVERITY_ERROR) {
+        SDL_LogError(
+            SDL_LOG_CATEGORY_GPU,
+            "D3D12 ERROR: %s [%s %s #%d]",
+            description,
+            catStr,
+            sevStr,
+            id);
+    } else {
+        SDL_LogWarn(
+            SDL_LOG_CATEGORY_GPU,
+            "D3D12 WARNING: %s [%s %s #%d]",
+            description,
+            catStr,
+            sevStr,
+            id);
+    }
+}
+
+static void D3D12_INTERNAL_TryInitializeD3D12DebugInfoLogger(D3D12Renderer *renderer)
+{
+    ID3D12InfoQueue1 *infoQueue = NULL;
+    HRESULT res;
+
+    res = ID3D12Device_QueryInterface(
+        renderer->device,
+        D3D_GUID(D3D_IID_ID3D12InfoQueue1),
+        (void **)&infoQueue);
+    if (FAILED(res)) {
+        return;
+    }
+
+    ID3D12InfoQueue1_RegisterMessageCallback(
+        infoQueue,
+        D3D12_INTERNAL_OnD3D12DebugInfoMsg,
+        D3D12_MESSAGE_CALLBACK_FLAG_NONE,
+        NULL,
+        NULL);
+    
+    ID3D12InfoQueue1_Release(infoQueue);
+}
 #endif
 
 static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SDL_PropertiesID props)
@@ -8408,6 +8516,7 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
         if (!D3D12_INTERNAL_TryInitializeD3D12DebugInfoQueue(renderer)) {
             return NULL;
         }
+        D3D12_INTERNAL_TryInitializeD3D12DebugInfoLogger(renderer);
     }
 #endif