Skip to content

SDL DisplayID to GPU map RFC #11545

@NostraMagister

Description

@NostraMagister

I would like to post the following Request For Change. While I write this from a Vulkan perspective because with Graphics APIs like DirectX or Metal the developer is already doing OS specific coding and may not seek abstraction. Vulkan and openGL applications tend to be cross-platform and would, IMO, benefit from this RFC although users of other graphical APIs might too.

Subject

Have an OS abstracted way to associate an SDL_DisplayID with an underlying GPU, expressed in terms of the used graphical API's handles (e.g. for Vulkan a vkPhysicalDevice) as a void*.

Justification

Abstracting the mapping of SDL_DisplayIDs and GPUs (Vulkan PhysicalDevices) is important for devs that use DeviceGroups or that use any multi-monitor/multi-GPU configuration with non-grouped physical devices. Such applications need to be able to do resource assignment to keep GPU and CPU bandwidth use as low as possible and avoid retrieving staging buffers (unfetch) from one GPU to move them to a staging buffer (fetch) on another GPU (or have it done behind the scene by Vulkan). They typically want to balance load between the graphical pipeline and compute pipelines and direct pre-presentation GPU work (e.g. rendering) to the GPU to which the target display monitor is connected and run related compute shaders on the same GPU so that Storage Images can be shared and rendered into a framebuffer's color attachment by the fragment shader on the same GPU.

Such application will not use the SDL GPU category API because they tend to be either more bleeding edge or are performance sensitive and will want to leverage the features of APIs like Vulkan with amongst others good decoupled rendering and presentation. Games using 3D headsets, stereo-vision video, trading room, control room, traffic monitoring, e-currency mining, broadcasting and security center applications are just an example applications that must do careful GPU resource allocation even if some don't have intensive graphical work. Even 2D UI APIs like Dear Imgui will one day want multi-monitor support and would greatly profit in their SDL based backends from having this abstraction as will everyone that writes a graphical backend for use with any UI library. Using SDL 3 would largely simplify and tremendously reduce the number of lines to code in such backends.

SDL 3 Status

SDL provides a way to enumerate the display monitors through SDL_GetDisplays() that returns a list of SDL_DisplayIDs. It also offers the means to retrieve the SDL_DisplayID associated with an SDL_Window with SDL_GetDisplayForWindow() or to get the one of the primary display with SDL_GetPrimaryDispaly(). A dev can then use a graphical API like Vulkan to render and present to the display through use of a Surface created for a window on that display with SDL_Vulkan_CreateSurface(), which is an abstraction by itself. Other SDL functions to retrieve the display name, properties, boundaries, driver, etc. are also available. I think EGL isn't of any use for this abstraction, if I understood it correctly.

Nochtans, when combining the above functions with Vulkan functions such as vkEnumeratePhysicalDevices(), vkGetPhysicalDeviceProperties() and vkGetPhysicalDeviceProperties2() there is no possibility to find out what SDL_DisplayID is connected to what GPU. This is because any possible approach fails when multiple identical GPUs are present in a same system (and have the same name and features), which is mostly the case for the above mentioned application types. Users tend to stick to GPUs of a same type or vendor under a same driver. Only those ones can be used in a same Vulkan DeviceGroup by the way.

In Linux the Vulkan returned deviceID and vendorID or in Windows the LUIDs of Vulkan physical devices cannot be compared/matched with anything SDL returns to make a 100% map. As a consequences without SDL abstraction, no optimal GPU resource assignment is possible without using OS and/or underlying Windowing System (X11, Wayland, etc.) specific coding.

OS abstraction is SDL's strength and therefore i wrote this RFC because that is were, IMO, the above functionality belongs.

Possible Solution

On Windows DXGI adapter LUIDs can be retrieved which can be compared with the LUID's from Vulkan's physical devices.
On Linux Vulkan's VkPhysicalDevicePCIBusInfoPropertiesEXT() can be used to match with PCI Bus IDs of devices queried with libdrm. Then, X11 or Wayland functions or the RandR extension can get the output (monitor) information and associate it with DRM devices.
On Mac it will be APIs like CGDisplayIOServicePort or Metal System Trace that can be used for mapping displays to GPUs.

While I do not have in-depth knowledge of the SDL code, looking at SDL categories like SDL Video and SDL GPU I think there is even a good chance that the needed information or code is already available under the hood of SDL. I would suggest that a simple to use function is added that could be used even if the graphical API is not Vulkan.

void* SDL_GetDisplayGPU(SDL_DisplayID)

The function returns the unique identifier needed by the application/implementation devs to reference the GPU in terms of the graphical API they use. For Vulkan the void* would be a vkPhysicalDevice handle. The GPU is now associated with the SDL_DisplayID until the display is disconnected. When a display is connected it is the application/implementation that is responsible to call SDL_GetDisplayGPU() again and make whatever changes that are needed for GPU resource allocation/deallocation/reallocation.

For all devices where there is a one-to-one relation the returned void* might even be 0 to indicate that no mapping is needed and that the only SDL_DisplayID is mapped to the only GPU. This would allow to skip the abstraction code on mobiles (Android, iOS), Raspberry Pi, laptops, etc. and actually on all single monitor/single GPU configurations (which SDL can detect).

All the rest, like building Devices or DeviceGroups, remains the responsibility of the application/implementation developers too as it is not generic. It is now possible to find out what GPUs have no display monitor attached to it (even though they may support graphical queues) or to run the graphical pipelines on the GPU that has the target monitor. GPU resource allocation can be optimize.

Thank you for reading this and in all cases much success with your great library.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions