diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index dd922cd39c..75a1b0a76a 100644 --- a/include/SDL3/SDL_gpu.h +++ b/include/SDL3/SDL_gpu.h @@ -2147,6 +2147,8 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice( * properties and validations, defaults to true. * - `SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN`: enable to prefer * energy efficiency over maximum GPU performance, defaults to false. + * - `SDL_PROP_GPU_DEVICE_CREATE_VERBOSE_BOOLEAN`: enable to automatically log + * useful debug information on device creation, defaults to true. * - `SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING`: the name of the GPU driver to * use, if a specific one is desired. * @@ -2186,6 +2188,7 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDeviceWithProperties( #define SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN "SDL.gpu.device.create.debugmode" #define SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN "SDL.gpu.device.create.preferlowpower" +#define SDL_PROP_GPU_DEVICE_CREATE_VERBOSE_BOOLEAN "SDL.gpu.device.create.verbose" #define SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING "SDL.gpu.device.create.name" #define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN "SDL.gpu.device.create.shaders.private" #define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN "SDL.gpu.device.create.shaders.spirv" @@ -2257,6 +2260,131 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGPUDeviceDriver(SDL_GPUDevice *d */ extern SDL_DECLSPEC SDL_GPUShaderFormat SDLCALL SDL_GetGPUShaderFormats(SDL_GPUDevice *device); +/** + * Returns a property group containing read-only debug information associated + * with this GPU context. All properties are optionally provided and may differ + * between GPU backends and SDL versions. + * + * The following properties are provided by SDL: + * + * ### `SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING` + * + * Contains the name of the underlying device as reported by the system driver. + * This string has no standardized format, is highly inconsistent between + * hardware devices and drivers, and is able to change at any time. Do not + * attempt to parse this string as it is bound to fail at some point in the + * future when system drivers are updated, new hardware devices are introduced, + * or when SDL adds new GPU backends or modifies existing ones. + * + * Strings that have been found in the wild include: + * + * - GTX 970 + * - GeForce GTX 970 + * - NVIDIA GeForce GTX 970 + * - Microsoft Direct3D12 (NVIDIA GeForce GTX 970) + * - NVIDIA Graphics Device + * - GeForce GPU + * - P106-100 + * - AMD 15D8:C9 + * - AMD Custom GPU 0405 + * - AMD Radeon (TM) Graphics + * - ASUS Radeon RX 470 Series + * - Intel(R) Arc(tm) A380 Graphics (DG2) + * - Virtio-GPU Venus (NVIDIA TITAN V) + * - SwiftShader Device (LLVM 16.0.0) + * - llvmpipe (LLVM 15.0.4, 256 bits) + * - Microsoft Basic Render Driver + * - unknown device + * + * The above list shows that the same device can have different formats, the + * vendor name may or may not appear in the string, the included vendor name may + * not be the vendor of the chipset on the device, some manufacturers include + * pseudo-legal marks while others don't, some devices may not use a marketing + * name in the string, the device string may be wrapped by the name of a + * translation interface, the device may be emulated in software, or the string + * may contain generic text that does not identify the device at all. + * + * ### `SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_NAME_STRING` + * + * Contains the self-reported name of the underlying system driver. + * + * Strings that have been found in the wild include: + * + * - Intel Corporation + * - Intel open-source Mesa driver + * - Qualcomm Technologies Inc. Adreno Vulkan Driver + * - MoltenVK + * - Mali-G715 + * - venus + * + * ### `SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING` + * + * Contains the self-reported version of the underlying system driver. This is a + * relatively short version string in an unspecified format. If + * SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_INFO_STRING is available then that property + * should be preferred over this one as it may contain additional information + * that is useful for identifying the exact driver version used. + * + * Strings that have been found in the wild include: + * + * - 53.0.0 + * - 0.405.2463 + * - 32.0.15.6614 + * + * ### `SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_INFO_STRING` + * + * Contains the detailed version information of the underlying system driver as + * reported by the driver. This is an arbitrary string with no standardized + * format and it may contain newlines. This property should be preferred over + * SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING if it is available as it + * usually contains the same information but in a format that is easier to read. + * + * Strings that have been found in the wild include: + * + * - 101.6559 + * - 1.2.11 + * - Mesa 21.2.2 (LLVM 12.0.1) + * - Mesa 22.2.0-devel (git-f226222 2022-04-14 impish-oibaf-ppa) + * - v1.r53p0-00eac0.824c4f31403fb1fbf8ee1042422c2129 + * + * As well as the multiline string (which has a trailing newline): + * + * ``` + * Driver Build: 85da404, I46ff5fc46f, 1606794520 + * Date: 11/30/20 + * Compiler Version: EV031.31.04.01 + * Driver Branch: promo490_3_Google + * ``` + * + * ### `SDL_PROP_GPU_DEVICE_DEBUG_VULKAN_CONFORMANCE_STRING` + * + * When using the Vulkan backend, contains the highest Vulkan version number + * that the system driver claims that the underlying hardware conforms to. This + * is self-reported and may not be truthful. + * + * Strings that have been found in the wild include: + * + * - 0.0.0.0 + * - 1.0.0.0 + * - 1.3.8.2 + * + * \param device a GPU context to query. + * \returns a valid property ID or 0. A value of 0 indicates that no properties + * are available and is not an error. The returned property group is + * owned by SDL and has the same lifetime as the containing context. It + * should not be destroyed manually when no longer needed. + * + * \since This function is available since SDL 3.4.0. + */ +extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetGPUDeviceDebugProperties( + SDL_GPUDevice *device); + +#define SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING "SDL.gpu.device.debug.name" +#define SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_NAME_STRING "SDL.gpu.device.debug.driver_name" +#define SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING "SDL.gpu.device.debug.driver_version" +#define SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_INFO_STRING "SDL.gpu.device.debug.driver_info" +#define SDL_PROP_GPU_DEVICE_DEBUG_VULKAN_CONFORMANCE_STRING "SDL.gpu.device.debug.vulkan.conformance" + /* State Creation */ /** diff --git a/src/dynapi/SDL_dynapi.sym b/src/dynapi/SDL_dynapi.sym index 6ec8127dfa..f90b3637e5 100644 --- a/src/dynapi/SDL_dynapi.sym +++ b/src/dynapi/SDL_dynapi.sym @@ -1248,6 +1248,7 @@ SDL3_0.0.0 { SDL_GetWindowProgressValue; SDL_SetRenderTextureAddressMode; SDL_GetRenderTextureAddressMode; + SDL_GetGPUDeviceDebugProperties; # extra symbols go here (don't modify this line) local: *; }; diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index c005264900..e31c6ebd10 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -1273,3 +1273,4 @@ #define SDL_GetWindowProgressValue SDL_GetWindowProgressValue_REAL #define SDL_SetRenderTextureAddressMode SDL_SetRenderTextureAddressMode_REAL #define SDL_GetRenderTextureAddressMode SDL_GetRenderTextureAddressMode_REAL +#define SDL_GetGPUDeviceDebugProperties SDL_GetGPUDeviceDebugProperties_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index 31f56143e3..ffa0063d70 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -1281,3 +1281,4 @@ SDL_DYNAPI_PROC(SDL_ProgressState,SDL_GetWindowProgressState,(SDL_Window *a),(a) SDL_DYNAPI_PROC(float,SDL_GetWindowProgressValue,(SDL_Window *a),(a),return) SDL_DYNAPI_PROC(bool,SDL_SetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode b,SDL_TextureAddressMode c),(a,b,c),return) SDL_DYNAPI_PROC(bool,SDL_GetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode *b,SDL_TextureAddressMode *c),(a,b,c),return) +SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetGPUDeviceDebugProperties,(SDL_GPUDevice *a),(a),return) diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c index 58c578fbcf..01edbc51d3 100644 --- a/src/gpu/SDL_gpu.c +++ b/src/gpu/SDL_gpu.c @@ -586,6 +586,13 @@ SDL_GPUShaderFormat SDL_GetGPUShaderFormats(SDL_GPUDevice *device) return device->shader_formats; } +SDL_PropertiesID SDL_GetGPUDeviceDebugProperties(SDL_GPUDevice *device) +{ + CHECK_DEVICE_MAGIC(device, 0); + + return device->GetDeviceDebugProperties(device); +} + Uint32 SDL_GPUTextureFormatTexelBlockSize( SDL_GPUTextureFormat format) { diff --git a/src/gpu/SDL_sysgpu.h b/src/gpu/SDL_sysgpu.h index 31e6b8d472..c192443c93 100644 --- a/src/gpu/SDL_sysgpu.h +++ b/src/gpu/SDL_sysgpu.h @@ -459,10 +459,12 @@ typedef struct SDL_GPURenderer SDL_GPURenderer; struct SDL_GPUDevice { - // Quit + // Device void (*DestroyDevice)(SDL_GPUDevice *device); + SDL_PropertiesID (*GetDeviceDebugProperties)(SDL_GPUDevice *device); + // State Creation SDL_GPUComputePipeline *(*CreateComputePipeline)( @@ -894,6 +896,7 @@ struct SDL_GPUDevice result->func = name##_##func; #define ASSIGN_DRIVER(name) \ ASSIGN_DRIVER_FUNC(DestroyDevice, name) \ + ASSIGN_DRIVER_FUNC(GetDeviceDebugProperties, name) \ ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \ ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \ ASSIGN_DRIVER_FUNC(CreateSampler, name) \ diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index 19601ff0b6..7b7ba7a32f 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -765,6 +765,7 @@ struct D3D12Renderer // FIXME: these might not be necessary since we're not using custom heaps bool UMA; bool UMACacheCoherent; + SDL_PropertiesID debugProps; Uint32 allowedFramesInFlight; // Indirect command signatures @@ -1535,6 +1536,8 @@ static void D3D12_INTERNAL_DestroyRenderer(D3D12Renderer *renderer) SDL_free(renderer->graphicsPipelinesToDestroy); SDL_free(renderer->computePipelinesToDestroy); + SDL_DestroyProperties(renderer->debugProps); + // Tear down D3D12 objects if (renderer->indirectDrawCommandSignature) { ID3D12CommandSignature_Release(renderer->indirectDrawCommandSignature); @@ -1622,6 +1625,12 @@ static void D3D12_DestroyDevice(SDL_GPUDevice *device) SDL_free(device); } +static SDL_PropertiesID D3D12_GetDeviceDebugProperties(SDL_GPUDevice *device) +{ + D3D12Renderer *renderer = (D3D12Renderer *)device->driverData; + return renderer->debugProps; +} + // Barriers static inline Uint32 D3D12_INTERNAL_CalcSubresource( @@ -8512,6 +8521,11 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD D3D12_FEATURE_DATA_ARCHITECTURE architecture; D3D12_COMMAND_QUEUE_DESC queueDesc; + bool verboseLogs = SDL_GetBooleanProperty( + props, + SDL_PROP_GPU_DEVICE_CREATE_VERBOSE_BOOLEAN, + true); + renderer = (D3D12Renderer *)SDL_calloc(1, sizeof(D3D12Renderer)); #if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)) @@ -8612,15 +8626,39 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD CHECK_D3D12_ERROR_AND_RETURN("Could not get adapter driver version", NULL); } - SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: D3D12"); - SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Adapter: %S", adapterDesc.Description); - SDL_LogInfo( - SDL_LOG_CATEGORY_GPU, - "D3D12 Driver: %d.%d.%d.%d", + renderer->debugProps = SDL_CreateProperties(); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: D3D12"); + } + + // Record device name + char *deviceName = SDL_iconv_wchar_utf8(&adapterDesc.Description[0]); + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING, + deviceName); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Adapter: %s", deviceName); + } + SDL_free(deviceName); + + // Record driver version + char driverVer[64]; + (void)SDL_snprintf( + driverVer, + SDL_arraysize(driverVer), + "%d.%d.%d.%d", HIWORD(umdVersion.HighPart), LOWORD(umdVersion.HighPart), HIWORD(umdVersion.LowPart), LOWORD(umdVersion.LowPart)); + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING, + driverVer); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Driver: %s", driverVer); + } #endif // Load the D3D library diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index 250c03928b..49044b674b 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -643,6 +643,7 @@ struct MetalRenderer id queue; bool debugMode; + SDL_PropertiesID debugProps; Uint32 allowedFramesInFlight; MetalWindowData **claimedWindows; @@ -765,11 +766,20 @@ static void METAL_DestroyDevice(SDL_GPUDevice *device) // Release the command queue renderer->queue = nil; + // Release debug properties + SDL_DestroyProperties(renderer->debugProps); + // Free the primary structures SDL_free(renderer); SDL_free(device); } +static SDL_PropertiesID METAL_GetDeviceDebugProperties(SDL_GPUDevice *device) +{ + MetalRenderer *renderer = (MetalRenderer *)device->driverData; + return renderer->debugProps; +} + // Resource tracking static void METAL_INTERNAL_TrackBuffer( @@ -4444,6 +4454,11 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD id device = NULL; bool hasHardwareSupport = false; + bool verboseLogs = SDL_GetBooleanProperty( + props, + SDL_PROP_GPU_DEVICE_CREATE_VERBOSE_BOOLEAN, + true); + if (debugMode) { /* Due to a Metal driver quirk, once a MTLDevice has been created * with this environment variable set, the Metal validation layers @@ -4497,12 +4512,20 @@ static SDL_GPUDevice *METAL_CreateDevice(bool debugMode, bool preferLowPower, SD renderer->device = device; renderer->queue = [device newCommandQueue]; - // Print driver info - SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Metal"); - SDL_LogInfo( - SDL_LOG_CATEGORY_GPU, - "Metal Device: %s", - [device.name UTF8String]); + renderer->debugProps = SDL_CreateProperties(); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Metal"); + } + + // Record device name + const char *deviceName = [device.name UTF8String]; + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING, + deviceName); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Metal Device: %s", deviceName); + } // Remember debug mode renderer->debugMode = debugMode; diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index d2b64b2b54..e512566483 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -1096,6 +1096,7 @@ struct VulkanRenderer bool debugMode; bool preferLowPower; + SDL_PropertiesID debugProps; Uint32 allowedFramesInFlight; VulkanExtensions supports; @@ -4917,11 +4918,20 @@ static void VULKAN_DestroyDevice( renderer->vkDestroyDevice(renderer->logicalDevice, NULL); renderer->vkDestroyInstance(renderer->instance, NULL); + SDL_DestroyProperties(renderer->debugProps); + SDL_free(renderer); SDL_free(device); SDL_Vulkan_UnloadLibrary(); } +static SDL_PropertiesID VULKAN_GetDeviceDebugProperties( + SDL_GPUDevice *device) +{ + VulkanRenderer *renderer = (VulkanRenderer *)device->driverData; + return renderer->debugProps; +} + static DescriptorSetCache *VULKAN_INTERNAL_AcquireDescriptorSetCache( VulkanRenderer *renderer) { @@ -11568,6 +11578,11 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S SDL_GPUDevice *result; Uint32 i; + bool verboseLogs = SDL_GetBooleanProperty( + props, + SDL_PROP_GPU_DEVICE_CREATE_VERBOSE_BOOLEAN, + true); + if (!SDL_Vulkan_LoadLibrary(NULL)) { SDL_assert(!"This should have failed in PrepareDevice first!"); return NULL; @@ -11585,25 +11600,108 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S SET_STRING_ERROR_AND_RETURN("Failed to initialize Vulkan!", NULL); } - SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan"); - SDL_LogInfo( - SDL_LOG_CATEGORY_GPU, - "Vulkan Device: %s", - renderer->physicalDeviceProperties.properties.deviceName); + renderer->debugProps = SDL_CreateProperties(); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Vulkan"); + } + + // Record device name + const char *deviceName = renderer->physicalDeviceProperties.properties.deviceName; + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING, + deviceName); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Vulkan Device: %s", deviceName); + } + + // Record driver version. This is provided as a backup if + // VK_KHR_driver_properties is not available but as most drivers support it + // this property should be rarely used. + // + // This uses a vendor-specific encoding and it isn't well documented. The + // vendor ID is the registered PCI ID of the vendor and can be found in + // online databases. + char driverVer[64]; + Uint32 rawDriverVer = renderer->physicalDeviceProperties.properties.driverVersion; + Uint32 vendorId = renderer->physicalDeviceProperties.properties.vendorID; + if (vendorId == 0x10de) { + // Nvidia uses 10|8|8|6 encoding. + (void)SDL_snprintf( + driverVer, + SDL_arraysize(driverVer), + "%d.%d.%d.%d", + (rawDriverVer >> 22) & 0x3ff, + (rawDriverVer >> 14) & 0xff, + (rawDriverVer >> 6) & 0xff, + rawDriverVer & 0x3f); + } +#ifdef SDL_PLATFORM_WINDOWS + else if (vendorId == 0x8086) { + // Intel uses 18|14 encoding on Windows only. + (void)SDL_snprintf( + driverVer, + SDL_arraysize(driverVer), + "%d.%d", + (rawDriverVer >> 14) & 0x3ffff, + rawDriverVer & 0x3fff); + } +#endif + else { + // Assume standard Vulkan 10|10|12 encoding for everything else. AMD and + // Mesa are known to use this encoding. + (void)SDL_snprintf( + driverVer, + SDL_arraysize(driverVer), + "%d.%d.%d", + (rawDriverVer >> 22) & 0x3ff, + (rawDriverVer >> 12) & 0x3ff, + rawDriverVer & 0xfff); + } + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING, + driverVer); + // Log this only if VK_KHR_driver_properties is not available. + if (renderer->supports.KHR_driver_properties) { - SDL_LogInfo( - SDL_LOG_CATEGORY_GPU, - "Vulkan Driver: %s %s", - renderer->physicalDeviceDriverProperties.driverName, - renderer->physicalDeviceDriverProperties.driverInfo); - SDL_LogInfo( - SDL_LOG_CATEGORY_GPU, - "Vulkan Conformance: %u.%u.%u", + // Record driver name and version + const char *driverName = renderer->physicalDeviceDriverProperties.driverName; + const char *driverInfo = renderer->physicalDeviceDriverProperties.driverInfo; + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_NAME_STRING, + driverName); + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_INFO_STRING, + driverInfo); + if (verboseLogs) { + // FIXME: driverInfo can be a multiline string. + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Vulkan Driver: %s %s", driverName, driverInfo); + } + + // Record conformance level + char conformance[64]; + (void)SDL_snprintf( + conformance, + SDL_arraysize(conformance), + "%u.%u.%u.%u", renderer->physicalDeviceDriverProperties.conformanceVersion.major, renderer->physicalDeviceDriverProperties.conformanceVersion.minor, + renderer->physicalDeviceDriverProperties.conformanceVersion.subminor, renderer->physicalDeviceDriverProperties.conformanceVersion.patch); + SDL_SetStringProperty( + renderer->debugProps, + SDL_PROP_GPU_DEVICE_DEBUG_VULKAN_CONFORMANCE_STRING, + conformance); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Vulkan Conformance: %s", conformance); + } } else { - SDL_LogWarn(SDL_LOG_CATEGORY_GPU, "KHR_driver_properties unsupported! Bother your vendor about this!"); + if (verboseLogs) { + SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Vulkan Driver: %s", driverVer); + } } if (!VULKAN_INTERNAL_CreateLogicalDevice(