Kaynağa Gözat

GPU: Allow rendering into depth texture layers and levels

cosmonaut 2 gün önce
ebeveyn
işleme
9603360b7e

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

+ 8 - 1
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;
     }
 }
-

+ 4 - 4
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);
 

+ 4 - 2
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;

+ 8 - 8
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);