feat: depth buffer + 3D model matrix — rotating cube now looks correct
- Depth image (D32_SFLOAT) + image view created in VulkanSwapchain - VkPipelineDepthStencilStateCreateInfo: depth test + write enabled, CompareOp=Less - Push constant changed from float angle (4B) to mat4 model (64B) - 3D rotation: RotateY * RotateX in renderer, applied via push constant - Vertex shader: gl_Position = vp * model * vec4(pos, 1.0) - Depth attachment in VkRenderingInfo + depth clear (1.0) - Depth image layout transition (Undefined → DepthStencilAttachmentOptimal) - New Vulkan functions: vkCreateImage, vkDestroyImage, vkGetImageMemoryRequirements, vkBindImageMemory - New structs: VkPipelineDepthStencilStateCreateInfo, VkStencilOpState, VkImageCreateInfo - New enums: VkCompareOp, VkImageType, VkImageTiling - 0 validation errors
This commit is contained in:
@@ -10,18 +10,11 @@ layout(row_major, set = 0, binding = 0) uniform CameraUBO {
|
||||
mat4 vp;
|
||||
};
|
||||
|
||||
layout(push_constant) uniform PC {
|
||||
float angle;
|
||||
layout(row_major, push_constant) uniform PC {
|
||||
mat4 model;
|
||||
} pc;
|
||||
|
||||
void main() {
|
||||
float c = cos(pc.angle);
|
||||
float s = sin(pc.angle);
|
||||
vec3 rotated = vec3(
|
||||
inPosition.x * c - inPosition.y * s,
|
||||
inPosition.x * s + inPosition.y * c,
|
||||
inPosition.z
|
||||
);
|
||||
gl_Position = vp * vec4(rotated, 1.0);
|
||||
gl_Position = vp * pc.model * vec4(inPosition, 1.0);
|
||||
fragColor = inColor;
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -47,6 +47,10 @@ internal static unsafe class Vk
|
||||
public delegate VkResult VkGetFenceStatus(VkDevice device, VkFence fence);
|
||||
public delegate VkResult VkCreateBuffer(VkDevice device, VkBufferCreateInfo* pCreateInfo, nint pAllocator, VkBuffer* pBuffer);
|
||||
public delegate void VkDestroyBuffer(VkDevice device, VkBuffer buffer, nint pAllocator);
|
||||
public delegate VkResult VkCreateImage(VkDevice device, VkImageCreateInfo* pCreateInfo, nint pAllocator, VkImage* pImage);
|
||||
public delegate void VkDestroyImage(VkDevice device, VkImage image, nint pAllocator);
|
||||
public delegate void VkGetImageMemoryRequirements(VkDevice device, VkImage image, VkMemoryRequirements* pMemoryRequirements);
|
||||
public delegate VkResult VkBindImageMemory(VkDevice device, VkImage image, VkDeviceMemory memory, ulong memoryOffset);
|
||||
public delegate VkResult VkAllocateMemory(VkDevice device, VkMemoryAllocateInfo* pAllocateInfo, nint pAllocator, VkDeviceMemory* pMemory);
|
||||
public delegate void VkFreeMemory(VkDevice device, VkDeviceMemory memory, nint pAllocator);
|
||||
public delegate VkResult VkBindBufferMemory(VkDevice device, VkBuffer buffer, VkDeviceMemory memory, ulong memoryOffset);
|
||||
@@ -124,6 +128,10 @@ internal static unsafe class Vk
|
||||
public static VkGetFenceStatus vkGetFenceStatus;
|
||||
public static VkCreateBuffer vkCreateBuffer;
|
||||
public static VkDestroyBuffer vkDestroyBuffer;
|
||||
public static VkCreateImage vkCreateImage;
|
||||
public static VkDestroyImage vkDestroyImage;
|
||||
public static VkGetImageMemoryRequirements vkGetImageMemoryRequirements;
|
||||
public static VkBindImageMemory vkBindImageMemory;
|
||||
public static VkAllocateMemory vkAllocateMemory;
|
||||
public static VkFreeMemory vkFreeMemory;
|
||||
public static VkBindBufferMemory vkBindBufferMemory;
|
||||
@@ -208,6 +216,10 @@ internal static unsafe class Vk
|
||||
vkGetFenceStatus = LoadDev<VkGetFenceStatus>(p, "vkGetFenceStatus");
|
||||
vkCreateBuffer = LoadDev<VkCreateBuffer>(p, "vkCreateBuffer");
|
||||
vkDestroyBuffer = LoadDev<VkDestroyBuffer>(p, "vkDestroyBuffer");
|
||||
vkCreateImage = LoadDev<VkCreateImage>(p, "vkCreateImage");
|
||||
vkDestroyImage = LoadDev<VkDestroyImage>(p, "vkDestroyImage");
|
||||
vkGetImageMemoryRequirements = LoadDev<VkGetImageMemoryRequirements>(p, "vkGetImageMemoryRequirements");
|
||||
vkBindImageMemory = LoadDev<VkBindImageMemory>(p, "vkBindImageMemory");
|
||||
vkAllocateMemory = LoadDev<VkAllocateMemory>(p, "vkAllocateMemory");
|
||||
vkFreeMemory = LoadDev<VkFreeMemory>(p, "vkFreeMemory");
|
||||
vkBindBufferMemory = LoadDev<VkBindBufferMemory>(p, "vkBindBufferMemory");
|
||||
|
||||
@@ -61,6 +61,7 @@ public enum VkStructureType : int
|
||||
CommandBufferBeginInfo = 42,
|
||||
RenderPassBeginInfo = 43,
|
||||
ImageViewCreateInfo = 15,
|
||||
ImageCreateInfo = 14,
|
||||
SemaphoreCreateInfo = 9,
|
||||
FenceCreateInfo = 8,
|
||||
SwapchainCreateInfoKHR = 1000001000,
|
||||
@@ -207,6 +208,31 @@ public enum VkFrontFace : int
|
||||
Clockwise = 1,
|
||||
}
|
||||
|
||||
public enum VkCompareOp : int
|
||||
{
|
||||
Never = 0,
|
||||
Less = 1,
|
||||
Equal = 2,
|
||||
LessOrEqual = 3,
|
||||
Greater = 4,
|
||||
NotEqual = 5,
|
||||
GreaterOrEqual = 6,
|
||||
Always = 7,
|
||||
}
|
||||
|
||||
public enum VkImageType : int
|
||||
{
|
||||
Type1D = 0,
|
||||
Type2D = 1,
|
||||
Type3D = 2,
|
||||
}
|
||||
|
||||
public enum VkImageTiling : int
|
||||
{
|
||||
Optimal = 0,
|
||||
Linear = 1,
|
||||
}
|
||||
|
||||
public enum VkBlendFactor : int
|
||||
{
|
||||
Zero = 0,
|
||||
@@ -283,6 +309,8 @@ public enum VkPipelineStageFlags2 : ulong
|
||||
public enum VkAccessFlags2 : ulong
|
||||
{
|
||||
None = 0,
|
||||
DepthStencilAttachmentWrite = 0x00000400,
|
||||
DepthStencilAttachmentRead = 0x00000200,
|
||||
ColorAttachmentRead = 0x00000080,
|
||||
ColorAttachmentWrite = 0x00000100,
|
||||
TransferRead = 0x00000800,
|
||||
|
||||
@@ -14,7 +14,7 @@ internal sealed unsafe class VulkanPipeline : IDisposable
|
||||
private readonly VkDevice _device;
|
||||
private bool _disposed;
|
||||
|
||||
public VulkanPipeline(VkDevice device, VkFormat colorFormat, byte[] vertSpv, byte[] fragSpv)
|
||||
public VulkanPipeline(VkDevice device, VkFormat colorFormat, VkFormat depthFormat, byte[] vertSpv, byte[] fragSpv)
|
||||
{
|
||||
_device = device;
|
||||
VertModule = CreateShaderModule(vertSpv);
|
||||
@@ -115,6 +115,16 @@ internal sealed unsafe class VulkanPipeline : IDisposable
|
||||
sampleShadingEnable = VkBool32.False,
|
||||
};
|
||||
|
||||
var depthStencilState = new VkPipelineDepthStencilStateCreateInfo
|
||||
{
|
||||
sType = VkStructureType.PipelineDepthStencilStateCreateInfo,
|
||||
depthTestEnable = VkBool32.True,
|
||||
depthWriteEnable = VkBool32.True,
|
||||
depthCompareOp = VkCompareOp.Less,
|
||||
depthBoundsTestEnable = VkBool32.False,
|
||||
stencilTestEnable = VkBool32.False,
|
||||
};
|
||||
|
||||
var blendAttachment = new VkPipelineColorBlendAttachmentState
|
||||
{
|
||||
blendEnable = VkBool32.False,
|
||||
@@ -144,7 +154,7 @@ internal sealed unsafe class VulkanPipeline : IDisposable
|
||||
{
|
||||
stageFlags = VkShaderStageFlags.Vertex,
|
||||
offset = 0,
|
||||
size = 4,
|
||||
size = 64,
|
||||
};
|
||||
|
||||
var descLayout = DescriptorSetLayout;
|
||||
@@ -169,6 +179,7 @@ internal sealed unsafe class VulkanPipeline : IDisposable
|
||||
sType = VkStructureType.PipelineRenderingCreateInfo,
|
||||
colorAttachmentCount = 1,
|
||||
pColorAttachmentFormats = &colorFormat,
|
||||
depthAttachmentFormat = depthFormat,
|
||||
};
|
||||
|
||||
var pipelineInfo = new VkGraphicsPipelineCreateInfo
|
||||
@@ -182,6 +193,7 @@ internal sealed unsafe class VulkanPipeline : IDisposable
|
||||
pViewportState = &viewportState,
|
||||
pRasterizationState = &rasterizationState,
|
||||
pMultisampleState = &multisampleState,
|
||||
pDepthStencilState = &depthStencilState,
|
||||
pColorBlendState = &colorBlendState,
|
||||
pDynamicState = &dynamicState,
|
||||
layout = PipelineLayout,
|
||||
|
||||
@@ -23,7 +23,7 @@ internal sealed class VulkanRenderContext : IRenderContext
|
||||
};
|
||||
|
||||
_swapchain = new VulkanSwapchain(_ctx.Device, _ctx.PhysicalDevice, _ctx.Surface,
|
||||
surfaceFormat, window.Width, window.Height);
|
||||
surfaceFormat, window.Width, window.Height, _ctx);
|
||||
}
|
||||
|
||||
public IRenderer CreateRenderer()
|
||||
|
||||
@@ -34,7 +34,7 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
||||
var vertSpv = LoadShader("Shaders/triangle.vert.spv");
|
||||
var fragSpv = LoadShader("Shaders/triangle.frag.spv");
|
||||
|
||||
_pipeline = new VulkanPipeline(ctx.Device, swapchain.Format, vertSpv, fragSpv);
|
||||
_pipeline = new VulkanPipeline(ctx.Device, swapchain.Format, swapchain.DepthFormat, vertSpv, fragSpv);
|
||||
|
||||
_frameResources = new VulkanFrameResources(ctx.Device, ctx.GraphicsQueueFamilyIndex,
|
||||
swapchain.ImageCount, ctx, _pipeline.DescriptorSetLayout);
|
||||
@@ -109,11 +109,21 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
||||
0, 0,
|
||||
0x400, 0x100);
|
||||
|
||||
TransitionImageLayoutDepth(cmd, _swapchain.DepthImage,
|
||||
VkImageLayout.Undefined, VkImageLayout.DepthStencilAttachmentOptimal,
|
||||
0, 0,
|
||||
0x100, 0x200);
|
||||
|
||||
var clearValue = new VkClearValue
|
||||
{
|
||||
Color = new VkClearColorValue { Float0 = 0.02f, Float1 = 0.02f, Float2 = 0.02f, Float3 = 1.0f },
|
||||
};
|
||||
|
||||
var depthClearValue = new VkClearValue
|
||||
{
|
||||
DepthStencil = new VkClearDepthStencilValue { Depth = 1.0f, Stencil = 0 },
|
||||
};
|
||||
|
||||
var colorAttachment = new VkRenderingAttachmentInfo
|
||||
{
|
||||
sType = VkStructureType.RenderingAttachmentInfo,
|
||||
@@ -124,6 +134,16 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
||||
clearValue = clearValue,
|
||||
};
|
||||
|
||||
var depthAttachment = new VkRenderingAttachmentInfo
|
||||
{
|
||||
sType = VkStructureType.RenderingAttachmentInfo,
|
||||
imageView = _swapchain.DepthImageView,
|
||||
imageLayout = VkImageLayout.DepthStencilAttachmentOptimal,
|
||||
loadOp = VkAttachmentLoadOp.Clear,
|
||||
storeOp = VkAttachmentStoreOp.Store,
|
||||
clearValue = depthClearValue,
|
||||
};
|
||||
|
||||
var renderingInfo = new VkRenderingInfo
|
||||
{
|
||||
sType = VkStructureType.RenderingInfo,
|
||||
@@ -135,6 +155,7 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
||||
layerCount = 1,
|
||||
colorAttachmentCount = 1,
|
||||
pColorAttachments = &colorAttachment,
|
||||
pDepthAttachment = &depthAttachment,
|
||||
};
|
||||
|
||||
Vk.vkCmdBeginRendering(cmd, &renderingInfo);
|
||||
@@ -168,7 +189,8 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
||||
Vk.vkCmdBindIndexBuffer(cmd, _indexBuffer.Buffer, 0, 0);
|
||||
|
||||
var angle = _totalTime;
|
||||
Vk.vkCmdPushConstants(cmd, _pipeline.PipelineLayout, VkShaderStageFlags.Vertex, 0, 4, &angle);
|
||||
var model = Matrix4x4.CreateRotationY(angle) * Matrix4x4.CreateRotationX(angle * 0.5f);
|
||||
Vk.vkCmdPushConstants(cmd, _pipeline.PipelineLayout, VkShaderStageFlags.Vertex, 0, 64, &model);
|
||||
|
||||
Vk.vkCmdDrawIndexed(cmd, _indexCount, 1, 0, 0, 0);
|
||||
|
||||
@@ -282,6 +304,39 @@ internal sealed unsafe class VulkanRenderer : IRenderer, Engine.Graphics.IScreen
|
||||
Vk.vkCmdPipelineBarrier2(cmd, &depInfo);
|
||||
}
|
||||
|
||||
private static void TransitionImageLayoutDepth(VkCommandBuffer cmd, VkImage image,
|
||||
VkImageLayout oldLayout, VkImageLayout newLayout,
|
||||
ulong srcStage, ulong srcAccess,
|
||||
ulong dstStage, ulong dstAccess)
|
||||
{
|
||||
var barrier = new VkImageMemoryBarrier2
|
||||
{
|
||||
sType = VkStructureType.ImageMemoryBarrier2,
|
||||
srcStageMask = srcStage,
|
||||
srcAccessMask = srcAccess,
|
||||
dstStageMask = dstStage,
|
||||
dstAccessMask = dstAccess,
|
||||
oldLayout = oldLayout,
|
||||
newLayout = newLayout,
|
||||
image = image,
|
||||
subresourceRange = new VkImageSubresourceRange
|
||||
{
|
||||
AspectMask = VkImageAspectFlags.Depth,
|
||||
LevelCount = 1,
|
||||
LayerCount = 1,
|
||||
},
|
||||
};
|
||||
|
||||
var depInfo = new VkDependencyInfo
|
||||
{
|
||||
sType = VkStructureType.DependencyInfo,
|
||||
imageMemoryBarrierCount = 1,
|
||||
pImageMemoryBarriers = &barrier,
|
||||
};
|
||||
|
||||
Vk.vkCmdPipelineBarrier2(cmd, &depInfo);
|
||||
}
|
||||
|
||||
private static byte[] LoadShader(string path)
|
||||
{
|
||||
if (!File.Exists(path))
|
||||
|
||||
@@ -671,7 +671,7 @@ public unsafe struct VkGraphicsPipelineCreateInfo
|
||||
public VkPipelineViewportStateCreateInfo* pViewportState;
|
||||
public VkPipelineRasterizationStateCreateInfo* pRasterizationState;
|
||||
public VkPipelineMultisampleStateCreateInfo* pMultisampleState;
|
||||
public nint pDepthStencilState;
|
||||
public VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
|
||||
public VkPipelineColorBlendStateCreateInfo* pColorBlendState;
|
||||
public VkPipelineDynamicStateCreateInfo* pDynamicState;
|
||||
public VkPipelineLayout layout;
|
||||
@@ -792,7 +792,7 @@ public unsafe struct VkRenderingInfo
|
||||
public uint viewMask;
|
||||
public uint colorAttachmentCount;
|
||||
public VkRenderingAttachmentInfo* pColorAttachments;
|
||||
public nint pDepthAttachment;
|
||||
public VkRenderingAttachmentInfo* pDepthAttachment;
|
||||
public nint pStencilAttachment;
|
||||
}
|
||||
|
||||
@@ -908,6 +908,55 @@ public unsafe struct VkDebugUtilsMessengerCallbackDataEXT
|
||||
public nint pObjects;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct VkStencilOpState
|
||||
{
|
||||
public int failOp;
|
||||
public int passOp;
|
||||
public int depthFailOp;
|
||||
public int compareOp;
|
||||
public uint compareMask;
|
||||
public uint writeMask;
|
||||
public uint reference;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct VkPipelineDepthStencilStateCreateInfo
|
||||
{
|
||||
public VkStructureType sType;
|
||||
public nint pNext;
|
||||
public uint flags;
|
||||
public VkBool32 depthTestEnable;
|
||||
public VkBool32 depthWriteEnable;
|
||||
public VkCompareOp depthCompareOp;
|
||||
public VkBool32 depthBoundsTestEnable;
|
||||
public VkBool32 stencilTestEnable;
|
||||
public VkStencilOpState front;
|
||||
public VkStencilOpState back;
|
||||
public float minDepthBounds;
|
||||
public float maxDepthBounds;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct VkImageCreateInfo
|
||||
{
|
||||
public VkStructureType sType;
|
||||
public nint pNext;
|
||||
public uint flags;
|
||||
public VkImageType imageType;
|
||||
public VkFormat format;
|
||||
public VkExtent3D extent;
|
||||
public uint mipLevels;
|
||||
public uint arrayLayers;
|
||||
public VkSampleCountFlags samples;
|
||||
public VkImageTiling tiling;
|
||||
public VkImageUsageFlags usage;
|
||||
public VkSharingMode sharingMode;
|
||||
public uint queueFamilyIndexCount;
|
||||
public uint* pQueueFamilyIndices;
|
||||
public VkImageLayout initialLayout;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public unsafe struct VkPushConstantRange
|
||||
{
|
||||
|
||||
@@ -11,19 +11,26 @@ internal sealed unsafe class VulkanSwapchain : IDisposable
|
||||
public VkExtent2D Extent;
|
||||
public uint ImageCount;
|
||||
|
||||
public VkImage DepthImage;
|
||||
public VkDeviceMemory DepthImageMemory;
|
||||
public VkImageView DepthImageView;
|
||||
public VkFormat DepthFormat = VkFormat.D32Sfloat;
|
||||
|
||||
private readonly VkDevice _device;
|
||||
private readonly VkPhysicalDevice _physicalDevice;
|
||||
private readonly VkSurfaceKHR _surface;
|
||||
private readonly VkSurfaceFormatKHR _surfaceFormat;
|
||||
private readonly VulkanContext _ctx;
|
||||
private bool _disposed;
|
||||
|
||||
public VulkanSwapchain(VkDevice device, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
|
||||
VkSurfaceFormatKHR surfaceFormat, int width, int height)
|
||||
VkSurfaceFormatKHR surfaceFormat, int width, int height, VulkanContext ctx)
|
||||
{
|
||||
_device = device;
|
||||
_physicalDevice = physicalDevice;
|
||||
_surface = surface;
|
||||
_surfaceFormat = surfaceFormat;
|
||||
_ctx = ctx;
|
||||
Create(width, height);
|
||||
}
|
||||
|
||||
@@ -132,6 +139,81 @@ internal sealed unsafe class VulkanSwapchain : IDisposable
|
||||
}
|
||||
|
||||
Console.WriteLine($"[Vulkan] Swapchain: {actualCount} images, {Extent.Width}x{Extent.Height}, format={Format}");
|
||||
|
||||
CreateDepthResources();
|
||||
}
|
||||
|
||||
private void CreateDepthResources()
|
||||
{
|
||||
var imageInfo = new VkImageCreateInfo
|
||||
{
|
||||
sType = VkStructureType.ImageCreateInfo,
|
||||
imageType = VkImageType.Type2D,
|
||||
format = DepthFormat,
|
||||
extent = new VkExtent3D { Width = Extent.Width, Height = Extent.Height, Depth = 1 },
|
||||
mipLevels = 1,
|
||||
arrayLayers = 1,
|
||||
samples = VkSampleCountFlags.Count1,
|
||||
tiling = VkImageTiling.Optimal,
|
||||
usage = VkImageUsageFlags.DepthStencilAttachment,
|
||||
sharingMode = VkSharingMode.Exclusive,
|
||||
initialLayout = VkImageLayout.Undefined,
|
||||
};
|
||||
|
||||
var depthImg = VkImage.Null;
|
||||
var result = Vk.vkCreateImage(_device, &imageInfo, 0, &depthImg);
|
||||
if (result != VkResult.Success)
|
||||
throw new InvalidOperationException($"vkCreateImage (depth) failed: {result}");
|
||||
DepthImage = depthImg;
|
||||
|
||||
var reqs = new VkMemoryRequirements();
|
||||
Vk.vkGetImageMemoryRequirements(_device, DepthImage, &reqs);
|
||||
|
||||
var memTypeIndex = _ctx.FindMemoryType(reqs.memoryTypeBits, VkMemoryPropertyFlags.DeviceLocal);
|
||||
|
||||
var allocInfo = new VkMemoryAllocateInfo
|
||||
{
|
||||
sType = VkStructureType.MemoryAllocateInfo,
|
||||
allocationSize = reqs.size,
|
||||
memoryTypeIndex = memTypeIndex,
|
||||
};
|
||||
|
||||
var depthMem = VkDeviceMemory.Null;
|
||||
result = Vk.vkAllocateMemory(_device, &allocInfo, 0, &depthMem);
|
||||
if (result != VkResult.Success)
|
||||
throw new InvalidOperationException($"vkAllocateMemory (depth) failed: {result}");
|
||||
DepthImageMemory = depthMem;
|
||||
|
||||
Vk.vkBindImageMemory(_device, DepthImage, DepthImageMemory, 0);
|
||||
|
||||
var viewInfo = new VkImageViewCreateInfo
|
||||
{
|
||||
sType = VkStructureType.ImageViewCreateInfo,
|
||||
image = DepthImage,
|
||||
viewType = VkImageViewType.Type2D,
|
||||
format = DepthFormat,
|
||||
components = new VkComponentMapping
|
||||
{
|
||||
R = VkComponentSwizzle.Identity,
|
||||
G = VkComponentSwizzle.Identity,
|
||||
B = VkComponentSwizzle.Identity,
|
||||
A = VkComponentSwizzle.Identity,
|
||||
},
|
||||
subresourceRange = new VkImageSubresourceRange
|
||||
{
|
||||
AspectMask = VkImageAspectFlags.Depth,
|
||||
BaseMipLevel = 0,
|
||||
LevelCount = 1,
|
||||
BaseArrayLayer = 0,
|
||||
LayerCount = 1,
|
||||
},
|
||||
};
|
||||
|
||||
var depthView = VkImageView.Null;
|
||||
result = Vk.vkCreateImageView(_device, &viewInfo, 0, &depthView);
|
||||
if (result != VkResult.Success)
|
||||
throw new InvalidOperationException($"vkCreateImageView (depth) failed: {result}");
|
||||
DepthImageView = depthView;
|
||||
}
|
||||
|
||||
public void Recreate(int width, int height)
|
||||
@@ -143,6 +225,22 @@ internal sealed unsafe class VulkanSwapchain : IDisposable
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
if (DepthImageView.Handle != 0)
|
||||
{
|
||||
Vk.vkDestroyImageView(_device, DepthImageView, 0);
|
||||
DepthImageView = VkImageView.Null;
|
||||
}
|
||||
if (DepthImage.Handle != 0)
|
||||
{
|
||||
Vk.vkDestroyImage(_device, DepthImage, 0);
|
||||
DepthImage = VkImage.Null;
|
||||
}
|
||||
if (DepthImageMemory.Handle != 0)
|
||||
{
|
||||
Vk.vkFreeMemory(_device, DepthImageMemory, 0);
|
||||
DepthImageMemory = VkDeviceMemory.Null;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ImageViews.Length; i++)
|
||||
{
|
||||
if (ImageViews[i].Handle != 0)
|
||||
|
||||
Reference in New Issue
Block a user