GPU: Resource binding state shadowing (#12138)

---------

Co-authored-by: Caleb Cornett <caleb.cornett@outlook.com>
This commit is contained in:
Evan Hemsley
2025-01-31 08:34:10 -08:00
committed by GitHub
parent 43924ec873
commit 8e766c9252
3 changed files with 560 additions and 415 deletions

View File

@@ -4552,15 +4552,18 @@ static void D3D12_BindVertexBuffers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
D3D12Buffer *currentBuffer = ((D3D12BufferContainer *)bindings[i].buffer)->activeBuffer; D3D12Buffer *currentBuffer = ((D3D12BufferContainer *)bindings[i].buffer)->activeBuffer;
if (d3d12CommandBuffer->vertexBuffers[firstSlot + i] != currentBuffer || d3d12CommandBuffer->vertexBufferOffsets[firstSlot + i] != bindings[i].offset) {
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, currentBuffer);
d3d12CommandBuffer->vertexBuffers[firstSlot + i] = currentBuffer; d3d12CommandBuffer->vertexBuffers[firstSlot + i] = currentBuffer;
d3d12CommandBuffer->vertexBufferOffsets[firstSlot + i] = bindings[i].offset; d3d12CommandBuffer->vertexBufferOffsets[firstSlot + i] = bindings[i].offset;
D3D12_INTERNAL_TrackBuffer(d3d12CommandBuffer, currentBuffer); d3d12CommandBuffer->needVertexBufferBind = true;
}
} }
d3d12CommandBuffer->vertexBufferCount = d3d12CommandBuffer->vertexBufferCount =
SDL_max(d3d12CommandBuffer->vertexBufferCount, firstSlot + numBindings); SDL_max(d3d12CommandBuffer->vertexBufferCount, firstSlot + numBindings);
d3d12CommandBuffer->needVertexBufferBind = true;
} }
static void D3D12_BindIndexBuffer( static void D3D12_BindIndexBuffer(
@@ -4596,20 +4599,25 @@ static void D3D12_BindVertexSamplers(
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
D3D12_INTERNAL_TrackTexture( if (d3d12CommandBuffer->vertexSamplers[firstSlot + i] != sampler) {
d3d12CommandBuffer,
container->activeTexture);
D3D12_INTERNAL_TrackSampler( D3D12_INTERNAL_TrackSampler(
d3d12CommandBuffer, d3d12CommandBuffer,
sampler); sampler);
d3d12CommandBuffer->vertexSamplers[firstSlot + i] = sampler; d3d12CommandBuffer->vertexSamplers[firstSlot + i] = sampler;
d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] = container->activeTexture; d3d12CommandBuffer->needVertexSamplerBind = true;
} }
if (d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] != container->activeTexture) {
D3D12_INTERNAL_TrackTexture(
d3d12CommandBuffer,
container->activeTexture);
d3d12CommandBuffer->vertexSamplerTextures[firstSlot + i] = container->activeTexture;
d3d12CommandBuffer->needVertexSamplerBind = true; d3d12CommandBuffer->needVertexSamplerBind = true;
} }
}
}
static void D3D12_BindVertexStorageTextures( static void D3D12_BindVertexStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -4623,13 +4631,14 @@ static void D3D12_BindVertexStorageTextures(
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i]; D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
D3D12Texture *texture = container->activeTexture; D3D12Texture *texture = container->activeTexture;
if (d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] != texture) {
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture); D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] = texture; d3d12CommandBuffer->vertexStorageTextures[firstSlot + i] = texture;
}
d3d12CommandBuffer->needVertexStorageTextureBind = true; d3d12CommandBuffer->needVertexStorageTextureBind = true;
} }
}
}
static void D3D12_BindVertexStorageBuffers( static void D3D12_BindVertexStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -4641,16 +4650,16 @@ static void D3D12_BindVertexStorageBuffers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i]; D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
if (d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] != container->activeBuffer) {
D3D12_INTERNAL_TrackBuffer( D3D12_INTERNAL_TrackBuffer(
d3d12CommandBuffer, d3d12CommandBuffer,
container->activeBuffer); container->activeBuffer);
d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] = container->activeBuffer; d3d12CommandBuffer->vertexStorageBuffers[firstSlot + i] = container->activeBuffer;
}
d3d12CommandBuffer->needVertexStorageBufferBind = true; d3d12CommandBuffer->needVertexStorageBufferBind = true;
} }
}
}
static void D3D12_BindFragmentSamplers( static void D3D12_BindFragmentSamplers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -4664,20 +4673,25 @@ static void D3D12_BindFragmentSamplers(
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler; D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
D3D12_INTERNAL_TrackTexture( if (d3d12CommandBuffer->fragmentSamplers[firstSlot + i] != sampler) {
d3d12CommandBuffer,
container->activeTexture);
D3D12_INTERNAL_TrackSampler( D3D12_INTERNAL_TrackSampler(
d3d12CommandBuffer, d3d12CommandBuffer,
sampler); sampler);
d3d12CommandBuffer->fragmentSamplers[firstSlot + i] = sampler; d3d12CommandBuffer->fragmentSamplers[firstSlot + i] = sampler;
d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] = container->activeTexture; d3d12CommandBuffer->needFragmentSamplerBind = true;
} }
if (d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] != container->activeTexture) {
D3D12_INTERNAL_TrackTexture(
d3d12CommandBuffer,
container->activeTexture);
d3d12CommandBuffer->fragmentSamplerTextures[firstSlot + i] = container->activeTexture;
d3d12CommandBuffer->needFragmentSamplerBind = true; d3d12CommandBuffer->needFragmentSamplerBind = true;
} }
}
}
static void D3D12_BindFragmentStorageTextures( static void D3D12_BindFragmentStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -4691,13 +4705,14 @@ static void D3D12_BindFragmentStorageTextures(
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i]; D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
D3D12Texture *texture = container->activeTexture; D3D12Texture *texture = container->activeTexture;
if (d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] != texture) {
D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture); D3D12_INTERNAL_TrackTexture(d3d12CommandBuffer, texture);
d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] = texture; d3d12CommandBuffer->fragmentStorageTextures[firstSlot + i] = texture;
}
d3d12CommandBuffer->needFragmentStorageTextureBind = true; d3d12CommandBuffer->needFragmentStorageTextureBind = true;
} }
}
}
static void D3D12_BindFragmentStorageBuffers( static void D3D12_BindFragmentStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -4710,15 +4725,16 @@ static void D3D12_BindFragmentStorageBuffers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i]; D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
if (d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] != container->activeBuffer) {
D3D12_INTERNAL_TrackBuffer( D3D12_INTERNAL_TrackBuffer(
d3d12CommandBuffer, d3d12CommandBuffer,
container->activeBuffer); container->activeBuffer);
d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] = container->activeBuffer; d3d12CommandBuffer->fragmentStorageBuffers[firstSlot + i] = container->activeBuffer;
}
d3d12CommandBuffer->needFragmentStorageBufferBind = true; d3d12CommandBuffer->needFragmentStorageBufferBind = true;
} }
}
}
static void D3D12_PushVertexUniformData( static void D3D12_PushVertexUniformData(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -5330,21 +5346,27 @@ static void D3D12_BindComputeSamplers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture; D3D12TextureContainer *container = (D3D12TextureContainer *)textureSamplerBindings[i].texture;
D3D12Sampler *sampler = (D3D12Sampler *)textureSamplerBindings[i].sampler;
if (d3d12CommandBuffer->computeSamplers[firstSlot + i] != sampler) {
D3D12_INTERNAL_TrackSampler( D3D12_INTERNAL_TrackSampler(
d3d12CommandBuffer, d3d12CommandBuffer,
(D3D12Sampler *)textureSamplerBindings[i].sampler); (D3D12Sampler *)textureSamplerBindings[i].sampler);
d3d12CommandBuffer->computeSamplers[firstSlot + i] = (D3D12Sampler *)textureSamplerBindings[i].sampler;
d3d12CommandBuffer->needComputeSamplerBind = true;
}
if (d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] != container->activeTexture) {
D3D12_INTERNAL_TrackTexture( D3D12_INTERNAL_TrackTexture(
d3d12CommandBuffer, d3d12CommandBuffer,
container->activeTexture); container->activeTexture);
d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] = container->activeTexture; d3d12CommandBuffer->computeSamplerTextures[firstSlot + i] = container->activeTexture;
d3d12CommandBuffer->computeSamplers[firstSlot + i] = (D3D12Sampler *)textureSamplerBindings[i].sampler;
}
d3d12CommandBuffer->needComputeSamplerBind = true; d3d12CommandBuffer->needComputeSamplerBind = true;
} }
}
}
static void D3D12_BindComputeStorageTextures( static void D3D12_BindComputeStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -5355,6 +5377,10 @@ static void D3D12_BindComputeStorageTextures(
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer; D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i];
if (d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] != container->activeTexture) {
/* If a different texture was in this slot, transition it back to its default usage */
if (d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] != NULL) { if (d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] != NULL) {
D3D12_INTERNAL_TextureTransitionToDefaultUsage( D3D12_INTERNAL_TextureTransitionToDefaultUsage(
d3d12CommandBuffer, d3d12CommandBuffer,
@@ -5362,9 +5388,7 @@ static void D3D12_BindComputeStorageTextures(
d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i]); d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i]);
} }
D3D12TextureContainer *container = (D3D12TextureContainer *)storageTextures[i]; /* Then transition the new texture and prepare it for binding */
d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] = container->activeTexture;
D3D12_INTERNAL_TextureTransitionFromDefaultUsage( D3D12_INTERNAL_TextureTransitionFromDefaultUsage(
d3d12CommandBuffer, d3d12CommandBuffer,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
@@ -5373,10 +5397,12 @@ static void D3D12_BindComputeStorageTextures(
D3D12_INTERNAL_TrackTexture( D3D12_INTERNAL_TrackTexture(
d3d12CommandBuffer, d3d12CommandBuffer,
container->activeTexture); container->activeTexture);
}
d3d12CommandBuffer->computeReadOnlyStorageTextures[firstSlot + i] = container->activeTexture;
d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true; d3d12CommandBuffer->needComputeReadOnlyStorageTextureBind = true;
} }
}
}
static void D3D12_BindComputeStorageBuffers( static void D3D12_BindComputeStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -5387,6 +5413,11 @@ static void D3D12_BindComputeStorageBuffers(
D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer; D3D12CommandBuffer *d3d12CommandBuffer = (D3D12CommandBuffer *)commandBuffer;
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i];
D3D12Buffer *buffer = container->activeBuffer;
if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] != buffer) {
/* If a different buffer was in this slot, transition it back to its default usage */
if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] != NULL) { if (d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] != NULL) {
D3D12_INTERNAL_BufferTransitionToDefaultUsage( D3D12_INTERNAL_BufferTransitionToDefaultUsage(
d3d12CommandBuffer, d3d12CommandBuffer,
@@ -5394,11 +5425,7 @@ static void D3D12_BindComputeStorageBuffers(
d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i]); d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i]);
} }
D3D12BufferContainer *container = (D3D12BufferContainer *)storageBuffers[i]; /* Then transition the new buffer and prepare it for binding */
D3D12Buffer *buffer = container->activeBuffer;
d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer;
D3D12_INTERNAL_BufferTransitionFromDefaultUsage( D3D12_INTERNAL_BufferTransitionFromDefaultUsage(
d3d12CommandBuffer, d3d12CommandBuffer,
D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE,
@@ -5407,10 +5434,12 @@ static void D3D12_BindComputeStorageBuffers(
D3D12_INTERNAL_TrackBuffer( D3D12_INTERNAL_TrackBuffer(
d3d12CommandBuffer, d3d12CommandBuffer,
buffer); buffer);
}
d3d12CommandBuffer->computeReadOnlyStorageBuffers[firstSlot + i] = buffer;
d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true; d3d12CommandBuffer->needComputeReadOnlyStorageBufferBind = true;
} }
}
}
static void D3D12_PushComputeUniformData( static void D3D12_PushComputeUniformData(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,

View File

@@ -567,30 +567,37 @@ typedef struct MetalCommandBuffer
MetalComputePipeline *compute_pipeline; MetalComputePipeline *compute_pipeline;
// Resource slot state // Resource slot state
bool needVertexBufferBind;
bool needVertexSamplerBind; bool needVertexSamplerBind;
bool needVertexStorageTextureBind; bool needVertexStorageTextureBind;
bool needVertexStorageBufferBind; bool needVertexStorageBufferBind;
bool needVertexUniformBind; bool needVertexUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
bool needFragmentSamplerBind; bool needFragmentSamplerBind;
bool needFragmentStorageTextureBind; bool needFragmentStorageTextureBind;
bool needFragmentStorageBufferBind; bool needFragmentStorageBufferBind;
bool needFragmentUniformBind; bool needFragmentUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
bool needComputeSamplerBind; bool needComputeSamplerBind;
bool needComputeTextureBind; bool needComputeReadOnlyStorageTextureBind;
bool needComputeBufferBind; bool needComputeReadOnlyStorageBufferBind;
bool needComputeUniformBind; bool needComputeUniformBufferBind[MAX_UNIFORM_BUFFERS_PER_STAGE];
id<MTLBuffer> vertexBuffers[MAX_VERTEX_BUFFERS];
Uint32 vertexBufferOffsets[MAX_VERTEX_BUFFERS];
Uint32 vertexBufferCount;
id<MTLSamplerState> vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; id<MTLSamplerState> vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
id<MTLTexture> vertexTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; id<MTLTexture> vertexTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
id<MTLTexture> vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; id<MTLTexture> vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
id<MTLBuffer> vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; id<MTLBuffer> vertexStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
MetalUniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
id<MTLSamplerState> fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; id<MTLSamplerState> fragmentSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
id<MTLTexture> fragmentTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; id<MTLTexture> fragmentTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
id<MTLTexture> fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; id<MTLTexture> fragmentStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
id<MTLBuffer> fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; id<MTLBuffer> fragmentStorageBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
MetalUniformBuffer *fragmentUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
id<MTLTexture> computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; id<MTLTexture> computeSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
id<MTLSamplerState> computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; id<MTLSamplerState> computeSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
@@ -598,10 +605,6 @@ typedef struct MetalCommandBuffer
id<MTLBuffer> computeReadOnlyBuffers[MAX_STORAGE_BUFFERS_PER_STAGE]; id<MTLBuffer> computeReadOnlyBuffers[MAX_STORAGE_BUFFERS_PER_STAGE];
id<MTLTexture> computeReadWriteTextures[MAX_COMPUTE_WRITE_TEXTURES]; id<MTLTexture> computeReadWriteTextures[MAX_COMPUTE_WRITE_TEXTURES];
id<MTLBuffer> computeReadWriteBuffers[MAX_COMPUTE_WRITE_BUFFERS]; id<MTLBuffer> computeReadWriteBuffers[MAX_COMPUTE_WRITE_BUFFERS];
// Uniform buffers
MetalUniformBuffer *vertexUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
MetalUniformBuffer *fragmentUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
MetalUniformBuffer *computeUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE]; MetalUniformBuffer *computeUniformBuffers[MAX_UNIFORM_BUFFERS_PER_STAGE];
MetalUniformBuffer **usedUniformBuffers; MetalUniformBuffer **usedUniformBuffers;
@@ -2130,20 +2133,6 @@ static SDL_GPUCommandBuffer *METAL_AcquireCommandBuffer(
commandBuffer->computeUniformBuffers[i] = NULL; commandBuffer->computeUniformBuffers[i] = NULL;
} }
// FIXME: Do we actually need to set this?
commandBuffer->needVertexSamplerBind = true;
commandBuffer->needVertexStorageTextureBind = true;
commandBuffer->needVertexStorageBufferBind = true;
commandBuffer->needVertexUniformBind = true;
commandBuffer->needFragmentSamplerBind = true;
commandBuffer->needFragmentStorageTextureBind = true;
commandBuffer->needFragmentStorageBufferBind = true;
commandBuffer->needFragmentUniformBind = true;
commandBuffer->needComputeSamplerBind = true;
commandBuffer->needComputeBufferBind = true;
commandBuffer->needComputeTextureBind = true;
commandBuffer->needComputeUniformBind = true;
commandBuffer->autoReleaseFence = true; commandBuffer->autoReleaseFence = true;
SDL_UnlockMutex(renderer->acquireCommandBufferLock); SDL_UnlockMutex(renderer->acquireCommandBufferLock);
@@ -2397,73 +2386,71 @@ static void METAL_BindGraphicsPipeline(
{ {
@autoreleasepool { @autoreleasepool {
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
MetalGraphicsPipeline *metalGraphicsPipeline = (MetalGraphicsPipeline *)graphicsPipeline; MetalGraphicsPipeline *pipeline = (MetalGraphicsPipeline *)graphicsPipeline;
SDL_GPURasterizerState *rast = &metalGraphicsPipeline->rasterizerState; SDL_GPURasterizerState *rast = &pipeline->rasterizerState;
Uint32 i;
metalCommandBuffer->graphics_pipeline = metalGraphicsPipeline; metalCommandBuffer->graphics_pipeline = pipeline;
[metalCommandBuffer->renderEncoder setRenderPipelineState:metalGraphicsPipeline->handle]; [metalCommandBuffer->renderEncoder setRenderPipelineState:pipeline->handle];
// Apply rasterizer state // Apply rasterizer state
[metalCommandBuffer->renderEncoder setTriangleFillMode:SDLToMetal_PolygonMode[metalGraphicsPipeline->rasterizerState.fill_mode]]; [metalCommandBuffer->renderEncoder setTriangleFillMode:SDLToMetal_PolygonMode[pipeline->rasterizerState.fill_mode]];
[metalCommandBuffer->renderEncoder setCullMode:SDLToMetal_CullMode[metalGraphicsPipeline->rasterizerState.cull_mode]]; [metalCommandBuffer->renderEncoder setCullMode:SDLToMetal_CullMode[pipeline->rasterizerState.cull_mode]];
[metalCommandBuffer->renderEncoder setFrontFacingWinding:SDLToMetal_FrontFace[metalGraphicsPipeline->rasterizerState.front_face]]; [metalCommandBuffer->renderEncoder setFrontFacingWinding:SDLToMetal_FrontFace[pipeline->rasterizerState.front_face]];
[metalCommandBuffer->renderEncoder setDepthClipMode:SDLToMetal_DepthClipMode(metalGraphicsPipeline->rasterizerState.enable_depth_clip)]; [metalCommandBuffer->renderEncoder setDepthClipMode:SDLToMetal_DepthClipMode(pipeline->rasterizerState.enable_depth_clip)];
[metalCommandBuffer->renderEncoder [metalCommandBuffer->renderEncoder
setDepthBias:((rast->enable_depth_bias) ? rast->depth_bias_constant_factor : 0) setDepthBias:((rast->enable_depth_bias) ? rast->depth_bias_constant_factor : 0)
slopeScale:((rast->enable_depth_bias) ? rast->depth_bias_slope_factor : 0) slopeScale:((rast->enable_depth_bias) ? rast->depth_bias_slope_factor : 0)
clamp:((rast->enable_depth_bias) ? rast->depth_bias_clamp : 0)]; clamp:((rast->enable_depth_bias) ? rast->depth_bias_clamp : 0)];
// Apply depth-stencil state // Apply depth-stencil state
if (metalGraphicsPipeline->depth_stencil_state != NULL) { if (pipeline->depth_stencil_state != NULL) {
[metalCommandBuffer->renderEncoder [metalCommandBuffer->renderEncoder
setDepthStencilState:metalGraphicsPipeline->depth_stencil_state]; setDepthStencilState:pipeline->depth_stencil_state];
} }
for (Uint32 i = 0; i < metalGraphicsPipeline->vertexUniformBufferCount; i += 1) { for (i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
metalCommandBuffer->needVertexUniformBufferBind[i] = true;
metalCommandBuffer->needFragmentUniformBufferBind[i] = true;
}
for (i = 0; i < pipeline->vertexUniformBufferCount; i += 1) {
if (metalCommandBuffer->vertexUniformBuffers[i] == NULL) { if (metalCommandBuffer->vertexUniformBuffers[i] == NULL) {
metalCommandBuffer->vertexUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer->vertexUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
metalCommandBuffer); metalCommandBuffer);
} }
} }
for (Uint32 i = 0; i < metalGraphicsPipeline->fragmentUniformBufferCount; i += 1) { for (i = 0; i < pipeline->fragmentUniformBufferCount; i += 1) {
if (metalCommandBuffer->fragmentUniformBuffers[i] == NULL) { if (metalCommandBuffer->fragmentUniformBuffers[i] == NULL) {
metalCommandBuffer->fragmentUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer->fragmentUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
metalCommandBuffer); metalCommandBuffer);
} }
} }
metalCommandBuffer->needVertexUniformBind = true;
metalCommandBuffer->needFragmentUniformBind = true;
} }
} }
static void METAL_BindVertexBuffers( static void METAL_BindVertexBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
Uint32 firstBinding, Uint32 firstSlot,
const SDL_GPUBufferBinding *bindings, const SDL_GPUBufferBinding *bindings,
Uint32 numBindings) Uint32 numBindings)
{ {
@autoreleasepool {
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
id<MTLBuffer> metalBuffers[MAX_VERTEX_BUFFERS];
NSUInteger bufferOffsets[MAX_VERTEX_BUFFERS];
NSRange range = NSMakeRange(METAL_FIRST_VERTEX_BUFFER_SLOT + firstBinding, numBindings);
if (range.length == 0) {
return;
}
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
MetalBuffer *currentBuffer = ((MetalBufferContainer *)bindings[i].buffer)->activeBuffer; MetalBuffer *currentBuffer = ((MetalBufferContainer *)bindings[i].buffer)->activeBuffer;
metalBuffers[firstBinding + i] = currentBuffer->handle; if (metalCommandBuffer->vertexBuffers[firstSlot + i] != currentBuffer->handle || metalCommandBuffer->vertexBufferOffsets[firstSlot + i] != bindings[i].offset) {
bufferOffsets[firstBinding + i] = bindings[i].offset; metalCommandBuffer->vertexBuffers[firstSlot + i] = currentBuffer->handle;
metalCommandBuffer->vertexBufferOffsets[firstSlot + i] = bindings[i].offset;
metalCommandBuffer->needVertexBufferBind = true;
METAL_INTERNAL_TrackBuffer(metalCommandBuffer, currentBuffer); METAL_INTERNAL_TrackBuffer(metalCommandBuffer, currentBuffer);
} }
[metalCommandBuffer->renderEncoder setVertexBuffers:metalBuffers offsets:bufferOffsets withRange:range];
} }
metalCommandBuffer->vertexBufferCount =
SDL_max(metalCommandBuffer->vertexBufferCount, firstSlot + numBindings);
} }
static void METAL_BindIndexBuffer( static void METAL_BindIndexBuffer(
@@ -2487,23 +2474,29 @@ static void METAL_BindVertexSamplers(
{ {
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
MetalTextureContainer *textureContainer; MetalTextureContainer *textureContainer;
MetalSampler *sampler;
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
textureContainer = (MetalTextureContainer *)textureSamplerBindings[i].texture; textureContainer = (MetalTextureContainer *)textureSamplerBindings[i].texture;
sampler = (MetalSampler *)textureSamplerBindings[i].sampler;
if (metalCommandBuffer->vertexSamplers[firstSlot + i] != sampler->handle) {
metalCommandBuffer->vertexSamplers[firstSlot + i] = sampler->handle;
metalCommandBuffer->needVertexSamplerBind = true;
}
if (metalCommandBuffer->vertexTextures[firstSlot + i] != textureContainer->activeTexture->handle) {
METAL_INTERNAL_TrackTexture( METAL_INTERNAL_TrackTexture(
metalCommandBuffer, metalCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
metalCommandBuffer->vertexSamplers[firstSlot + i] =
((MetalSampler *)textureSamplerBindings[i].sampler)->handle;
metalCommandBuffer->vertexTextures[firstSlot + i] = metalCommandBuffer->vertexTextures[firstSlot + i] =
textureContainer->activeTexture->handle; textureContainer->activeTexture->handle;
}
metalCommandBuffer->needVertexSamplerBind = true; metalCommandBuffer->needVertexSamplerBind = true;
} }
}
}
static void METAL_BindVertexStorageTextures( static void METAL_BindVertexStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -2517,16 +2510,18 @@ static void METAL_BindVertexStorageTextures(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
textureContainer = (MetalTextureContainer *)storageTextures[i]; textureContainer = (MetalTextureContainer *)storageTextures[i];
if (metalCommandBuffer->vertexStorageTextures[firstSlot + i] != textureContainer->activeTexture->handle) {
METAL_INTERNAL_TrackTexture( METAL_INTERNAL_TrackTexture(
metalCommandBuffer, metalCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
metalCommandBuffer->vertexStorageTextures[firstSlot + i] = metalCommandBuffer->vertexStorageTextures[firstSlot + i] =
textureContainer->activeTexture->handle; textureContainer->activeTexture->handle;
}
metalCommandBuffer->needVertexStorageTextureBind = true; metalCommandBuffer->needVertexStorageTextureBind = true;
} }
}
}
static void METAL_BindVertexStorageBuffers( static void METAL_BindVertexStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -2540,16 +2535,18 @@ static void METAL_BindVertexStorageBuffers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
bufferContainer = (MetalBufferContainer *)storageBuffers[i]; bufferContainer = (MetalBufferContainer *)storageBuffers[i];
if (metalCommandBuffer->vertexStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer->handle) {
METAL_INTERNAL_TrackBuffer( METAL_INTERNAL_TrackBuffer(
metalCommandBuffer, metalCommandBuffer,
bufferContainer->activeBuffer); bufferContainer->activeBuffer);
metalCommandBuffer->vertexStorageBuffers[firstSlot + i] = metalCommandBuffer->vertexStorageBuffers[firstSlot + i] =
bufferContainer->activeBuffer->handle; bufferContainer->activeBuffer->handle;
}
metalCommandBuffer->needVertexStorageBufferBind = true; metalCommandBuffer->needVertexStorageBufferBind = true;
} }
}
}
static void METAL_BindFragmentSamplers( static void METAL_BindFragmentSamplers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -2559,23 +2556,29 @@ static void METAL_BindFragmentSamplers(
{ {
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
MetalTextureContainer *textureContainer; MetalTextureContainer *textureContainer;
MetalSampler *sampler;
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
textureContainer = (MetalTextureContainer *)textureSamplerBindings[i].texture; textureContainer = (MetalTextureContainer *)textureSamplerBindings[i].texture;
sampler = (MetalSampler *)textureSamplerBindings[i].sampler;
if (metalCommandBuffer->fragmentSamplers[firstSlot + i] != sampler->handle) {
metalCommandBuffer->fragmentSamplers[firstSlot + i] = sampler->handle;
metalCommandBuffer->needFragmentSamplerBind = true;
}
if (metalCommandBuffer->fragmentTextures[firstSlot + i] != textureContainer->activeTexture->handle) {
METAL_INTERNAL_TrackTexture( METAL_INTERNAL_TrackTexture(
metalCommandBuffer, metalCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
metalCommandBuffer->fragmentSamplers[firstSlot + i] =
((MetalSampler *)textureSamplerBindings[i].sampler)->handle;
metalCommandBuffer->fragmentTextures[firstSlot + i] = metalCommandBuffer->fragmentTextures[firstSlot + i] =
textureContainer->activeTexture->handle; textureContainer->activeTexture->handle;
}
metalCommandBuffer->needFragmentSamplerBind = true; metalCommandBuffer->needFragmentSamplerBind = true;
} }
}
}
static void METAL_BindFragmentStorageTextures( static void METAL_BindFragmentStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -2589,16 +2592,18 @@ static void METAL_BindFragmentStorageTextures(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
textureContainer = (MetalTextureContainer *)storageTextures[i]; textureContainer = (MetalTextureContainer *)storageTextures[i];
if (metalCommandBuffer->fragmentStorageTextures[firstSlot + i] != textureContainer->activeTexture->handle) {
METAL_INTERNAL_TrackTexture( METAL_INTERNAL_TrackTexture(
metalCommandBuffer, metalCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
metalCommandBuffer->fragmentStorageTextures[firstSlot + i] = metalCommandBuffer->fragmentStorageTextures[firstSlot + i] =
textureContainer->activeTexture->handle; textureContainer->activeTexture->handle;
}
metalCommandBuffer->needFragmentStorageTextureBind = true; metalCommandBuffer->needFragmentStorageTextureBind = true;
} }
}
}
static void METAL_BindFragmentStorageBuffers( static void METAL_BindFragmentStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -2612,16 +2617,18 @@ static void METAL_BindFragmentStorageBuffers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
bufferContainer = (MetalBufferContainer *)storageBuffers[i]; bufferContainer = (MetalBufferContainer *)storageBuffers[i];
if (metalCommandBuffer->fragmentStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer->handle) {
METAL_INTERNAL_TrackBuffer( METAL_INTERNAL_TrackBuffer(
metalCommandBuffer, metalCommandBuffer,
bufferContainer->activeBuffer); bufferContainer->activeBuffer);
metalCommandBuffer->fragmentStorageBuffers[firstSlot + i] = metalCommandBuffer->fragmentStorageBuffers[firstSlot + i] =
bufferContainer->activeBuffer->handle; bufferContainer->activeBuffer->handle;
}
metalCommandBuffer->needFragmentStorageBufferBind = true; metalCommandBuffer->needFragmentStorageBufferBind = true;
} }
}
}
// This function assumes that it's called from within an autorelease pool // This function assumes that it's called from within an autorelease pool
static void METAL_INTERNAL_BindGraphicsResources( static void METAL_INTERNAL_BindGraphicsResources(
@@ -2630,85 +2637,115 @@ static void METAL_INTERNAL_BindGraphicsResources(
MetalGraphicsPipeline *graphicsPipeline = commandBuffer->graphics_pipeline; MetalGraphicsPipeline *graphicsPipeline = commandBuffer->graphics_pipeline;
NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 }; NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 };
// Vertex Buffers
if (commandBuffer->needVertexBufferBind) {
id<MTLBuffer> metalBuffers[MAX_VERTEX_BUFFERS];
NSUInteger bufferOffsets[MAX_VERTEX_BUFFERS];
NSRange range = NSMakeRange(METAL_FIRST_VERTEX_BUFFER_SLOT, commandBuffer->vertexBufferCount);
for (Uint32 i = 0; i < commandBuffer->vertexBufferCount; i += 1) {
metalBuffers[i] = commandBuffer->vertexBuffers[i];
bufferOffsets[i] = commandBuffer->vertexBufferOffsets[i];
}
[commandBuffer->renderEncoder setVertexBuffers:metalBuffers offsets:bufferOffsets withRange:range];
commandBuffer->needVertexBufferBind = false;
}
// Vertex Samplers+Textures // Vertex Samplers+Textures
if (graphicsPipeline->vertexSamplerCount > 0 && commandBuffer->needVertexSamplerBind) { if (commandBuffer->needVertexSamplerBind) {
if (graphicsPipeline->vertexSamplerCount > 0) {
[commandBuffer->renderEncoder setVertexSamplerStates:commandBuffer->vertexSamplers [commandBuffer->renderEncoder setVertexSamplerStates:commandBuffer->vertexSamplers
withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)]; withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)];
[commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexTextures [commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexTextures
withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)]; withRange:NSMakeRange(0, graphicsPipeline->vertexSamplerCount)];
}
commandBuffer->needVertexSamplerBind = false; commandBuffer->needVertexSamplerBind = false;
} }
// Vertex Storage Textures // Vertex Storage Textures
if (graphicsPipeline->vertexStorageTextureCount > 0 && commandBuffer->needVertexStorageTextureBind) { if (commandBuffer->needVertexStorageTextureBind) {
if (graphicsPipeline->vertexStorageTextureCount > 0) {
[commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexStorageTextures [commandBuffer->renderEncoder setVertexTextures:commandBuffer->vertexStorageTextures
withRange:NSMakeRange(graphicsPipeline->vertexSamplerCount, withRange:NSMakeRange(graphicsPipeline->vertexSamplerCount,
graphicsPipeline->vertexStorageTextureCount)]; graphicsPipeline->vertexStorageTextureCount)];
}
commandBuffer->needVertexStorageTextureBind = false; commandBuffer->needVertexStorageTextureBind = false;
} }
// Vertex Storage Buffers // Vertex Storage Buffers
if (graphicsPipeline->vertexStorageBufferCount > 0 && commandBuffer->needVertexStorageBufferBind) { if (commandBuffer->needVertexStorageBufferBind) {
if (graphicsPipeline->vertexStorageBufferCount > 0) {
[commandBuffer->renderEncoder setVertexBuffers:commandBuffer->vertexStorageBuffers [commandBuffer->renderEncoder setVertexBuffers:commandBuffer->vertexStorageBuffers
offsets:offsets offsets:offsets
withRange:NSMakeRange(graphicsPipeline->vertexUniformBufferCount, withRange:NSMakeRange(graphicsPipeline->vertexUniformBufferCount,
graphicsPipeline->vertexStorageBufferCount)]; graphicsPipeline->vertexStorageBufferCount)];
}
commandBuffer->needVertexStorageBufferBind = false; commandBuffer->needVertexStorageBufferBind = false;
} }
// Vertex Uniform Buffers // Vertex Uniform Buffers
if (graphicsPipeline->vertexUniformBufferCount > 0 && commandBuffer->needVertexUniformBind) {
for (Uint32 i = 0; i < graphicsPipeline->vertexUniformBufferCount; i += 1) { for (Uint32 i = 0; i < graphicsPipeline->vertexUniformBufferCount; i += 1) {
if (commandBuffer->needVertexUniformBufferBind[i]) {
if (graphicsPipeline->vertexUniformBufferCount > i) {
[commandBuffer->renderEncoder [commandBuffer->renderEncoder
setVertexBuffer:commandBuffer->vertexUniformBuffers[i]->handle setVertexBuffer:commandBuffer->vertexUniformBuffers[i]->handle
offset:commandBuffer->vertexUniformBuffers[i]->drawOffset offset:commandBuffer->vertexUniformBuffers[i]->drawOffset
atIndex:i]; atIndex:i];
} }
commandBuffer->needVertexUniformBind = false; commandBuffer->needVertexUniformBufferBind[i] = false;
}
} }
// Fragment Samplers+Textures // Fragment Samplers+Textures
if (graphicsPipeline->fragmentSamplerCount > 0 && commandBuffer->needFragmentSamplerBind) { if (commandBuffer->needFragmentSamplerBind) {
if (graphicsPipeline->fragmentSamplerCount > 0) {
[commandBuffer->renderEncoder setFragmentSamplerStates:commandBuffer->fragmentSamplers [commandBuffer->renderEncoder setFragmentSamplerStates:commandBuffer->fragmentSamplers
withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)]; withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)];
[commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentTextures [commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentTextures
withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)]; withRange:NSMakeRange(0, graphicsPipeline->fragmentSamplerCount)];
}
commandBuffer->needFragmentSamplerBind = false; commandBuffer->needFragmentSamplerBind = false;
} }
// Fragment Storage Textures // Fragment Storage Textures
if (graphicsPipeline->fragmentStorageTextureCount > 0 && commandBuffer->needFragmentStorageTextureBind) { if (commandBuffer->needFragmentStorageTextureBind) {
if (graphicsPipeline->fragmentStorageTextureCount > 0) {
[commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentStorageTextures [commandBuffer->renderEncoder setFragmentTextures:commandBuffer->fragmentStorageTextures
withRange:NSMakeRange(graphicsPipeline->fragmentSamplerCount, withRange:NSMakeRange(graphicsPipeline->fragmentSamplerCount,
graphicsPipeline->fragmentStorageTextureCount)]; graphicsPipeline->fragmentStorageTextureCount)];
}
commandBuffer->needFragmentStorageTextureBind = false; commandBuffer->needFragmentStorageTextureBind = false;
} }
// Fragment Storage Buffers // Fragment Storage Buffers
if (graphicsPipeline->fragmentStorageBufferCount > 0 && commandBuffer->needFragmentStorageBufferBind) { if (commandBuffer->needFragmentStorageBufferBind) {
if (graphicsPipeline->fragmentStorageBufferCount > 0) {
[commandBuffer->renderEncoder setFragmentBuffers:commandBuffer->fragmentStorageBuffers [commandBuffer->renderEncoder setFragmentBuffers:commandBuffer->fragmentStorageBuffers
offsets:offsets offsets:offsets
withRange:NSMakeRange(graphicsPipeline->fragmentUniformBufferCount, withRange:NSMakeRange(graphicsPipeline->fragmentUniformBufferCount,
graphicsPipeline->fragmentStorageBufferCount)]; graphicsPipeline->fragmentStorageBufferCount)];
}
commandBuffer->needFragmentStorageBufferBind = false; commandBuffer->needFragmentStorageBufferBind = false;
} }
// Fragment Uniform Buffers // Fragment Uniform Buffers
if (graphicsPipeline->fragmentUniformBufferCount > 0 && commandBuffer->needFragmentUniformBind) {
for (Uint32 i = 0; i < graphicsPipeline->fragmentUniformBufferCount; i += 1) { for (Uint32 i = 0; i < graphicsPipeline->fragmentUniformBufferCount; i += 1) {
if (commandBuffer->needFragmentUniformBufferBind[i]) {
if (graphicsPipeline->fragmentUniformBufferCount > i) {
[commandBuffer->renderEncoder [commandBuffer->renderEncoder
setFragmentBuffer:commandBuffer->fragmentUniformBuffers[i]->handle setFragmentBuffer:commandBuffer->fragmentUniformBuffers[i]->handle
offset:commandBuffer->fragmentUniformBuffers[i]->drawOffset offset:commandBuffer->fragmentUniformBuffers[i]->drawOffset
atIndex:i]; atIndex:i];
} }
commandBuffer->needFragmentUniformBind = false; commandBuffer->needFragmentUniformBufferBind[i] = false;
}
} }
} }
@@ -2720,7 +2757,6 @@ static void METAL_INTERNAL_BindComputeResources(
NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 }; NSUInteger offsets[MAX_STORAGE_BUFFERS_PER_STAGE] = { 0 };
if (commandBuffer->needComputeSamplerBind) { if (commandBuffer->needComputeSamplerBind) {
// Bind sampler textures
if (computePipeline->numSamplers > 0) { if (computePipeline->numSamplers > 0) {
[commandBuffer->computeEncoder setTextures:commandBuffer->computeSamplerTextures [commandBuffer->computeEncoder setTextures:commandBuffer->computeSamplerTextures
withRange:NSMakeRange(0, computePipeline->numSamplers)]; withRange:NSMakeRange(0, computePipeline->numSamplers)];
@@ -2730,54 +2766,36 @@ static void METAL_INTERNAL_BindComputeResources(
commandBuffer->needComputeSamplerBind = false; commandBuffer->needComputeSamplerBind = false;
} }
if (commandBuffer->needComputeTextureBind) { if (commandBuffer->needComputeReadOnlyStorageTextureBind) {
// Bind read-only textures
if (computePipeline->numReadonlyStorageTextures > 0) { if (computePipeline->numReadonlyStorageTextures > 0) {
[commandBuffer->computeEncoder setTextures:commandBuffer->computeReadOnlyTextures [commandBuffer->computeEncoder setTextures:commandBuffer->computeReadOnlyTextures
withRange:NSMakeRange( withRange:NSMakeRange(
computePipeline->numSamplers, computePipeline->numSamplers,
computePipeline->numReadonlyStorageTextures)]; computePipeline->numReadonlyStorageTextures)];
} }
commandBuffer->needComputeReadOnlyStorageTextureBind = false;
// Bind write-only textures
if (computePipeline->numReadWriteStorageTextures > 0) {
[commandBuffer->computeEncoder setTextures:commandBuffer->computeReadWriteTextures
withRange:NSMakeRange(
computePipeline->numSamplers + computePipeline->numReadonlyStorageTextures,
computePipeline->numReadWriteStorageTextures)];
}
commandBuffer->needComputeTextureBind = false;
} }
if (commandBuffer->needComputeBufferBind) { if (commandBuffer->needComputeReadOnlyStorageBufferBind) {
// Bind read-only buffers
if (computePipeline->numReadonlyStorageBuffers > 0) { if (computePipeline->numReadonlyStorageBuffers > 0) {
[commandBuffer->computeEncoder setBuffers:commandBuffer->computeReadOnlyBuffers [commandBuffer->computeEncoder setBuffers:commandBuffer->computeReadOnlyBuffers
offsets:offsets offsets:offsets
withRange:NSMakeRange(computePipeline->numUniformBuffers, withRange:NSMakeRange(computePipeline->numUniformBuffers,
computePipeline->numReadonlyStorageBuffers)]; computePipeline->numReadonlyStorageBuffers)];
} }
// Bind write-only buffers commandBuffer->needComputeReadOnlyStorageBufferBind = false;
if (computePipeline->numReadWriteStorageBuffers > 0) {
[commandBuffer->computeEncoder setBuffers:commandBuffer->computeReadWriteBuffers
offsets:offsets
withRange:NSMakeRange(
computePipeline->numUniformBuffers +
computePipeline->numReadonlyStorageBuffers,
computePipeline->numReadWriteStorageBuffers)];
}
commandBuffer->needComputeBufferBind = false;
} }
if (commandBuffer->needComputeUniformBind) { for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
for (Uint32 i = 0; i < computePipeline->numUniformBuffers; i += 1) { if (commandBuffer->needComputeUniformBufferBind[i]) {
if (computePipeline->numUniformBuffers > i) {
[commandBuffer->computeEncoder [commandBuffer->computeEncoder
setBuffer:commandBuffer->computeUniformBuffers[i]->handle setBuffer:commandBuffer->computeUniformBuffers[i]->handle
offset:commandBuffer->computeUniformBuffers[i]->drawOffset offset:commandBuffer->computeUniformBuffers[i]->drawOffset
atIndex:i]; atIndex:i];
} }
}
commandBuffer->needComputeUniformBind = false; commandBuffer->needComputeUniformBufferBind[i] = false;
} }
} }
@@ -2892,6 +2910,11 @@ static void METAL_EndRenderPass(
[metalCommandBuffer->renderEncoder endEncoding]; [metalCommandBuffer->renderEncoder endEncoding];
metalCommandBuffer->renderEncoder = nil; metalCommandBuffer->renderEncoder = nil;
for (Uint32 i = 0; i < MAX_VERTEX_BUFFERS; i += 1) {
metalCommandBuffer->vertexBuffers[i] = nil;
metalCommandBuffer->vertexBufferOffsets[i] = 0;
metalCommandBuffer->vertexBufferCount = 0;
}
for (Uint32 i = 0; i < MAX_TEXTURE_SAMPLERS_PER_STAGE; i += 1) { for (Uint32 i = 0; i < MAX_TEXTURE_SAMPLERS_PER_STAGE; i += 1) {
metalCommandBuffer->vertexSamplers[i] = nil; metalCommandBuffer->vertexSamplers[i] = nil;
metalCommandBuffer->vertexTextures[i] = nil; metalCommandBuffer->vertexTextures[i] = nil;
@@ -2976,11 +2999,11 @@ static void METAL_INTERNAL_PushUniformData(
metalUniformBuffer->writeOffset += alignedDataLength; metalUniformBuffer->writeOffset += alignedDataLength;
if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) { if (shaderStage == SDL_GPU_SHADERSTAGE_VERTEX) {
metalCommandBuffer->needVertexUniformBind = true; metalCommandBuffer->needVertexUniformBufferBind[slotIndex] = true;
} else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) { } else if (shaderStage == SDL_GPU_SHADERSTAGE_FRAGMENT) {
metalCommandBuffer->needFragmentUniformBind = true; metalCommandBuffer->needFragmentUniformBufferBind[slotIndex] = true;
} else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) { } else if (shaderStage == SDL_GPU_SHADERSTAGE_COMPUTE) {
metalCommandBuffer->needComputeUniformBind = true; metalCommandBuffer->needComputeUniformBufferBind[slotIndex] = true;
} else { } else {
SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!"); SDL_LogError(SDL_LOG_CATEGORY_GPU, "Unrecognized shader stage!");
} }
@@ -3078,7 +3101,6 @@ static void METAL_BeginComputePass(
slices:NSMakeRange(storageTextureBindings[i].layer, 1)]; slices:NSMakeRange(storageTextureBindings[i].layer, 1)];
metalCommandBuffer->computeReadWriteTextures[i] = textureView; metalCommandBuffer->computeReadWriteTextures[i] = textureView;
metalCommandBuffer->needComputeTextureBind = true;
} }
for (Uint32 i = 0; i < numStorageBufferBindings; i += 1) { for (Uint32 i = 0; i < numStorageBufferBindings; i += 1) {
@@ -3094,7 +3116,6 @@ static void METAL_BeginComputePass(
buffer); buffer);
metalCommandBuffer->computeReadWriteBuffers[i] = buffer->handle; metalCommandBuffer->computeReadWriteBuffers[i] = buffer->handle;
metalCommandBuffer->needComputeBufferBind = true;
} }
} }
} }
@@ -3111,6 +3132,10 @@ static void METAL_BindComputePipeline(
[metalCommandBuffer->computeEncoder setComputePipelineState:pipeline->handle]; [metalCommandBuffer->computeEncoder setComputePipelineState:pipeline->handle];
for (Uint32 i = 0; i < MAX_UNIFORM_BUFFERS_PER_STAGE; i += 1) {
metalCommandBuffer->needComputeUniformBufferBind[i] = true;
}
for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) { for (Uint32 i = 0; i < pipeline->numUniformBuffers; i += 1) {
if (metalCommandBuffer->computeUniformBuffers[i] == NULL) { if (metalCommandBuffer->computeUniformBuffers[i] == NULL) {
metalCommandBuffer->computeUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool( metalCommandBuffer->computeUniformBuffers[i] = METAL_INTERNAL_AcquireUniformBufferFromPool(
@@ -3118,7 +3143,24 @@ static void METAL_BindComputePipeline(
} }
} }
metalCommandBuffer->needComputeUniformBind = true; // Bind write-only resources
if (pipeline->numReadWriteStorageTextures > 0) {
[metalCommandBuffer->computeEncoder setTextures:metalCommandBuffer->computeReadWriteTextures
withRange:NSMakeRange(
pipeline->numSamplers +
pipeline->numReadonlyStorageTextures,
pipeline->numReadWriteStorageTextures)];
}
NSUInteger offsets[MAX_COMPUTE_WRITE_BUFFERS] = { 0 };
if (pipeline->numReadWriteStorageBuffers > 0) {
[metalCommandBuffer->computeEncoder setBuffers:metalCommandBuffer->computeReadWriteBuffers
offsets:offsets
withRange:NSMakeRange(
pipeline->numUniformBuffers +
pipeline->numReadonlyStorageBuffers,
pipeline->numReadWriteStorageBuffers)];
}
} }
} }
@@ -3130,23 +3172,29 @@ static void METAL_BindComputeSamplers(
{ {
MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer; MetalCommandBuffer *metalCommandBuffer = (MetalCommandBuffer *)commandBuffer;
MetalTextureContainer *textureContainer; MetalTextureContainer *textureContainer;
MetalSampler *sampler;
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
textureContainer = (MetalTextureContainer *)textureSamplerBindings[i].texture; textureContainer = (MetalTextureContainer *)textureSamplerBindings[i].texture;
sampler = (MetalSampler *)textureSamplerBindings[i].sampler;
if (metalCommandBuffer->computeSamplers[firstSlot + i] != sampler->handle) {
metalCommandBuffer->computeSamplers[firstSlot + i] = sampler->handle;
metalCommandBuffer->needComputeSamplerBind = true;
}
if (metalCommandBuffer->computeSamplerTextures[firstSlot + i] != textureContainer->activeTexture->handle) {
METAL_INTERNAL_TrackTexture( METAL_INTERNAL_TrackTexture(
metalCommandBuffer, metalCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
metalCommandBuffer->computeSamplers[firstSlot + i] =
((MetalSampler *)textureSamplerBindings[i].sampler)->handle;
metalCommandBuffer->computeSamplerTextures[firstSlot + i] = metalCommandBuffer->computeSamplerTextures[firstSlot + i] =
textureContainer->activeTexture->handle; textureContainer->activeTexture->handle;
}
metalCommandBuffer->needComputeSamplerBind = true; metalCommandBuffer->needComputeSamplerBind = true;
} }
}
}
static void METAL_BindComputeStorageTextures( static void METAL_BindComputeStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -3160,15 +3208,17 @@ static void METAL_BindComputeStorageTextures(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
textureContainer = (MetalTextureContainer *)storageTextures[i]; textureContainer = (MetalTextureContainer *)storageTextures[i];
if (metalCommandBuffer->computeReadOnlyTextures[firstSlot + i] != textureContainer->activeTexture->handle) {
METAL_INTERNAL_TrackTexture( METAL_INTERNAL_TrackTexture(
metalCommandBuffer, metalCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
metalCommandBuffer->computeReadOnlyTextures[firstSlot + i] = metalCommandBuffer->computeReadOnlyTextures[firstSlot + i] =
textureContainer->activeTexture->handle; textureContainer->activeTexture->handle;
}
metalCommandBuffer->needComputeTextureBind = true; metalCommandBuffer->needComputeReadOnlyStorageTextureBind = true;
}
}
} }
static void METAL_BindComputeStorageBuffers( static void METAL_BindComputeStorageBuffers(
@@ -3183,15 +3233,17 @@ static void METAL_BindComputeStorageBuffers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
bufferContainer = (MetalBufferContainer *)storageBuffers[i]; bufferContainer = (MetalBufferContainer *)storageBuffers[i];
if (metalCommandBuffer->computeReadOnlyBuffers[firstSlot + i] != bufferContainer->activeBuffer->handle) {
METAL_INTERNAL_TrackBuffer( METAL_INTERNAL_TrackBuffer(
metalCommandBuffer, metalCommandBuffer,
bufferContainer->activeBuffer); bufferContainer->activeBuffer);
metalCommandBuffer->computeReadOnlyBuffers[firstSlot + i] = metalCommandBuffer->computeReadOnlyBuffers[firstSlot + i] =
bufferContainer->activeBuffer->handle; bufferContainer->activeBuffer->handle;
}
metalCommandBuffer->needComputeBufferBind = true; metalCommandBuffer->needComputeReadOnlyStorageBufferBind = true;
}
}
} }
static void METAL_PushComputeUniformData( static void METAL_PushComputeUniformData(
@@ -3368,6 +3420,11 @@ static void METAL_INTERNAL_CleanCommandBuffer(
commandBuffer->windowDataCount = 0; commandBuffer->windowDataCount = 0;
// Reset bindings // Reset bindings
for (i = 0; i < MAX_VERTEX_BUFFERS; i += 1) {
commandBuffer->vertexBuffers[i] = nil;
commandBuffer->vertexBufferOffsets[i] = 0;
}
commandBuffer->vertexBufferCount = 0;
commandBuffer->indexBuffer = NULL; commandBuffer->indexBuffer = NULL;
for (i = 0; i < MAX_TEXTURE_SAMPLERS_PER_STAGE; i += 1) { for (i = 0; i < MAX_TEXTURE_SAMPLERS_PER_STAGE; i += 1) {
commandBuffer->vertexSamplers[i] = nil; commandBuffer->vertexSamplers[i] = nil;
@@ -3394,6 +3451,22 @@ static void METAL_INTERNAL_CleanCommandBuffer(
commandBuffer->computeReadWriteBuffers[i] = nil; commandBuffer->computeReadWriteBuffers[i] = nil;
} }
commandBuffer->needVertexBufferBind = false;
commandBuffer->needVertexSamplerBind = false;
commandBuffer->needVertexStorageBufferBind = false;
commandBuffer->needVertexStorageTextureBind = false;
SDL_zeroa(commandBuffer->needVertexUniformBufferBind);
commandBuffer->needFragmentSamplerBind = false;
commandBuffer->needFragmentStorageBufferBind = false;
commandBuffer->needFragmentStorageTextureBind = false;
SDL_zeroa(commandBuffer->needFragmentUniformBufferBind);
commandBuffer->needComputeSamplerBind = false;
commandBuffer->needComputeReadOnlyStorageBufferBind = false;
commandBuffer->needComputeReadOnlyStorageTextureBind = false;
SDL_zeroa(commandBuffer->needComputeUniformBufferBind);
// The fence is now available (unless SubmitAndAcquireFence was called) // The fence is now available (unless SubmitAndAcquireFence was called)
if (commandBuffer->autoReleaseFence) { if (commandBuffer->autoReleaseFence) {
METAL_ReleaseFence( METAL_ReleaseFence(

View File

@@ -1035,6 +1035,11 @@ typedef struct VulkanCommandBuffer
VkDescriptorSet computeReadWriteDescriptorSet; VkDescriptorSet computeReadWriteDescriptorSet;
VkDescriptorSet computeUniformDescriptorSet; VkDescriptorSet computeUniformDescriptorSet;
VkBuffer vertexBuffers[MAX_VERTEX_BUFFERS];
VkDeviceSize vertexBufferOffsets[MAX_VERTEX_BUFFERS];
Uint32 vertexBufferCount;
bool needVertexBufferBind;
VulkanTexture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE]; VulkanTexture *vertexSamplerTextures[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanSampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE]; VulkanSampler *vertexSamplers[MAX_TEXTURE_SAMPLERS_PER_STAGE];
VulkanTexture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE]; VulkanTexture *vertexStorageTextures[MAX_STORAGE_TEXTURES_PER_STAGE];
@@ -5027,6 +5032,7 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
Uint32 dynamicOffsetCount = 0; Uint32 dynamicOffsetCount = 0;
if ( if (
!commandBuffer->needVertexBufferBind &&
!commandBuffer->needNewVertexResourceDescriptorSet && !commandBuffer->needNewVertexResourceDescriptorSet &&
!commandBuffer->needNewVertexUniformDescriptorSet && !commandBuffer->needNewVertexUniformDescriptorSet &&
!commandBuffer->needNewVertexUniformOffsets && !commandBuffer->needNewVertexUniformOffsets &&
@@ -5037,6 +5043,17 @@ static void VULKAN_INTERNAL_BindGraphicsDescriptorSets(
return; return;
} }
if (commandBuffer->needVertexBufferBind && commandBuffer->vertexBufferCount > 0) {
renderer->vkCmdBindVertexBuffers(
commandBuffer->commandBuffer,
0,
commandBuffer->vertexBufferCount,
commandBuffer->vertexBuffers,
commandBuffer->vertexBufferOffsets);
commandBuffer->needVertexBufferBind = false;
}
resourceLayout = commandBuffer->currentGraphicsPipeline->resourceLayout; resourceLayout = commandBuffer->currentGraphicsPipeline->resourceLayout;
if (commandBuffer->needNewVertexResourceDescriptorSet) { if (commandBuffer->needNewVertexResourceDescriptorSet) {
@@ -7404,20 +7421,27 @@ static void VULKAN_BindVertexSamplers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] = textureContainer->activeTexture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
vulkanCommandBuffer->vertexSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
if (vulkanCommandBuffer->vertexSamplers[firstSlot + i] != sampler) {
VULKAN_INTERNAL_TrackSampler( VULKAN_INTERNAL_TrackSampler(
vulkanCommandBuffer, vulkanCommandBuffer,
(VulkanSampler *)textureSamplerBindings[i].sampler); (VulkanSampler *)textureSamplerBindings[i].sampler);
vulkanCommandBuffer->vertexSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
}
if (vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
VULKAN_INTERNAL_TrackTexture( VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer, vulkanCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
}
vulkanCommandBuffer->vertexSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
} }
}
}
static void VULKAN_BindVertexStorageTextures( static void VULKAN_BindVertexStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -7430,15 +7454,16 @@ static void VULKAN_BindVertexStorageTextures(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i]; VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i];
vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] = textureContainer->activeTexture; if (vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] != textureContainer->activeTexture) {
VULKAN_INTERNAL_TrackTexture( VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer, vulkanCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
}
vulkanCommandBuffer->vertexStorageTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
} }
}
}
static void VULKAN_BindVertexStorageBuffers( static void VULKAN_BindVertexStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -7447,21 +7472,20 @@ static void VULKAN_BindVertexStorageBuffers(
Uint32 numBindings) Uint32 numBindings)
{ {
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer;
VulkanBufferContainer *bufferContainer;
Uint32 i;
for (i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
bufferContainer = (VulkanBufferContainer *)storageBuffers[i]; VulkanBufferContainer *bufferContainer = (VulkanBufferContainer *)storageBuffers[i];
vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
if (vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) {
VULKAN_INTERNAL_TrackBuffer( VULKAN_INTERNAL_TrackBuffer(
vulkanCommandBuffer, vulkanCommandBuffer,
bufferContainer->activeBuffer); bufferContainer->activeBuffer);
}
vulkanCommandBuffer->vertexStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true; vulkanCommandBuffer->needNewVertexResourceDescriptorSet = true;
} }
}
}
static void VULKAN_BindFragmentSamplers( static void VULKAN_BindFragmentSamplers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -7473,20 +7497,27 @@ static void VULKAN_BindFragmentSamplers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] = textureContainer->activeTexture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
vulkanCommandBuffer->fragmentSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
if (vulkanCommandBuffer->fragmentSamplers[firstSlot + i] != sampler) {
VULKAN_INTERNAL_TrackSampler( VULKAN_INTERNAL_TrackSampler(
vulkanCommandBuffer, vulkanCommandBuffer,
(VulkanSampler *)textureSamplerBindings[i].sampler); (VulkanSampler *)textureSamplerBindings[i].sampler);
vulkanCommandBuffer->fragmentSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
}
if (vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
VULKAN_INTERNAL_TrackTexture( VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer, vulkanCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
}
vulkanCommandBuffer->fragmentSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
} }
}
}
static void VULKAN_BindFragmentStorageTextures( static void VULKAN_BindFragmentStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -7499,16 +7530,16 @@ static void VULKAN_BindFragmentStorageTextures(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i]; VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i];
vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] = if (vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] != textureContainer->activeTexture) {
textureContainer->activeTexture;
VULKAN_INTERNAL_TrackTexture( VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer, vulkanCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
}
vulkanCommandBuffer->fragmentStorageTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
} }
}
}
static void VULKAN_BindFragmentStorageBuffers( static void VULKAN_BindFragmentStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -7523,15 +7554,16 @@ static void VULKAN_BindFragmentStorageBuffers(
for (i = 0; i < numBindings; i += 1) { for (i = 0; i < numBindings; i += 1) {
bufferContainer = (VulkanBufferContainer *)storageBuffers[i]; bufferContainer = (VulkanBufferContainer *)storageBuffers[i];
vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer; if (vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) {
VULKAN_INTERNAL_TrackBuffer( VULKAN_INTERNAL_TrackBuffer(
vulkanCommandBuffer, vulkanCommandBuffer,
bufferContainer->activeBuffer); bufferContainer->activeBuffer);
}
vulkanCommandBuffer->fragmentStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true; vulkanCommandBuffer->needNewFragmentResourceDescriptorSet = true;
} }
}
}
static VulkanUniformBuffer *VULKAN_INTERNAL_AcquireUniformBufferFromPool( static VulkanUniformBuffer *VULKAN_INTERNAL_AcquireUniformBufferFromPool(
VulkanCommandBuffer *commandBuffer) VulkanCommandBuffer *commandBuffer)
@@ -7922,28 +7954,20 @@ static void VULKAN_BindVertexBuffers(
Uint32 numBindings) Uint32 numBindings)
{ {
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer;
VulkanRenderer *renderer = (VulkanRenderer *)vulkanCommandBuffer->renderer;
VulkanBuffer *currentVulkanBuffer;
VkBuffer *buffers = SDL_stack_alloc(VkBuffer, numBindings);
VkDeviceSize *offsets = SDL_stack_alloc(VkDeviceSize, numBindings);
Uint32 i;
for (i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
currentVulkanBuffer = ((VulkanBufferContainer *)bindings[i].buffer)->activeBuffer; VulkanBuffer *buffer = ((VulkanBufferContainer *)bindings[i].buffer)->activeBuffer;
buffers[i] = currentVulkanBuffer->buffer; if (vulkanCommandBuffer->vertexBuffers[i] != buffer->buffer || vulkanCommandBuffer->vertexBufferOffsets[i] != bindings[i].offset) {
offsets[i] = (VkDeviceSize)bindings[i].offset; VULKAN_INTERNAL_TrackBuffer(vulkanCommandBuffer, buffer);
VULKAN_INTERNAL_TrackBuffer(vulkanCommandBuffer, currentVulkanBuffer);
vulkanCommandBuffer->vertexBuffers[i] = buffer->buffer;
vulkanCommandBuffer->vertexBufferOffsets[i] = bindings[i].offset;
vulkanCommandBuffer->needVertexBufferBind = true;
}
} }
renderer->vkCmdBindVertexBuffers( vulkanCommandBuffer->vertexBufferCount =
vulkanCommandBuffer->commandBuffer, SDL_max(vulkanCommandBuffer->vertexBufferCount, firstSlot + numBindings);
firstSlot,
numBindings,
buffers,
offsets);
SDL_stack_free(buffers);
SDL_stack_free(offsets);
} }
static void VULKAN_BindIndexBuffer( static void VULKAN_BindIndexBuffer(
@@ -8045,6 +8069,10 @@ static void VULKAN_EndRenderPass(
SDL_zeroa(vulkanCommandBuffer->resolveAttachmentSubresources); SDL_zeroa(vulkanCommandBuffer->resolveAttachmentSubresources);
vulkanCommandBuffer->depthStencilAttachmentSubresource = NULL; vulkanCommandBuffer->depthStencilAttachmentSubresource = NULL;
SDL_zeroa(vulkanCommandBuffer->vertexBuffers);
SDL_zeroa(vulkanCommandBuffer->vertexBufferOffsets);
vulkanCommandBuffer->vertexBufferCount = 0;
SDL_zeroa(vulkanCommandBuffer->vertexSamplers); SDL_zeroa(vulkanCommandBuffer->vertexSamplers);
SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextures); SDL_zeroa(vulkanCommandBuffer->vertexSamplerTextures);
SDL_zeroa(vulkanCommandBuffer->vertexStorageTextures); SDL_zeroa(vulkanCommandBuffer->vertexStorageTextures);
@@ -8148,20 +8176,27 @@ static void VULKAN_BindComputeSamplers(
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture; VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)textureSamplerBindings[i].texture;
vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] = textureContainer->activeTexture; VulkanSampler *sampler = (VulkanSampler *)textureSamplerBindings[i].sampler;
vulkanCommandBuffer->computeSamplers[firstSlot + i] = (VulkanSampler *)textureSamplerBindings[i].sampler;
if (vulkanCommandBuffer->computeSamplers[firstSlot + i] != sampler) {
VULKAN_INTERNAL_TrackSampler( VULKAN_INTERNAL_TrackSampler(
vulkanCommandBuffer, vulkanCommandBuffer,
(VulkanSampler *)textureSamplerBindings[i].sampler); sampler);
vulkanCommandBuffer->computeSamplers[firstSlot + i] = sampler;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
}
if (vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] != textureContainer->activeTexture) {
VULKAN_INTERNAL_TrackTexture( VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer, vulkanCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
}
vulkanCommandBuffer->computeSamplerTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
} }
}
}
static void VULKAN_BindComputeStorageTextures( static void VULKAN_BindComputeStorageTextures(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -8173,6 +8208,10 @@ static void VULKAN_BindComputeStorageTextures(
VulkanRenderer *renderer = vulkanCommandBuffer->renderer; VulkanRenderer *renderer = vulkanCommandBuffer->renderer;
for (Uint32 i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i];
if (vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] != textureContainer->activeTexture) {
/* If a different texture as in this slot, transition it back to its default usage */
if (vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] != NULL) { if (vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] != NULL) {
VULKAN_INTERNAL_TextureTransitionToDefaultUsage( VULKAN_INTERNAL_TextureTransitionToDefaultUsage(
renderer, renderer,
@@ -8181,24 +8220,23 @@ static void VULKAN_BindComputeStorageTextures(
vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i]); vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i]);
} }
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)storageTextures[i]; /* Then transition the new texture and prepare it for binding */
vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] =
textureContainer->activeTexture;
VULKAN_INTERNAL_TextureTransitionFromDefaultUsage( VULKAN_INTERNAL_TextureTransitionFromDefaultUsage(
renderer, renderer,
vulkanCommandBuffer, vulkanCommandBuffer,
VULKAN_TEXTURE_USAGE_MODE_COMPUTE_STORAGE_READ, VULKAN_TEXTURE_USAGE_MODE_COMPUTE_STORAGE_READ,
textureContainer->activeTexture); textureContainer->activeTexture);
VULKAN_INTERNAL_TrackTexture( VULKAN_INTERNAL_TrackTexture(
vulkanCommandBuffer, vulkanCommandBuffer,
textureContainer->activeTexture); textureContainer->activeTexture);
}
vulkanCommandBuffer->readOnlyComputeStorageTextures[firstSlot + i] = textureContainer->activeTexture;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
} }
}
}
static void VULKAN_BindComputeStorageBuffers( static void VULKAN_BindComputeStorageBuffers(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -8208,10 +8246,12 @@ static void VULKAN_BindComputeStorageBuffers(
{ {
VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer *)commandBuffer;
VulkanRenderer *renderer = vulkanCommandBuffer->renderer; VulkanRenderer *renderer = vulkanCommandBuffer->renderer;
VulkanBufferContainer *bufferContainer;
Uint32 i;
for (i = 0; i < numBindings; i += 1) { for (Uint32 i = 0; i < numBindings; i += 1) {
VulkanBufferContainer *bufferContainer = (VulkanBufferContainer *)storageBuffers[i];
if (vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] != bufferContainer->activeBuffer) {
/* If a different buffer was in this slot, transition it back to its default usage */
if (vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] != NULL) { if (vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] != NULL) {
VULKAN_INTERNAL_BufferTransitionToDefaultUsage( VULKAN_INTERNAL_BufferTransitionToDefaultUsage(
renderer, renderer,
@@ -8220,10 +8260,7 @@ static void VULKAN_BindComputeStorageBuffers(
vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i]); vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i]);
} }
bufferContainer = (VulkanBufferContainer *)storageBuffers[i]; /* Then transition the new buffer and prepare it for binding */
vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
VULKAN_INTERNAL_BufferTransitionFromDefaultUsage( VULKAN_INTERNAL_BufferTransitionFromDefaultUsage(
renderer, renderer,
vulkanCommandBuffer, vulkanCommandBuffer,
@@ -8233,10 +8270,12 @@ static void VULKAN_BindComputeStorageBuffers(
VULKAN_INTERNAL_TrackBuffer( VULKAN_INTERNAL_TrackBuffer(
vulkanCommandBuffer, vulkanCommandBuffer,
bufferContainer->activeBuffer); bufferContainer->activeBuffer);
}
vulkanCommandBuffer->readOnlyComputeStorageBuffers[firstSlot + i] = bufferContainer->activeBuffer;
vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true; vulkanCommandBuffer->needNewComputeReadOnlyDescriptorSet = true;
} }
}
}
static void VULKAN_PushComputeUniformData( static void VULKAN_PushComputeUniformData(
SDL_GPUCommandBuffer *commandBuffer, SDL_GPUCommandBuffer *commandBuffer,
@@ -9226,6 +9265,7 @@ static bool VULKAN_INTERNAL_AllocateCommandBuffer(
// Resource bind tracking // Resource bind tracking
commandBuffer->needVertexBufferBind = false;
commandBuffer->needNewVertexResourceDescriptorSet = true; commandBuffer->needNewVertexResourceDescriptorSet = true;
commandBuffer->needNewVertexUniformDescriptorSet = true; commandBuffer->needNewVertexUniformDescriptorSet = true;
commandBuffer->needNewVertexUniformOffsets = true; commandBuffer->needNewVertexUniformOffsets = true;
@@ -9419,6 +9459,7 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
commandBuffer->computeUniformBuffers[i] = NULL; commandBuffer->computeUniformBuffers[i] = NULL;
} }
commandBuffer->needVertexBufferBind = false;
commandBuffer->needNewVertexResourceDescriptorSet = true; commandBuffer->needNewVertexResourceDescriptorSet = true;
commandBuffer->needNewVertexUniformDescriptorSet = true; commandBuffer->needNewVertexUniformDescriptorSet = true;
commandBuffer->needNewVertexUniformOffsets = true; commandBuffer->needNewVertexUniformOffsets = true;
@@ -9439,6 +9480,10 @@ static SDL_GPUCommandBuffer *VULKAN_AcquireCommandBuffer(
commandBuffer->computeReadWriteDescriptorSet = VK_NULL_HANDLE; commandBuffer->computeReadWriteDescriptorSet = VK_NULL_HANDLE;
commandBuffer->computeUniformDescriptorSet = VK_NULL_HANDLE; commandBuffer->computeUniformDescriptorSet = VK_NULL_HANDLE;
SDL_zeroa(commandBuffer->vertexBuffers);
SDL_zeroa(commandBuffer->vertexBufferOffsets);
commandBuffer->vertexBufferCount = 0;
SDL_zeroa(commandBuffer->vertexSamplerTextures); SDL_zeroa(commandBuffer->vertexSamplerTextures);
SDL_zeroa(commandBuffer->vertexSamplers); SDL_zeroa(commandBuffer->vertexSamplers);
SDL_zeroa(commandBuffer->vertexStorageTextures); SDL_zeroa(commandBuffer->vertexStorageTextures);
@@ -9868,8 +9913,6 @@ static bool VULKAN_INTERNAL_AcquireSwapchainTexture(
VK_NULL_HANDLE, VK_NULL_HANDLE,
&swapchainImageIndex); &swapchainImageIndex);
//if (acquireResult == VK_ERROR_OUT_OF_DATE_KHR) { SDL_Log("VULKAN SWAPCHAIN OUT OF DATE"); }
if (acquireResult == VK_SUCCESS || acquireResult == VK_SUBOPTIMAL_KHR) { if (acquireResult == VK_SUCCESS || acquireResult == VK_SUBOPTIMAL_KHR) {
break; // we got the next image! break; // we got the next image!
} }