GPU: Allow rendering into depth texture layers and levels

This commit is contained in:
cosmonaut
2025-09-12 13:14:38 -07:00
committed by Sam Lantinga
parent 98e22213da
commit 9603360b7e
5 changed files with 28 additions and 22 deletions

View File

@@ -2055,6 +2055,8 @@ typedef struct SDL_GPUColorTargetInfo
* *
* Note that depth/stencil targets do not support multisample resolves. * 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. * \since This struct is available since SDL 3.2.0.
* *
* \sa SDL_BeginGPURenderPass * \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. */ 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 */ 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 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 mip_level; /**< The mip level to use as the depth stencil target. */
Uint8 padding2; Uint8 layer; /**< The layer index to use as the depth stencil target. */
} SDL_GPUDepthStencilTargetInfo; } SDL_GPUDepthStencilTargetInfo;
/** /**
@@ -4492,8 +4494,3 @@ extern SDL_DECLSPEC void SDLCALL SDL_GDKResumeGPU(SDL_GPUDevice *device);
#include <SDL3/SDL_close_code.h> #include <SDL3/SDL_close_code.h>
#endif /* SDL_gpu_h_ */ #endif /* SDL_gpu_h_ */

View File

@@ -1688,6 +1688,14 @@ SDL_GPURenderPass *SDL_BeginGPURenderPass(
return NULL; 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) { if (COMMAND_BUFFER_DEVICE->debug_mode) {
CHECK_COMMAND_BUFFER_RETURN_NULL CHECK_COMMAND_BUFFER_RETURN_NULL
CHECK_ANY_PASS_IN_PROGRESS("Cannot begin render pass during another pass!", 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; return SDL_GPU_TEXTUREFORMAT_INVALID;
} }
} }

View File

@@ -4289,8 +4289,8 @@ static void D3D12_BeginRenderPass(
if (depthStencilTargetInfo != NULL) { if (depthStencilTargetInfo != NULL) {
D3D12TextureContainer *container = (D3D12TextureContainer *)depthStencilTargetInfo->texture; D3D12TextureContainer *container = (D3D12TextureContainer *)depthStencilTargetInfo->texture;
Uint32 h = container->header.info.height; Uint32 h = container->header.info.height >> depthStencilTargetInfo->mip_level;
Uint32 w = container->header.info.width; Uint32 w = container->header.info.width >> depthStencilTargetInfo->mip_level;
// The framebuffer cannot be larger than the smallest target. // The framebuffer cannot be larger than the smallest target.
@@ -4359,8 +4359,8 @@ static void D3D12_BeginRenderPass(
D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite( D3D12TextureSubresource *subresource = D3D12_INTERNAL_PrepareTextureSubresourceForWrite(
d3d12CommandBuffer, d3d12CommandBuffer,
container, container,
0, depthStencilTargetInfo->layer,
0, depthStencilTargetInfo->mip_level,
depthStencilTargetInfo->cycle, depthStencilTargetInfo->cycle,
D3D12_RESOURCE_STATE_DEPTH_WRITE); D3D12_RESOURCE_STATE_DEPTH_WRITE);

View File

@@ -2319,6 +2319,8 @@ static void METAL_BeginRenderPass(
depthStencilTargetInfo->cycle); depthStencilTargetInfo->cycle);
passDescriptor.depthAttachment.texture = texture->handle; 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.loadAction = SDLToMetal_LoadOp[depthStencilTargetInfo->load_op];
passDescriptor.depthAttachment.storeAction = SDLToMetal_StoreOp[depthStencilTargetInfo->store_op]; passDescriptor.depthAttachment.storeAction = SDLToMetal_StoreOp[depthStencilTargetInfo->store_op];
passDescriptor.depthAttachment.clearDepth = depthStencilTargetInfo->clear_depth; passDescriptor.depthAttachment.clearDepth = depthStencilTargetInfo->clear_depth;
@@ -2352,8 +2354,8 @@ static void METAL_BeginRenderPass(
if (depthStencilTargetInfo != NULL) { if (depthStencilTargetInfo != NULL) {
MetalTextureContainer *container = (MetalTextureContainer *)depthStencilTargetInfo->texture; MetalTextureContainer *container = (MetalTextureContainer *)depthStencilTargetInfo->texture;
Uint32 w = container->header.info.width; Uint32 w = container->header.info.width >> depthStencilTargetInfo->mip_level;
Uint32 h = container->header.info.height; Uint32 h = container->header.info.height >> depthStencilTargetInfo->mip_level;
if (w < vpWidth) { if (w < vpWidth) {
vpWidth = w; vpWidth = w;

View File

@@ -7276,8 +7276,8 @@ static VulkanFramebuffer *VULKAN_INTERNAL_FetchFramebuffer(
} else { } else {
VulkanTextureSubresource *subresource = VULKAN_INTERNAL_FetchTextureSubresource( VulkanTextureSubresource *subresource = VULKAN_INTERNAL_FetchTextureSubresource(
(VulkanTextureContainer *)depthStencilTargetInfo->texture, (VulkanTextureContainer *)depthStencilTargetInfo->texture,
0, depthStencilTargetInfo->layer,
0); depthStencilTargetInfo->mip_level);
key.depthStencilAttachmentView = subresource->depthStencilView; key.depthStencilAttachmentView = subresource->depthStencilView;
} }
@@ -7332,8 +7332,8 @@ static VulkanFramebuffer *VULKAN_INTERNAL_FetchFramebuffer(
if (depthStencilTargetInfo != NULL) { if (depthStencilTargetInfo != NULL) {
VulkanTextureSubresource *subresource = VULKAN_INTERNAL_FetchTextureSubresource( VulkanTextureSubresource *subresource = VULKAN_INTERNAL_FetchTextureSubresource(
(VulkanTextureContainer *)depthStencilTargetInfo->texture, (VulkanTextureContainer *)depthStencilTargetInfo->texture,
0, depthStencilTargetInfo->layer,
0); depthStencilTargetInfo->mip_level);
imageViewAttachments[attachmentCount] = subresource->depthStencilView; imageViewAttachments[attachmentCount] = subresource->depthStencilView;
attachmentCount += 1; attachmentCount += 1;
@@ -7813,8 +7813,8 @@ static void VULKAN_BeginRenderPass(
if (depthStencilTargetInfo != NULL) { if (depthStencilTargetInfo != NULL) {
VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)depthStencilTargetInfo->texture; VulkanTextureContainer *textureContainer = (VulkanTextureContainer *)depthStencilTargetInfo->texture;
w = textureContainer->header.info.width; w = textureContainer->header.info.width >> depthStencilTargetInfo->mip_level;
h = textureContainer->header.info.height; h = textureContainer->header.info.height >> depthStencilTargetInfo->mip_level;
// The framebuffer cannot be larger than the smallest attachment. // The framebuffer cannot be larger than the smallest attachment.
@@ -7869,8 +7869,8 @@ static void VULKAN_BeginRenderPass(
renderer, renderer,
vulkanCommandBuffer, vulkanCommandBuffer,
textureContainer, textureContainer,
0, depthStencilTargetInfo->layer,
0, depthStencilTargetInfo->mip_level,
depthStencilTargetInfo->cycle, depthStencilTargetInfo->cycle,
VULKAN_TEXTURE_USAGE_MODE_DEPTH_STENCIL_ATTACHMENT); VULKAN_TEXTURE_USAGE_MODE_DEPTH_STENCIL_ATTACHMENT);