Added support for using the GPU renderer as an offscreen renderer

SDL_CreateGPURenderer() now allows passing in an existing GPU device and passing in a NULL window to create an offscreen renderer.

Also renamed SDL_SetRenderGPUState() to SDL_SetGPURenderState().
This commit is contained in:
Sam Lantinga
2025-10-01 14:36:56 -07:00
parent 9461db1ec8
commit a864dcac25
36 changed files with 2390 additions and 3981 deletions

View File

@@ -1240,7 +1240,7 @@ SDL3_0.0.0 {
SDL_GetDefaultTextureScaleMode;
SDL_CreateGPURenderState;
SDL_SetGPURenderStateFragmentUniforms;
SDL_SetRenderGPUState;
SDL_SetGPURenderState;
SDL_DestroyGPURenderState;
SDL_SetWindowProgressState;
SDL_SetWindowProgressValue;
@@ -1259,6 +1259,7 @@ SDL3_0.0.0 {
SDL_GetGPUTextureFormatFromPixelFormat;
SDL_SetTexturePalette;
SDL_GetTexturePalette;
SDL_GetGPURendererDevice;
# extra symbols go here (don't modify this line)
local: *;
};

View File

@@ -1265,7 +1265,7 @@
#define SDL_GetDefaultTextureScaleMode SDL_GetDefaultTextureScaleMode_REAL
#define SDL_CreateGPURenderState SDL_CreateGPURenderState_REAL
#define SDL_SetGPURenderStateFragmentUniforms SDL_SetGPURenderStateFragmentUniforms_REAL
#define SDL_SetRenderGPUState SDL_SetRenderGPUState_REAL
#define SDL_SetGPURenderState SDL_SetGPURenderState_REAL
#define SDL_DestroyGPURenderState SDL_DestroyGPURenderState_REAL
#define SDL_SetWindowProgressState SDL_SetWindowProgressState_REAL
#define SDL_SetWindowProgressValue SDL_SetWindowProgressValue_REAL
@@ -1285,3 +1285,4 @@
#define JNI_OnLoad JNI_OnLoad_REAL
#define SDL_SetTexturePalette SDL_SetTexturePalette_REAL
#define SDL_GetTexturePalette SDL_GetTexturePalette_REAL
#define SDL_GetGPURendererDevice SDL_GetGPURendererDevice_REAL

View File

@@ -1273,7 +1273,7 @@ SDL_DYNAPI_PROC(bool,SDL_SetDefaultTextureScaleMode,(SDL_Renderer *a,SDL_ScaleMo
SDL_DYNAPI_PROC(bool,SDL_GetDefaultTextureScaleMode,(SDL_Renderer *a,SDL_ScaleMode *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_GPURenderState*,SDL_CreateGPURenderState,(SDL_Renderer *a,SDL_GPURenderStateCreateInfo *b),(a,b),return)
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(bool,SDL_SetGPURenderState,(SDL_Renderer *a,SDL_GPURenderState *b),(a,b),return)
SDL_DYNAPI_PROC(void,SDL_DestroyGPURenderState,(SDL_GPURenderState *a),(a),)
SDL_DYNAPI_PROC(bool,SDL_SetWindowProgressState,(SDL_Window *a,SDL_ProgressState b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_SetWindowProgressValue,(SDL_Window *a,float b),(a,b),return)
@@ -1282,7 +1282,7 @@ 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_GetGPUDeviceProperties,(SDL_GPUDevice *a),(a),return)
SDL_DYNAPI_PROC(SDL_Renderer*,SDL_CreateGPURenderer,(SDL_Window *a,SDL_GPUShaderFormat b,SDL_GPUDevice **c),(a,b,c),return)
SDL_DYNAPI_PROC(SDL_Renderer*,SDL_CreateGPURenderer,(SDL_GPUDevice *a,SDL_Window *b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamPlanarData,(SDL_AudioStream *a,const void * const*b,int c,int d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_GetEventDescription,(const SDL_Event *a,char *b,int c),(a,b,c),return)
SDL_DYNAPI_PROC(bool,SDL_PutAudioStreamDataNoCopy,(SDL_AudioStream *a,const void *b,int c,SDL_AudioStreamDataCompleteCallback d,void *e),(a,b,c,d,e),return)
@@ -1293,3 +1293,4 @@ SDL_DYNAPI_PROC(SDL_GPUTextureFormat,SDL_GetGPUTextureFormatFromPixelFormat,(SDL
SDL_DYNAPI_PROC(Sint32,JNI_OnLoad,(JavaVM *a, void *b),(a,b),return)
SDL_DYNAPI_PROC(bool,SDL_SetTexturePalette,(SDL_Texture *a,SDL_Palette *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_Palette*,SDL_GetTexturePalette,(SDL_Texture *a),(a),return)
SDL_DYNAPI_PROC(SDL_GPUDevice*,SDL_GetGPURendererDevice,(SDL_Renderer *a),(a),return)

View File

@@ -1047,11 +1047,17 @@ SDL_Renderer *SDL_CreateRendererWithProperties(SDL_PropertiesID props)
const char *hint;
SDL_PropertiesID new_props;
CHECK_PARAM((!window && !surface) || (window && surface)) {
// The GPU renderer is the only one that can be created without a window or surface
CHECK_PARAM(!window && !surface && (!driver_name || SDL_strcmp(driver_name, SDL_GPU_RENDERER) != 0)) {
SDL_InvalidParamError("window");
return NULL;
}
CHECK_PARAM(window && surface) {
SDL_SetError("A renderer can't target both a window and surface");
return NULL;
}
CHECK_PARAM(window && SDL_WindowHasSurface(window)) {
SDL_SetError("Surface already associated with window");
return NULL;
@@ -1269,37 +1275,32 @@ SDL_Renderer *SDL_CreateRenderer(SDL_Window *window, const char *name)
return renderer;
}
SDL_Renderer *SDL_CreateGPURenderer(SDL_Window *window, SDL_GPUShaderFormat format_flags, SDL_GPUDevice **device)
SDL_Renderer *SDL_CreateGPURenderer(SDL_GPUDevice *device, SDL_Window *window)
{
CHECK_PARAM(!device) {
SDL_InvalidParamError("device");
return NULL;
}
*device = NULL;
SDL_Renderer *renderer;
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_GPU_DEVICE_POINTER, device);
SDL_SetPointerProperty(props, SDL_PROP_RENDERER_CREATE_WINDOW_POINTER, window);
if (format_flags & SDL_GPU_SHADERFORMAT_SPIRV) {
SDL_SetBooleanProperty(props, SDL_PROP_RENDERER_CREATE_GPU_SHADERS_SPIRV_BOOLEAN, true);
}
if (format_flags & SDL_GPU_SHADERFORMAT_DXIL) {
SDL_SetBooleanProperty(props, SDL_PROP_RENDERER_CREATE_GPU_SHADERS_DXIL_BOOLEAN, true);
}
if (format_flags & SDL_GPU_SHADERFORMAT_MSL) {
SDL_SetBooleanProperty(props, SDL_PROP_RENDERER_CREATE_GPU_SHADERS_MSL_BOOLEAN, true);
}
SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, "gpu");
SDL_SetStringProperty(props, SDL_PROP_RENDERER_CREATE_NAME_STRING, SDL_GPU_RENDERER);
renderer = SDL_CreateRendererWithProperties(props);
if (renderer) {
*device = (SDL_GPUDevice *)SDL_GetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_GPU_DEVICE_POINTER, NULL);
}
SDL_DestroyProperties(props);
return renderer;
}
SDL_GPUDevice *SDL_GetGPURendererDevice(SDL_Renderer *renderer)
{
CHECK_RENDERER_MAGIC(renderer, NULL);
SDL_GPUDevice *device = SDL_GetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_GPU_DEVICE_POINTER, NULL);
if (!device) {
SDL_SetError("Renderer isn't a GPU renderer");
return NULL;
}
return device;
}
SDL_Renderer *SDL_CreateSoftwareRenderer(SDL_Surface *surface)
{
#ifdef SDL_VIDEO_RENDER_SW
@@ -1365,8 +1366,8 @@ bool SDL_GetRenderOutputSize(SDL_Renderer *renderer, int *w, int *h)
} else if (renderer->window) {
return SDL_GetWindowSizeInPixels(renderer->window, w, h);
} else {
SDL_assert(!"This should never happen");
return SDL_SetError("Renderer doesn't support querying output size");
// We don't have any output size, this might be an offscreen-only renderer
return true;
}
}
@@ -5548,7 +5549,11 @@ bool SDL_RenderPresent(SDL_Renderer *renderer)
CHECK_RENDERER_MAGIC(renderer, false);
CHECK_PARAM(renderer->target) {
return SDL_SetError("You can't present on a render target");
if (!renderer->window && SDL_strcmp(renderer->name, SDL_GPU_RENDERER) == 0) {
// We're an offscreen renderer, we must submit the command queue
} else {
return SDL_SetError("You can't present on a render target");
}
}
if (renderer->transparent_window) {
@@ -6218,7 +6223,7 @@ bool SDL_SetGPURenderStateFragmentUniforms(SDL_GPURenderState *state, Uint32 slo
return true;
}
bool SDL_SetRenderGPUState(SDL_Renderer *renderer, SDL_GPURenderState *state)
bool SDL_SetGPURenderState(SDL_Renderer *renderer, SDL_GPURenderState *state)
{
CHECK_RENDERER_MAGIC(renderer, false);

View File

@@ -83,6 +83,7 @@ static const float INPUTTYPE_HDR10 = 3;
typedef struct GPU_RenderData
{
bool external_device;
SDL_GPUDevice *device;
GPU_Shaders shaders;
GPU_PipelineCache pipeline_cache;
@@ -1415,34 +1416,37 @@ static bool GPU_RenderPresent(SDL_Renderer *renderer)
{
GPU_RenderData *data = (GPU_RenderData *)renderer->internal;
SDL_GPUTexture *swapchain;
Uint32 swapchain_texture_width, swapchain_texture_height;
bool result = SDL_WaitAndAcquireGPUSwapchainTexture(data->state.command_buffer, renderer->window, &swapchain, &swapchain_texture_width, &swapchain_texture_height);
if (renderer->window) {
SDL_GPUTexture *swapchain;
Uint32 swapchain_texture_width, swapchain_texture_height;
bool result = SDL_WaitAndAcquireGPUSwapchainTexture(data->state.command_buffer, renderer->window, &swapchain, &swapchain_texture_width, &swapchain_texture_height);
if (!result) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to acquire swapchain texture: %s", SDL_GetError());
}
if (!result) {
SDL_LogError(SDL_LOG_CATEGORY_RENDER, "Failed to acquire swapchain texture: %s", SDL_GetError());
}
if (swapchain != NULL) {
SDL_GPUBlitInfo blit_info;
SDL_zero(blit_info);
if (swapchain != NULL) {
SDL_GPUBlitInfo blit_info;
SDL_zero(blit_info);
blit_info.source.texture = data->backbuffer.texture;
blit_info.source.w = data->backbuffer.width;
blit_info.source.h = data->backbuffer.height;
blit_info.destination.texture = swapchain;
blit_info.destination.w = swapchain_texture_width;
blit_info.destination.h = swapchain_texture_height;
blit_info.load_op = SDL_GPU_LOADOP_DONT_CARE;
blit_info.filter = SDL_GPU_FILTER_LINEAR;
blit_info.source.texture = data->backbuffer.texture;
blit_info.source.w = data->backbuffer.width;
blit_info.source.h = data->backbuffer.height;
blit_info.destination.texture = swapchain;
blit_info.destination.w = swapchain_texture_width;
blit_info.destination.h = swapchain_texture_height;
blit_info.load_op = SDL_GPU_LOADOP_DONT_CARE;
blit_info.filter = SDL_GPU_FILTER_LINEAR;
SDL_BlitGPUTexture(data->state.command_buffer, &blit_info);
SDL_BlitGPUTexture(data->state.command_buffer, &blit_info);
SDL_SubmitGPUCommandBuffer(data->state.command_buffer);
SDL_SubmitGPUCommandBuffer(data->state.command_buffer);
if (swapchain_texture_width != data->backbuffer.width || swapchain_texture_height != data->backbuffer.height) {
SDL_ReleaseGPUTexture(data->device, data->backbuffer.texture);
CreateBackbuffer(data, swapchain_texture_width, swapchain_texture_height, SDL_GetGPUSwapchainTextureFormat(data->device, renderer->window));
if (swapchain_texture_width != data->backbuffer.width || swapchain_texture_height != data->backbuffer.height) {
CreateBackbuffer(data, swapchain_texture_width, swapchain_texture_height, SDL_GetGPUSwapchainTextureFormat(data->device, renderer->window));
}
} else {
SDL_SubmitGPUCommandBuffer(data->state.command_buffer);
}
} else {
SDL_SubmitGPUCommandBuffer(data->state.command_buffer);
@@ -1486,7 +1490,7 @@ static void GPU_DestroyRenderer(SDL_Renderer *renderer)
}
if (data->state.command_buffer) {
SDL_SubmitGPUCommandBuffer(data->state.command_buffer);
SDL_CancelGPUCommandBuffer(data->state.command_buffer);
data->state.command_buffer = NULL;
}
@@ -1509,7 +1513,9 @@ static void GPU_DestroyRenderer(SDL_Renderer *renderer)
if (data->device) {
GPU_ReleaseShaders(&data->shaders, data->device);
SDL_DestroyGPUDevice(data->device);
if (!data->external_device) {
SDL_DestroyGPUDevice(data->device);
}
}
SDL_free(data);
@@ -1551,6 +1557,14 @@ static bool GPU_SetVSync(SDL_Renderer *renderer, const int vsync)
GPU_RenderData *data = (GPU_RenderData *)renderer->internal;
SDL_GPUPresentMode mode = SDL_GPU_PRESENTMODE_VSYNC;
if (!renderer->window) {
if (!vsync) {
return true;
} else {
return SDL_Unsupported();
}
}
if (!ChoosePresentMode(data->device, renderer->window, vsync, &mode)) {
return false;
}
@@ -1575,8 +1589,8 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
SDL_SetupRendererColorspace(renderer, create_props);
if (renderer->output_colorspace != SDL_COLORSPACE_SRGB &&
renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR &&
renderer->output_colorspace != SDL_COLORSPACE_HDR10) {
renderer->output_colorspace != SDL_COLORSPACE_SRGB_LINEAR
/*&& renderer->output_colorspace != SDL_COLORSPACE_HDR10*/) {
return SDL_SetError("Unsupported output colorspace");
}
@@ -1614,40 +1628,45 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
renderer->window = window;
renderer->name = GPU_RenderDriver.name;
bool debug = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, false);
bool lowpower = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, false);
data->device = SDL_GetPointerProperty(create_props, SDL_PROP_RENDERER_CREATE_GPU_DEVICE_POINTER, NULL);
if (data->device) {
data->external_device = true;
} else {
bool debug = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, false);
bool lowpower = SDL_GetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, false);
// Prefer environment variables/hints if they exist, otherwise defer to properties
debug = SDL_GetHintBoolean(SDL_HINT_RENDER_GPU_DEBUG, debug);
lowpower = SDL_GetHintBoolean(SDL_HINT_RENDER_GPU_LOW_POWER, lowpower);
// Prefer environment variables/hints if they exist, otherwise defer to properties
debug = SDL_GetHintBoolean(SDL_HINT_RENDER_GPU_DEBUG, debug);
lowpower = SDL_GetHintBoolean(SDL_HINT_RENDER_GPU_LOW_POWER, lowpower);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, debug);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, lowpower);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_DEBUGMODE_BOOLEAN, debug);
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_PREFERLOWPOWER_BOOLEAN, lowpower);
// Set hints for the greatest hardware compatibility
// This property allows using the renderer on Intel Haswell and Broadwell GPUs.
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN, true);
}
// These properties allow using the renderer on more Android devices.
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN, false);
}
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN, false);
}
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN, false);
}
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN, false);
}
// Set hints for the greatest hardware compatibility
// This property allows using the renderer on Intel Haswell and Broadwell GPUs.
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_D3D12_ALLOW_FEWER_RESOURCE_SLOTS_BOOLEAN, true);
}
// These properties allow using the renderer on more Android devices.
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_CLIP_DISTANCE_BOOLEAN, false);
}
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_DEPTH_CLAMPING_BOOLEAN, false);
}
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_INDIRECT_DRAW_FIRST_INSTANCE_BOOLEAN, false);
}
if (!SDL_HasProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN)) {
SDL_SetBooleanProperty(create_props, SDL_PROP_GPU_DEVICE_CREATE_FEATURE_ANISOTROPY_BOOLEAN, false);
}
GPU_FillSupportedShaderFormats(create_props);
data->device = SDL_CreateGPUDeviceWithProperties(create_props);
GPU_FillSupportedShaderFormats(create_props);
data->device = SDL_CreateGPUDeviceWithProperties(create_props);
if (!data->device) {
return false;
if (!data->device) {
return false;
}
}
if (!GPU_InitShaders(&data->shaders, data->device)) {
@@ -1663,31 +1682,40 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
return false;
}
if (!SDL_ClaimWindowForGPUDevice(data->device, window)) {
return false;
if (window) {
if (!SDL_ClaimWindowForGPUDevice(data->device, window)) {
return false;
}
switch (renderer->output_colorspace) {
case SDL_COLORSPACE_SRGB_LINEAR:
data->swapchain.composition = SDL_GPU_SWAPCHAINCOMPOSITION_HDR_EXTENDED_LINEAR;
break;
case SDL_COLORSPACE_HDR10:
data->swapchain.composition = SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2084;
break;
case SDL_COLORSPACE_SRGB:
default:
data->swapchain.composition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR;
break;
}
data->swapchain.present_mode = SDL_GPU_PRESENTMODE_VSYNC;
int vsync = (int)SDL_GetNumberProperty(create_props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 0);
ChoosePresentMode(data->device, window, vsync, &data->swapchain.present_mode);
SDL_SetGPUSwapchainParameters(data->device, window, data->swapchain.composition, data->swapchain.present_mode);
SDL_SetGPUAllowedFramesInFlight(data->device, 1);
int w, h;
SDL_GetWindowSizeInPixels(window, &w, &h);
if (!CreateBackbuffer(data, w, h, SDL_GetGPUSwapchainTextureFormat(data->device, window))) {
return false;
}
}
switch (renderer->output_colorspace) {
case SDL_COLORSPACE_SRGB_LINEAR:
data->swapchain.composition = SDL_GPU_SWAPCHAINCOMPOSITION_HDR_EXTENDED_LINEAR;
break;
case SDL_COLORSPACE_HDR10:
data->swapchain.composition = SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2084;
break;
case SDL_COLORSPACE_SRGB:
default:
data->swapchain.composition = SDL_GPU_SWAPCHAINCOMPOSITION_SDR;
break;
}
data->swapchain.present_mode = SDL_GPU_PRESENTMODE_VSYNC;
int vsync = (int)SDL_GetNumberProperty(create_props, SDL_PROP_RENDERER_CREATE_PRESENT_VSYNC_NUMBER, 0);
ChoosePresentMode(data->device, window, vsync, &data->swapchain.present_mode);
SDL_SetGPUSwapchainParameters(data->device, window, data->swapchain.composition, data->swapchain.present_mode);
SDL_SetGPUAllowedFramesInFlight(data->device, 1);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRA32);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_RGBA32);
SDL_AddSupportedTextureFormat(renderer, SDL_PIXELFORMAT_BGRX32);
@@ -1711,13 +1739,6 @@ static bool GPU_CreateRenderer(SDL_Renderer *renderer, SDL_Window *window, SDL_P
data->state.viewport.max_depth = 1;
data->state.command_buffer = SDL_AcquireGPUCommandBuffer(data->device);
int w, h;
SDL_GetWindowSizeInPixels(window, &w, &h);
if (!CreateBackbuffer(data, w, h, SDL_GetGPUSwapchainTextureFormat(data->device, window))) {
return false;
}
SDL_SetPointerProperty(SDL_GetRendererProperties(renderer), SDL_PROP_RENDERER_GPU_DEVICE_POINTER, data->device);
return true;