GPU: Binding validation and prevent null dereference if expected binding is missing (#13164)
Build (All) / Create test plan (push) Has been cancelled
Build (All) / level1 (push) Has been cancelled
Build (All) / level2 (push) Has been cancelled

This commit is contained in:
Evan Hemsley
2025-06-02 13:39:58 -07:00
committed by GitHub
parent cf6c42e6e6
commit fbba5b272a
5 changed files with 588 additions and 337 deletions
+208 -43
View File
@@ -93,10 +93,10 @@
} \
}
#define CHECK_GRAPHICS_PIPELINE_BOUND \
if (!((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->graphics_pipeline_bound) { \
SDL_assert_release(!"Graphics pipeline not bound!"); \
return; \
#define CHECK_GRAPHICS_PIPELINE_BOUND \
if (!((RenderPass *)render_pass)->graphics_pipeline) { \
SDL_assert_release(!"Graphics pipeline not bound!"); \
return; \
}
#define CHECK_COMPUTEPASS \
@@ -106,7 +106,7 @@
}
#define CHECK_COMPUTE_PIPELINE_BOUND \
if (!((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->compute_pipeline_bound) { \
if (!((ComputePass *)compute_pass)->compute_pipeline) { \
SDL_assert_release(!"Compute pipeline not bound!"); \
return; \
}
@@ -174,12 +174,18 @@
#define RENDERPASS_DEVICE \
((CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER)->device
#define RENDERPASS_BOUND_PIPELINE \
((RenderPass *)render_pass)->graphics_pipeline
#define COMPUTEPASS_COMMAND_BUFFER \
((Pass *)compute_pass)->command_buffer
#define COMPUTEPASS_DEVICE \
((CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER)->device
#define COMPUTEPASS_BOUND_PIPELINE \
((ComputePass *)compute_pass)->compute_pipeline
#define COPYPASS_COMMAND_BUFFER \
((Pass *)copy_pass)->command_buffer
@@ -511,6 +517,73 @@ void SDL_GPU_BlitCommon(
SDL_EndGPURenderPass(render_pass);
}
static void SDL_GPU_CheckGraphicsBindings(SDL_GPURenderPass *render_pass)
{
RenderPass *rp = (RenderPass *)render_pass;
GraphicsPipelineCommonHeader *pipeline = (GraphicsPipelineCommonHeader *)RENDERPASS_BOUND_PIPELINE;
for (Uint32 i = 0; i < pipeline->num_vertex_samplers; i += 1) {
if (!rp->vertex_sampler_bound[i]) {
SDL_assert_release(!"Missing vertex sampler binding!");
}
}
for (Uint32 i = 0; i < pipeline->num_vertex_storage_textures; i += 1) {
if (!rp->vertex_storage_texture_bound[i]) {
SDL_assert_release(!"Missing vertex storage texture binding!");
}
}
for (Uint32 i = 0; i < pipeline->num_vertex_storage_buffers; i += 1) {
if (!rp->vertex_storage_buffer_bound[i]) {
SDL_assert_release(!"Missing vertex storage buffer binding!");
}
}
for (Uint32 i = 0; i < pipeline->num_fragment_samplers; i += 1) {
if (!rp->fragment_sampler_bound[i]) {
SDL_assert_release(!"Missing fragment sampler binding!");
}
}
for (Uint32 i = 0; i < pipeline->num_fragment_storage_textures; i += 1) {
if (!rp->fragment_storage_texture_bound[i]) {
SDL_assert_release(!"Missing fragment storage texture binding!");
}
}
for (Uint32 i = 0; i < pipeline->num_fragment_storage_buffers; i += 1) {
if (!rp->fragment_storage_buffer_bound[i]) {
SDL_assert_release(!"Missing fragment storage buffer binding!");
}
}
}
static void SDL_GPU_CheckComputeBindings(SDL_GPUComputePass *compute_pass)
{
ComputePass *cp = (ComputePass *)compute_pass;
ComputePipelineCommonHeader *pipeline = (ComputePipelineCommonHeader *)COMPUTEPASS_BOUND_PIPELINE;
for (Uint32 i = 0; i < pipeline->numSamplers; i += 1) {
if (!cp->sampler_bound[i]) {
SDL_assert_release(!"Missing compute sampler binding!");
}
}
for (Uint32 i = 0; i < pipeline->numReadonlyStorageTextures; i += 1) {
if (!cp->read_only_storage_texture_bound[i]) {
SDL_assert_release(!"Missing compute readonly storage texture binding!");
}
}
for (Uint32 i = 0; i < pipeline->numReadonlyStorageBuffers; i += 1) {
if (!cp->read_only_storage_buffer_bound[i]) {
SDL_assert_release(!"Missing compute readonly storage buffer binding!");
}
}
for (Uint32 i = 0; i < pipeline->numReadWriteStorageTextures; i += 1) {
if (!cp->read_write_storage_texture_bound[i]) {
SDL_assert_release(!"Missing compute read-write storage texture binding!");
}
}
for (Uint32 i = 0; i < pipeline->numReadWriteStorageBuffers; i += 1) {
if (!cp->read_write_storage_buffer_bound[i]) {
SDL_assert_release(!"Missing compute read-write storage buffer bbinding!");
}
}
}
// Driver Functions
#ifndef SDL_GPU_DISABLED
@@ -1482,15 +1555,29 @@ SDL_GPUCommandBuffer *SDL_AcquireGPUCommandBuffer(
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
commandBufferHeader->device = device;
commandBufferHeader->render_pass.command_buffer = command_buffer;
commandBufferHeader->render_pass.in_progress = false;
commandBufferHeader->graphics_pipeline_bound = false;
commandBufferHeader->compute_pass.command_buffer = command_buffer;
commandBufferHeader->compute_pass.in_progress = false;
commandBufferHeader->compute_pipeline_bound = false;
commandBufferHeader->copy_pass.command_buffer = command_buffer;
commandBufferHeader->copy_pass.in_progress = false;
commandBufferHeader->swapchain_texture_acquired = false;
commandBufferHeader->submitted = false;
if (device->debug_mode) {
commandBufferHeader->render_pass.in_progress = false;
commandBufferHeader->render_pass.graphics_pipeline = NULL;
commandBufferHeader->compute_pass.in_progress = false;
commandBufferHeader->compute_pass.compute_pipeline = NULL;
commandBufferHeader->copy_pass.in_progress = false;
commandBufferHeader->swapchain_texture_acquired = false;
commandBufferHeader->submitted = false;
SDL_zeroa(commandBufferHeader->render_pass.vertex_sampler_bound);
SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_texture_bound);
SDL_zeroa(commandBufferHeader->render_pass.vertex_storage_buffer_bound);
SDL_zeroa(commandBufferHeader->render_pass.fragment_sampler_bound);
SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_texture_bound);
SDL_zeroa(commandBufferHeader->render_pass.fragment_storage_buffer_bound);
SDL_zeroa(commandBufferHeader->compute_pass.sampler_bound);
SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_texture_bound);
SDL_zeroa(commandBufferHeader->compute_pass.read_only_storage_buffer_bound);
SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_texture_bound);
SDL_zeroa(commandBufferHeader->compute_pass.read_write_storage_buffer_bound);
}
return command_buffer;
}
@@ -1681,14 +1768,18 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
depth_stencil_target_info);
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;
if (COMMAND_BUFFER_DEVICE->debug_mode) {
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);
}
@@ -1696,8 +1787,6 @@ void SDL_BindGPUGraphicsPipeline(
SDL_GPURenderPass *render_pass,
SDL_GPUGraphicsPipeline *graphics_pipeline)
{
CommandBufferCommonHeader *commandBufferHeader;
if (render_pass == NULL) {
SDL_InvalidParamError("render_pass");
return;
@@ -1711,8 +1800,10 @@ void SDL_BindGPUGraphicsPipeline(
RENDERPASS_COMMAND_BUFFER,
graphics_pipeline);
commandBufferHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
commandBufferHeader->graphics_pipeline_bound = true;
if (RENDERPASS_DEVICE->debug_mode) {
RENDERPASS_BOUND_PIPELINE = graphics_pipeline;
}
}
void SDL_SetGPUViewport(
@@ -1867,6 +1958,10 @@ void SDL_BindGPUVertexSamplers(
{
CHECK_SAMPLER_TEXTURES
}
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->vertex_sampler_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindVertexSamplers(
@@ -1894,6 +1989,10 @@ void SDL_BindGPUVertexStorageTextures(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_STORAGE_TEXTURES
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->vertex_storage_texture_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindVertexStorageTextures(
@@ -1920,6 +2019,10 @@ void SDL_BindGPUVertexStorageBuffers(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->vertex_storage_buffer_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindVertexStorageBuffers(
@@ -1947,10 +2050,13 @@ void SDL_BindGPUFragmentSamplers(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation)
{
if (!((CommandBufferCommonHeader*)RENDERPASS_COMMAND_BUFFER)->ignore_render_pass_texture_validation) {
CHECK_SAMPLER_TEXTURES
}
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->fragment_sampler_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindFragmentSamplers(
@@ -1978,6 +2084,10 @@ void SDL_BindGPUFragmentStorageTextures(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_STORAGE_TEXTURES
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->fragment_storage_texture_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindFragmentStorageTextures(
@@ -2004,6 +2114,10 @@ void SDL_BindGPUFragmentStorageBuffers(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
for (Uint32 i = 0; i < num_bindings; i += 1) {
((RenderPass *)render_pass)->fragment_storage_buffer_bound[first_slot + i] = true;
}
}
RENDERPASS_DEVICE->BindFragmentStorageBuffers(
@@ -2029,6 +2143,7 @@ void SDL_DrawGPUIndexedPrimitives(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_GRAPHICS_PIPELINE_BOUND
SDL_GPU_CheckGraphicsBindings(render_pass);
}
RENDERPASS_DEVICE->DrawIndexedPrimitives(
@@ -2055,6 +2170,7 @@ void SDL_DrawGPUPrimitives(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_GRAPHICS_PIPELINE_BOUND
SDL_GPU_CheckGraphicsBindings(render_pass);
}
RENDERPASS_DEVICE->DrawPrimitives(
@@ -2083,6 +2199,7 @@ void SDL_DrawGPUPrimitivesIndirect(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_GRAPHICS_PIPELINE_BOUND
SDL_GPU_CheckGraphicsBindings(render_pass);
}
RENDERPASS_DEVICE->DrawPrimitivesIndirect(
@@ -2110,6 +2227,7 @@ void SDL_DrawGPUIndexedPrimitivesIndirect(
if (RENDERPASS_DEVICE->debug_mode) {
CHECK_RENDERPASS
CHECK_GRAPHICS_PIPELINE_BOUND
SDL_GPU_CheckGraphicsBindings(render_pass);
}
RENDERPASS_DEVICE->DrawIndexedPrimitivesIndirect(
@@ -2123,6 +2241,7 @@ void SDL_EndGPURenderPass(
SDL_GPURenderPass *render_pass)
{
CommandBufferCommonHeader *commandBufferCommonHeader;
commandBufferCommonHeader = (CommandBufferCommonHeader *)RENDERPASS_COMMAND_BUFFER;
if (render_pass == NULL) {
SDL_InvalidParamError("render_pass");
@@ -2136,15 +2255,22 @@ void SDL_EndGPURenderPass(
RENDERPASS_DEVICE->EndRenderPass(
RENDERPASS_COMMAND_BUFFER);
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;
if (RENDERPASS_DEVICE->debug_mode) {
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->render_pass.graphics_pipeline = NULL;
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_sampler_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_texture_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.vertex_storage_buffer_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_sampler_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_texture_bound);
SDL_zeroa(commandBufferCommonHeader->render_pass.fragment_storage_buffer_bound);
}
commandBufferCommonHeader->render_pass.num_color_targets = 0;
commandBufferCommonHeader->render_pass.depth_stencil_target = NULL;
commandBufferCommonHeader->graphics_pipeline_bound = false;
}
// Compute Pass
@@ -2211,7 +2337,19 @@ SDL_GPUComputePass *SDL_BeginGPUComputePass(
num_storage_buffer_bindings);
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
commandBufferHeader->compute_pass.in_progress = true;
if (COMMAND_BUFFER_DEVICE->debug_mode) {
commandBufferHeader->compute_pass.in_progress = true;
for (Uint32 i = 0; i < num_storage_texture_bindings; i += 1) {
commandBufferHeader->compute_pass.read_write_storage_texture_bound[i] = true;
}
for (Uint32 i = 0; i < num_storage_buffer_bindings; i += 1) {
commandBufferHeader->compute_pass.read_write_storage_buffer_bound[i] = true;
}
}
return (SDL_GPUComputePass *)&(commandBufferHeader->compute_pass);
}
@@ -2219,8 +2357,6 @@ void SDL_BindGPUComputePipeline(
SDL_GPUComputePass *compute_pass,
SDL_GPUComputePipeline *compute_pipeline)
{
CommandBufferCommonHeader *commandBufferHeader;
if (compute_pass == NULL) {
SDL_InvalidParamError("compute_pass");
return;
@@ -2238,8 +2374,10 @@ void SDL_BindGPUComputePipeline(
COMPUTEPASS_COMMAND_BUFFER,
compute_pipeline);
commandBufferHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
commandBufferHeader->compute_pipeline_bound = true;
if (COMPUTEPASS_DEVICE->debug_mode) {
COMPUTEPASS_BOUND_PIPELINE = compute_pipeline;
}
}
void SDL_BindGPUComputeSamplers(
@@ -2259,6 +2397,10 @@ void SDL_BindGPUComputeSamplers(
if (COMPUTEPASS_DEVICE->debug_mode) {
CHECK_COMPUTEPASS
for (Uint32 i = 0; i < num_bindings; i += 1) {
((ComputePass *)compute_pass)->sampler_bound[first_slot + i] = true;
}
}
COMPUTEPASS_DEVICE->BindComputeSamplers(
@@ -2285,6 +2427,10 @@ void SDL_BindGPUComputeStorageTextures(
if (COMPUTEPASS_DEVICE->debug_mode) {
CHECK_COMPUTEPASS
for (Uint32 i = 0; i < num_bindings; i += 1) {
((ComputePass *)compute_pass)->read_only_storage_texture_bound[first_slot + i] = true;
}
}
COMPUTEPASS_DEVICE->BindComputeStorageTextures(
@@ -2311,6 +2457,10 @@ void SDL_BindGPUComputeStorageBuffers(
if (COMPUTEPASS_DEVICE->debug_mode) {
CHECK_COMPUTEPASS
for (Uint32 i = 0; i < num_bindings; i += 1) {
((ComputePass *)compute_pass)->read_only_storage_buffer_bound[first_slot + i] = true;
}
}
COMPUTEPASS_DEVICE->BindComputeStorageBuffers(
@@ -2334,6 +2484,7 @@ void SDL_DispatchGPUCompute(
if (COMPUTEPASS_DEVICE->debug_mode) {
CHECK_COMPUTEPASS
CHECK_COMPUTE_PIPELINE_BOUND
SDL_GPU_CheckComputeBindings(compute_pass);
}
COMPUTEPASS_DEVICE->DispatchCompute(
@@ -2356,6 +2507,7 @@ void SDL_DispatchGPUComputeIndirect(
if (COMPUTEPASS_DEVICE->debug_mode) {
CHECK_COMPUTEPASS
CHECK_COMPUTE_PIPELINE_BOUND
SDL_GPU_CheckComputeBindings(compute_pass);
}
COMPUTEPASS_DEVICE->DispatchComputeIndirect(
@@ -2381,9 +2533,16 @@ void SDL_EndGPUComputePass(
COMPUTEPASS_DEVICE->EndComputePass(
COMPUTEPASS_COMMAND_BUFFER);
commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
commandBufferCommonHeader->compute_pass.in_progress = false;
commandBufferCommonHeader->compute_pipeline_bound = false;
if (COMPUTEPASS_DEVICE->debug_mode) {
commandBufferCommonHeader = (CommandBufferCommonHeader *)COMPUTEPASS_COMMAND_BUFFER;
commandBufferCommonHeader->compute_pass.in_progress = false;
commandBufferCommonHeader->compute_pass.compute_pipeline = false;
SDL_zeroa(commandBufferCommonHeader->compute_pass.sampler_bound);
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_texture_bound);
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_only_storage_buffer_bound);
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_texture_bound);
SDL_zeroa(commandBufferCommonHeader->compute_pass.read_write_storage_buffer_bound);
}
}
// TransferBuffer Data
@@ -2441,7 +2600,11 @@ SDL_GPUCopyPass *SDL_BeginGPUCopyPass(
command_buffer);
commandBufferHeader = (CommandBufferCommonHeader *)command_buffer;
commandBufferHeader->copy_pass.in_progress = true;
if (COMMAND_BUFFER_DEVICE->debug_mode) {
commandBufferHeader->copy_pass.in_progress = true;
}
return (SDL_GPUCopyPass *)&(commandBufferHeader->copy_pass);
}
@@ -2699,7 +2862,9 @@ void SDL_EndGPUCopyPass(
COPYPASS_DEVICE->EndCopyPass(
COPYPASS_COMMAND_BUFFER);
((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false;
if (COPYPASS_DEVICE->debug_mode) {
((CommandBufferCommonHeader *)COPYPASS_COMMAND_BUFFER)->copy_pass.in_progress = false;
}
}
void SDL_GenerateMipmapsForGPUTexture(
+50 -3
View File
@@ -47,6 +47,20 @@ typedef struct Pass
bool in_progress;
} Pass;
typedef struct ComputePass
{
SDL_GPUCommandBuffer *command_buffer;
bool in_progress;
SDL_GPUComputePipeline *compute_pipeline;
bool sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
bool read_only_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
bool read_only_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
bool read_write_storage_texture_bound[MAX_COMPUTE_WRITE_TEXTURES];
bool read_write_storage_buffer_bound[MAX_COMPUTE_WRITE_BUFFERS];
} ComputePass;
typedef struct RenderPass
{
SDL_GPUCommandBuffer *command_buffer;
@@ -54,15 +68,25 @@ typedef struct RenderPass
SDL_GPUTexture *color_targets[MAX_COLOR_TARGET_BINDINGS];
Uint32 num_color_targets;
SDL_GPUTexture *depth_stencil_target;
SDL_GPUGraphicsPipeline *graphics_pipeline;
bool vertex_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
bool vertex_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
bool vertex_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
bool fragment_sampler_bound[MAX_TEXTURE_SAMPLERS_PER_STAGE];
bool fragment_storage_texture_bound[MAX_STORAGE_TEXTURES_PER_STAGE];
bool fragment_storage_buffer_bound[MAX_STORAGE_BUFFERS_PER_STAGE];
} RenderPass;
typedef struct CommandBufferCommonHeader
{
SDL_GPUDevice *device;
RenderPass render_pass;
bool graphics_pipeline_bound;
Pass compute_pass;
bool compute_pipeline_bound;
ComputePass compute_pass;
Pass copy_pass;
bool swapchain_texture_acquired;
bool submitted;
@@ -75,6 +99,29 @@ typedef struct TextureCommonHeader
SDL_GPUTextureCreateInfo info;
} TextureCommonHeader;
typedef struct GraphicsPipelineCommonHeader
{
Uint32 num_vertex_samplers;
Uint32 num_vertex_storage_textures;
Uint32 num_vertex_storage_buffers;
Uint32 num_vertex_uniform_buffers;
Uint32 num_fragment_samplers;
Uint32 num_fragment_storage_textures;
Uint32 num_fragment_storage_buffers;
Uint32 num_fragment_uniform_buffers;
} GraphicsPipelineCommonHeader;
typedef struct ComputePipelineCommonHeader
{
Uint32 numSamplers;
Uint32 numReadonlyStorageTextures;
Uint32 numReadonlyStorageBuffers;
Uint32 numReadWriteStorageTextures;
Uint32 numReadWriteStorageBuffers;
Uint32 numUniformBuffers;
} ComputePipelineCommonHeader;
typedef struct BlitFragmentUniforms
{
// texcoord space
File diff suppressed because it is too large Load Diff
+61 -73
View File
@@ -476,33 +476,21 @@ typedef struct MetalShader
typedef struct MetalGraphicsPipeline
{
GraphicsPipelineCommonHeader header;
id<MTLRenderPipelineState> handle;
SDL_GPURasterizerState rasterizerState;
SDL_GPUPrimitiveType primitiveType;
id<MTLDepthStencilState> depth_stencil_state;
Uint32 vertexSamplerCount;
Uint32 vertexUniformBufferCount;
Uint32 vertexStorageBufferCount;
Uint32 vertexStorageTextureCount;
Uint32 fragmentSamplerCount;
Uint32 fragmentUniformBufferCount;
Uint32 fragmentStorageBufferCount;
Uint32 fragmentStorageTextureCount;
} MetalGraphicsPipeline;
typedef struct MetalComputePipeline
{
ComputePipelineCommonHeader header;
id<MTLComputePipelineState> handle;
Uint32 numSamplers;
Uint32 numReadonlyStorageTextures;
Uint32 numReadWriteStorageTextures;
Uint32 numReadonlyStorageBuffers;
Uint32 numReadWriteStorageBuffers;
Uint32 numUniformBuffers;
Uint32 threadcountX;
Uint32 threadcountY;
Uint32 threadcountZ;
@@ -1085,12 +1073,12 @@ static SDL_GPUComputePipeline *METAL_CreateComputePipeline(
pipeline = SDL_calloc(1, sizeof(MetalComputePipeline));
pipeline->handle = handle;
pipeline->numSamplers = createinfo->num_samplers;
pipeline->numReadonlyStorageTextures = createinfo->num_readonly_storage_textures;
pipeline->numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures;
pipeline->numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers;
pipeline->numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers;
pipeline->numUniformBuffers = createinfo->num_uniform_buffers;
pipeline->header.numSamplers = createinfo->num_samplers;
pipeline->header.numReadonlyStorageTextures = createinfo->num_readonly_storage_textures;
pipeline->header.numReadWriteStorageTextures = createinfo->num_readwrite_storage_textures;
pipeline->header.numReadonlyStorageBuffers = createinfo->num_readonly_storage_buffers;
pipeline->header.numReadWriteStorageBuffers = createinfo->num_readwrite_storage_buffers;
pipeline->header.numUniformBuffers = createinfo->num_uniform_buffers;
pipeline->threadcountX = createinfo->threadcount_x;
pipeline->threadcountY = createinfo->threadcount_y;
pipeline->threadcountZ = createinfo->threadcount_z;
@@ -1234,14 +1222,14 @@ static SDL_GPUGraphicsPipeline *METAL_CreateGraphicsPipeline(
result->depth_stencil_state = depthStencilState;
result->rasterizerState = createinfo->rasterizer_state;
result->primitiveType = createinfo->primitive_type;
result->vertexSamplerCount = vertexShader->numSamplers;
result->vertexUniformBufferCount = vertexShader->numUniformBuffers;
result->vertexStorageBufferCount = vertexShader->numStorageBuffers;
result->vertexStorageTextureCount = vertexShader->numStorageTextures;
result->fragmentSamplerCount = fragmentShader->numSamplers;
result->fragmentUniformBufferCount = fragmentShader->numUniformBuffers;
result->fragmentStorageBufferCount = fragmentShader->numStorageBuffers;
result->fragmentStorageTextureCount = fragmentShader->numStorageTextures;
result->header.num_vertex_samplers = vertexShader->numSamplers;
result->header.num_vertex_uniform_buffers = vertexShader->numUniformBuffers;
result->header.num_vertex_storage_buffers = vertexShader->numStorageBuffers;
result->header.num_vertex_storage_textures = vertexShader->numStorageTextures;
result->header.num_fragment_samplers = fragmentShader->numSamplers;
result->header.num_fragment_uniform_buffers = fragmentShader->numUniformBuffers;
result->header.num_fragment_storage_buffers = fragmentShader->numStorageBuffers;
result->header.num_fragment_storage_textures = fragmentShader->numStorageTextures;
return (SDL_GPUGraphicsPipeline *)result;
}
}
@@ -2439,14 +2427,14 @@ static void METAL_BindGraphicsPipeline(
metalCommandBuffer->needFragmentUniformBufferBind[i] = true;
}
for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) {
for (i = 0; i < pipeline->header.num_vertex_uniform_buffers; i += 1) {
if (metalCommandBuffer->vertexUniformBuffers[i] == NULL) {
metalCommandBuffer->vertexUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
metalCommandBuffer);
}
}
for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) {
for (i = 0; i < pipeline->header.num_fragment_uniform_buffers; i += 1) {
if (metalCommandBuffer->fragmentUniformBuffers[i] == NULL) {
metalCommandBuffer->fragmentUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
metalCommandBuffer);
@@ -2677,11 +2665,11 @@ static void METAL_INTERNAL_BindGraphicsResources(
// Vertex Samplers+Textures
if (commandBuffer->needVertexSamplerBind) {
if (graphicsPipeline->vertexSamplerCount > 0) {
if (graphicsPipeline->header.num_vertex_samplers > 0) {
[commandBuffer->renderEncoder setVertexSamplerStates:commandBuffer->vertexSamplers
withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)];
withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)];
[commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexTextures
withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)];
withRange:NSMakeRange(0, graphicsPipeline->header.num_vertex_samplers)];
}
commandBuffer->needVertexSamplerBind = false;
}
@@ -2689,10 +2677,10 @@ static void METAL_INTERNAL_BindGraphicsResources(
// Vertex Storage Textures
if (commandBuffer->needVertexStorageTextureBind) {
if (graphicsPipeline->vertexStorageTextureCount > 0) {
if (graphicsPipeline->header.num_vertex_storage_textures > 0) {
[commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexStorageTextures
withRange:NSMakeRange(graphicsPipeline->vertexSamplerCount,
graphicsPipeline->vertexStorageTextureCount)];
withRange:NSMakeRange(graphicsPipeline->header.num_vertex_samplers,
graphicsPipeline->header.num_vertex_storage_textures)];
}
commandBuffer->needVertexStorageTextureBind = false;
}
@@ -2700,20 +2688,20 @@ static void METAL_INTERNAL_BindGraphicsResources(
// Vertex Storage Buffers
if (commandBuffer->needVertexStorageBufferBind) {
if (graphicsPipeline->vertexStorageBufferCount > 0) {
if (graphicsPipeline->header.num_vertex_storage_buffers > 0) {
[commandBuffer->renderEncoder setVertexBuffers:commandBuffer->vertexStorageBuffers
offsets:offsets
withRange:NSMakeRange(graphicsPipeline->vertexUniformBufferCount,
graphicsPipeline->vertexStorageBufferCount)];
withRange:NSMakeRange(graphicsPipeline->header.num_vertex_uniform_buffers,
graphicsPipeline->header.num_vertex_storage_buffers)];
}
commandBuffer->needVertexStorageBufferBind = false;
}
// Vertex Uniform Buffers
for (Uint32 i = 0; i < graphicsPipeline->vertexUniformBufferCount; i += 1) {
for (Uint32 i = 0; i < graphicsPipeline->header.num_vertex_uniform_buffers; i += 1) {
if (commandBuffer->needVertexUniformBufferBind[i]) {
if (graphicsPipeline->vertexUniformBufferCount > i) {
if (graphicsPipeline->header.num_vertex_uniform_buffers > i) {
[commandBuffer->renderEncoder
setVertexBuffer:commandBuffer->vertexUniformBuffers[i]->handle
offset:commandBuffer->vertexUniformBuffers[i]->drawOffset
@@ -2726,11 +2714,11 @@ static void METAL_INTERNAL_BindGraphicsResources(
// Fragment Samplers+Textures
if (commandBuffer->needFragmentSamplerBind) {
if (graphicsPipeline->fragmentSamplerCount > 0) {
if (graphicsPipeline->header.num_fragment_samplers > 0) {
[commandBuffer->renderEncoder setFragmentSamplerStates:commandBuffer->fragmentSamplers
withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)];
withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)];
[commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentTextures
withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)];
withRange:NSMakeRange(0, graphicsPipeline->header.num_fragment_samplers)];
}
commandBuffer->needFragmentSamplerBind = false;
}
@@ -2738,10 +2726,10 @@ static void METAL_INTERNAL_BindGraphicsResources(
// Fragment Storage Textures
if (commandBuffer->needFragmentStorageTextureBind) {
if (graphicsPipeline->fragmentStorageTextureCount > 0) {
if (graphicsPipeline->header.num_fragment_storage_textures > 0) {
[commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentStorageTextures
withRange:NSMakeRange(graphicsPipeline->fragmentSamplerCount,
graphicsPipeline->fragmentStorageTextureCount)];
withRange:NSMakeRange(graphicsPipeline->header.num_fragment_samplers,
graphicsPipeline->header.num_fragment_storage_textures)];
}
commandBuffer->needFragmentStorageTextureBind = false;
}
@@ -2749,20 +2737,20 @@ static void METAL_INTERNAL_BindGraphicsResources(
// Fragment Storage Buffers
if (commandBuffer->needFragmentStorageBufferBind) {
if (graphicsPipeline->fragmentStorageBufferCount > 0) {
if (graphicsPipeline->header.num_fragment_storage_buffers > 0) {
[commandBuffer->renderEncoder setFragmentBuffers:commandBuffer->fragmentStorageBuffers
offsets:offsets
withRange:NSMakeRange(graphicsPipeline->fragmentUniformBufferCount,
graphicsPipeline->fragmentStorageBufferCount)];
withRange:NSMakeRange(graphicsPipeline->header.num_fragment_uniform_buffers,
graphicsPipeline->header.num_fragment_storage_buffers)];
}
commandBuffer->needFragmentStorageBufferBind = false;
}
// Fragment Uniform Buffers
for (Uint32 i = 0; i < graphicsPipeline->fragmentUniformBufferCount; i += 1) {
for (Uint32 i = 0; i < graphicsPipeline->header.num_fragment_uniform_buffers; i += 1) {
if (commandBuffer->needFragmentUniformBufferBind[i]) {
if (graphicsPipeline->fragmentUniformBufferCount > i) {
if (graphicsPipeline->header.num_fragment_uniform_buffers > i) {
[commandBuffer->renderEncoder
setFragmentBuffer:commandBuffer->fragmentUniformBuffers[i]->handle
offset:commandBuffer->fragmentUniformBuffers[i]->drawOffset
@@ -2781,38 +2769,38 @@ static void METAL_INTERNAL_BindComputeResources(
NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 };
if (commandBuffer->needComputeSamplerBind) {
if (computePipeline->numSamplers > 0) {
if (computePipeline->header.numSamplers > 0) {
[commandBuffer->computeEncoder setTextures:commandBuffer->computeSamplerTextures
withRange:NSMakeRange(0, computePipeline->numSamplers)];
withRange:NSMakeRange(0, computePipeline->header.numSamplers)];
[commandBuffer->computeEncoder setSamplerStates:commandBuffer->computeSamplers
withRange:NSMakeRange(0, computePipeline->numSamplers)];
withRange:NSMakeRange(0, computePipeline->header.numSamplers)];
}
commandBuffer->needComputeSamplerBind = false;
}
if (commandBuffer->needComputeReadOnlyStorageTextureBind) {
if (computePipeline->numReadonlyStorageTextures > 0) {
if (computePipeline->header.numReadonlyStorageTextures > 0) {
[commandBuffer->computeEncoder setTextures:commandBuffer->computeReadOnlyTextures
withRange:NSMakeRange(
computePipeline->numSamplers,
computePipeline->numReadonlyStorageTextures)];
computePipeline->header.numSamplers,
computePipeline->header.numReadonlyStorageTextures)];
}
commandBuffer->needComputeReadOnlyStorageTextureBind = false;
}
if (commandBuffer->needComputeReadOnlyStorageBufferBind) {
if (computePipeline->numReadonlyStorageBuffers > 0) {
if (computePipeline->header.numReadonlyStorageBuffers > 0) {
[commandBuffer->computeEncoder setBuffers:commandBuffer->computeReadOnlyBuffers
offsets:offsets
withRange:NSMakeRange(computePipeline->numUniformBuffers,
computePipeline->numReadonlyStorageBuffers)];
withRange:NSMakeRange(computePipeline->header.numUniformBuffers,
computePipeline->header.numReadonlyStorageBuffers)];
}
commandBuffer->needComputeReadOnlyStorageBufferBind = false;
}
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
if (commandBuffer->needComputeUniformBufferBind[i]) {
if (computePipeline->numUniformBuffers > i) {
if (computePipeline->header.numUniformBuffers > i) {
[commandBuffer->computeEncoder
setBuffer:commandBuffer->computeUniformBuffers[i]->handle
offset:commandBuffer->computeUniformBuffers[i]->drawOffset
@@ -3160,7 +3148,7 @@ static void METAL_BindComputePipeline(
metalCommandBuffer->needComputeUniformBufferBind[i] = true;
}
for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) {
for (Uint32 i = 0; i < pipeline->header.numUniformBuffers; i += 1) {
if (metalCommandBuffer->computeUniformBuffers[i] == NULL) {
metalCommandBuffer->computeUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
metalCommandBuffer);
@@ -3168,22 +3156,22 @@ static void METAL_BindComputePipeline(
}
// Bind write-only resources
if (pipeline->numReadWriteStorageTextures > 0) {
if (pipeline->header.numReadWriteStorageTextures > 0) {
[metalCommandBuffer->computeEncoder setTextures:metalCommandBuffer->computeReadWriteTextures
withRange:NSMakeRange(
pipeline->numSamplers +
pipeline->numReadonlyStorageTextures,
pipeline->numReadWriteStorageTextures)];
pipeline->header.numSamplers +
pipeline->header.numReadonlyStorageTextures,
pipeline->header.numReadWriteStorageTextures)];
}
NSUInteger offsets[MAX_COMPUTE_WRITE_BUFFERS] = { 0 };
if (pipeline->numReadWriteStorageBuffers > 0) {
if (pipeline->header.numReadWriteStorageBuffers > 0) {
[metalCommandBuffer->computeEncoder setBuffers:metalCommandBuffer->computeReadWriteBuffers
offsets:offsets
withRange:NSMakeRange(
pipeline->numUniformBuffers +
pipeline->numReadonlyStorageBuffers,
pipeline->numReadWriteStorageBuffers)];
pipeline->header.numUniformBuffers +
pipeline->header.numReadonlyStorageBuffers,
pipeline->header.numReadWriteStorageBuffers)];
}
}
}
+111 -72
View File
@@ -793,13 +793,13 @@ typedef struct DescriptorSetLayout
typedef struct GraphicsPipelineResourceLayoutHashTableKey
{
Uint32 vertexSamplerCount;
Uint32 vertexStorageBufferCount;
Uint32 vertexStorageTextureCount;
Uint32 vertexStorageBufferCount;
Uint32 vertexUniformBufferCount;
Uint32 fragmentSamplerCount;
Uint32 fragmentStorageBufferCount;
Uint32 fragmentStorageTextureCount;
Uint32 fragmentStorageBufferCount;
Uint32 fragmentUniformBufferCount;
} GraphicsPipelineResourceLayoutHashTableKey;
@@ -817,18 +817,20 @@ typedef struct VulkanGraphicsPipelineResourceLayout
DescriptorSetLayout *descriptorSetLayouts[4];
Uint32 vertexSamplerCount;
Uint32 vertexStorageBufferCount;
Uint32 vertexStorageTextureCount;
Uint32 vertexStorageBufferCount;
Uint32 vertexUniformBufferCount;
Uint32 fragmentSamplerCount;
Uint32 fragmentStorageBufferCount;
Uint32 fragmentStorageTextureCount;
Uint32 fragmentStorageBufferCount;
Uint32 fragmentUniformBufferCount;
} VulkanGraphicsPipelineResourceLayout;
typedef struct VulkanGraphicsPipeline
{
GraphicsPipelineCommonHeader header;
VkPipeline pipeline;
SDL_GPUPrimitiveType primitiveType;
@@ -872,6 +874,8 @@ typedef struct VulkanComputePipelineResourceLayout
typedef struct VulkanComputePipeline
{
ComputePipelineCommonHeader header;
VkShaderModule shaderModule;
VkPipeline pipeline;
VulkanComputePipelineResourceLayout *resourceLayout;
@@ -1009,25 +1013,33 @@ typedef struct VulkanCommandBuffer
Uint32 vertexBufferCount;
bool needVertexBufferBind;
VulkanTexture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanSampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanTexture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
VulkanBuffer *vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
VkImageView vertexSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VkSampler vertexSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VkImageView vertexStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE];
VkBuffer vertexStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE];
VulkanTexture *fragmentSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanSampler *fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanTexture *fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
VulkanBuffer *fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
VkImageView fragmentSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VkSampler fragmentSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VkImageView fragmentStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE];
VkBuffer fragmentStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE];
VkImageView computeSamplerTextureViewBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VkSampler computeSamplerBindings[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VkImageView readOnlyComputeStorageTextureViewBindings[MAX_STORAGE_TEXTURES_PER_STAGE];
VkBuffer readOnlyComputeStorageBufferBindings[MAX_STORAGE_BUFFERS_PER_STAGE];
// Track these separately because barriers can happen mid compute pass
VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
VkImageView readWriteComputeStorageTextureViewBindings[MAX_COMPUTE_WRITE_TEXTURES];
VkBuffer readWriteComputeStorageBufferBindings[MAX_COMPUTE_WRITE_BUFFERS];
// Track these separately because they are barriered when the compute pass begins
VulkanTextureSubresource *readWriteComputeStorageTextureSubresources[MAX_COMPUTE_WRITE_TEXTURES];
Uint32 readWriteComputeStorageTextureSubresourceCount;
VulkanBuffer *readWriteComputeStorageBuffers[MAX_COMPUTE_WRITE_BUFFERS];
VulkanTexture *computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanSampler *computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanTexture *readOnlyComputeStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
VulkanBuffer *readOnlyComputeStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
// Uniform buffers
VulkanUniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
@@ -5103,8 +5115,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
currentWriteDescriptorSet->pTexelBufferView = NULL;
currentWriteDescriptorSet->pBufferInfo = NULL;
imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplers[i]->sampler;
imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextures[i]->fullView;
imageInfos[imageInfoCount].sampler = commandBuffer->vertexSamplerBindings[i];
imageInfos[imageInfoCount].imageView = commandBuffer->vertexSamplerTextureViewBindings[i];
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
@@ -5127,7 +5139,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
currentWriteDescriptorSet->pBufferInfo = NULL;
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextures[i]->fullView;
imageInfos[imageInfoCount].imageView = commandBuffer->vertexStorageTextureViewBindings[i];
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
@@ -5149,7 +5161,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
currentWriteDescriptorSet->pTexelBufferView = NULL;
currentWriteDescriptorSet->pImageInfo = NULL;
bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBuffers[i]->buffer;
bufferInfos[bufferInfoCount].buffer = commandBuffer->vertexStorageBufferBindings[i];
bufferInfos[bufferInfoCount].offset = 0;
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
@@ -5222,8 +5234,8 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
currentWriteDescriptorSet->pTexelBufferView = NULL;
currentWriteDescriptorSet->pBufferInfo = NULL;
imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplers[i]->sampler;
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextures[i]->fullView;
imageInfos[imageInfoCount].sampler = commandBuffer->fragmentSamplerBindings[i];
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentSamplerTextureViewBindings[i];
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
@@ -5246,7 +5258,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
currentWriteDescriptorSet->pBufferInfo = NULL;
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextures[i]->fullView;
imageInfos[imageInfoCount].imageView = commandBuffer->fragmentStorageTextureViewBindings[i];
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
@@ -5268,7 +5280,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
currentWriteDescriptorSet->pTexelBufferView = NULL;
currentWriteDescriptorSet->pImageInfo = NULL;
bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBuffers[i]->buffer;
bufferInfos[bufferInfoCount].buffer = commandBuffer->fragmentStorageBufferBindings[i];
bufferInfos[bufferInfoCount].offset = 0;
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
@@ -6541,6 +6553,16 @@ static SDL_GPUGraphicsPipeline *VULKAN_CreateGraphicsPipeline(
&nameInfo);
}
// Put this data in the pipeline we can do validation in gpu.c
graphicsPipeline->header.num_vertex_samplers = graphicsPipeline->resourceLayout->vertexSamplerCount;
graphicsPipeline->header.num_vertex_storage_buffers = graphicsPipeline->resourceLayout->vertexStorageBufferCount;
graphicsPipeline->header.num_vertex_storage_textures = graphicsPipeline->resourceLayout->vertexStorageTextureCount;
graphicsPipeline->header.num_vertex_uniform_buffers = graphicsPipeline->resourceLayout->vertexUniformBufferCount;
graphicsPipeline->header.num_fragment_samplers = graphicsPipeline->resourceLayout->fragmentSamplerCount;
graphicsPipeline->header.num_fragment_storage_buffers = graphicsPipeline->resourceLayout->fragmentStorageBufferCount;
graphicsPipeline->header.num_fragment_storage_textures = graphicsPipeline->resourceLayout->fragmentStorageTextureCount;
graphicsPipeline->header.num_fragment_uniform_buffers = graphicsPipeline->resourceLayout->fragmentUniformBufferCount;
return (SDL_GPUGraphicsPipeline *)graphicsPipeline;
}
@@ -6658,6 +6680,14 @@ static SDL_GPUComputePipeline *VULKAN_CreateComputePipeline(
&nameInfo);
}
// Track these here for debug layer
vulkanComputePipeline->header.numSamplers = vulkanComputePipeline->resourceLayout->numSamplers;
vulkanComputePipeline->header.numReadonlyStorageTextures = vulkanComputePipeline->resourceLayout->numReadonlyStorageTextures;
vulkanComputePipeline->header.numReadonlyStorageBuffers = vulkanComputePipeline->resourceLayout->numReadonlyStorageBuffers;
vulkanComputePipeline->header.numReadWriteStorageTextures = vulkanComputePipeline->resourceLayout->numReadWriteStorageTextures;
vulkanComputePipeline->header.numReadWriteStorageBuffers = vulkanComputePipeline->resourceLayout->numReadWriteStorageBuffers;
vulkanComputePipeline->header.numUniformBuffers = vulkanComputePipeline->resourceLayout->numUniformBuffers;
return (SDL_GPUComputePipeline *)vulkanComputePipeline;
}
@@ -7458,21 +7488,21 @@ static void VULKAN_BindVertexSamplers(
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
if (vulkanCommandBuffer->vertexSamplers[firstSlot + i] != sampler) {
if (vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] != sampler->sampler) {
VULKAN_INTERNAL_TrackSampler(
vulkanCommandBuffer,
(VulkanSampler *)textureSamplerBindings[i].sampler);
vulkanCommandBuffer->vertexSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
vulkanCommandBuffer->vertexSamplerBindings[firstSlot + i] = sampler->sampler;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
}
if (vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
if (vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer,
textureContainer->activeTexture);
vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->vertexSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
}
}
@@ -7489,12 +7519,12 @@ static void VULKAN_BindVertexStorageTextures(
for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i];
if (vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] != textureContainer->activeTexture) {
if (vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer,
textureContainer->activeTexture);
vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->vertexStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
}
}
@@ -7511,12 +7541,12 @@ static void VULKAN_BindVertexStorageBuffers(
for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanBufferContainer *bufferContainer = (VulkanBufferContainer *)storageBuffers[i];
if (vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) {
if (vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) {
VULKAN_INTERNAL_TrackBuffer(
vulkanCommandBuffer,
bufferContainer->activeBuffer);
vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
vulkanCommandBuffer->vertexStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
}
}
@@ -7534,21 +7564,21 @@ static void VULKAN_BindFragmentSamplers(
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
if (vulkanCommandBuffer->fragmentSamplers[firstSlot + i] != sampler) {
if (vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] != sampler->sampler) {
VULKAN_INTERNAL_TrackSampler(
vulkanCommandBuffer,
(VulkanSampler *)textureSamplerBindings[i].sampler);
vulkanCommandBuffer->fragmentSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
vulkanCommandBuffer->fragmentSamplerBindings[firstSlot + i] = sampler->sampler;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
}
if (vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
if (vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer,
textureContainer->activeTexture);
vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->fragmentSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
}
}
@@ -7565,12 +7595,12 @@ static void VULKAN_BindFragmentStorageTextures(
for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i];
if (vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] != textureContainer->activeTexture) {
if (vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer,
textureContainer->activeTexture);
vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->fragmentStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
}
}
@@ -7589,12 +7619,12 @@ static void VULKAN_BindFragmentStorageBuffers(
for (i = 0; i < numBindings; i += 1) {
bufferContainer = (VulkanBufferContainer *)storageBuffers[i];
if (vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) {
if (vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] != bufferContainer->activeBuffer->buffer) {
VULKAN_INTERNAL_TrackBuffer(
vulkanCommandBuffer,
bufferContainer->activeBuffer);
vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
vulkanCommandBuffer->fragmentStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
}
}
@@ -8107,15 +8137,15 @@ static void VULKAN_EndRenderPass(
SDL_zeroa(vulkanCommandBuffer->vertexBufferOffsets);
vulkanCommandBuffer->vertexBufferCount = 0;
SDL_zeroa(vulkanCommandBuffer->vertexSamplers);
SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextures);
SDL_zeroa(vulkanCommandBuffer->vertexStorageTextures);
SDL_zeroa(vulkanCommandBuffer->vertexStorageBuffers);
SDL_zeroa(vulkanCommandBuffer->vertexSamplerBindings);
SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextureViewBindings);
SDL_zeroa(vulkanCommandBuffer->vertexStorageTextureViewBindings);
SDL_zeroa(vulkanCommandBuffer->vertexStorageBufferBindings);
SDL_zeroa(vulkanCommandBuffer->fragmentSamplers);
SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextures);
SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextures);
SDL_zeroa(vulkanCommandBuffer->fragmentStorageBuffers);
SDL_zeroa(vulkanCommandBuffer->fragmentSamplerBindings);
SDL_zeroa(vulkanCommandBuffer->fragmentSamplerTextureViewBindings);
SDL_zeroa(vulkanCommandBuffer->fragmentStorageTextureViewBindings);
SDL_zeroa(vulkanCommandBuffer->fragmentStorageBufferBindings);
}
static void VULKAN_BeginComputePass(
@@ -8145,6 +8175,7 @@ static void VULKAN_BeginComputePass(
VULKAN_TEXTURE_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE);
vulkanCommandBuffer->readWriteComputeStorageTextureSubresources[i] = subresource;
vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings[i] = subresource->computeWriteView;
VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer,
@@ -8161,6 +8192,7 @@ static void VULKAN_BeginComputePass(
VULKAN_BUFFER_USAGE_MODE_COMPUTE_STORAGE_READ_WRITE);
vulkanCommandBuffer->readWriteComputeStorageBuffers[i] = buffer;
vulkanCommandBuffer->readWriteComputeStorageBufferBindings[i] = buffer->buffer;
VULKAN_INTERNAL_TrackBuffer(
vulkanCommandBuffer,
@@ -8212,21 +8244,21 @@ static void VULKAN_BindComputeSamplers(
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
if (vulkanCommandBuffer->computeSamplers[firstSlot + i] != sampler) {
if (vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] != sampler->sampler) {
VULKAN_INTERNAL_TrackSampler(
vulkanCommandBuffer,
sampler);
vulkanCommandBuffer->computeSamplers[firstSlot + i] = sampler;
vulkanCommandBuffer->computeSamplerBindings[firstSlot + i] = sampler->sampler;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
}
if (vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
if (vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] != textureContainer->activeTexture->fullView) {
VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer,
textureContainer->activeTexture);
vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->computeSamplerTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
}
}
@@ -8267,6 +8299,7 @@ static void VULKAN_BindComputeStorageTextures(
textureContainer->activeTexture);
vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->readOnlyComputeStorageTextureViewBindings[firstSlot + i] = textureContainer->activeTexture->fullView;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
}
}
@@ -8306,6 +8339,7 @@ static void VULKAN_BindComputeStorageBuffers(
bufferContainer->activeBuffer);
vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
vulkanCommandBuffer->readOnlyComputeStorageBufferBindings[firstSlot + i] = bufferContainer->activeBuffer->buffer;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
}
}
@@ -8380,8 +8414,8 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
currentWriteDescriptorSet->pTexelBufferView = NULL;
currentWriteDescriptorSet->pBufferInfo = NULL;
imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplers[i]->sampler;
imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextures[i]->fullView;
imageInfos[imageInfoCount].sampler = commandBuffer->computeSamplerBindings[i];
imageInfos[imageInfoCount].imageView = commandBuffer->computeSamplerTextureViewBindings[i];
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
@@ -8404,7 +8438,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
currentWriteDescriptorSet->pBufferInfo = NULL;
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextures[i]->fullView;
imageInfos[imageInfoCount].imageView = commandBuffer->readOnlyComputeStorageTextureViewBindings[i];
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
@@ -8426,7 +8460,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
currentWriteDescriptorSet->pTexelBufferView = NULL;
currentWriteDescriptorSet->pImageInfo = NULL;
bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBuffers[i]->buffer;
bufferInfos[bufferInfoCount].buffer = commandBuffer->readOnlyComputeStorageBufferBindings[i];
bufferInfos[bufferInfoCount].offset = 0;
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
@@ -8461,7 +8495,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
currentWriteDescriptorSet->pBufferInfo = NULL;
imageInfos[imageInfoCount].sampler = VK_NULL_HANDLE;
imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureSubresources[i]->computeWriteView;
imageInfos[imageInfoCount].imageView = commandBuffer->readWriteComputeStorageTextureViewBindings[i];
imageInfos[imageInfoCount].imageLayout = VK_IMAGE_LAYOUT_GENERAL;
currentWriteDescriptorSet->pImageInfo = &imageInfos[imageInfoCount];
@@ -8483,7 +8517,7 @@ static void VULKAN_INTERNAL_BindComputeDescriptorSets(
currentWriteDescriptorSet->pTexelBufferView = NULL;
currentWriteDescriptorSet->pImageInfo = NULL;
bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBuffers[i]->buffer;
bufferInfos[bufferInfoCount].buffer = commandBuffer->readWriteComputeStorageBufferBindings[i];
bufferInfos[bufferInfoCount].offset = 0;
bufferInfos[bufferInfoCount].range = VK_WHOLE_SIZE;
@@ -8650,9 +8684,12 @@ static void VULKAN_EndComputePass(
}
}
// we don't need a barrier because sampler state is always the default if sampler bit is set
SDL_zeroa(vulkanCommandBuffer->computeSamplerTextures);
SDL_zeroa(vulkanCommandBuffer->computeSamplers);
// we don't need a barrier for sampler resources because sampler state is always the default if sampler bit is set
SDL_zeroa(vulkanCommandBuffer->computeSamplerTextureViewBindings);
SDL_zeroa(vulkanCommandBuffer->computeSamplerBindings);
SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageTextureViewBindings);
SDL_zeroa(vulkanCommandBuffer->readWriteComputeStorageBufferBindings);
vulkanCommandBuffer->currentComputePipeline = NULL;
@@ -9518,21 +9555,23 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
SDL_zeroa(commandBuffer->vertexBufferOffsets);
commandBuffer->vertexBufferCount = 0;
SDL_zeroa(commandBuffer->vertexSamplerTextures);
SDL_zeroa(commandBuffer->vertexSamplers);
SDL_zeroa(commandBuffer->vertexStorageTextures);
SDL_zeroa(commandBuffer->vertexStorageBuffers);
SDL_zeroa(commandBuffer->vertexSamplerTextureViewBindings);
SDL_zeroa(commandBuffer->vertexSamplerBindings);
SDL_zeroa(commandBuffer->vertexStorageTextureViewBindings);
SDL_zeroa(commandBuffer->vertexStorageBufferBindings);
SDL_zeroa(commandBuffer->fragmentSamplerTextures);
SDL_zeroa(commandBuffer->fragmentSamplers);
SDL_zeroa(commandBuffer->fragmentStorageTextures);
SDL_zeroa(commandBuffer->fragmentStorageBuffers);
SDL_zeroa(commandBuffer->fragmentSamplerTextureViewBindings);
SDL_zeroa(commandBuffer->fragmentSamplerBindings);
SDL_zeroa(commandBuffer->fragmentStorageTextureViewBindings);
SDL_zeroa(commandBuffer->fragmentStorageBufferBindings);
SDL_zeroa(commandBuffer->readWriteComputeStorageTextureSubresources);
commandBuffer->readWriteComputeStorageTextureSubresourceCount = 0;
SDL_zeroa(commandBuffer->readWriteComputeStorageBuffers);
SDL_zeroa(commandBuffer->computeSamplerTextures);
SDL_zeroa(commandBuffer->computeSamplers);
SDL_zeroa(commandBuffer->computeSamplerTextureViewBindings);
SDL_zeroa(commandBuffer->computeSamplerBindings);
SDL_zeroa(commandBuffer->readOnlyComputeStorageTextureViewBindings);
SDL_zeroa(commandBuffer->readOnlyComputeStorageBufferBindings);
SDL_zeroa(commandBuffer->readOnlyComputeStorageTextures);
SDL_zeroa(commandBuffer->readOnlyComputeStorageBuffers);