Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7d6850f

Browse files
lmurrayMrOnlineCoder
andcommittedApr 2, 2025·
GPU: Expose debug information from devices
Co-authored-by: Nikita Kogut <glinka1202@gmail.com>
1 parent e236a48 commit 7d6850f

File tree

9 files changed

+318
-26
lines changed

9 files changed

+318
-26
lines changed
 

Diff for: ‎include/SDL3/SDL_gpu.h

+120
Original file line numberDiff line numberDiff line change
@@ -2147,6 +2147,8 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDevice(
21472147
* properties and validations, defaults to true.
21482148
* - `SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN`: enable to prefer
21492149
* energy efficiency over maximum GPU performance, defaults to false.
2150+
* - `SDL_PROP_GPU_DEVICE_CREATE_LOGDEBUGPROPS_BOOLEAN`: enable to automatically
2151+
* log all debug properties on device creation, defaults to true.
21502152
* - `SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING`: the name of the GPU driver to
21512153
* use, if a specific one is desired.
21522154
*
@@ -2186,6 +2188,7 @@ extern SDL_DECLSPEC SDL_GPUDevice * SDLCALL SDL_CreateGPUDeviceWithProperties(
21862188

21872189
#define SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN "SDL.gpu.device.create.debugmode"
21882190
#define SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN "SDL.gpu.device.create.preferlowpower"
2191+
#define SDL_PROP_GPU_DEVICE_CREATE_LOGDEBUGPROPS_BOOLEAN "SDL.gpu.device.create.logdebugprops"
21892192
#define SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING "SDL.gpu.device.create.name"
21902193
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOLEAN "SDL.gpu.device.create.shaders.private"
21912194
#define SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOLEAN "SDL.gpu.device.create.shaders.spirv"
@@ -2257,6 +2260,123 @@ extern SDL_DECLSPEC const char * SDLCALL SDL_GetGPUDeviceDriver(SDL_GPUDevice *d
22572260
*/
22582261
extern SDL_DECLSPEC SDL_GPUShaderFormat SDLCALL SDL_GetGPUShaderFormats(SDL_GPUDevice *device);
22592262

2263+
/**
2264+
* Returns a property group containing read-only debug information associated
2265+
* with this GPU context. All properties are optionally provided and may differ
2266+
* between GPU backends and SDL versions.
2267+
*
2268+
* The following properties are provided by SDL:
2269+
*
2270+
* ```
2271+
* SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING:
2272+
* Contains the name of the underlying device as reported by the system
2273+
* driver. This string has no standardized format, is highly inconsistent
2274+
* between hardware devices and drivers, and is able to change at any time. Do
2275+
* not attempt to parse this string as it is bound to fail at some point in
2276+
* the future when system drivers are updated, new hardware devices are
2277+
* introduced, or when SDL adds new GPU backends or modifies existing ones.
2278+
*
2279+
* Strings that have been found in the wild include:
2280+
* GTX 970
2281+
* GeForce GTX 970
2282+
* NVIDIA GeForce GTX 970
2283+
* Microsoft Direct3D12 (NVIDIA GeForce GTX 970)
2284+
* NVIDIA GeForce RTX 2060
2285+
* GeForce RTX 2060 SUPER
2286+
* NVIDIA GeForce RTX 2060 with Max-Q Design
2287+
* NVIDIA Graphics Device
2288+
* GeForce GPU
2289+
* P106-100
2290+
* AMD 15D8:C9
2291+
* AMD Custom GPU 0405
2292+
* ASUS Radeon RX 470 Series
2293+
* Intel(R) RaptorLake-S Mobile Graphics Controller
2294+
* Virtio-GPU Venus (NVIDIA TITAN V)
2295+
* SwiftShader Device
2296+
* SwiftShader Device (LLVM 16.0.0)
2297+
* llvmpipe (LLVM 15.0.4, 256 bits)
2298+
* Microsoft Basic Render Driver
2299+
* unknown device
2300+
*
2301+
* SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_NAME_STRING:
2302+
* Contains the self-reported name of the underlying system driver.
2303+
*
2304+
* Strings that have been found in the wild include:
2305+
* NVIDIA
2306+
* Intel Corporation
2307+
* Qualcomm Technologies Inc. Adreno Vulkan Driver
2308+
* MoltenVK
2309+
* Mali-G715
2310+
* Dozen
2311+
* venus
2312+
*
2313+
* SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING:
2314+
* Contains the self-reported version of the underlying system driver. This is
2315+
* a relatively short version string in an unspecified format. If
2316+
* SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_INFO_STRING is available then that
2317+
* property should be preferred over this one as it may contain additional
2318+
* information that is useful for identifying the exact driver version used.
2319+
*
2320+
* Strings that have been found in the wild include:
2321+
* 53.0.0
2322+
* 0.2.2019
2323+
* 0.405.2463
2324+
* 572.91.0.0
2325+
* 32.0.15.6614
2326+
*
2327+
* SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_INFO_STRING:
2328+
* Contains the detailed version information of the underlying system driver
2329+
* as reported by the driver. This is an arbitrary string with no standardized
2330+
* format and it may contain newlines. This property should be preferred over
2331+
* SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING if it is available as it
2332+
* usually contains the same information but in a format that is easier to
2333+
* read.
2334+
*
2335+
* Strings that have been found in the wild include:
2336+
* 566.14
2337+
* 101.6559
2338+
* 1.2.11
2339+
* Mesa 21.2.2 (LLVM 12.0.1)
2340+
* Mesa 22.2.0-devel (git-f226222 2022-04-14 impish-oibaf-ppa)
2341+
* Mesa 25.1.0-devel (git-7e2c3be454)
2342+
* v1.r53p0-00eac0.824c4f31403fb1fbf8ee1042422c2129
2343+
*
2344+
* As well as the multiline string (which has a trailing newline):
2345+
* Driver Build: 85da404, I46ff5fc46f, 1606794520
2346+
* Date: 11/30/20
2347+
* Compiler Version: EV031.31.04.01
2348+
* Driver Branch: promo490_3_Google
2349+
*
2350+
* SDL_PROP_GPU_DEVICE_DEBUG_VULKAN_CONFORMANCE_STRING:
2351+
* When using the Vulkan backend, contains the highest Vulkan version number
2352+
* that the system driver claims that the underlying hardware conforms to.
2353+
* This is self-reported and may not be truthful.
2354+
*
2355+
* Strings that have been found in the wild include:
2356+
* 0.0.0.0
2357+
* 1.0.0.0
2358+
* 1.1.2.0
2359+
* 1.3.8.2
2360+
* 1.4.0.0
2361+
* ```
2362+
*
2363+
* \param device a GPU context to query.
2364+
* \returns a valid property ID or 0. A value of 0 indicates that no properties
2365+
* are available and is not an error. The returned property group is
2366+
* owned by SDL and has the same lifetime as the containing context. It
2367+
* should not be destroyed manually when no longer needed.
2368+
*
2369+
* \since This function is available since SDL 3.4.0.
2370+
*/
2371+
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetGPUDeviceDebugProperties(
2372+
SDL_GPUDevice *device);
2373+
2374+
#define SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING "SDL.gpu.device.debug.name"
2375+
#define SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_NAME_STRING "SDL.gpu.device.debug.driver_name"
2376+
#define SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING "SDL.gpu.device.debug.driver_version"
2377+
#define SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_INFO_STRING "SDL.gpu.device.debug.driver_info"
2378+
#define SDL_PROP_GPU_DEVICE_DEBUG_VULKAN_CONFORMANCE_STRING "SDL.gpu.device.debug.vulkan_conformance"
2379+
22602380
/* State Creation */
22612381

22622382
/**

Diff for: ‎src/dynapi/SDL_dynapi.sym

+1
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,7 @@ SDL3_0.0.0 {
12481248
SDL_GetWindowProgressValue;
12491249
SDL_SetRenderTextureAddressMode;
12501250
SDL_GetRenderTextureAddressMode;
1251+
SDL_GetGPUDeviceDebugProperties;
12511252
# extra symbols go here (don't modify this line)
12521253
local: *;
12531254
};

Diff for: ‎src/dynapi/SDL_dynapi_overrides.h

+1
Original file line numberDiff line numberDiff line change
@@ -1273,3 +1273,4 @@
12731273
#define SDL_GetWindowProgressValue SDL_GetWindowProgressValue_REAL
12741274
#define SDL_SetRenderTextureAddressMode SDL_SetRenderTextureAddressMode_REAL
12751275
#define SDL_GetRenderTextureAddressMode SDL_GetRenderTextureAddressMode_REAL
1276+
#define SDL_GetGPUDeviceDebugProperties SDL_GetGPUDeviceDebugProperties_REAL

Diff for: ‎src/dynapi/SDL_dynapi_procs.h

+1
Original file line numberDiff line numberDiff line change
@@ -1281,3 +1281,4 @@ SDL_DYNAPI_PROC(SDL_ProgressState,SDL_GetWindowProgressState,(SDL_Window *a),(a)
12811281
SDL_DYNAPI_PROC(float,SDL_GetWindowProgressValue,(SDL_Window *a),(a),return)
12821282
SDL_DYNAPI_PROC(bool,SDL_SetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode b,SDL_TextureAddressMode c),(a,b,c),return)
12831283
SDL_DYNAPI_PROC(bool,SDL_GetRenderTextureAddressMode,(SDL_Renderer *a,SDL_TextureAddressMode *b,SDL_TextureAddressMode *c),(a,b,c),return)
1284+
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetGPUDeviceDebugProperties,(SDL_GPUDevice *a),(a),return)

Diff for: ‎src/gpu/SDL_gpu.c

+7
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,13 @@ SDL_GPUShaderFormat SDL_GetGPUShaderFormats(SDL_GPUDevice *device)
586586
return device->shader_formats;
587587
}
588588

589+
SDL_PropertiesID SDL_GetGPUDeviceDebugProperties(SDL_GPUDevice *device)
590+
{
591+
CHECK_DEVICE_MAGIC(device, 0);
592+
593+
return device->GetDeviceDebugProperties(device);
594+
}
595+
589596
Uint32 SDL_GPUTextureFormatTexelBlockSize(
590597
SDL_GPUTextureFormat format)
591598
{

Diff for: ‎src/gpu/SDL_sysgpu.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,12 @@ typedef struct SDL_GPURenderer SDL_GPURenderer;
459459

460460
struct SDL_GPUDevice
461461
{
462-
// Quit
462+
// Device
463463

464464
void (*DestroyDevice)(SDL_GPUDevice *device);
465465

466+
SDL_PropertiesID (*GetDeviceDebugProperties)(SDL_GPUDevice *device);
467+
466468
// State Creation
467469

468470
SDL_GPUComputePipeline *(*CreateComputePipeline)(
@@ -894,6 +896,7 @@ struct SDL_GPUDevice
894896
result->func = name##_##func;
895897
#define ASSIGN_DRIVER(name) \
896898
ASSIGN_DRIVER_FUNC(DestroyDevice, name) \
899+
ASSIGN_DRIVER_FUNC(GetDeviceDebugProperties, name) \
897900
ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \
898901
ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \
899902
ASSIGN_DRIVER_FUNC(CreateSampler, name) \

Diff for: ‎src/gpu/d3d12/SDL_gpu_d3d12.c

+43-5
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,7 @@ struct D3D12Renderer
765765
// FIXME: these might not be necessary since we're not using custom heaps
766766
bool UMA;
767767
bool UMACacheCoherent;
768+
SDL_PropertiesID debugProps;
768769
Uint32 allowedFramesInFlight;
769770

770771
// Indirect command signatures
@@ -1535,6 +1536,8 @@ static void D3D12_INTERNAL_DestroyRenderer(D3D12Renderer *renderer)
15351536
SDL_free(renderer->graphicsPipelinesToDestroy);
15361537
SDL_free(renderer->computePipelinesToDestroy);
15371538

1539+
SDL_DestroyProperties(renderer->debugProps);
1540+
15381541
// Tear down D3D12 objects
15391542
if (renderer->indirectDrawCommandSignature) {
15401543
ID3D12CommandSignature_Release(renderer->indirectDrawCommandSignature);
@@ -1622,6 +1625,12 @@ static void D3D12_DestroyDevice(SDL_GPUDevice *device)
16221625
SDL_free(device);
16231626
}
16241627

1628+
static SDL_PropertiesID D3D12_GetDeviceDebugProperties(SDL_GPUDevice *device)
1629+
{
1630+
D3D12Renderer *renderer = (D3D12Renderer *)device->driverData;
1631+
return renderer->debugProps;
1632+
}
1633+
16251634
// Barriers
16261635

16271636
static inline Uint32 D3D12_INTERNAL_CalcSubresource(
@@ -8512,6 +8521,11 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
85128521
D3D12_FEATURE_DATA_ARCHITECTURE architecture;
85138522
D3D12_COMMAND_QUEUE_DESC queueDesc;
85148523

8524+
bool logDebugProps = SDL_GetBooleanProperty(
8525+
props,
8526+
SDL_PROP_GPU_DEVICE_CREATE_LOGDEBUGPROPS_BOOLEAN,
8527+
true);
8528+
85158529
renderer = (D3D12Renderer *)SDL_calloc(1, sizeof(D3D12Renderer));
85168530

85178531
#if !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))
@@ -8612,15 +8626,39 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
86128626
CHECK_D3D12_ERROR_AND_RETURN("Could not get adapter driver version", NULL);
86138627
}
86148628

8615-
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: D3D12");
8616-
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Adapter: %S", adapterDesc.Description);
8617-
SDL_LogInfo(
8618-
SDL_LOG_CATEGORY_GPU,
8619-
"D3D12 Driver: %d.%d.%d.%d",
8629+
renderer->debugProps = SDL_CreateProperties();
8630+
if (logDebugProps) {
8631+
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: D3D12");
8632+
}
8633+
8634+
// Record device name
8635+
char *deviceName = SDL_iconv_wchar_utf8(&adapterDesc.Description[0]);
8636+
SDL_SetStringProperty(
8637+
renderer->debugProps,
8638+
SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING,
8639+
deviceName);
8640+
if (logDebugProps) {
8641+
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Adapter: %s", deviceName);
8642+
}
8643+
SDL_free(deviceName);
8644+
8645+
// Record driver version
8646+
char driverVer[64];
8647+
(void)SDL_snprintf(
8648+
driverVer,
8649+
SDL_arraysize(driverVer),
8650+
"%d.%d.%d.%d",
86208651
HIWORD(umdVersion.HighPart),
86218652
LOWORD(umdVersion.HighPart),
86228653
HIWORD(umdVersion.LowPart),
86238654
LOWORD(umdVersion.LowPart));
8655+
SDL_SetStringProperty(
8656+
renderer->debugProps,
8657+
SDL_PROP_GPU_DEVICE_DEBUG_DRIVER_VERSION_STRING,
8658+
driverVer);
8659+
if (logDebugProps) {
8660+
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "D3D12 Driver: %s", driverVer);
8661+
}
86248662
#endif
86258663

86268664
// Load the D3D library

Diff for: ‎src/gpu/metal/SDL_gpu_metal.m

+29-6
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,7 @@ static MTLDepthClipMode SDLToMetal_DepthClipMode(
643643
id<MTLCommandQueue> queue;
644644

645645
bool debugMode;
646+
SDL_PropertiesID debugProps;
646647
Uint32 allowedFramesInFlight;
647648

648649
MetalWindowData **claimedWindows;
@@ -765,11 +766,20 @@ static void METAL_DestroyDevice(SDL_GPUDevice *device)
765766
// Release the command queue
766767
renderer->queue = nil;
767768

769+
// Release debug properties
770+
SDL_DestroyProperties(renderer->debugProps);
771+
768772
// Free the primary structures
769773
SDL_free(renderer);
770774
SDL_free(device);
771775
}
772776

777+
static SDL_PropertiesID METAL_GetDeviceDebugProperties(SDL_GPUDevice *device)
778+
{
779+
MetalRenderer *renderer = (MetalRenderer *)device->driverData;
780+
return renderer->debugProps;
781+
}
782+
773783
// Resource tracking
774784

775785
static void METAL_INTERNAL_TrackBuffer(
@@ -4444,6 +4454,11 @@ static void METAL_INTERNAL_DestroyBlitResources(
44444454
id<MTLDevice> device = NULL;
44454455
bool hasHardwareSupport = false;
44464456

4457+
bool logDebugProps = SDL_GetBooleanProperty(
4458+
props,
4459+
SDL_PROP_GPU_DEVICE_CREATE_LOGDEBUGPROPS_BOOLEAN,
4460+
true);
4461+
44474462
if (debugMode) {
44484463
/* Due to a Metal driver quirk, once a MTLDevice has been created
44494464
* with this environment variable set, the Metal validation layers
@@ -4497,12 +4512,20 @@ static void METAL_INTERNAL_DestroyBlitResources(
44974512
renderer->device = device;
44984513
renderer->queue = [device newCommandQueue];
44994514

4500-
// Print driver info
4501-
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Metal");
4502-
SDL_LogInfo(
4503-
SDL_LOG_CATEGORY_GPU,
4504-
"Metal Device: %s",
4505-
[device.name UTF8String]);
4515+
renderer->debugProps = SDL_CreateProperties();
4516+
if (logDebugProps) {
4517+
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "SDL_GPU Driver: Metal");
4518+
}
4519+
4520+
// Record device name
4521+
const char *deviceName = [device.name UTF8String];
4522+
SDL_SetStringProperty(
4523+
renderer->debugProps,
4524+
SDL_PROP_GPU_DEVICE_DEBUG_NAME_STRING,
4525+
deviceName);
4526+
if (logDebugProps) {
4527+
SDL_LogInfo(SDL_LOG_CATEGORY_GPU, "Metal Device: %s", deviceName);
4528+
}
45064529

45074530
// Remember debug mode
45084531
renderer->debugMode = debugMode;

0 commit comments

Comments
 (0)
Please sign in to comment.