gpu: Add SDL_QueryGPUSupport

This commit is contained in:
Ethan Lee 2024-09-13 13:23:55 -04:00
parent 262ffa27e7
commit 0160e9eac6
5 changed files with 115 additions and 45 deletions

View File

@ -1675,6 +1675,36 @@ typedef struct SDL_GPUStorageTextureWriteOnlyBinding
/* Device */
/**
* Checks for GPU runtime support.
*
* \param format_flags a bitflag indicating which shader formats the app is
* able to provide.
* \param name the preferred GPU driver, or NULL to let SDL pick the optimal
* driver.
* \returns SDL_TRUE if supported, SDL_FALSE otherwise.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CreateGPUDevice
*/
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_QueryGPUSupport(
SDL_GPUShaderFormat format_flags,
const char *name);
/**
* Checks for GPU runtime support.
*
* \param props the properties to use.
* \returns SDL_TRUE if supported, SDL_FALSE otherwise.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_CreateGPUDeviceWithProperties
*/
extern SDL_DECLSPEC SDL_bool SDLCALL SDL_QueryGPUSupportWithProperties(
SDL_PropertiesID props);
/**
* Creates a GPU context.
*
@ -1690,6 +1720,7 @@ typedef struct SDL_GPUStorageTextureWriteOnlyBinding
* \sa SDL_GetGPUShaderFormats
* \sa SDL_GetGPUDeviceDriver
* \sa SDL_DestroyGPUDevice
* \sa SDL_QueryGPUSupport
*/
extern SDL_DECLSPEC SDL_GPUDevice *SDLCALL SDL_CreateGPUDevice(
SDL_GPUShaderFormat format_flags,
@ -1736,6 +1767,7 @@ extern SDL_DECLSPEC SDL_GPUDevice *SDLCALL SDL_CreateGPUDevice(
* \sa SDL_GetGPUShaderFormats
* \sa SDL_GetGPUDeviceDriver
* \sa SDL_DestroyGPUDevice
* \sa SDL_QueryGPUSupportWithProperties
*/
extern SDL_DECLSPEC SDL_GPUDevice *SDLCALL SDL_CreateGPUDeviceWithProperties(
SDL_PropertiesID props);

View File

@ -669,6 +669,8 @@ SDL3_0.0.0 {
SDL_PushGPUVertexUniformData;
SDL_PutAudioStreamData;
SDL_QueryGPUFence;
SDL_QueryGPUSupport;
SDL_QueryGPUSupportWithProperties;
SDL_Quit;
SDL_QuitSubSystem;
SDL_RaiseWindow;

View File

@ -694,6 +694,8 @@
#define SDL_PushGPUVertexUniformData SDL_PushGPUVertexUniformData_REAL
#define SDL_PutAudioStreamData SDL_PutAudioStreamData_REAL
#define SDL_QueryGPUFence SDL_QueryGPUFence_REAL
#define SDL_QueryGPUSupport SDL_QueryGPUSupport_REAL
#define SDL_QueryGPUSupportWithProperties SDL_QueryGPUSupportWithProperties_REAL
#define SDL_Quit SDL_Quit_REAL
#define SDL_QuitSubSystem SDL_QuitSubSystem_REAL
#define SDL_RaiseWindow SDL_RaiseWindow_REAL

View File

@ -705,6 +705,8 @@ SDL_DYNAPI_PROC(void,SDL_PushGPUFragmentUniformData,(SDL_GPUCommandBuffer *a, Ui
SDL_DYNAPI_PROC(void,SDL_PushGPUVertexUniformData,(SDL_GPUCommandBuffer *a, Uint32 b, const void *c, Uint32 d),(a,b,c,d),)
SDL_DYNAPI_PROC(SDL_bool,SDL_PutAudioStreamData,(SDL_AudioStream *a, const void *b, int c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_QueryGPUFence,(SDL_GPUDevice *a, SDL_GPUFence *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_QueryGPUSupport,(SDL_GPUShaderFormat a, const char *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_QueryGPUSupportWithProperties,(SDL_PropertiesID a),(a),return)
SDL_DYNAPI_PROC(void,SDL_Quit,(void),(),)
SDL_DYNAPI_PROC(void,SDL_QuitSubSystem,(SDL_InitFlags a),(a),)
SDL_DYNAPI_PROC(SDL_bool,SDL_RaiseWindow,(SDL_Window *a),(a),return)

View File

@ -371,12 +371,41 @@ void SDL_GPU_BlitCommon(
// Driver Functions
#ifndef SDL_GPU_DISABLED
static const SDL_GPUBootstrap * SDL_GPUSelectBackend(
SDL_VideoDevice *_this,
const char *gpudriver,
SDL_GPUShaderFormat format_flags)
static const SDL_GPUBootstrap * SDL_GPUSelectBackend(SDL_PropertiesID props)
{
Uint32 i;
SDL_GPUShaderFormat format_flags = 0;
const char *gpudriver;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (_this == NULL) {
SDL_SetError("Video subsystem not initialized");
return NULL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_PRIVATE;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_SPIRV;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_DXBC;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_DXIL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_MSL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_METALLIB;
}
gpudriver = SDL_GetHint(SDL_HINT_GPU_DRIVER);
if (gpudriver == NULL) {
gpudriver = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, NULL);
}
// Environment/Properties override...
if (gpudriver != NULL) {
@ -411,14 +440,12 @@ static const SDL_GPUBootstrap * SDL_GPUSelectBackend(
}
#endif // SDL_GPU_DISABLED
SDL_GPUDevice *SDL_CreateGPUDevice(
static void SDL_GPU_FillProperties(
SDL_PropertiesID props,
SDL_GPUShaderFormat format_flags,
SDL_bool debug_mode,
const char *name)
{
#ifndef SDL_GPU_DISABLED
SDL_GPUDevice *result;
SDL_PropertiesID props = SDL_CreateProperties();
if (format_flags & SDL_GPU_SHADERFORMAT_PRIVATE) {
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOL, true);
}
@ -439,6 +466,44 @@ SDL_GPUDevice *SDL_CreateGPUDevice(
}
SDL_SetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, debug_mode);
SDL_SetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, name);
}
SDL_bool SDL_QueryGPUSupport(
SDL_GPUShaderFormat format_flags,
const char *name)
{
#ifndef SDL_GPU_DISABLED
bool result;
SDL_PropertiesID props = SDL_CreateProperties();
SDL_GPU_FillProperties(props, format_flags, SDL_FALSE, name);
result = SDL_QueryGPUSupportWithProperties(props);
SDL_DestroyProperties(props);
return result;
#else
SDL_SetError("SDL not built with GPU support");
return SDL_FALSE;
#endif
}
SDL_bool SDL_QueryGPUSupportWithProperties(SDL_PropertiesID props)
{
#ifndef SDL_GPU_DISABLED
return (SDL_GPUSelectBackend(props) != NULL);
#else
SDL_SetError("SDL not built with GPU support");
return SDL_FALSE;
#endif
}
SDL_GPUDevice *SDL_CreateGPUDevice(
SDL_GPUShaderFormat format_flags,
SDL_bool debug_mode,
const char *name)
{
#ifndef SDL_GPU_DISABLED
SDL_GPUDevice *result;
SDL_PropertiesID props = SDL_CreateProperties();
SDL_GPU_FillProperties(props, format_flags, debug_mode, name);
result = SDL_CreateGPUDeviceWithProperties(props);
SDL_DestroyProperties(props);
return result;
@ -451,49 +516,16 @@ SDL_GPUDevice *SDL_CreateGPUDevice(
SDL_GPUDevice *SDL_CreateGPUDeviceWithProperties(SDL_PropertiesID props)
{
#ifndef SDL_GPU_DISABLED
SDL_GPUShaderFormat format_flags = 0;
bool debug_mode;
bool preferLowPower;
const char *gpudriver;
SDL_GPUDevice *result = NULL;
const SDL_GPUBootstrap *selectedBackend;
SDL_VideoDevice *_this = SDL_GetVideoDevice();
if (_this == NULL) {
SDL_SetError("Video subsystem not initialized");
return NULL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_PRIVATE_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_PRIVATE;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_SPIRV_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_SPIRV;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXBC_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_DXBC;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_DXIL_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_DXIL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_MSL_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_MSL;
}
if (SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_SHADERS_METALLIB_BOOL, false)) {
format_flags |= SDL_GPU_SHADERFORMAT_METALLIB;
}
debug_mode = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, true);
preferLowPower = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOL, false);
gpudriver = SDL_GetHint(SDL_HINT_GPU_DRIVER);
if (gpudriver == NULL) {
gpudriver = SDL_GetStringProperty(props, SDL_PROP_GPU_DEVICE_CREATE_NAME_STRING, NULL);
}
selectedBackend = SDL_GPUSelectBackend(_this, gpudriver, format_flags);
selectedBackend = SDL_GPUSelectBackend(props);
if (selectedBackend != NULL) {
debug_mode = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOL, true);
preferLowPower = SDL_GetBooleanProperty(props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOL, false);
result = selectedBackend->CreateDevice(debug_mode, preferLowPower, props);
if (result != NULL) {
result->backend = selectedBackend->name;