From 0b6f993deac687394e69ad62e4ab82fd8019b49a Mon Sep 17 00:00:00 2001
From: Evan Hemsley <[EMAIL REDACTED]>
Date: Tue, 10 Sep 2024 18:17:08 -0700
Subject: [PATCH] GPU: Zero-init handling (#10786)
---
include/SDL3/SDL_gpu.h | 73 +++++++------
src/gpu/SDL_gpu.c | 151 +++++++++++++++++++++++++--
src/gpu/SDL_sysgpu.h | 11 +-
src/gpu/d3d11/SDL_gpu_d3d11.c | 45 +++++---
src/gpu/d3d12/SDL_gpu_d3d12.c | 37 +++++--
src/gpu/metal/SDL_gpu_metal.m | 34 ++++--
src/gpu/vulkan/SDL_gpu_vulkan.c | 34 ++++--
src/render/sdlgpu/SDL_pipeline_gpu.c | 2 +-
test/testgpu_spinning_cube.c | 11 +-
9 files changed, 310 insertions(+), 88 deletions(-)
diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h
index ffbc51a9692b7..e6dbdf52c7487 100644
--- a/include/SDL3/SDL_gpu.h
+++ b/include/SDL3/SDL_gpu.h
@@ -250,11 +250,11 @@ typedef struct SDL_GPUFence SDL_GPUFence;
*/
typedef enum SDL_GPUPrimitiveType
{
- SDL_GPU_PRIMITIVETYPE_POINTLIST, /**< A series of separate points. */
+ SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, /**< A series of separate triangles. */
+ SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP, /**< A series of connected triangles. */
SDL_GPU_PRIMITIVETYPE_LINELIST, /**< A series of separate lines. */
SDL_GPU_PRIMITIVETYPE_LINESTRIP, /**< A series of connected lines. */
- SDL_GPU_PRIMITIVETYPE_TRIANGLELIST, /**< A series of separate triangles. */
- SDL_GPU_PRIMITIVETYPE_TRIANGLESTRIP /**< A series of connected triangles. */
+ SDL_GPU_PRIMITIVETYPE_POINTLIST /**< A series of separate points. */
} SDL_GPUPrimitiveType;
/**
@@ -384,7 +384,7 @@ typedef enum SDL_GPUIndexElementSize
*/
typedef enum SDL_GPUTextureFormat
{
- SDL_GPU_TEXTUREFORMAT_INVALID = -1,
+ SDL_GPU_TEXTUREFORMAT_INVALID,
/* Unsigned Normalized Float Color Formats */
SDL_GPU_TEXTUREFORMAT_A8_UNORM,
@@ -586,12 +586,13 @@ typedef enum SDL_GPUShaderStage
*/
typedef Uint32 SDL_GPUShaderFormat;
-#define SDL_GPU_SHADERFORMAT_PRIVATE (1u << 0) /**< Shaders for NDA'd platforms. */
-#define SDL_GPU_SHADERFORMAT_SPIRV (1u << 1) /**< SPIR-V shaders for Vulkan. */
-#define SDL_GPU_SHADERFORMAT_DXBC (1u << 2) /**< DXBC SM5_0 shaders for D3D11. */
-#define SDL_GPU_SHADERFORMAT_DXIL (1u << 3) /**< DXIL shaders for D3D12. */
-#define SDL_GPU_SHADERFORMAT_MSL (1u << 4) /**< MSL shaders for Metal. */
-#define SDL_GPU_SHADERFORMAT_METALLIB (1u << 5) /**< Precompiled metallib shaders for Metal. */
+#define SDL_GPU_SHADERFORMAT_INVALID 0
+#define SDL_GPU_SHADERFORMAT_PRIVATE (1u << 1) /**< Shaders for NDA'd platforms. */
+#define SDL_GPU_SHADERFORMAT_SPIRV (1u << 2) /**< SPIR-V shaders for Vulkan. */
+#define SDL_GPU_SHADERFORMAT_DXBC (1u << 3) /**< DXBC SM5_0 shaders for D3D11. */
+#define SDL_GPU_SHADERFORMAT_DXIL (1u << 4) /**< DXIL shaders for D3D12. */
+#define SDL_GPU_SHADERFORMAT_MSL (1u << 5) /**< MSL shaders for Metal. */
+#define SDL_GPU_SHADERFORMAT_METALLIB (1u << 6) /**< Precompiled metallib shaders for Metal. */
/**
* Specifies the format of a vertex attribute.
@@ -602,6 +603,8 @@ typedef Uint32 SDL_GPUShaderFormat;
*/
typedef enum SDL_GPUVertexElementFormat
{
+ SDL_GPU_VERTEXELEMENTFORMAT_INVALID,
+
/* 32-bit Signed Integers */
SDL_GPU_VERTEXELEMENTFORMAT_INT,
SDL_GPU_VERTEXELEMENTFORMAT_INT2,
@@ -666,8 +669,8 @@ typedef enum SDL_GPUVertexElementFormat
*/
typedef enum SDL_GPUVertexInputRate
{
- SDL_GPU_VERTEXINPUTRATE_VERTEX = 0, /**< Attribute addressing is a function of the vertex index. */
- SDL_GPU_VERTEXINPUTRATE_INSTANCE = 1 /**< Attribute addressing is a function of the instance index. */
+ SDL_GPU_VERTEXINPUTRATE_VERTEX, /**< Attribute addressing is a function of the vertex index. */
+ SDL_GPU_VERTEXINPUTRATE_INSTANCE /**< Attribute addressing is a function of the instance index. */
} SDL_GPUVertexInputRate;
/**
@@ -720,6 +723,7 @@ typedef enum SDL_GPUFrontFace
*/
typedef enum SDL_GPUCompareOp
{
+ SDL_GPU_COMPAREOP_INVALID,
SDL_GPU_COMPAREOP_NEVER, /**< The comparison always evaluates false. */
SDL_GPU_COMPAREOP_LESS, /**< The comparison evaluates reference < test. */
SDL_GPU_COMPAREOP_EQUAL, /**< The comparison evaluates reference == test. */
@@ -740,6 +744,7 @@ typedef enum SDL_GPUCompareOp
*/
typedef enum SDL_GPUStencilOp
{
+ SDL_GPU_STENCILOP_INVALID,
SDL_GPU_STENCILOP_KEEP, /**< Keeps the current value. */
SDL_GPU_STENCILOP_ZERO, /**< Sets the value to 0. */
SDL_GPU_STENCILOP_REPLACE, /**< Sets the value to reference. */
@@ -763,6 +768,7 @@ typedef enum SDL_GPUStencilOp
*/
typedef enum SDL_GPUBlendOp
{
+ SDL_GPU_BLENDOP_INVALID,
SDL_GPU_BLENDOP_ADD, /**< (source * source_factor) + (destination * destination_factor) */
SDL_GPU_BLENDOP_SUBTRACT, /**< (source * source_factor) - (destination * destination_factor) */
SDL_GPU_BLENDOP_REVERSE_SUBTRACT, /**< (destination * destination_factor) - (source * source_factor) */
@@ -783,6 +789,7 @@ typedef enum SDL_GPUBlendOp
*/
typedef enum SDL_GPUBlendFactor
{
+ SDL_GPU_BLENDFACTOR_INVALID,
SDL_GPU_BLENDFACTOR_ZERO, /**< 0 */
SDL_GPU_BLENDFACTOR_ONE, /**< 1 */
SDL_GPU_BLENDFACTOR_SRC_COLOR, /**< source color */
@@ -933,7 +940,7 @@ typedef enum SDL_GPUSwapchainComposition
*/
typedef enum SDL_GPUDriver
{
- SDL_GPU_DRIVER_INVALID = -1,
+ SDL_GPU_DRIVER_INVALID,
SDL_GPU_DRIVER_PRIVATE, /* NDA'd platforms */
SDL_GPU_DRIVER_VULKAN,
SDL_GPU_DRIVER_D3D11,
@@ -1159,13 +1166,13 @@ typedef struct SDL_GPUSamplerCreateInfo
SDL_GPUSamplerAddressMode address_mode_w; /**< The addressing mode for W coordinates outside [0, 1). */
float mip_lod_bias; /**< The bias to be added to mipmap LOD calculation. */
float max_anisotropy; /**< The anisotropy value clamp used by the sampler. If enable_anisotropy is SDL_FALSE, this is ignored. */
+ SDL_GPUCompareOp compare_op; /**< The comparison operator to apply to fetched data before filtering. */
+ float min_lod; /**< Clamps the minimum of the computed LOD value. */
+ float max_lod; /**< Clamps the maximum of the computed LOD value. */
SDL_bool enable_anisotropy; /**< SDL_TRUE to enable anisotropic filtering. */
SDL_bool enable_compare; /**< SDL_TRUE to enable comparison against a reference value during lookups. */
Uint8 padding1;
Uint8 padding2;
- SDL_GPUCompareOp compare_op; /**< The comparison operator to apply to fetched data before filtering. */
- float min_lod; /**< Clamps the minimum of the computed LOD value. */
- float max_lod; /**< Clamps the maximum of the computed LOD value. */
SDL_PropertiesID props; /**< A properties ID for extensions. Should be 0 if no extensions are needed. */
} SDL_GPUSamplerCreateInfo;
@@ -1251,17 +1258,17 @@ typedef struct SDL_GPUStencilOpState
*/
typedef struct SDL_GPUColorTargetBlendState
{
- SDL_bool enable_blend; /**< Whether blending is enabled for the color target. */
- Uint8 padding1;
- Uint8 padding2;
- Uint8 padding3;
SDL_GPUBlendFactor src_color_blendfactor; /**< The value to be multiplied by the source RGB value. */
SDL_GPUBlendFactor dst_color_blendfactor; /**< The value to be multiplied by the destination RGB value. */
SDL_GPUBlendOp color_blend_op; /**< The blend operation for the RGB components. */
SDL_GPUBlendFactor src_alpha_blendfactor; /**< The value to be multiplied by the source alpha. */
SDL_GPUBlendFactor dst_alpha_blendfactor; /**< The value to be multiplied by the destination alpha. */
SDL_GPUBlendOp alpha_blend_op; /**< The blend operation for the alpha component. */
- SDL_GPUColorComponentFlags color_write_mask; /**< A bitmask specifying which of the RGBA components are enabled for writing. */
+ SDL_GPUColorComponentFlags color_write_mask; /**< A bitmask specifying which of the RGBA components are enabled for writing. Writes to all channels if enable_color_write_mask is SDL_FALSE. */
+ SDL_bool enable_blend; /**< Whether blending is enabled for the color target. */
+ SDL_bool enable_color_write_mask; /**< Whether the color write mask is enabled. */
+ Uint8 padding2;
+ Uint8 padding3;
} SDL_GPUColorTargetBlendState;
@@ -1367,13 +1374,13 @@ typedef struct SDL_GPURasterizerState
SDL_GPUFillMode fill_mode; /**< Whether polygons will be filled in or drawn as lines. */
SDL_GPUCullMode cull_mode; /**< The facing direction in which triangles will be culled. */
SDL_GPUFrontFace front_face; /**< The vertex winding that will cause a triangle to be determined as front-facing. */
+ float depth_bias_constant_factor; /**< A scalar factor controlling the depth value added to each fragment. */
+ float depth_bias_clamp; /**< The maximum depth bias of a fragment. */
+ float depth_bias_slope_factor; /**< A scalar factor applied to a fragment's slope in depth calculations. */
SDL_bool enable_depth_bias; /**< SDL_TRUE to bias fragment depth values. */
Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
- float depth_bias_constant_factor; /**< A scalar factor controlling the depth value added to each fragment. */
- float depth_bias_clamp; /**< The maximum depth bias of a fragment. */
- float depth_bias_slope_factor; /**< A scalar factor applied to a fragment's slope in depth calculations. */
} SDL_GPURasterizerState;
/**
@@ -1387,7 +1394,11 @@ typedef struct SDL_GPURasterizerState
typedef struct SDL_GPUMultisampleState
{
SDL_GPUSampleCount sample_count; /**< The number of samples to be used in rasterization. */
- Uint32 sample_mask; /**< Determines which samples get updated in the render targets. 0xFFFFFFFF is a reasonable default. */
+ Uint32 sample_mask; /**< Determines which samples get updated in the render targets. Treated as 0xFFFFFFFF if enable_mask is SDL_FALSE. */
+ SDL_bool enable_mask; /**< Enables sample masking. */
+ Uint8 padding1;
+ Uint8 padding2;
+ Uint8 padding3;
} SDL_GPUMultisampleState;
/**
@@ -1400,15 +1411,15 @@ typedef struct SDL_GPUMultisampleState
*/
typedef struct SDL_GPUDepthStencilState
{
- SDL_bool enable_depth_test; /**< SDL_TRUE enables the depth test. */
- SDL_bool enable_depth_write; /**< SDL_TRUE enables depth writes. Depth writes are always disabled when enable_depth_test is SDL_FALSE. */
- SDL_bool enable_stencil_test; /**< SDL_TRUE enables the stencil test. */
- Uint8 padding1;
SDL_GPUCompareOp compare_op; /**< The comparison operator used for depth testing. */
SDL_GPUStencilOpState back_stencil_state; /**< The stencil op state for back-facing triangles. */
SDL_GPUStencilOpState front_stencil_state; /**< The stencil op state for front-facing triangles. */
Uint8 compare_mask; /**< Selects the bits of the stencil values participating in the stencil test. */
Uint8 write_mask; /**< Selects the bits of the stencil values updated by the stencil test. */
+ SDL_bool enable_depth_test; /**< SDL_TRUE enables the depth test. */
+ SDL_bool enable_depth_write; /**< SDL_TRUE enables depth writes. Depth writes are always disabled when enable_depth_test is SDL_FALSE. */
+ SDL_bool enable_stencil_test; /**< SDL_TRUE enables the stencil test. */
+ Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
} SDL_GPUDepthStencilState;
@@ -1439,11 +1450,11 @@ typedef struct SDL_GpuGraphicsPipelineTargetInfo
{
const SDL_GPUColorTargetDescription *color_target_descriptions; /**< A pointer to an array of color target descriptions. */
Uint32 num_color_targets; /**< The number of color target descriptions in the above array. */
+ SDL_GPUTextureFormat depth_stencil_format; /**< The pixel format of the depth-stencil target. Ignored if has_depth_stencil_target is SDL_FALSE. */
SDL_bool has_depth_stencil_target; /**< SDL_TRUE specifies that the pipeline uses a depth-stencil target. */
Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
- SDL_GPUTextureFormat depth_stencil_format; /**< The pixel format of the depth-stencil target. Ignored if has_depth_stencil_target is SDL_FALSE. */
} SDL_GpuGraphicsPipelineTargetInfo;
/**
@@ -1601,7 +1612,7 @@ typedef struct SDL_GPUBlitInfo {
SDL_FlipMode flip_mode; /**< The flip mode for the source region. */
SDL_GPUFilter filter; /**< The filter mode used when blitting. */
SDL_bool cycle; /**< SDL_TRUE cycles the destination texture if it is already bound. */
- Uint8 padding;
+ Uint8 padding1;
Uint8 padding2;
Uint8 padding3;
} SDL_GPUBlitInfo;
diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c
index bfd94b68372ac..7e2396d92bab0 100644
--- a/src/gpu/SDL_gpu.c
+++ b/src/gpu/SDL_gpu.c
@@ -79,20 +79,50 @@
return; \
}
-#define CHECK_TEXTUREFORMAT_ENUM_INVALID(format, retval) \
- if (format >= SDL_GPU_TEXTUREFORMAT_MAX) { \
+#define CHECK_TEXTUREFORMAT_ENUM_INVALID(enumval, retval) \
+ if (enumval <= SDL_GPU_TEXTUREFORMAT_INVALID || enumval >= SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE) { \
SDL_assert_release(!"Invalid texture format enum!"); \
return retval; \
}
+#define CHECK_VERTEXELEMENTFORMAT_ENUM_INVALID(enumval, retval) \
+ if (enumval <= SDL_GPU_VERTEXELEMENTFORMAT_INVALID || enumval >= SDL_GPU_VERTEXELEMENTFORMAT_MAX_ENUM_VALUE) { \
+ SDL_assert_release(!"Invalid vertex format enum!"); \
+ return retval; \
+ }
+
+#define CHECK_COMPAREOP_ENUM_INVALID(enumval, retval) \
+ if (enumval <= SDL_GPU_COMPAREOP_INVALID || enumval >= SDL_GPU_COMPAREOP_MAX_ENUM_VALUE) { \
+ SDL_assert_release(!"Invalid compare op enum!"); \
+ return retval; \
+ }
+
+#define CHECK_STENCILOP_ENUM_INVALID(enumval, retval) \
+ if (enumval <= SDL_GPU_STENCILOP_INVALID || enumval >= SDL_GPU_STENCILOP_MAX_ENUM_VALUE) { \
+ SDL_assert_release(!"Invalid stencil op enum!"); \
+ return retval; \
+ }
+
+#define CHECK_BLENDOP_ENUM_INVALID(enumval, retval) \
+ if (enumval <= SDL_GPU_BLENDOP_INVALID || enumval >= SDL_GPU_BLENDOP_MAX_ENUM_VALUE) { \
+ SDL_assert_release(!"Invalid blend op enum!"); \
+ return retval; \
+ }
+
+#define CHECK_BLENDFACTOR_ENUM_INVALID(enumval, retval) \
+ if (enumval <= SDL_GPU_BLENDFACTOR_INVALID || enumval >= SDL_GPU_BLENDFACTOR_MAX_ENUM_VALUE) { \
+ SDL_assert_release(!"Invalid blend factor enum!"); \
+ return retval; \
+ }
+
#define CHECK_SWAPCHAINCOMPOSITION_ENUM_INVALID(enumval, retval) \
- if (enumval >= SDL_GPU_SWAPCHAINCOMPOSITION_MAX) { \
+ if (enumval < 0 || enumval >= SDL_GPU_SWAPCHAINCOMPOSITION_MAX_ENUM_VALUE) { \
SDL_assert_release(!"Invalid swapchain composition enum!"); \
return retval; \
}
#define CHECK_PRESENTMODE_ENUM_INVALID(enumval, retval) \
- if (enumval >= SDL_GPU_PRESENTMODE_MAX) { \
+ if (enumval < 0 || enumval >= SDL_GPU_PRESENTMODE_MAX_ENUM_VALUE) { \
SDL_assert_release(!"Invalid present mode enum!"); \
return retval; \
}
@@ -190,7 +220,7 @@ SDL_GPUGraphicsPipeline *SDL_GPU_FetchBlitPipeline(
}
blit_pipeline_create_info.multisample_state.sample_count = SDL_GPU_SAMPLECOUNT_1;
- blit_pipeline_create_info.multisample_state.sample_mask = 0xFFFFFFFF;
+ blit_pipeline_create_info.multisample_state.enable_mask = SDL_FALSE;
blit_pipeline_create_info.primitive_type = SDL_GPU_PRIMITIVETYPE_TRIANGLELIST;
@@ -590,11 +620,14 @@ SDL_GPUComputePipeline *SDL_CreateGPUComputePipeline(
}
if (device->debug_mode) {
+ if (createinfo->format == SDL_GPU_SHADERFORMAT_INVALID) {
+ SDL_assert_release(!"Shader format cannot be INVALID!");
+ return NULL;
+ }
if (!(createinfo->format & device->shader_formats)) {
SDL_assert_release(!"Incompatible shader format for GPU backend");
return NULL;
}
-
if (createinfo->num_writeonly_storage_textures > MAX_COMPUTE_WRITE_TEXTURES) {
SDL_assert_release(!"Compute pipeline write-only texture count cannot be higher than 8!");
return NULL;
@@ -627,12 +660,25 @@ SDL_GPUGraphicsPipeline *SDL_CreateGPUGraphicsPipeline(
}
if (device->debug_mode) {
+ if (graphicsPipelineCreateInfo->target_info.num_color_targets > 0 && graphicsPipelineCreateInfo->target_info.color_target_descriptions == NULL) {
+ SDL_assert_release(!"Color target descriptions array pointer cannot be NULL if num_color_targets is greater than zero!");
+ return NULL;
+ }
for (Uint32 i = 0; i < graphicsPipelineCreateInfo->target_info.num_color_targets; i += 1) {
CHECK_TEXTUREFORMAT_ENUM_INVALID(graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].format, NULL);
if (IsDepthFormat(graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].format)) {
SDL_assert_release(!"Color target formats cannot be a depth format!");
return NULL;
}
+ if (graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].blend_state.enable_blend) {
+ const SDL_GPUColorTargetBlendState *blend_state = &graphicsPipelineCreateInfo->target_info.color_target_descriptions[i].blend_state;
+ CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->src_color_blendfactor, NULL)
+ CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->dst_color_blendfactor, NULL)
+ CHECK_BLENDOP_ENUM_INVALID(blend_state->color_blend_op, NULL)
+ CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->src_alpha_blendfactor, NULL)
+ CHECK_BLENDFACTOR_ENUM_INVALID(blend_state->dst_alpha_blendfactor, NULL)
+ CHECK_BLENDOP_ENUM_INVALID(blend_state->alpha_blend_op, NULL)
+ }
}
if (graphicsPipelineCreateInfo->target_info.has_depth_stencil_target) {
CHECK_TEXTUREFORMAT_ENUM_INVALID(graphicsPipelineCreateInfo->target_info.depth_stencil_format, NULL);
@@ -641,6 +687,27 @@ SDL_GPUGraphicsPipeline *SDL_CreateGPUGraphicsPipeline(
return NULL;
}
}
+ if (graphicsPipelineCreateInfo->vertex_input_state.num_vertex_bindings > 0 && graphicsPipelineCreateInfo->vertex_input_state.vertex_bindings == NULL) {
+ SDL_assert_release(!"Vertex bindings array pointer cannot be NULL!");
+ return NULL;
+ }
+ if (graphicsPipelineCreateInfo->vertex_input_state.num_vertex_attributes > 0 && graphicsPipelineCreateInfo->vertex_input_state.vertex_attributes == NULL) {
+ SDL_assert_release(!"Vertex attributes array pointer cannot be NULL!");
+ return NULL;
+ }
+ for (Uint32 i = 0; i < graphicsPipelineCreateInfo->vertex_input_state.num_vertex_attributes; i += 1) {
+ CHECK_VERTEXELEMENTFORMAT_ENUM_INVALID(graphicsPipelineCreateInfo->vertex_input_state.vertex_attributes[i].format, NULL);
+ }
+ if (graphicsPipelineCreateInfo->depth_stencil_state.enable_depth_test) {
+ CHECK_COMPAREOP_ENUM_INVALID(graphicsPipelineCreateInfo->depth_stencil_state.compare_op, NULL)
+ }
+ if (graphicsPipelineCreateInfo->depth_stencil_state.enable_stencil_test) {
+ const SDL_GPUStencilOpState *stencil_state = &graphicsPipelineCreateInfo->depth_stencil_state.back_stencil_state;
+ CHECK_COMPAREOP_ENUM_INVALID(stencil_state->compare_op, NULL)
+ CHECK_STENCILOP_ENUM_INVALID(stencil_state->fail_op, NULL)
+ CHECK_STENCILOP_ENUM_INVALID(stencil_state->pass_op, NULL)
+ CHECK_STENCILOP_ENUM_INVALID(stencil_state->depth_fail_op, NULL)
+ }
}
return device->CreateGraphicsPipeline(
@@ -674,6 +741,10 @@ SDL_GPUShader *SDL_CreateGPUShader(
}
if (device->debug_mode) {
+ if (createinfo->format == SDL_GPU_SHADERFORMAT_INVALID) {
+ SDL_assert_release(!"Shader format cannot be INVALID!");
+ return NULL;
+ }
if (!(createinfo->format & device->shader_formats)) {
SDL_assert_release(!"Incompatible shader format for GPU backend");
return NULL;
@@ -1909,6 +1980,14 @@ void SDL_UploadToGPUTexture(
if (COPYPASS_DEVICE->debug_mode) {
CHECK_COPYPASS
+ if (source->transfer_buffer == NULL) {
+ SDL_assert_release(!"Source transfer buffer cannot be NULL!");
+ return;
+ }
+ if (destination->texture == NULL) {
+ SDL_assert_release(!"Destination texture cannot be NULL!");
+ return;
+ }
}
COPYPASS_DEVICE->UploadToTexture(
@@ -1937,6 +2016,18 @@ void SDL_UploadToGPUBuffer(
return;
}
+ if (COPYPASS_DEVICE->debug_mode) {
+ CHECK_COPYPASS
+ if (source->transfer_buffer == NULL) {
+ SDL_assert_release(!"Source transfer buffer cannot be NULL!");
+ return;
+ }
+ if (destination->buffer == NULL) {
+ SDL_assert_release(!"Destination buffer cannot be NULL!");
+ return;
+ }
+ }
+
COPYPASS_DEVICE->UploadToBuffer(
COPYPASS_COMMAND_BUFFER,
source,
@@ -1966,6 +2057,18 @@ void SDL_CopyGPUTextureToTexture(
return;
}
+ if (COPYPASS_DEVICE->debug_mode) {
+ CHECK_COPYPASS
+ if (source->texture == NULL) {
+ SDL_assert_release(!"Source texture cannot be NULL!");
+ return;
+ }
+ if (destination->texture == NULL) {
+ SDL_assert_release(!"Destination texture cannot be NULL!");
+ return;
+ }
+ }
+
COPYPASS_DEVICE->CopyTextureToTexture(
COPYPASS_COMMAND_BUFFER,
source,
@@ -1996,6 +2099,18 @@ void SDL_CopyGPUBufferToBuffer(
return;
}
+ if (COPYPASS_DEVICE->debug_mode) {
+ CHECK_COPYPASS
+ if (source->buffer == NULL) {
+ SDL_assert_release(!"Source buffer cannot be NULL!");
+ return;
+ }
+ if (destination->buffer == NULL) {
+ SDL_assert_release(!"Destination buffer cannot be NULL!");
+ return;
+ }
+ }
+
COPYPASS_DEVICE->CopyBufferToBuffer(
COPYPASS_COMMAND_BUFFER,
source,
@@ -2022,6 +2137,18 @@ void SDL_DownloadFromGPUTexture(
return;
}
+ if (COPYPASS_DEVICE->debug_mode) {
+ CHECK_COPYPASS
+ if (source->texture == NULL) {
+ SDL_assert_release(!"Source texture cannot be NULL!");
+ return;
+ }
+ if (destination->transfer_buffer == NULL) {
+ SDL_assert_release(!"Destination transfer buffer cannot be NULL!");
+ return;
+ }
+ }
+
COPYPASS_DEVICE->DownloadFromTexture(
COPYPASS_COMMAND_BUFFER,
source,
@@ -2046,6 +2173,18 @@ void SDL_DownloadFromGPUBuffer(
return;
}
+ if (COPYPASS_DEVICE->debug_mode) {
+ CHECK_COPYPASS
+ if (source->buffer == NULL) {
+ SDL_assert_release(!"Source buffer cannot be NULL!");
+ return;
+ }
+ if (destination->transfer_buffer == NULL) {
+ SDL_assert_release(!"Destination transfer buffer cannot be NULL!");
+ return;
+ }
+ }
+
COPYPASS_DEVICE->DownloadFromBuffer(
COPYPASS_COMMAND_BUFFER,
source,
diff --git a/src/gpu/SDL_sysgpu.h b/src/gpu/SDL_sysgpu.h
index 47a9653205350..1706071dc2082 100644
--- a/src/gpu/SDL_sysgpu.h
+++ b/src/gpu/SDL_sysgpu.h
@@ -69,9 +69,14 @@ typedef struct BlitPipelineCacheEntry
// Internal Helper Utilities
-#define SDL_GPU_TEXTUREFORMAT_MAX (SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT + 1)
-#define SDL_GPU_SWAPCHAINCOMPOSITION_MAX (SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2048 + 1)
-#define SDL_GPU_PRESENTMODE_MAX (SDL_GPU_PRESENTMODE_MAILBOX + 1)
+#define SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE (SDL_GPU_TEXTUREFORMAT_D32_FLOAT_S8_UINT + 1)
+#define SDL_GPU_VERTEXELEMENTFORMAT_MAX_ENUM_VALUE (SDL_GPU_VERTEXELEMENTFORMAT_HALF4 + 1)
+#define SDL_GPU_COMPAREOP_MAX_ENUM_VALUE (SDL_GPU_COMPAREOP_ALWAYS + 1)
+#define SDL_GPU_STENCILOP_MAX_ENUM_VALUE (SDL_GPU_STENCILOP_DECREMENT_AND_WRAP + 1)
+#define SDL_GPU_BLENDOP_MAX_ENUM_VALUE (SDL_GPU_BLENDOP_MAX + 1)
+#define SDL_GPU_BLENDFACTOR_MAX_ENUM_VALUE (SDL_GPU_BLENDFACTOR_SRC_ALPHA_SATURATE + 1)
+#define SDL_GPU_SWAPCHAINCOMPOSITION_MAX_ENUM_VALUE (SDL_GPU_SWAPCHAINCOMPOSITION_HDR10_ST2048 + 1)
+#define SDL_GPU_PRESENTMODE_MAX_ENUM_VALUE (SDL_GPU_PRESENTMODE_MAILBOX + 1)
static inline Sint32 Texture_GetBlockSize(
SDL_GPUTextureFormat format)
diff --git a/src/gpu/d3d11/SDL_gpu_d3d11.c b/src/gpu/d3d11/SDL_gpu_d3d11.c
index e2df614302544..711688ae3b635 100644
--- a/src/gpu/d3d11/SDL_gpu_d3d11.c
+++ b/src/gpu/d3d11/SDL_gpu_d3d11.c
@@ -168,6 +168,7 @@ static DXGI_COLOR_SPACE_TYPE SwapchainCompositionToColorSpace[] = {
};
static DXGI_FORMAT SDLToD3D11_TextureFormat[] = {
+ DXGI_FORMAT_UNKNOWN, // INVALID
DXGI_FORMAT_A8_UNORM, // A8_UNORM
DXGI_FORMAT_R8_UNORM, // R8_UNORM
DXGI_FORMAT_R8G8_UNORM, // R8G8_UNORM
@@ -225,9 +226,10 @@ static DXGI_FORMAT SDLToD3D11_TextureFormat[] = {
DXGI_FORMAT_D24_UNORM_S8_UINT, // D24_UNORM_S8_UINT
DXGI_FORMAT_D32_FLOAT_S8X24_UINT, // D32_FLOAT_S8_UINT
};
-SDL_COMPILE_TIME_ASSERT(SDLToD3D11_TextureFormat, SDL_arraysize(SDLToD3D11_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX);
+SDL_COMPILE_TIME_ASSERT(SDLToD3D11_TextureFormat, SDL_arraysize(SDLToD3D11_TextureFormat) == SDL_GPU_TEXTUREFORMAT_MAX_ENUM_VALUE);
static DXGI_FORMAT SDLToD3D11_VertexFormat[] = {
+ DXGI_FORMAT_UNKNOWN, // INVALID
DXGI_FORMAT_R32_SINT, // INT
DXGI_FORMAT_R32G32_SINT, // INT2
DXGI_FORMAT_R32G32B32_SINT, // INT3
@@ -259,6 +261,7 @@ static DXGI_FORMAT SDLToD3D11_VertexFormat[] = {
DXGI_FORMAT_R16G16_FLOAT, // HALF2
DXGI_FORMAT_R16G16B16A16_FLOAT // HALF4
};
+SDL_COMPILE_TIME_ASSERT(SDLToD3D11_VertexFormat, SDL_arraysize(SDLToD3D11_VertexFormat) == SDL_GPU_VERTEXELEMENTFORMAT_MAX_ENUM_VALUE);
static Uint32 SDLToD3D11_SampleCount[] = {
1, // SDL_GPU_SAMPLECOUNT_1
@@ -273,11 +276,11 @@ static DXGI_FORMAT SDLToD3D11_IndexType[] = {
};
static D3D11_PRIMITIVE_TOPOLOGY SDLToD3D11_PrimitiveType[] = {
- D3D_PRIMITIVE_TOPOLOGY_POINTLIST, // POINTLIST
- D3D_PRIMITIVE_TOPOLOGY_LINELIST, // LINELIST
- D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, // LINESTRIP
- D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // TRIANGLELIST
- D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP // TRIANGLESTRIP
+ D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST, // TRIANGLELIST
+ D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP, // TRIANGLESTRIP
+ D3D_PRIMITIVE_TOPOLOGY_LINELIST, // LINELIST
+ D3D_PRIMITIVE_TOPOLOGY_LINESTRIP, // LINESTRIP
+ D3D_PRIMITIVE_TOPOLOGY_POINTLIST // POINTLIST
};
static D3D11_CULL_MODE SDLToD3D11_CullMode[] = {
@@ -287,6 +290,7 @@ static D3D11_CULL_MODE SDLToD3D11_CullMode[] = {
};
static D3D11_BLEND SDLToD3D11_BlendFactor[] = {
+ D3D11_BLEND_ZERO, // INVALID
D3D11_BLEND_ZERO, // ZERO
D3D11_BLEND_ONE, // ONE
D3D11_BLEND_SRC_COLOR, // SRC_COLOR
@@ -301,8 +305,10 @@ static D3D11_BLEND SDLToD3D11_BlendFactor[] = {
D3D11_BLEND_INV_BLEND_FACTOR, // ONE_MINUS_CONSTANT_COLOR
D3D11_BLEND_SRC_ALPHA_SAT, // SRC_ALPHA_SATURATE
};
+SDL_COMPILE_TIME_ASSERT(SDLToD3D11_BlendFactor, SDL_arraysize(SDLToD3D11_BlendFactor) == SDL_GPU_BLENDFACTOR_MAX_ENUM_VALUE);
static D3D11_BLEND SDLToD3D11_BlendFactorAlpha[] = {
+ D3D11_BLEND_ZERO, // ALPHA
D3D11_BLEND_ZERO, // ZERO
D3D11_BLEND_ONE, // ONE
D3D11_BLEND_SRC_ALPHA, // SRC_COLOR
@@ -317,16 +323,20 @@ static D3D11_BLEND SDLToD3D11_BlendFactorAlpha[] = {
D3D11_BLEND_INV_BLEND_FACTOR, // ONE_MINUS_CONSTANT_COLOR
D3D11_BLEND_SRC_ALPHA_SAT, // SRC_ALPHA_SATURATE
};
+SDL_COMPILE_TIME_ASSERT(SDLToD3D11_BlendFactorAlpha, SDL_arraysize(SDLToD3D11_BlendFactorAlpha) == SDL_GPU_BLENDFACTOR_MAX_ENUM_VALUE);
static D3D11_BLEND_OP SDLToD3D11_BlendOp[] = {
+ D3D11_BLEND_OP_ADD, // INVALID
D3D11_BLEND_OP_ADD, // ADD
D3D11_BLEND_OP_SUBTRACT, // SUBTRACT
D3D11_BLEND_OP_REV_SUBTRACT, // REVERSE_SUBTRACT
D3D11_BLEND_OP_MIN, // MIN
D3D11_BLEND_OP_MAX // MAX
};
+SDL_COMPILE_TIME_ASSERT(SDLToD3D11_BlendOp, SDL_arraysize(SDLToD3D11_BlendOp) == SDL_GPU_BLENDOP_MAX_ENUM_VALUE);
static D3D11_COMPARISON_FUNC SDLToD3D11_CompareOp[] = {
+ D3D11_COMPARISON_NEVER, // INVALID
D3D11_COMPARISON_NEVER, // NEVER
D3D11_COMPARISON_LESS, // LESS
D3D11_COMPARISON_EQUAL, // EQUAL
@@ -336,8 +346,10 @@ static D3D11_COMPARISON_FUNC SDLToD3D11_CompareOp[] = {
D3D11_COMPARISON_GREATER_EQUAL, // GREATER_OR_EQUAL
D3D11_COMPARISON_ALWAYS // ALWAYS
};
+SDL_COMPILE_TIME_ASSERT(SDLToD3D11_CompareOp, SDL_arraysize(SDLToD3D11_CompareOp) == SDL_GPU_COMPAREOP_MAX_ENUM_VALUE);
static D3D11_STENCIL_OP SDLToD3D11_StencilOp[] = {
+ D3D11_STENCIL_OP_KEEP, // INVALID
D3D11_STENCIL_OP_KEEP, // KEEP
D3D11_STENCIL_OP_ZERO, // ZERO
D3D11_STENCIL_OP_REPLACE, // REPLACE
@@ -347,6 +359,7 @@ static D3D11_STENCIL_OP SDLToD3D11_StencilOp[] = {
D3D11_STENCIL_OP_INCR, // INCREMENT_AND_WRAP
D3D11_STENCIL_OP_DECR // DECREMENT_AND_WRAP
};
+SDL_COMPILE_TIME_ASSERT(SDLToD3D11_StencilOp, SDL_arraysize(SDLToD3D11_StencilOp) == SDL_GPU_STENCILOP_MAX_ENUM_VALUE);
static D3D11_INPUT_CLASSIFICATION SDLToD3D11_VertexInputRate[] = {
D3D11_INPUT_PER_VERTEX_DATA, // VERTEX
@@ -1
(Patch may be truncated, please check the link at the top of this post.)