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.
*
* 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 <SDL3/SDL_close_code.h>
#endif /* SDL_gpu_h_ */

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);