From aa61a5cc653f587f4dfae8e2d485f4e79dffdb27 Mon Sep 17 00:00:00 2001 From: Aqua Date: Mon, 2 Sep 2024 20:32:07 +0100 Subject: [PATCH] swapchain textures --- src/grabs.Graphics.Vulkan/VkSwapchain.cs | 17 ++++- .../VkSwapchainTexture.cs | 64 +++++++++++++++++++ tests/grabs.Tests/Program.cs | 4 ++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 src/grabs.Graphics.Vulkan/VkSwapchainTexture.cs diff --git a/src/grabs.Graphics.Vulkan/VkSwapchain.cs b/src/grabs.Graphics.Vulkan/VkSwapchain.cs index 1ca5399..221e8b8 100644 --- a/src/grabs.Graphics.Vulkan/VkSwapchain.cs +++ b/src/grabs.Graphics.Vulkan/VkSwapchain.cs @@ -1,3 +1,4 @@ +using System; using System.Runtime.CompilerServices; using Silk.NET.Vulkan; using Silk.NET.Vulkan.Extensions.KHR; @@ -9,6 +10,10 @@ public sealed unsafe class VkSwapchain : Swapchain { private readonly Vk _vk; private readonly VulkanDevice _device; + + private readonly Format _format; + private uint _width; + private uint _height; private readonly KhrSwapchain _khrSwapchain; @@ -33,6 +38,10 @@ public VkSwapchain(Vk vk, VkDevice device, SurfaceKHR surface, in SwapchainDescr _graphicsQueue = device.GraphicsQueue; _presentQueue = device.PresentQueue; + _format = description.Format; + _width = description.Width; + _height = description.Height; + SwapchainCreateInfoKHR swapchainCreateInfo = new SwapchainCreateInfoKHR() { SType = StructureType.SwapchainCreateInfoKhr, @@ -81,7 +90,13 @@ public VkSwapchain(Vk vk, VkDevice device, SurfaceKHR surface, in SwapchainDescr public override Texture GetSwapchainTexture() { - throw new System.NotImplementedException(); + uint numImages; + _khrSwapchain.GetSwapchainImages(_device, Swapchain, &numImages, null); + Span images = stackalloc Image[(int) numImages]; + fixed (Image* pImages = images) + _khrSwapchain.GetSwapchainImages(_device, Swapchain, &numImages, pImages); + + return new VkSwapchainTexture(_vk, _device, images, _format, _width, _height); } public override void Resize(uint width, uint height) diff --git a/src/grabs.Graphics.Vulkan/VkSwapchainTexture.cs b/src/grabs.Graphics.Vulkan/VkSwapchainTexture.cs new file mode 100644 index 0000000..a91a952 --- /dev/null +++ b/src/grabs.Graphics.Vulkan/VkSwapchainTexture.cs @@ -0,0 +1,64 @@ +using System; +using Silk.NET.Vulkan; +using static grabs.Graphics.Vulkan.VkResult; + +namespace grabs.Graphics.Vulkan; + +public sealed unsafe class VkSwapchainTexture : Texture +{ + private readonly Vk _vk; + private readonly VulkanDevice _device; + + public readonly Image[] Images; + + public readonly ImageView[] Views; + + public VkSwapchainTexture(Vk vk, VulkanDevice device, in ReadOnlySpan images, Format format, uint width, uint height) + : base(TextureDescription.Texture2D(width, height, 1, format, TextureUsage.None)) + { + _vk = vk; + _device = device; + + Images = images.ToArray(); + Views = new ImageView[images.Length]; + + for (int i = 0; i < Views.Length; i++) + { + ImageViewCreateInfo viewInfo = new ImageViewCreateInfo() + { + SType = StructureType.ImageViewCreateInfo, + + Image = images[i], + ViewType = ImageViewType.Type2D, + Format = VkUtils.FormatToVk(format), + + Components = new ComponentMapping() + { + R = ComponentSwizzle.Identity, + G = ComponentSwizzle.Identity, + B = ComponentSwizzle.Identity, + A = ComponentSwizzle.Identity + }, + + SubresourceRange = new ImageSubresourceRange() + { + AspectMask = ImageAspectFlags.ColorBit, + BaseMipLevel = 0, + LevelCount = 1, + BaseArrayLayer = 0, + LayerCount = 1 + } + }; + + CheckResult(_vk.CreateImageView(_device, &viewInfo, null, out Views[i]), "Create swapchain image view"); + } + } + + public override void Dispose() + { + for (int i = 0; i < Images.Length; i++) + _vk.DestroyImageView(_device, Views[i], null); + + // Cannot destroy the actual images themselves as they are owned by the swapchain. + } +} \ No newline at end of file diff --git a/tests/grabs.Tests/Program.cs b/tests/grabs.Tests/Program.cs index cbb16c7..58a7534 100644 --- a/tests/grabs.Tests/Program.cs +++ b/tests/grabs.Tests/Program.cs @@ -12,6 +12,7 @@ using Event = Silk.NET.SDL.Event; using Instance = grabs.Graphics.Instance; using Surface = grabs.Graphics.Surface; +using Texture = grabs.Graphics.Texture; GrabsLog.LogMessage += (type, message) => Console.WriteLine($"[{type}] {message}"); @@ -122,6 +123,8 @@ Swapchain swapchain = device.CreateSwapchain(new SwapchainDescription(width, height, bufferCount: 4, presentMode: PresentMode.VerticalSync)); + Texture swapchainTexture = swapchain.GetSwapchainTexture(); + CommandList commandList = device.CreateCommandList(); bool alive = true; @@ -150,6 +153,7 @@ } commandList.Dispose(); + swapchainTexture.Dispose(); swapchain.Dispose(); device.Dispose(); surface.Dispose();