Example #1
0
        void CreateInstance()
        {
            //LayerProperties[] available_layers = DelegateUtility.EnumerateToArray<LayerProperties> ( vk.EnumerateInstanceLayerProperties );

            ExtensionProperties[] available_extensions = DelegateUtility.EnumerateToArray <ExtensionProperties> (vk.EnumerateInstanceExtensionProperties, IntPtr.Zero);

            List <string> extensions = new List <string> {
                KhrWin32Surface.EXTENSION_NAME, KhrSurface.EXTENSION_NAME
            };

            for (int i = 0; i < extensions.Count; ++i)
            {
                if (!CheckExtensionAvailability(extensions[i], available_extensions))
                {
                    //std::cout << "Could not find instance extension named \"" << extensions[i] << "\"!" << std::endl;
                    return;
                }
            }

            if (CheckExtensionAvailability(ExtDebugReport.EXTENSION_NAME, available_extensions))
            {
                extensions.Add(ExtDebugReport.EXTENSION_NAME);
                supportDebugReport = true;
            }


            var exPtr = MarshalUtility.AllocateString(extensions);

            ApplicationInfo application_info = new ApplicationInfo
            {
                sType              = StructureType.ApplicationInfo,
                pNext              = IntPtr.Zero,
                pApplicationName   = (byte *)Marshal.StringToHGlobalAnsi("Vulkan Window"),
                applicationVersion = new Version(1, 0, 0),
                pEngineName        = (byte *)Marshal.StringToHGlobalAnsi("Vulkan Tutorial"),
                engineVersion      = new Version(1, 0, 0),
                apiVersion         = new Version(1, 0, 0),
            };

            InstanceCreateInfo instance_create_info = new InstanceCreateInfo
            {
                sType                   = StructureType.InstanceCreateInfo,
                pNext                   = IntPtr.Zero,
                flags                   = 0,
                pApplicationInfo        = &application_info,
                enabledLayerCount       = 0,
                ppEnabledLayerNames     = (byte *)0,
                enabledExtensionCount   = (uint)extensions.Count,
                ppEnabledExtensionNames = (byte *)exPtr,
            };

            vk.CreateInstance(ref instance_create_info, (AllocationCallbacks *)0, out vulkan.Instance).CheckError();

            MarshalUtility.FreeString(exPtr, extensions.Count);

            Marshal.FreeHGlobal((IntPtr)application_info.pApplicationName);
            Marshal.FreeHGlobal((IntPtr)application_info.pEngineName);
        }
