diff --git a/include/SDL3/SDL_gpu.h b/include/SDL3/SDL_gpu.h index 8214b85aed..67fbdbd871 100644 --- a/include/SDL3/SDL_gpu.h +++ b/include/SDL3/SDL_gpu.h @@ -2055,6 +2055,8 @@ typedef struct SDL_GPUColorTargetInfo * * Note that depth/stencil targets do not support multisample resolves. * + * Due to ABI limitations, depth textures with more than 255 layers are not supported. + * * \since This struct is available since SDL 3.2.0. * * \sa SDL_BeginGPURenderPass @@ -2069,8 +2071,8 @@ typedef struct SDL_GPUDepthStencilTargetInfo SDL_GPUStoreOp stencil_store_op; /**< What is done with the stencil results of the render pass. */ bool cycle; /**< true cycles the texture if the texture is bound and any load ops are not LOAD */ Uint8 clear_stencil; /**< The value to clear the stencil component to at the beginning of the render pass. Ignored if SDL_GPU_LOADOP_CLEAR is not used. */ - Uint8 padding1; - Uint8 padding2; + Uint8 mip_level; /**< The mip level to use as the depth stencil target. */ + Uint8 layer; /**< The layer index to use as the depth stencil target. */ } SDL_GPUDepthStencilTargetInfo; /** @@ -4492,8 +4494,3 @@ extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeGPU(SDL_GPUDevice *device); #include #endif /* SDL_gpu_h_ */ - - - - - diff --git a/src/gpu/SDL_gpu.c b/src/gpu/SDL_gpu.c index ede4c54117..c112ac6a12 100644 --- a/src/gpu/SDL_gpu.c +++ b/src/gpu/SDL_gpu.c @@ -1688,6 +1688,14 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass( return NULL; } + if (depth_stencil_target_info != NULL) { + TextureCommonHeader *depthTextureCommonHeader = (TextureCommonHeader *) depth_stencil_target_info->texture; + if (depthTextureCommonHeader->info.layer_count_or_depth > 255) { + SDL_SetError("Cannot bind a depth texture with more than 255 layers!"); + return NULL; + } + } + if (COMMAND_BUFFER_DEVICE->debug_mode) { CHECK_COMMAND_BUFFER_RETURN_NULL CHECK_ANY_PASS_IN_PROGRESS("Cannot begin render pass during another pass!", NULL) @@ -3408,4 +3416,3 @@ SDL_GPUTextureFormat SDL_GetGPUTextureFormatFromPixelFormat(SDL_PixelFormat form return SDL_GPU_TEXTUREFORMAT_INVALID; } } - diff --git a/src/gpu/d3d12/SDL_gpu_d3d12.c b/src/gpu/d3d12/SDL_gpu_d3d12.c index e2d3b3cbe2..28a7c5ce57 100644 --- a/src/gpu/d3d12/SDL_gpu_d3d12.c +++ b/src/gpu/d3d12/SDL_gpu_d3d12.c @@ -4289,8 +4289,8 @@ static void D3D12_BeginRenderPass( if (depthStencilTargetInfo != NULL) { D3D12TextureContainer *container = (D3D12TextureContainer *)depthStencilTargetInfo->texture; - Uint32 h = container->header.info.height; - Uint32 w = container->header.info.width; + Uint32 h = container->header.info.height >> depthStencilTargetInfo->mip_level; + Uint32 w = container->header.info.width >> depthStencilTargetInfo->mip_level; // The framebuffer cannot be larger than the smallest target. @@ -4359,8 +4359,8 @@ static void D3D12_BeginRenderPass( D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite( d3d12CommandBuffer, container, - 0, - 0, + depthStencilTargetInfo->layer, + depthStencilTargetInfo->mip_level, depthStencilTargetInfo->cycle, D3D12_RESOURCE_STATE_DEPTH_WRITE); diff --git a/src/gpu/metal/SDL_gpu_metal.m b/src/gpu/metal/SDL_gpu_metal.m index fff9282f86..b2341e5d54 100644 --- a/src/gpu/metal/SDL_gpu_metal.m +++ b/src/gpu/metal/SDL_gpu_metal.m @@ -2319,6 +2319,8 @@ static void METAL_BeginRenderPass( depthStencilTargetInfo->cycle); passDescriptor.depthAttachment.texture = texture->handle; + passDescriptor.depthAttachment.level = depthStencilTargetInfo->mip_level; + passDescriptor.depthAttachment.slice = depthStencilTargetInfo->layer; passDescriptor.depthAttachment.loadAction = SDLToMetal_LoadOp[depthStencilTargetInfo->load_op]; passDescriptor.depthAttachment.storeAction = SDLToMetal_StoreOp[depthStencilTargetInfo->store_op]; passDescriptor.depthAttachment.clearDepth = depthStencilTargetInfo->clear_depth; @@ -2352,8 +2354,8 @@ static void METAL_BeginRenderPass( if (depthStencilTargetInfo != NULL) { MetalTextureContainer *container = (MetalTextureContainer *)depthStencilTargetInfo->texture; - Uint32 w = container->header.info.width; - Uint32 h = container->header.info.height; + Uint32 w = container->header.info.width >> depthStencilTargetInfo->mip_level; + Uint32 h = container->header.info.height >> depthStencilTargetInfo->mip_level; if (w < vpWidth) { vpWidth = w; diff --git a/src/gpu/vulkan/SDL_gpu_vulkan.c b/src/gpu/vulkan/SDL_gpu_vulkan.c index faf8102ee1..bfe4ed5637 100644 --- a/src/gpu/vulkan/SDL_gpu_vulkan.c +++ b/src/gpu/vulkan/SDL_gpu_vulkan.c @@ -7276,8 +7276,8 @@ static VulkanFramebuffer *VULKAN_INTERNAL_FetchFramebuffer( } else { VulkanTextureSubresource *subresource = VULKAN_INTERNAL_FetchTextureSubresource( (VulkanTextureContainer *)depthStencilTargetInfo->texture, - 0, - 0); + depthStencilTargetInfo->layer, + depthStencilTargetInfo->mip_level); key.depthStencilAttachmentView = subresource->depthStencilView; } @@ -7332,8 +7332,8 @@ static VulkanFramebuffer *VULKAN_INTERNAL_FetchFramebuffer( if (depthStencilTargetInfo != NULL) { VulkanTextureSubresource *subresource = VULKAN_INTERNAL_FetchTextureSubresource( (VulkanTextureContainer *)depthStencilTargetInfo->texture, - 0, - 0); + depthStencilTargetInfo->layer, + depthStencilTargetInfo->mip_level); imageViewAttachments[attachmentCount] = subresource->depthStencilView; attachmentCount += 1; @@ -7813,8 +7813,8 @@ static void VULKAN_BeginRenderPass( if (depthStencilTargetInfo != NULL) { VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)depthStencilTargetInfo->texture; - w = textureContainer->header.info.width; - h = textureContainer->header.info.height; + w = textureContainer->header.info.width >> depthStencilTargetInfo->mip_level; + h = textureContainer->header.info.height >> depthStencilTargetInfo->mip_level; // The framebuffer cannot be larger than the smallest attachment. @@ -7869,8 +7869,8 @@ static void VULKAN_BeginRenderPass( renderer, vulkanCommandBuffer, textureContainer, - 0, - 0, + depthStencilTargetInfo->layer, + depthStencilTargetInfo->mip_level, depthStencilTargetInfo->cycle, VULKAN_TEXTURE_USAGE_MODE_DEPTH_STENCIL_ATTACHMENT);