mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-06 19:38:14 +00:00
GPU: Validate that textures are not bound for both read and write on render passes (#12925)
(cherry picked from commit a163257295
)
This commit is contained in:
@@ -56,11 +56,43 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define CHECK_RENDERPASS \
|
#define CHECK_RENDERPASS \
|
||||||
if (!((Pass *)render_pass)->in_progress) { \
|
if (!((RenderPass *)render_pass)->in_progress) { \
|
||||||
SDL_assert_release(!"Render pass not in progress!"); \
|
SDL_assert_release(!"Render pass not in progress!"); \
|
||||||
return; \
|
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 \
|
#define CHECK_GRAPHICS_PIPELINE_BOUND \
|
||||||
if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \
|
if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \
|
||||||
SDL_assert_release(!"Graphics pipeline not bound!"); \
|
SDL_assert_release(!"Graphics pipeline not bound!"); \
|
||||||
@@ -137,7 +169,7 @@
|
|||||||
((CommandBufferCommonHeader *)command_buffer)->device
|
((CommandBufferCommonHeader *)command_buffer)->device
|
||||||
|
|
||||||
#define RENDERPASS_COMMAND_BUFFER \
|
#define RENDERPASS_COMMAND_BUFFER \
|
||||||
((Pass *)render_pass)->command_buffer
|
((RenderPass *)render_pass)->command_buffer
|
||||||
|
|
||||||
#define RENDERPASS_DEVICE \
|
#define RENDERPASS_DEVICE \
|
||||||
((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device
|
((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device
|
||||||
@@ -1523,6 +1555,13 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
|
|||||||
|
|
||||||
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
|
||||||
commandBufferHeader->render_pass.in_progress = true;
|
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);
|
return (SDL_GPURenderPass *)&(commandBufferHeader->render_pass);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1696,6 +1735,7 @@ void SDL_BindGPUVertexSamplers(
|
|||||||
|
|
||||||
if (RENDERPASS_DEVICE->debug_mode) {
|
if (RENDERPASS_DEVICE->debug_mode) {
|
||||||
CHECK_RENDERPASS
|
CHECK_RENDERPASS
|
||||||
|
CHECK_SAMPLER_TEXTURES
|
||||||
}
|
}
|
||||||
|
|
||||||
RENDERPASS_DEVICE->BindVertexSamplers(
|
RENDERPASS_DEVICE->BindVertexSamplers(
|
||||||
@@ -1722,6 +1762,7 @@ void SDL_BindGPUVertexStorageTextures(
|
|||||||
|
|
||||||
if (RENDERPASS_DEVICE->debug_mode) {
|
if (RENDERPASS_DEVICE->debug_mode) {
|
||||||
CHECK_RENDERPASS
|
CHECK_RENDERPASS
|
||||||
|
CHECK_STORAGE_TEXTURES
|
||||||
}
|
}
|
||||||
|
|
||||||
RENDERPASS_DEVICE->BindVertexStorageTextures(
|
RENDERPASS_DEVICE->BindVertexStorageTextures(
|
||||||
@@ -1774,6 +1815,7 @@ void SDL_BindGPUFragmentSamplers(
|
|||||||
|
|
||||||
if (RENDERPASS_DEVICE->debug_mode) {
|
if (RENDERPASS_DEVICE->debug_mode) {
|
||||||
CHECK_RENDERPASS
|
CHECK_RENDERPASS
|
||||||
|
CHECK_SAMPLER_TEXTURES
|
||||||
}
|
}
|
||||||
|
|
||||||
RENDERPASS_DEVICE->BindFragmentSamplers(
|
RENDERPASS_DEVICE->BindFragmentSamplers(
|
||||||
@@ -1800,6 +1842,7 @@ void SDL_BindGPUFragmentStorageTextures(
|
|||||||
|
|
||||||
if (RENDERPASS_DEVICE->debug_mode) {
|
if (RENDERPASS_DEVICE->debug_mode) {
|
||||||
CHECK_RENDERPASS
|
CHECK_RENDERPASS
|
||||||
|
CHECK_STORAGE_TEXTURES
|
||||||
}
|
}
|
||||||
|
|
||||||
RENDERPASS_DEVICE->BindFragmentStorageTextures(
|
RENDERPASS_DEVICE->BindFragmentStorageTextures(
|
||||||
@@ -1960,6 +2003,12 @@ void SDL_EndGPURenderPass(
|
|||||||
|
|
||||||
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
|
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
|
||||||
commandBufferCommonHeader->render_pass.in_progress = false;
|
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;
|
commandBufferCommonHeader->graphics_pipeline_bound = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -24,6 +24,21 @@
|
|||||||
#ifndef SDL_GPU_DRIVER_H
|
#ifndef SDL_GPU_DRIVER_H
|
||||||
#define SDL_GPU_DRIVER_H
|
#define SDL_GPU_DRIVER_H
|
||||||
|
|
||||||
|
// GraphicsDevice Limits
|
||||||
|
|
||||||
|
#define MAX_TEXTURE_SAMPLERS_PER_STAGE 16
|
||||||
|
#define MAX_STORAGE_TEXTURES_PER_STAGE 8
|
||||||
|
#define MAX_STORAGE_BUFFERS_PER_STAGE 8
|
||||||
|
#define MAX_UNIFORM_BUFFERS_PER_STAGE 4
|
||||||
|
#define MAX_COMPUTE_WRITE_TEXTURES 8
|
||||||
|
#define MAX_COMPUTE_WRITE_BUFFERS 8
|
||||||
|
#define UNIFORM_BUFFER_SIZE 32768
|
||||||
|
#define MAX_VERTEX_BUFFERS 16
|
||||||
|
#define MAX_VERTEX_ATTRIBUTES 16
|
||||||
|
#define MAX_COLOR_TARGET_BINDINGS 4
|
||||||
|
#define MAX_PRESENT_COUNT 16
|
||||||
|
#define MAX_FRAMES_IN_FLIGHT 3
|
||||||
|
|
||||||
// Common Structs
|
// Common Structs
|
||||||
|
|
||||||
typedef struct Pass
|
typedef struct Pass
|
||||||
@@ -32,10 +47,19 @@ typedef struct Pass
|
|||||||
bool in_progress;
|
bool in_progress;
|
||||||
} Pass;
|
} Pass;
|
||||||
|
|
||||||
|
typedef struct RenderPass
|
||||||
|
{
|
||||||
|
SDL_GPUCommandBuffer *command_buffer;
|
||||||
|
bool in_progress;
|
||||||
|
SDL_GPUTexture *color_targets[MAX_COLOR_TARGET_BINDINGS];
|
||||||
|
Uint32 num_color_targets;
|
||||||
|
SDL_GPUTexture *depth_stencil_target;
|
||||||
|
} RenderPass;
|
||||||
|
|
||||||
typedef struct CommandBufferCommonHeader
|
typedef struct CommandBufferCommonHeader
|
||||||
{
|
{
|
||||||
SDL_GPUDevice *device;
|
SDL_GPUDevice *device;
|
||||||
Pass render_pass;
|
RenderPass render_pass;
|
||||||
bool graphics_pipeline_bound;
|
bool graphics_pipeline_bound;
|
||||||
Pass compute_pass;
|
Pass compute_pass;
|
||||||
bool compute_pipeline_bound;
|
bool compute_pipeline_bound;
|
||||||
@@ -385,21 +409,6 @@ static inline Uint32 BytesPerRow(
|
|||||||
return blocksPerRow * SDL_GPUTextureFormatTexelBlockSize(format);
|
return blocksPerRow * SDL_GPUTextureFormatTexelBlockSize(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// GraphicsDevice Limits
|
|
||||||
|
|
||||||
#define MAX_TEXTURE_SAMPLERS_PER_STAGE 16
|
|
||||||
#define MAX_STORAGE_TEXTURES_PER_STAGE 8
|
|
||||||
#define MAX_STORAGE_BUFFERS_PER_STAGE 8
|
|
||||||
#define MAX_UNIFORM_BUFFERS_PER_STAGE 4
|
|
||||||
#define MAX_COMPUTE_WRITE_TEXTURES 8
|
|
||||||
#define MAX_COMPUTE_WRITE_BUFFERS 8
|
|
||||||
#define UNIFORM_BUFFER_SIZE 32768
|
|
||||||
#define MAX_VERTEX_BUFFERS 16
|
|
||||||
#define MAX_VERTEX_ATTRIBUTES 16
|
|
||||||
#define MAX_COLOR_TARGET_BINDINGS 4
|
|
||||||
#define MAX_PRESENT_COUNT 16
|
|
||||||
#define MAX_FRAMES_IN_FLIGHT 3
|
|
||||||
|
|
||||||
// Internal Macros
|
// Internal Macros
|
||||||
|
|
||||||
#define EXPAND_ARRAY_IF_NEEDED(arr, elementType, newCount, capacity, newCapacity) \
|
#define EXPAND_ARRAY_IF_NEEDED(arr, elementType, newCount, capacity, newCapacity) \
|
||||||
|
Reference in New Issue
Block a user