Example #2
0
        void CreateSwapChain()
        {
            CanRender = false;

            if (!vulkan.Device.IsZero)
            {
                vk.DeviceWaitIdle(vulkan.Device);
            }

            if (vulkan.SwapChain.Images != null)
            {
                for (int i = 0; i < vulkan.SwapChain.Images.Length; ++i)
                {
                    if (vulkan.SwapChain.Images[i].View != ImageView.Zero)
                    {
                        vk.DestroyImageView(vulkan.Device, vulkan.SwapChain.Images[i].View);
                    }
                }
            }

            SurfaceCapabilitiesKHR surface_capabilities;

            khrSurface.GetPhysicalDeviceSurfaceCapabilitiesKHR(vulkan.PhysicalDevice, vulkan.PresentationSurface, out surface_capabilities).CheckError();

            var surface_formats = DelegateUtility.EnumerateToArray <SurfaceFormatKHR> (khrSurface.GetPhysicalDeviceSurfaceFormatsKHR,
                                                                                       (IntPtr)vulkan.PhysicalDevice, (ulong)vulkan.PresentationSurface);

            var present_modes = DelegateUtility.EnumerateToArray <int> (khrSurface.GetPhysicalDeviceSurfacePresentModesKHR,
                                                                        (IntPtr)vulkan.PhysicalDevice, (ulong)vulkan.PresentationSurface);


            uint                        desired_number_of_images = GetSwapChainNumImages(ref surface_capabilities);
            SurfaceFormatKHR            desired_format           = GetSwapChainFormat(surface_formats);
            Extent2D                    desired_extent           = GetSwapChainExtent(ref surface_capabilities);
            ImageUsageFlagBits          desired_usage            = GetSwapChainUsageFlagBits(ref surface_capabilities);
            SurfaceTransformFlagBitsKHR desired_transform        = GetSwapChainTransform(ref surface_capabilities);
            PresentModeKHR              desired_present_mode     = GetSwapChainPresentMode(present_modes);
            SwapchainKHR                old_swap_chain           = vulkan.SwapChain.Handle;

            if (desired_usage == (ImageUsageFlagBits)(-1))
            {
                return;
            }
            if (desired_present_mode == (PresentModeKHR)(-1))
            {
                return;
            }

            if ((desired_extent.width == 0) || (desired_extent.height == 0))
            {
                // Current surface size is (0, 0) so we can't create a swap chain and render anything (CanRender == false)
                // But we don't wont to kill the application as this situation may occur i.e. when window gets minimized
                return;
            }

            SwapchainCreateInfoKHR swap_chain_create_info = new SwapchainCreateInfoKHR
            {
                sType                 = StructureType.SwapchainCreateInfoKhr,         // VkStructureType                sType
                pNext                 = IntPtr.Zero,                                  // const void                    *pNext
                flags                 = 0,                                            // VkSwapchainCreateFlagBitsKHR      flags
                surface               = vulkan.PresentationSurface,                   // VkSurfaceKHR                   surface
                minImageCount         = desired_number_of_images,                     // uint32_t                       minImageCount
                imageFormat           = desired_format.format,                        // VkFormat                       imageFormat
                imageColorSpace       = desired_format.colorSpace,                    // VkColorSpaceKHR                imageColorSpace
                imageExtent           = desired_extent,                               // VkExtent2D                     imageExtent
                imageArrayLayers      = 1,                                            // uint32_t                       imageArrayLayers
                imageUsage            = desired_usage,                                // VkImageUsageFlagBits              imageUsage
                imageSharingMode      = SharingMode.Exclusive,                        // VkSharingMode                  imageSharingMode
                queueFamilyIndexCount = 0,                                            // uint32_t                       queueFamilyIndexCount
                pQueueFamilyIndices   = (uint *)0,                                    // const uint32_t                *pQueueFamilyIndices
                preTransform          = desired_transform,                            // VkSurfaceTransformFlagBitsKHR  preTransform
                compositeAlpha        = CompositeAlphaFlagBitsKHR.OpaqueBitKhr,       // VkCompositeAlphaFlagBitsKHR    compositeAlpha
                presentMode           = desired_present_mode,                         // VkPresentModeKHR               presentMode
                clipped               = Boolean32.True,                               // VkBool32                       clipped
                oldSwapchain          = old_swap_chain                                // VkSwapchainKHR                 oldSwapchain
            };

            khrSwapChain.CreateSwapchainKHR(vulkan.Device, ref swap_chain_create_info, (AllocationCallbacks *)0, out vulkan.SwapChain.Handle).CheckError();

            if (!old_swap_chain.IsZero)
            {
                khrSwapChain.DestroySwapchainKHR(vulkan.Device, old_swap_chain);
            }

            vulkan.SwapChain.Format = desired_format.format;

            var images = DelegateUtility.EnumerateToArray <Image> (khrSwapChain.GetSwapchainImagesKHR,
                                                                   (IntPtr)vulkan.Device, (ulong)vulkan.SwapChain.Handle);

            if (vulkan.SwapChain.Images == null || vulkan.SwapChain.Images.Length != images.Length)
            {
                vulkan.SwapChain.Images = new ImageParameters[images.Length];
            }

            for (int i = 0; i < images.Length; ++i)
            {
                vulkan.SwapChain.Images[i].Handle = images[i];
            }

            vulkan.SwapChain.Extent = desired_extent;

            CreateSwapChainImageViews();
        }
Example #3
0
        bool CheckPhysicalDeviceProperties(PhysicalDevice physical_device,
                                           out uint graphics_queue_family_index,
                                           out uint present_queue_family_index)
        {
            graphics_queue_family_index = uint.MaxValue;
            present_queue_family_index  = uint.MaxValue;


            ExtensionProperties[] available_extensions = DelegateUtility.EnumerateToArray <ExtensionProperties> (
                vk.EnumerateDeviceExtensionProperties, (IntPtr)physical_device, IntPtr.Zero);

            if (available_extensions == null)
            {
                //std::cout << "Error occurred during physical device " << physical_device << " extensions enumeration!" << std::endl;
                return(false);
            }

            string[] device_extensions = { KhrSwapchain.EXTENSION_NAME };

            for (int i = 0; i < device_extensions.Length; ++i)
            {
                if (!CheckExtensionAvailability(device_extensions[i], available_extensions))
                {
                    //std::cout << "Physical device " << physical_device << " doesn't support extension named \"" << device_extensions[i] << "\"!" << std::endl;
                    return(false);
                }
            }

            PhysicalDeviceProperties device_properties;
            PhysicalDeviceFeatures   device_features;

            vk.GetPhysicalDeviceProperties(physical_device, out device_properties);
            vk.GetPhysicalDeviceFeatures(physical_device, out device_features);

            if (device_properties.apiVersion.Major < 1 ||
                device_properties.limits.maxImageDimension2D < 4096)
            {
                //std::cout << "Physical device " << physical_device << " doesn't support required parameters!" << std::endl;
                return(false);
            }

            QueueFamilyProperties[] queue_family_properties = DelegateUtility.EnumerateToArray <QueueFamilyProperties> (
                vk.GetPhysicalDeviceQueueFamilyProperties, (IntPtr)physical_device);

            if (queue_family_properties == null)
            {
                //std::cout << "Physical device " << physical_device << " doesn't have any queue families!" << std::endl;
                return(false);
            }

            bool[] queue_present_support = new bool[queue_family_properties.Length];

            for (uint i = 0; i < queue_family_properties.Length; ++i)
            {
                Boolean32 support;
                khrSurface.GetPhysicalDeviceSurfaceSupportKHR(physical_device, i, vulkan.PresentationSurface, out support).CheckError();
                queue_present_support[i] = support;

                if ((queue_family_properties[i].queueCount > 0) &&
                    (queue_family_properties[i].queueFlags & QueueFlagBits.GraphicsBit) > 0)
                {
                    // Select first queue that supports graphics
                    if (graphics_queue_family_index == uint.MaxValue)
                    {
                        graphics_queue_family_index = i;
                    }

                    // If there is queue that supports both graphics and present - prefer it
                    if (support)
                    {
                        graphics_queue_family_index = i;
                        present_queue_family_index  = i;

                        return(true);
                    }
                }
            }

            if (present_queue_family_index == uint.MaxValue)
            {
                present_queue_family_index = (uint)Array.IndexOf(queue_present_support, true);
            }

            if (present_queue_family_index == uint.MaxValue || graphics_queue_family_index == uint.MaxValue)
            {
                //std::cout << "Could not find queue families with required properties on physical device " << physical_device << "!" << std::endl;
                return(false);
            }

            return(true);
        }
