Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Expose GPU device name and driver version #12579

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions include/SDL3/SDL_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -4177,6 +4177,26 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_CalculateGPUTextureFormatSize(
Uint32 height,
Uint32 depth_or_layer_count);

/**
* Get readonly metadata properties of an existing GPU device.
*
* Currently available properties:
*
* - `SDL_PROP_GPU_DEVICE_PHYSICAL_NAME_STRING`: The physical name of the GPU device, as reported by the system driver.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the PHYSICAL part redundant? What other device name could it be referring to? Maybe ADAPTER instead?

Copy link
Contributor Author

@MrOnlineCoder MrOnlineCoder Mar 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I borrowed it from Vulkan properties name: physicalDeviceProperties.properties.deviceName.
I am just afraid to make it very general as SDL_PROP_GPU_DEVICE_NAME_STRING, but if you are fine - I can change that.

Adapter seems to me to be mostly D3D-specific thing, but maybe I am mistaken.

* - `SDL_PROP_GPU_DEVICE_DRIVER_VERSION_STRING`: Version of the GPU driver as a string. May be NULL on some platforms, like MacOS.
*
* \param device GPU device to query
*
* \returns a SDL_PropertiesID containing various data regarding the device or 0 on error. Use SDL_GetError() to get more information.
*
* \since This function is available since SDL 3.2.0.
*/
extern SDL_DECLSPEC SDL_PropertiesID SDLCALL SDL_GetGPUDeviceProperties(
SDL_GPUDevice *device);

#define SDL_PROP_GPU_DEVICE_PHYSICAL_NAME_STRING "SDL.gpu.device.physical.name"
#define SDL_PROP_GPU_DEVICE_DRIVER_VERSION_STRING "SDL.gpu.device.driver.version"

#ifdef SDL_PLATFORM_GDK

