fix: enable imageCubeArray feature + transition all 24 shadow layers

Two validation errors fixed:
1. imageCubeArray feature not enabled → added VkPhysicalDeviceImageCubeArrayFeatures
   to device creation chain (pNext: cubeArray → sync2 → dynamicRendering)
2. Shadow layers 18-23 in UNDEFINED layout → transition ALL 24 layers
   (MaxShadowLights * 6) instead of only numShadowLights * 6
   Descriptor references all 24 layers via CubeArray view
This commit is contained in:
emil28092005
2026-06-19 08:59:22 +03:00
parent d7b6851217
commit ab1a2d05c3
5 changed files with 21 additions and 4 deletions
Binary file not shown.
+8 -1
View File
@@ -305,10 +305,17 @@ internal sealed unsafe class VulkanContext : IDisposable
synchronization2 = VkBool32.True, synchronization2 = VkBool32.True,
}; };
var cubeArrayFeatures = new VkPhysicalDeviceImageCubeArrayFeatures
{
sType = VkStructureType.PhysicalDeviceImageCubeArrayFeatures,
pNext = (nint)(&sync2Features),
imageCubeArray = VkBool32.True,
};
var renderingFeatures = new VkPhysicalDeviceDynamicRenderingFeatures var renderingFeatures = new VkPhysicalDeviceDynamicRenderingFeatures
{ {
sType = VkStructureType.PhysicalDeviceDynamicRenderingFeatures, sType = VkStructureType.PhysicalDeviceDynamicRenderingFeatures,
pNext = (nint)(&sync2Features), pNext = (nint)(&cubeArrayFeatures),
dynamicRendering = VkBool32.True, dynamicRendering = VkBool32.True,
}; };
@@ -78,6 +78,7 @@ public enum VkStructureType : int
BufferMemoryBarrier2 = 1000314001, BufferMemoryBarrier2 = 1000314001,
DependencyInfo = 1000314003, DependencyInfo = 1000314003,
PhysicalDeviceDynamicRenderingFeatures = 1000044003, PhysicalDeviceDynamicRenderingFeatures = 1000044003,
PhysicalDeviceImageCubeArrayFeatures = 1000056000,
PhysicalDeviceSynchronization2Features = 1000314007, PhysicalDeviceSynchronization2Features = 1000314007,
} }
+4 -3
View File
@@ -308,12 +308,13 @@ public sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreensh
// === SHADOW CUBEMAP ARRAY PASSES (numShadowLights × 6 faces) === // === SHADOW CUBEMAP ARRAY PASSES (numShadowLights × 6 faces) ===
int totalLayers = numShadowLights * 6; int totalLayers = numShadowLights * 6;
// Always transition ALL layers (24) to avoid UNDEFINED layout errors for unused layers
TransitionImageLayout(cmd, _shadowMap.ColorImage, TransitionImageLayout(cmd, _shadowMap.ColorImage,
VkImageLayout.Undefined, VkImageLayout.ColorAttachmentOptimal, VkImageLayout.Undefined, VkImageLayout.ColorAttachmentOptimal,
0, 0, 0x400, 0x100, (uint)totalLayers); 0, 0, 0x400, 0x100, (uint)(VulkanShadowMap.MaxShadowLights * 6));
TransitionImageLayoutDepth(cmd, _shadowMap.DepthImage, TransitionImageLayoutDepth(cmd, _shadowMap.DepthImage,
VkImageLayout.Undefined, VkImageLayout.DepthStencilAttachmentOptimal, VkImageLayout.Undefined, VkImageLayout.DepthStencilAttachmentOptimal,
0, 0, 0x100, 0x200, (uint)totalLayers); 0, 0, 0x100, 0x200, (uint)(VulkanShadowMap.MaxShadowLights * 6));
for (int lightIdx = 0; lightIdx < numShadowLights; lightIdx++) for (int lightIdx = 0; lightIdx < numShadowLights; lightIdx++)
{ {
@@ -422,7 +423,7 @@ public sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreensh
// Transition shadow color array: ColorAttachmentOptimal → ShaderReadOnlyOptimal // Transition shadow color array: ColorAttachmentOptimal → ShaderReadOnlyOptimal
TransitionImageLayout(cmd, _shadowMap.ColorImage, TransitionImageLayout(cmd, _shadowMap.ColorImage,
VkImageLayout.ColorAttachmentOptimal, VkImageLayout.ShaderReadOnlyOptimal, VkImageLayout.ColorAttachmentOptimal, VkImageLayout.ShaderReadOnlyOptimal,
0x400, 0x100, 0x8, 0x20, (uint)totalLayers); 0x400, 0x100, 0x8, 0x20, (uint)(VulkanShadowMap.MaxShadowLights * 6));
// === MAIN PASS === // === MAIN PASS ===
TransitionImageLayout(cmd, _swapchain.Images[imageIndex], TransitionImageLayout(cmd, _swapchain.Images[imageIndex],
@@ -208,6 +208,14 @@ public unsafe struct VkPhysicalDeviceDynamicRenderingFeatures
public VkBool32 dynamicRendering; public VkBool32 dynamicRendering;
} }
[StructLayout(LayoutKind.Sequential)]
public unsafe struct VkPhysicalDeviceImageCubeArrayFeatures
{
public VkStructureType sType;
public nint pNext;
public VkBool32 imageCubeArray;
}
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public unsafe struct VkPhysicalDeviceSynchronization2Features public unsafe struct VkPhysicalDeviceSynchronization2Features
{ {