GPU: Validate that textures are not bound for both read and write on render passes (#12925)

This commit is contained in:
Evan Hemsley
2025-04-29 16:52:52 -07:00
committed by GitHub
parent ea67133e4f
commit a163257295
2 changed files with 76 additions and 18 deletions

View File

@@ -56,11 +56,43 @@
}
#define CHECK_RENDERPASS \
if (!((Pass *)render_pass)->in_progress) { \
if (!((RenderPass *)render_pass)->in_progress) { \
SDL_assert_release(!"Render pass not in progress!"); \
return; \
}
#define CHECK_SAMPLER_TEXTURES \
RenderPass *rp = (RenderPass *)render_pass; \
for (Uint32 color_target_index = 0; color_target_index < rp->num_color_targets; color_target_index += 1) { \
for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \
if (rp->color_targets[color_target_index] == texture_sampler_bindings[texture_sampler_index].texture) { \
SDL_assert_release(!"Texture cannot be simultaneously bound as a color target and a sampler!"); \
} \
} \
} \
\
for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \
if (rp->depth_stencil_target != NULL && rp->depth_stencil_target == texture_sampler_bindings[texture_sampler_index].texture) { \
SDL_assert_release(!"Texture cannot be simultaneously bound as a depth stencil target and a sampler!"); \
} \
}
#define CHECK_STORAGE_TEXTURES \
RenderPass *rp = (RenderPass *)render_pass; \
for (Uint32 color_target_index = 0; color_target_index < rp->num_color_targets; color_target_index += 1) { \
for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \
if (rp->color_targets[color_target_index] == storage_textures[texture_sampler_index]) { \
SDL_assert_release(!"Texture cannot be simultaneously bound as a color target and a storage texture!"); \
} \
} \
} \
\
for (Uint32 texture_sampler_index = 0; texture_sampler_index < num_bindings; texture_sampler_index += 1) { \
if (rp->depth_stencil_target != NULL && rp->depth_stencil_target == storage_textures[texture_sampler_index]) { \
SDL_assert_release(!"Texture cannot be simultaneously bound as a depth stencil target and a storage texture!"); \
} \
}
#define CHECK_GRAPHICS_PIPELINE_BOUND \
if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \
SDL_assert_release(!"Graphics pipeline not bound!"); \
@@ -137,7 +169,7 @@
((CommandBufferCommonHeader *)command_buffer)->device
#define RENDERPASS_COMMAND_BUFFER \
((Pass *)render_pass)->command_buffer
((RenderPass *)render_pass)->command_buffer
#define RENDERPASS_DEVICE \
((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device
@@ -1544,6 +1576,13 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
commandBufferHeader->render_pass.in_progress = true;
for (Uint32 i = 0; i < num_color_targets; i += 1) {
commandBufferHeader->render_pass.color_targets[i] = color_target_infos[i].texture;
}
commandBufferHeader->render_pass.num_color_targets = num_color_targets;
if (depth_stencil_target_info != NULL) {
commandBufferHeader->render_pass.depth_stencil_target = depth_stencil_target_info->texture;
}
return (SDL_GPURenderPass *)&(commandBufferHeader->render_pass);
}
@@ -1717,6 +1756,7 @@ void SDL_BindGPUVertexSamplers(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_SAMPLER_TEXTURES
}
RENDERPASS_DEVICE->BindVertexSamplers(
@@ -1743,6 +1783,7 @@ void SDL_BindGPUVertexStorageTextures(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_STORAGE_TEXTURES
}
RENDERPASS_DEVICE->BindVertexStorageTextures(
@@ -1795,6 +1836,7 @@ void SDL_BindGPUFragmentSamplers(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_SAMPLER_TEXTURES
}
RENDERPASS_DEVICE->BindFragmentSamplers(
@@ -1821,6 +1863,7 @@ void SDL_BindGPUFragmentStorageTextures(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_STORAGE_TEXTURES
}
RENDERPASS_DEVICE->BindFragmentStorageTextures(
@@ -1981,6 +2024,12 @@ void SDL_EndGPURenderPass(
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
commandBufferCommonHeader->render_pass.in_progress = false;
for (Uint32 i = 0; i < MAX_COLOR_TARGET_BINDINGS; i += 1)
{
commandBufferCommonHeader->render_pass.color_targets[i] = NULL;
}
commandBufferCommonHeader->render_pass.num_color_targets = 0;
commandBufferCommonHeader->render_pass.depth_stencil_target = NULL;
commandBufferCommonHeader->graphics_pipeline_bound = false;
}