/**
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,7 @@ SDL3_0.0.0 {
SDL_SetGPURenderStateFragmentUniforms;
SDL_SetRenderGPUState;
SDL_DestroyGPURenderState;
SDL_GetGPUDeviceProperties;
# extra symbols go here (don't modify this line)
local: *;
};
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -1267,3 +1267,4 @@
#define SDL_SetGPURenderStateFragmentUniforms SDL_SetGPURenderStateFragmentUniforms_REAL
#define SDL_SetRenderGPUState SDL_SetRenderGPUState_REAL
#define SDL_DestroyGPURenderState SDL_DestroyGPURenderState_REAL
#define SDL_GetGPUDeviceProperties SDL_GetGPUDeviceProperties_REAL
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1275,3 +1275,4 @@ SDL_DYNAPI_PROC(SDL_GPURenderState*,SDL_CreateGPURenderState,(SDL_Renderer *a,SD
SDL_DYNAPI_PROC(bool,SDL_SetGPURenderStateFragmentUniforms,(SDL_GPURenderState *a,Uint32 b,const void *c,Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(bool,SDL_SetRenderGPUState,(SDL_Renderer *a,SDL_GPURenderState *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_DestroyGPURenderState,(SDL_GPURenderState *a),(a),)
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetGPUDeviceProperties,(SDL_GPUDevice *a),(a),return)
9 changes: 9 additions & 0 deletions src/gpu/SDL_gpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2970,3 +2970,12 @@ Uint32 SDL_CalculateGPUTextureFormatSize(
Uint32 blocksPerColumn = (height + blockHeight - 1) / blockHeight;
return depth_or_layer_count * blocksPerRow * blocksPerColumn * SDL_GPUTextureFormatTexelBlockSize(format);
}


SDL_PropertiesID SDL_GetGPUDeviceProperties(
SDL_GPUDevice *device)
{
CHECK_DEVICE_MAGIC(device, 0);

return device->props;
}
167 changes: 85 additions & 82 deletions src/gpu/SDL_sysgpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -888,92 +888,95 @@ struct SDL_GPUDevice

// Store this for SDL_gpu.c's debug layer
bool debug_mode;

// Various readonly properties for the device
SDL_PropertiesID props;
};

#define ASSIGN_DRIVER_FUNC(func, name) \
result->func = name##_##func;
#define ASSIGN_DRIVER(name) \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These whitespace changes here serve no purpose and make the diff less readable

ASSIGN_DRIVER_FUNC(DestroyDevice, name) \
ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \
ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(CreateSampler, name) \
ASSIGN_DRIVER_FUNC(CreateShader, name) \
ASSIGN_DRIVER_FUNC(CreateTexture, name) \
ASSIGN_DRIVER_FUNC(CreateBuffer, name) \
ASSIGN_DRIVER_FUNC(CreateTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(SetBufferName, name) \
ASSIGN_DRIVER_FUNC(SetTextureName, name) \
ASSIGN_DRIVER_FUNC(InsertDebugLabel, name) \
ASSIGN_DRIVER_FUNC(PushDebugGroup, name) \
ASSIGN_DRIVER_FUNC(PopDebugGroup, name) \
ASSIGN_DRIVER_FUNC(ReleaseTexture, name) \
ASSIGN_DRIVER_FUNC(ReleaseSampler, name) \
ASSIGN_DRIVER_FUNC(ReleaseBuffer, name) \
ASSIGN_DRIVER_FUNC(ReleaseTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(ReleaseShader, name) \
ASSIGN_DRIVER_FUNC(ReleaseComputePipeline, name) \
ASSIGN_DRIVER_FUNC(ReleaseGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(BeginRenderPass, name) \
ASSIGN_DRIVER_FUNC(BindGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(SetViewport, name) \
ASSIGN_DRIVER_FUNC(SetScissor, name) \
ASSIGN_DRIVER_FUNC(SetBlendConstants, name) \
ASSIGN_DRIVER_FUNC(SetStencilReference, name) \
ASSIGN_DRIVER_FUNC(BindVertexBuffers, name) \
ASSIGN_DRIVER_FUNC(BindIndexBuffer, name) \
ASSIGN_DRIVER_FUNC(BindVertexSamplers, name) \
ASSIGN_DRIVER_FUNC(BindVertexStorageTextures, name) \
ASSIGN_DRIVER_FUNC(BindVertexStorageBuffers, name) \
ASSIGN_DRIVER_FUNC(BindFragmentSamplers, name) \
ASSIGN_DRIVER_FUNC(BindFragmentStorageTextures, name) \
ASSIGN_DRIVER_FUNC(BindFragmentStorageBuffers, name) \
ASSIGN_DRIVER_FUNC(PushVertexUniformData, name) \
ASSIGN_DRIVER_FUNC(PushFragmentUniformData, name) \
ASSIGN_DRIVER_FUNC(DrawIndexedPrimitives, name) \
ASSIGN_DRIVER_FUNC(DrawPrimitives, name) \
ASSIGN_DRIVER_FUNC(DrawPrimitivesIndirect, name) \
ASSIGN_DRIVER_FUNC(DrawIndexedPrimitivesIndirect, name) \
ASSIGN_DRIVER_FUNC(EndRenderPass, name) \
ASSIGN_DRIVER_FUNC(BeginComputePass, name) \
ASSIGN_DRIVER_FUNC(BindComputePipeline, name) \
ASSIGN_DRIVER_FUNC(BindComputeSamplers, name) \
ASSIGN_DRIVER_FUNC(BindComputeStorageTextures, name) \
ASSIGN_DRIVER_FUNC(BindComputeStorageBuffers, name) \
ASSIGN_DRIVER_FUNC(PushComputeUniformData, name) \
ASSIGN_DRIVER_FUNC(DispatchCompute, name) \
ASSIGN_DRIVER_FUNC(DispatchComputeIndirect, name) \
ASSIGN_DRIVER_FUNC(EndComputePass, name) \
ASSIGN_DRIVER_FUNC(MapTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(UnmapTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(BeginCopyPass, name) \
ASSIGN_DRIVER_FUNC(UploadToTexture, name) \
ASSIGN_DRIVER_FUNC(UploadToBuffer, name) \
ASSIGN_DRIVER_FUNC(DownloadFromTexture, name) \
ASSIGN_DRIVER_FUNC(DownloadFromBuffer, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \
ASSIGN_DRIVER_FUNC(CopyBufferToBuffer, name) \
ASSIGN_DRIVER_FUNC(GenerateMipmaps, name) \
ASSIGN_DRIVER_FUNC(EndCopyPass, name) \
ASSIGN_DRIVER_FUNC(Blit, name) \
ASSIGN_DRIVER_FUNC(SupportsSwapchainComposition, name) \
ASSIGN_DRIVER_FUNC(SupportsPresentMode, name) \
ASSIGN_DRIVER_FUNC(ClaimWindow, name) \
ASSIGN_DRIVER_FUNC(ReleaseWindow, name) \
ASSIGN_DRIVER_FUNC(SetSwapchainParameters, name) \
ASSIGN_DRIVER_FUNC(SetAllowedFramesInFlight, name) \
ASSIGN_DRIVER_FUNC(GetSwapchainTextureFormat, name) \
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
ASSIGN_DRIVER_FUNC(AcquireSwapchainTexture, name) \
ASSIGN_DRIVER_FUNC(WaitForSwapchain, name) \
ASSIGN_DRIVER_FUNC(WaitAndAcquireSwapchainTexture, name)\
ASSIGN_DRIVER_FUNC(Submit, name) \
ASSIGN_DRIVER_FUNC(SubmitAndAcquireFence, name) \
ASSIGN_DRIVER_FUNC(Cancel, name) \
ASSIGN_DRIVER_FUNC(Wait, name) \
ASSIGN_DRIVER_FUNC(WaitForFences, name) \
ASSIGN_DRIVER_FUNC(QueryFence, name) \
ASSIGN_DRIVER_FUNC(ReleaseFence, name) \
ASSIGN_DRIVER_FUNC(SupportsTextureFormat, name) \
#define ASSIGN_DRIVER(name) \
ASSIGN_DRIVER_FUNC(DestroyDevice, name) \
ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \
ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(CreateSampler, name) \
ASSIGN_DRIVER_FUNC(CreateShader, name) \
ASSIGN_DRIVER_FUNC(CreateTexture, name) \
ASSIGN_DRIVER_FUNC(CreateBuffer, name) \
ASSIGN_DRIVER_FUNC(CreateTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(SetBufferName, name) \
ASSIGN_DRIVER_FUNC(SetTextureName, name) \
ASSIGN_DRIVER_FUNC(InsertDebugLabel, name) \
ASSIGN_DRIVER_FUNC(PushDebugGroup, name) \
ASSIGN_DRIVER_FUNC(PopDebugGroup, name) \
ASSIGN_DRIVER_FUNC(ReleaseTexture, name) \
ASSIGN_DRIVER_FUNC(ReleaseSampler, name) \
ASSIGN_DRIVER_FUNC(ReleaseBuffer, name) \
ASSIGN_DRIVER_FUNC(ReleaseTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(ReleaseShader, name) \
ASSIGN_DRIVER_FUNC(ReleaseComputePipeline, name) \
ASSIGN_DRIVER_FUNC(ReleaseGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(BeginRenderPass, name) \
ASSIGN_DRIVER_FUNC(BindGraphicsPipeline, name) \
ASSIGN_DRIVER_FUNC(SetViewport, name) \
ASSIGN_DRIVER_FUNC(SetScissor, name) \
ASSIGN_DRIVER_FUNC(SetBlendConstants, name) \
ASSIGN_DRIVER_FUNC(SetStencilReference, name) \
ASSIGN_DRIVER_FUNC(BindVertexBuffers, name) \
ASSIGN_DRIVER_FUNC(BindIndexBuffer, name) \
ASSIGN_DRIVER_FUNC(BindVertexSamplers, name) \
ASSIGN_DRIVER_FUNC(BindVertexStorageTextures, name) \
ASSIGN_DRIVER_FUNC(BindVertexStorageBuffers, name) \
ASSIGN_DRIVER_FUNC(BindFragmentSamplers, name) \
ASSIGN_DRIVER_FUNC(BindFragmentStorageTextures, name) \
ASSIGN_DRIVER_FUNC(BindFragmentStorageBuffers, name) \
ASSIGN_DRIVER_FUNC(PushVertexUniformData, name) \
ASSIGN_DRIVER_FUNC(PushFragmentUniformData, name) \
ASSIGN_DRIVER_FUNC(DrawIndexedPrimitives, name) \
ASSIGN_DRIVER_FUNC(DrawPrimitives, name) \
ASSIGN_DRIVER_FUNC(DrawPrimitivesIndirect, name) \
ASSIGN_DRIVER_FUNC(DrawIndexedPrimitivesIndirect, name) \
ASSIGN_DRIVER_FUNC(EndRenderPass, name) \
ASSIGN_DRIVER_FUNC(BeginComputePass, name) \
ASSIGN_DRIVER_FUNC(BindComputePipeline, name) \
ASSIGN_DRIVER_FUNC(BindComputeSamplers, name) \
ASSIGN_DRIVER_FUNC(BindComputeStorageTextures, name) \
ASSIGN_DRIVER_FUNC(BindComputeStorageBuffers, name) \
ASSIGN_DRIVER_FUNC(PushComputeUniformData, name) \
ASSIGN_DRIVER_FUNC(DispatchCompute, name) \
ASSIGN_DRIVER_FUNC(DispatchComputeIndirect, name) \
ASSIGN_DRIVER_FUNC(EndComputePass, name) \
ASSIGN_DRIVER_FUNC(MapTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(UnmapTransferBuffer, name) \
ASSIGN_DRIVER_FUNC(BeginCopyPass, name) \
ASSIGN_DRIVER_FUNC(UploadToTexture, name) \
ASSIGN_DRIVER_FUNC(UploadToBuffer, name) \
ASSIGN_DRIVER_FUNC(DownloadFromTexture, name) \
ASSIGN_DRIVER_FUNC(DownloadFromBuffer, name) \
ASSIGN_DRIVER_FUNC(CopyTextureToTexture, name) \
ASSIGN_DRIVER_FUNC(CopyBufferToBuffer, name) \
ASSIGN_DRIVER_FUNC(GenerateMipmaps, name) \
ASSIGN_DRIVER_FUNC(EndCopyPass, name) \
ASSIGN_DRIVER_FUNC(Blit, name) \
ASSIGN_DRIVER_FUNC(SupportsSwapchainComposition, name) \
ASSIGN_DRIVER_FUNC(SupportsPresentMode, name) \
ASSIGN_DRIVER_FUNC(ClaimWindow, name) \
ASSIGN_DRIVER_FUNC(ReleaseWindow, name) \
ASSIGN_DRIVER_FUNC(SetSwapchainParameters, name) \
ASSIGN_DRIVER_FUNC(SetAllowedFramesInFlight, name) \
ASSIGN_DRIVER_FUNC(GetSwapchainTextureFormat, name) \
ASSIGN_DRIVER_FUNC(AcquireCommandBuffer, name) \
ASSIGN_DRIVER_FUNC(AcquireSwapchainTexture, name) \
ASSIGN_DRIVER_FUNC(WaitForSwapchain, name) \
ASSIGN_DRIVER_FUNC(WaitAndAcquireSwapchainTexture, name) \
ASSIGN_DRIVER_FUNC(Submit, name) \
ASSIGN_DRIVER_FUNC(SubmitAndAcquireFence, name) \
ASSIGN_DRIVER_FUNC(Cancel, name) \
ASSIGN_DRIVER_FUNC(Wait, name) \
ASSIGN_DRIVER_FUNC(WaitForFences, name) \
ASSIGN_DRIVER_FUNC(QueryFence, name) \
ASSIGN_DRIVER_FUNC(ReleaseFence, name) \
ASSIGN_DRIVER_FUNC(SupportsTextureFormat, name) \
ASSIGN_DRIVER_FUNC(SupportsSampleCount, name)

typedef struct SDL_GPUBootstrap
Expand Down
13 changes: 13 additions & 0 deletions src/gpu/d3d12/SDL_gpu_d3d12.c
Original file line number Diff line number Diff line change
Expand Up @@ -1619,6 +1619,9 @@ static void D3D12_DestroyDevice(SDL_GPUDevice *device)
}

D3D12_INTERNAL_DestroyRenderer(renderer);

SDL_DestroyProperties(device->props);

SDL_free(device);
}

Expand Down Expand Up @@ -8994,6 +8997,16 @@ static SDL_GPUDevice *D3D12_CreateDevice(bool debugMode, bool preferLowPower, SD
result->debug_mode = debugMode;
renderer->sdlGPUDevice = result;

result->props = SDL_CreateProperties();

char *adapterDescUtf8 = SDL_iconv_wchar_utf8(&adapterDesc.Description[0]);
SDL_SetStringProperty(result->props, SDL_PROP_GPU_DEVICE_PHYSICAL_NAME_STRING, adapterDescUtf8);
SDL_free(adapterDescUtf8);

char driverMetadataBuffer[256] = { 0 };
SDL_snprintf(&driverMetadataBuffer[0], 256, "%d.%d.%d.%d", HIWORD(umdVersion.HighPart), LOWORD(umdVersion.HighPart), HIWORD(umdVersion.LowPart), LOWORD(umdVersion.LowPart));
SDL_SetStringProperty(result->props, SDL_PROP_GPU_DEVICE_DRIVER_VERSION_STRING, driverMetadataBuffer);

return result;
}

Expand Down
6 changes: 6 additions & 0 deletions src/gpu/metal/SDL_gpu_metal.m
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,8 @@ static void METAL_DestroyDevice(SDL_GPUDevice *device)
// Release the command queue
renderer->queue = nil;

SDL_DestroyProperties(device->props);

// Free the primary structures
SDL_free(renderer);
SDL_free(device);
Expand Down Expand Up @@ -4570,6 +4572,10 @@ static void METAL_INTERNAL_DestroyBlitResources(
result->driverData = (SDL_GPURenderer *)renderer;
renderer->sdlGPUDevice = result;

result->props = SDL_CreateProperties();

SDL_SetStringProperty(result->props, SDL_PROP_GPU_DEVICE_PHYSICAL_NAME_STRING, [device.name UTF8String]);

return result;
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/gpu/vulkan/SDL_gpu_vulkan.c
Original file line number Diff line number Diff line change
Expand Up @@ -4895,6 +4895,8 @@ static void VULKAN_DestroyDevice(
renderer->vkDestroyDevice(renderer->logicalDevice, NULL);
renderer->vkDestroyInstance(renderer->instance, NULL);

SDL_DestroyProperties(device->props);

SDL_free(renderer);
SDL_free(device);
SDL_Vulkan_UnloadLibrary();
Expand Down Expand Up @@ -11590,6 +11592,10 @@ static SDL_GPUDevice *VULKAN_CreateDevice(bool debugMode, bool preferLowPower, S
ASSIGN_DRIVER(VULKAN)

result->driverData = (SDL_GPURenderer *)renderer;

result->props = SDL_CreateProperties();
SDL_SetStringProperty(result->props, SDL_PROP_GPU_DEVICE_PHYSICAL_NAME_STRING, renderer->physicalDeviceProperties.properties.deviceName);
SDL_SetStringProperty(result->props, SDL_PROP_GPU_DEVICE_DRIVER_VERSION_STRING, renderer->physicalDeviceDriverProperties.driverInfo);

/*
* Create initial swapchain array
Expand Down
Loading