private bool IsPhysicalDeviceSuitable(VkPhysicalDevice physicalDevice) { QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice); bool extensionsSupported = this.CheckPhysicalDeviceExtensionSupport(physicalDevice); // acquire Raytracing features VkPhysicalDeviceRayTracingFeaturesKHR rayTracingFeatures = new VkPhysicalDeviceRayTracingFeaturesKHR() { sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR, pNext = null, }; VkPhysicalDeviceFeatures2 deviceFeatures2 = new VkPhysicalDeviceFeatures2() { sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, pNext = &rayTracingFeatures, }; VulkanNative.vkGetPhysicalDeviceFeatures2(physicalDevice, &deviceFeatures2); extensionsSupported = extensionsSupported && rayTracingFeatures.rayTracing; bool swapChainAdequate = false; if (extensionsSupported) { SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(physicalDevice); swapChainAdequate = (swapChainSupport.formats.Length != 0 && swapChainSupport.presentModes.Length != 0); } return(indices.IsComplete() && extensionsSupported && swapChainAdequate); }
public Swapchain(GraphicsDevice device, Window window) { Device = device; Window = window; SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(device.PhysicalDevice, device._surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); VkPresentModeKHR presentMode = ChooseSwapPresentMode(swapChainSupport.PresentModes); _extent = ChooseSwapExtent(swapChainSupport.Capabilities); CreateRenderPass(surfaceFormat.format); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } var createInfo = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR, surface = device._surface, minImageCount = imageCount, imageFormat = surfaceFormat.format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = _extent, imageArrayLayers = 1, imageUsage = VkImageUsageFlags.ColorAttachment, imageSharingMode = VkSharingMode.Exclusive, preTransform = swapChainSupport.Capabilities.currentTransform, compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque, presentMode = presentMode, clipped = true, oldSwapchain = VkSwapchainKHR.Null }; vkCreateSwapchainKHR(device.VkDevice, &createInfo, null, out Handle).CheckResult(); var swapChainImages = vkGetSwapchainImagesKHR(device.VkDevice, Handle); _swapChainImageViews = new VkImageView[swapChainImages.Length]; _framebuffers = new VkFramebuffer[swapChainImages.Length]; for (var i = 0; i < swapChainImages.Length; i++) { var viewCreateInfo = new VkImageViewCreateInfo( swapChainImages[i], VkImageViewType.Image2D, surfaceFormat.format, VkComponentMapping.Identity, new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1) ); vkCreateImageView(Device.VkDevice, &viewCreateInfo, null, out _swapChainImageViews[i]).CheckResult(); vkCreateFramebuffer(Device.VkDevice, RenderPass, new[] { _swapChainImageViews[i] }, (uint)_extent.Width, (uint)_extent.Height, 1u, out _framebuffers[i]); } }
private static SwapChainSupportDetails QuerySwapChainSupport(VkPhysicalDevice device, VkSurfaceKHR surface) { SwapChainSupportDetails details = new SwapChainSupportDetails(); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, out details.Capabilities).CheckResult(); details.Formats = vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface); details.PresentModes = vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface); return(details); }
private void CreateSwapchain() { SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(physicalDevice, surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); VkPresentModeKHR presentMode = ChooseSwapPresentMode(swapChainSupport.PresentModes); var extent = ChooseSwapExtent(swapChainSupport.Capabilities); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } var createInfo = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR, surface = surface, minImageCount = imageCount, imageFormat = surfaceFormat.format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = extent, imageArrayLayers = 1, imageUsage = VkImageUsageFlags.ColorAttachment, imageSharingMode = VkSharingMode.Exclusive, preTransform = swapChainSupport.Capabilities.currentTransform, compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR, presentMode = presentMode, clipped = true, oldSwapchain = VkSwapchainKHR.Null }; vkCreateSwapchainKHR(device, &createInfo, null, out swapchain).CheckResult(); var swapChainImages = vkGetSwapchainImagesKHR(device, swapchain); swapChainImageViews = new VkImageView[swapChainImages.Length]; for (var i = 0; i < swapChainImages.Length; i++) { var viewCreateInfo = new VkImageViewCreateInfo( swapChainImages[i], VkImageViewType.Image2D, surfaceFormat.format, VkComponentMapping.Identity, new VkImageSubresourceRange(VkImageAspectFlags.Color, 0, 1, 0, 1) ); vkCreateImageView(device, &viewCreateInfo, null, out swapChainImageViews[i]).CheckResult(); } }
private bool IsPhysicalDeviceSuitable(VkPhysicalDevice physicalDevice) { QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice); bool extensionsSupported = this.CheckPhysicalDeviceExtensionSupport(physicalDevice); bool swapChainAdequate = false; if (extensionsSupported) { SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(physicalDevice); swapChainAdequate = (swapChainSupport.formats.Length != 0 && swapChainSupport.presentModes.Length != 0); } return(indices.IsComplete() && extensionsSupported && swapChainAdequate); }
private void CreateSwapChain() { SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice); uint imageCount = swapChainSupport.Capabilities.MinImageCount + 1; if (swapChainSupport.Capabilities.MaxImageCount > 0 && imageCount > swapChainSupport.Capabilities.MaxImageCount) { imageCount = swapChainSupport.Capabilities.MaxImageCount; } SurfaceFormat surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.Formats); QueueFamilyIndices queueFamilies = this.FindQueueFamilies(this.physicalDevice); var indices = queueFamilies.Indices.ToArray(); Extent2D extent = this.ChooseSwapExtent(swapChainSupport.Capabilities); this.swapChain = device.CreateSwapchain(new SwapchainCreateInfo { Surface = surface, Flags = SwapchainCreateFlags.None, PresentMode = this.ChooseSwapPresentMode(swapChainSupport.PresentModes), MinImageCount = imageCount, ImageExtent = extent, ImageUsage = ImageUsageFlags.ColorAttachment, PreTransform = swapChainSupport.Capabilities.CurrentTransform, ImageArrayLayers = 1, ImageSharingMode = indices.Length == 1 ? SharingMode.Exclusive : SharingMode.Concurrent, QueueFamilyIndices = indices, ImageFormat = surfaceFormat.Format, ImageColorSpace = surfaceFormat.ColorSpace, Clipped = true, CompositeAlpha = CompositeAlphaFlags.Opaque, OldSwapchain = this.swapChain }); this.swapChainFormat = surfaceFormat.Format; this.swapChainExtent = extent; this.swapChainImages = this.swapChain.GetImages(); this.swapChainImageViews = swapChainImages.Select(image => this.CreateImageView(image, this.swapChainFormat, ImageAspectFlags.Color)).ToArray(); }
private void CreateSwapChain() { SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice); uint imageCount = swapChainSupport.Capabilities.MinImageCount + 1; if (swapChainSupport.Capabilities.MaxImageCount > 0 && imageCount > swapChainSupport.Capabilities.MaxImageCount) { imageCount = swapChainSupport.Capabilities.MaxImageCount; } SurfaceFormat surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.Formats); QueueFamilyIndices queueFamilies = this.FindQueueFamilies(this.physicalDevice); var indices = queueFamilies.Indices.ToArray(); Extent2D extent = this.ChooseSwapExtent(swapChainSupport.Capabilities); this.swapChain = device.CreateSwapchain(surface, imageCount, surfaceFormat.Format, surfaceFormat.ColorSpace, extent, 1, ImageUsageFlags.ColorAttachment | ImageUsageFlags.TransferDestination, indices.Length == 1 ? SharingMode.Exclusive : SharingMode.Concurrent, indices, swapChainSupport.Capabilities.CurrentTransform, CompositeAlphaFlags.Opaque, this.ChooseSwapPresentMode(swapChainSupport.PresentModes), true, this.swapChain); this.swapChainFormat = surfaceFormat.Format; this.swapChainExtent = extent; this.swapChainImages = this.swapChain.GetImages(); this.swapChainImageViews = swapChainImages.Select(image => this.CreateImageView(image, this.swapChainFormat, ImageAspectFlags.Color)).ToArray(); }
internal unsafe VulkanPhysicalDevice(Vk vk, VulkanContext context, PhysicalDevice physicalDevice) : base(vk) { if (context.Instance is null) { throw new NullReferenceException(nameof(context.Instance)); } _Context = context; _PhysicalDevice = physicalDevice; VK.GetPhysicalDeviceProperties(this, out PhysicalDeviceProperties properties); APIVersion = properties.ApiVersion; DriverVersion = properties.DriverVersion; VendorID = properties.VendorID; DeviceID = properties.DeviceID; Type = properties.DeviceType; Name = SilkMarshal.PtrToString((nint)properties.DeviceName); SwapChainSupportDetails = GetSwapChainSupport(); _Extensions = GetExtensions(); }
private SwapChainSupportDetails QuerySwapChainSupport(VkPhysicalDevice physicalDevice) { SwapChainSupportDetails details = default; // Capabilities Helpers.CheckErrors(VulkanNative.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &details.capabilities)); // Formats uint formatCount; Helpers.CheckErrors(VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, null)); if (formatCount != 0) { details.formats = new VkSurfaceFormatKHR[formatCount]; fixed(VkSurfaceFormatKHR *formatsPtr = &details.formats[0]) { Helpers.CheckErrors(VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, surface, &formatCount, formatsPtr)); } } // Present Modes uint presentModeCount; Helpers.CheckErrors(VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, null)); if (presentModeCount != 0) { details.presentModes = new VkPresentModeKHR[presentModeCount]; fixed(VkPresentModeKHR *presentModesPtr = &details.presentModes[0]) { Helpers.CheckErrors(VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(physicalDevice, surface, &presentModeCount, presentModesPtr)); } } return(details); }
private void QuerySwapchainSupport(PhysicalDevice device, out SwapChainSupportDetails details) { details = new SwapChainSupportDetails(); var res = this.VkSurface.GetPhysicalDeviceSurfaceCapabilities(device, this.WindowSurface, out details.Capabilities); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Unable to get Surface Capabilities of this physical device!", res); } uint count = 0; res = this.VkSurface.GetPhysicalDeviceSurfaceFormats(device, this.WindowSurface, &count, null); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Unable to get Surface Formats of this physical device!", res); } if (count != 0) { details.Formats = new SurfaceFormatKHR[count]; fixed(SurfaceFormatKHR *pFormats = details.Formats) { res = this.VkSurface.GetPhysicalDeviceSurfaceFormats(device, this.WindowSurface, &count, pFormats); } if (res != Result.Success) { throw new VMASharp.VulkanResultException("Unable to get Surface Formats of this physical device!", res); } count = 0; //Reset count because its now non-zero } else { details.Formats = Array.Empty <SurfaceFormatKHR>(); } res = this.VkSurface.GetPhysicalDeviceSurfacePresentModes(device, this.WindowSurface, &count, null); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Unable to get Surface Present Modes of this physical device!", res); } if (count != 0) { details.PresentModes = new PresentModeKHR[count]; fixed(PresentModeKHR *pPresentModes = details.PresentModes) { res = this.VkSurface.GetPhysicalDeviceSurfacePresentModes(device, this.WindowSurface, &count, pPresentModes); } if (res != Result.Success) { throw new VMASharp.VulkanResultException("Unable to get Surface Present Modes of this physical device!", res); } } else { details.PresentModes = Array.Empty <PresentModeKHR>(); } }
private void CreateSwapChain() { // Create SwapChain SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice); VkSurfaceFormatKHR surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.formats); VkPresentModeKHR presentMode = this.ChooseSwapPresentMode(swapChainSupport.presentModes); VkExtent2D extent = this.ChooseSwapExtent(swapChainSupport.capabilities); uint imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { imageCount = swapChainSupport.capabilities.maxImageCount; } VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.surface = surface; createInfo.minImageCount = imageCount; createInfo.imageFormat = surfaceFormat.format; createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageExtent = extent; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; QueueFamilyIndices indices = this.FindQueueFamilies(this.physicalDevice); uint *queueFamilyIndices = stackalloc uint[] { indices.graphicsFamily.Value, indices.presentFamily.Value }; if (indices.graphicsFamily != indices.presentFamily) { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = 2; createInfo.pQueueFamilyIndices = queueFamilyIndices; } else { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE; createInfo.queueFamilyIndexCount = 0; //Optional createInfo.pQueueFamilyIndices = null; //Optional } createInfo.preTransform = swapChainSupport.capabilities.currentTransform; createInfo.compositeAlpha = VkCompositeAlphaFlagsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = presentMode; createInfo.clipped = true; createInfo.oldSwapchain = 0; fixed(VkSwapchainKHR *swapChainPtr = &swapChain) { Helpers.CheckErrors(VulkanNative.vkCreateSwapchainKHR(device, &createInfo, null, swapChainPtr)); } // SwapChain Images VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, null); this.swapChainImages = new VkImage[imageCount]; fixed(VkImage *swapChainImagesPtr = &this.swapChainImages[0]) { VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImagesPtr); } this.swapChainImageFormat = surfaceFormat.format; this.swapChainExtent = extent; }
private VkSwapchainKHR CreateSwapchain() { VkSurfaceCapabilitiesKHR capabilities; vkGetPhysicalDeviceSurfaceCapabilitiesKHR(Context.PhysicalDevice, Surface, out capabilities).CheckResult(); uint count; vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, null); VkSurfaceFormatKHR[] formats = new VkSurfaceFormatKHR[(int)count]; fixed(VkSurfaceFormatKHR *formatsPtr = formats) vkGetPhysicalDeviceSurfaceFormatsKHR(Context.PhysicalDevice, Surface, &count, formatsPtr).CheckResult(); vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, null).CheckResult(); VkPresentModeKHR[] presentModes = new VkPresentModeKHR[count]; fixed(VkPresentModeKHR *presentModesPtr = presentModes) vkGetPhysicalDeviceSurfacePresentModesKHR(Context.PhysicalDevice, Surface, &count, presentModesPtr).CheckResult(); VkFormat format = formats.Length == 1 && formats[0].format == VkFormat.Undefined ? VkFormat.B8G8R8A8UNorm : formats[0].format; VkPresentModeKHR presentMode = presentModes.Contains(VkPresentModeKHR.Mailbox) ? VkPresentModeKHR.Mailbox : presentModes.Contains(VkPresentModeKHR.FifoRelaxed) ? VkPresentModeKHR.FifoRelaxed : presentModes.Contains(VkPresentModeKHR.Fifo) ? VkPresentModeKHR.Fifo : VkPresentModeKHR.Immediate; SwapChainSupportDetails swapChainSupport = QuerySwapChainSupport(Context.PhysicalDevice, Surface); VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.Formats); uint imageCount = swapChainSupport.Capabilities.minImageCount + 1; if (swapChainSupport.Capabilities.maxImageCount > 0 && imageCount > swapChainSupport.Capabilities.maxImageCount) { imageCount = swapChainSupport.Capabilities.maxImageCount; } SwapchainFormat = format; VkSwapchainCreateInfoKHR swapchainCI = new VkSwapchainCreateInfoKHR() { sType = VkStructureType.SwapchainCreateInfoKHR, pNext = null, surface = Surface, minImageCount = imageCount, imageFormat = format, imageColorSpace = surfaceFormat.colorSpace, imageExtent = capabilities.currentExtent, imageUsage = VkImageUsageFlags.ColorAttachment, preTransform = capabilities.currentTransform, imageArrayLayers = 1, imageSharingMode = VkSharingMode.Exclusive, queueFamilyIndexCount = 0, pQueueFamilyIndices = null, presentMode = presentMode, //oldSwapchain = SwapChain, // Setting clipped to VK_TRUE allows the implementation to discard rendering outside of the Surface area clipped = true, compositeAlpha = VkCompositeAlphaFlagsKHR.Opaque, }; VkSwapchainKHR SwapChain; vkCreateSwapchainKHR(Context.Device, &swapchainCI, null, out SwapChain).CheckResult(); return(SwapChain); }