private void CreateDepthStencilBuffer() { var formats = new[] { SharpVulkan.Format.D32SFloatS8UInt, SharpVulkan.Format.D24UNormS8UInt, SharpVulkan.Format.D16UNormS8UInt }; depthStencilFormat = formats.First(format => { context.PhysicalDevice.GetFormatProperties(format, out var formatProperties); return((formatProperties.OptimalTilingFeatures & SharpVulkan.FormatFeatureFlags.DepthStencilAttachment) != 0); }); var tiling = SharpVulkan.ImageTiling.Optimal; var createInfo = new SharpVulkan.ImageCreateInfo { StructureType = SharpVulkan.StructureType.ImageCreateInfo, ImageType = SharpVulkan.ImageType.Image2D, Usage = SharpVulkan.ImageUsageFlags.DepthStencilAttachment, Format = depthStencilFormat, Extent = new SharpVulkan.Extent3D((uint)width, (uint)height, 1), MipLevels = 1, ArrayLayers = 1, Samples = SharpVulkan.SampleCountFlags.Sample1, SharingMode = SharpVulkan.SharingMode.Exclusive, Tiling = tiling, InitialLayout = SharpVulkan.ImageLayout.Undefined }; depthStencilBuffer = context.Device.CreateImage(ref createInfo); depthStencilMemory = context.MemoryAllocator.Allocate(depthStencilBuffer, SharpVulkan.MemoryPropertyFlags.DeviceLocal, tiling); var viewCreateInfo = new SharpVulkan.ImageViewCreateInfo { StructureType = SharpVulkan.StructureType.ImageViewCreateInfo, ViewType = SharpVulkan.ImageViewType.Image2D, Image = depthStencilBuffer, Format = depthStencilFormat, Components = SharpVulkan.ComponentMapping.Identity, SubresourceRange = new SharpVulkan.ImageSubresourceRange( SharpVulkan.ImageAspectFlags.Depth | SharpVulkan.ImageAspectFlags.Stencil) }; depthStencilView = context.Device.CreateImageView(ref viewCreateInfo); var memoryBarrier = new SharpVulkan.ImageMemoryBarrier { StructureType = SharpVulkan.StructureType.ImageMemoryBarrier, Image = depthStencilBuffer, OldLayout = SharpVulkan.ImageLayout.Undefined, NewLayout = SharpVulkan.ImageLayout.DepthStencilAttachmentOptimal, SourceAccessMask = SharpVulkan.AccessFlags.None, DestinationAccessMask = SharpVulkan.AccessFlags.DepthStencilAttachmentRead | SharpVulkan.AccessFlags.DepthStencilAttachmentWrite, SubresourceRange = new SharpVulkan.ImageSubresourceRange( SharpVulkan.ImageAspectFlags.Depth | SharpVulkan.ImageAspectFlags.Stencil) }; context.EndRenderPass(); context.EnsureCommandBuffer(); context.CommandBuffer.PipelineBarrier(SharpVulkan.PipelineStageFlags.TopOfPipe, SharpVulkan.PipelineStageFlags.EarlyFragmentTests | SharpVulkan.PipelineStageFlags.LateFragmentTests, SharpVulkan.DependencyFlags.None, 0, null, 0, null, 1, &memoryBarrier); }
public PlatformRenderTexture2D(PlatformRenderContext context, Format format, int width, int height, TextureParams textureParams) : base(context, format, width, height, false, true, textureParams) { colorFormat = VulkanHelper.GetVKFormat(format); CreateDepthStencilBuffer(); CreateRenderPass(); CreateFramebuffer(); }
private void CreateSwapchain() { var surfaceFormats = context.PhysicalDevice.GetSurfaceFormats(surface); if (surfaceFormats.Length == 1 && surfaceFormats[0].Format == SharpVulkan.Format.Undefined) { backbufferFormat = SharpVulkan.Format.B8G8R8A8UNorm; } else { backbufferFormat = surfaceFormats[0].Format; } context.PhysicalDevice.GetSurfaceCapabilities(surface, out var surfaceCapabilities); if (width < surfaceCapabilities.MinImageExtent.Width || height < surfaceCapabilities.MinImageExtent.Height || width > surfaceCapabilities.MaxImageExtent.Width || height > surfaceCapabilities.MaxImageExtent.Height ) { throw new InvalidOperationException(); } var desiredBufferCount = 3U; if (desiredBufferCount < surfaceCapabilities.MinImageCount) { desiredBufferCount = surfaceCapabilities.MinImageCount; } else if (surfaceCapabilities.MaxImageCount > 0 && desiredBufferCount > surfaceCapabilities.MaxImageCount) { desiredBufferCount = surfaceCapabilities.MaxImageCount; } var preTransform = SharpVulkan.SurfaceTransformFlags.Identity; if ((surfaceCapabilities.SupportedTransforms & preTransform) == 0) { throw new NotSupportedException(); } var compositeAlpha = SharpVulkan.CompositeAlphaFlags.Opaque; if ((surfaceCapabilities.SupportedCompositeAlpha & compositeAlpha) == 0) { throw new NotSupportedException(); } var backbufferUsage = SharpVulkan.ImageUsageFlags.ColorAttachment; if ((surfaceCapabilities.SupportedUsageFlags & backbufferUsage) == 0) { throw new NotSupportedException(); } var supportedPresentModes = context.PhysicalDevice.GetSurfacePresentModes(surface); var presentMode = SharpVulkan.PresentMode.Fifo; if (!vSync) { if (Array.IndexOf(supportedPresentModes, SharpVulkan.PresentMode.Immediate) >= 0) { presentMode = SharpVulkan.PresentMode.Immediate; } else if (Array.IndexOf(supportedPresentModes, SharpVulkan.PresentMode.Mailbox) >= 0) { presentMode = SharpVulkan.PresentMode.Mailbox; } } var oldSwapchain = swapchain; DestroySwapchain(); var createInfo = new SharpVulkan.SwapchainCreateInfo { StructureType = SharpVulkan.StructureType.SwapchainCreateInfo, Surface = surface, PresentMode = presentMode, PreTransform = preTransform, CompositeAlpha = compositeAlpha, ImageUsage = backbufferUsage, ImageFormat = backbufferFormat, ImageColorSpace = SharpVulkan.ColorSpace.SRgbNonlinear, ImageExtent = new SharpVulkan.Extent2D((uint)width, (uint)height), ImageArrayLayers = 1, ImageSharingMode = SharpVulkan.SharingMode.Exclusive, MinImageCount = desiredBufferCount, Clipped = true, OldSwapchain = oldSwapchain }; swapchain = context.Device.CreateSwapchain(ref createInfo); CreateBackbuffers(); CreateDepthStencilBuffer(); CreateRenderPass(); CreateFramebuffers(); AcquireNextImage(); }