Example #4
0
        void CreateDevice()
        {
            PhysicalDevice[] physical_devices = DelegateUtility.EnumerateToArray <PhysicalDevice> (vk.EnumeratePhysicalDevices, (IntPtr)vulkan.Instance);

            if (physical_devices == null)
            {
                //std::cout << "Error occurred during physical devices enumeration!" << std::endl;
                return;
            }

            uint selected_graphics_queue_family_index = uint.MaxValue;
            uint selected_present_queue_family_index  = uint.MaxValue;

            for (int i = 0; i < physical_devices.Length; ++i)
            {
                if (CheckPhysicalDeviceProperties(physical_devices[i],
                                                  out selected_graphics_queue_family_index, out selected_present_queue_family_index))
                {
                    vulkan.PhysicalDevice = physical_devices[i];
                }
            }

            if (vulkan.PhysicalDevice.IsZero ||
                selected_graphics_queue_family_index == uint.MaxValue ||
                selected_present_queue_family_index == uint.MaxValue)
            {
                //std::cout << "Could not select physical device based on the chosen properties!" << std::endl;
                return;
            }

            var    queue_create_infos = stackalloc DeviceQueueCreateInfo[2];
            uint   count            = 1;
            float *queue_priorities = stackalloc float[1];

            queue_priorities[0] = 1.0f;

            queue_create_infos[0] = new DeviceQueueCreateInfo
            {
                sType            = StructureType.DeviceQueueCreateInfo,                  // VkStructureType              sType
                pNext            = IntPtr.Zero,                                          // const void                  *pNext
                flags            = 0,                                                    // VkDeviceQueueCreateFlagBits     flags
                queueFamilyIndex = selected_graphics_queue_family_index,                 // uint32_t                     queueFamilyIndex
                queueCount       = 1,                                                    // uint32_t                     queueCount
                pQueuePriorities = queue_priorities                                      // const float                 *pQueuePriorities
            };

            if (selected_graphics_queue_family_index != selected_present_queue_family_index)
            {
                queue_create_infos[1] = new DeviceQueueCreateInfo
                {
                    sType            = StructureType.DeviceQueueCreateInfo,                     // VkStructureType              sType
                    pNext            = IntPtr.Zero,                                             // const void                  *pNext
                    flags            = 0,                                                       // VkDeviceQueueCreateFlagBits     flags
                    queueFamilyIndex = selected_present_queue_family_index,                     // uint32_t                     queueFamilyIndex
                    queueCount       = 1,                                                       // uint32_t                     queueCount
                    pQueuePriorities = queue_priorities                                         // const float                 *pQueuePriorities
                };
                count++;
            }

            const uint exCount = 1;
            var        exPtr   = MarshalUtility.AllocateString(new string[] { KhrSwapchain.EXTENSION_NAME });

            DeviceCreateInfo device_create_info = new DeviceCreateInfo
            {
                sType = StructureType.DeviceCreateInfo,                        // VkStructureType                    sType
                pNext = IntPtr.Zero,                                           // const void                        *pNext
                flags = 0,                                                     // VkDeviceCreateFlagBits                flags
                queueCreateInfoCount    = count,                               // uint32_t                           queueCreateInfoCount
                pQueueCreateInfos       = queue_create_infos,                  // const VkDeviceQueueCreateInfo     *pQueueCreateInfos
                enabledLayerCount       = 0,                                   // uint32_t                           enabledLayerCount
                ppEnabledLayerNames     = (byte *)0,                           // const char * const                *ppEnabledLayerNames
                enabledExtensionCount   = exCount,                             // uint32_t                           enabledExtensionCount
                ppEnabledExtensionNames = (byte *)exPtr,                       // const char * const                *ppEnabledExtensionNames
                pEnabledFeatures        = (PhysicalDeviceFeatures *)0          // const VkPhysicalDeviceFeatures    *pEnabledFeatures
            };

            vk.CreateDevice(vulkan.PhysicalDevice, ref device_create_info, (AllocationCallbacks *)0, out vulkan.Device).CheckError();

            MarshalUtility.FreeString(exPtr, (int)exCount);
        }