Example #1
0
        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);
        }
Example #2
0
        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]);
            }
        }
Example #3
0
    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);
    }
Example #4
0
            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();
                }
            }
Example #5
0
        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);
        }
Example #6
0
        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();
        }
Example #7
0
        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();
        }
Example #8
0
        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);
        }
Example #10
0
        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;
        }
Example #12
0
        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);
        }