コード例 #1
0
        public void CreateDevice()
        {
            /*
             * We create the logical device in this function.
             */

            /*
             * When creating the device, we also specify what queues it has.
             */
            // Store memory properties of the physical device.
            PhysicalDeviceMemoryProperties MemoryProperties = physicalDevice.GetMemoryProperties();
            PhysicalDeviceFeatures         Features         = physicalDevice.GetFeatures();
            PhysicalDeviceProperties       Properties       = physicalDevice.GetProperties();

            // Create a logical device.
            var queueCreateInfos = new DeviceQueueCreateInfo[1];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(computeQueueFamilyIndex, 1, 1.0f);

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.NVExternalMemory },
                Features);

            device = physicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            queue = device.GetQueue(computeQueueFamilyIndex);

            // Create command pool(s).
            //commandPool = device.CreateCommandPool(new CommandPoolCreateInfo(computeQueueFamilyIndex));
        }
コード例 #2
0
        static void CreateDevice()
        {
            var queueCreateInfo = new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = 0,
            };

            var deviceEnabledExtensions = new[]
            {
                "VK_KHR_swapchain",
            };

            var deviceCreateInfo = new DeviceCreateInfo
            {
                QueueCreateInfoCount  = 1,
                QueueCreateInfos      = queueCreateInfo,
                EnabledExtensionNames = deviceEnabledExtensions,
            };

            device = physicalDevice.CreateDevice(deviceCreateInfo, null);
            Console.WriteLine("[ OK ] Device");

            var queueNodeIndex = physicalDevice.GetQueueFamilyProperties()
                                 .Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0) //&& physicalDevice.GetSurfaceSupport((uint)index, surface)
                                 .Select((properties, index) => index)
                                 .First();

            queue = device.GetQueue(0, (uint)queueNodeIndex);
            Console.WriteLine("[ OK ] Queue");
        }
コード例 #3
0
        private void CreateLogicalDevice()
        {
            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            var queueCreateInfos = new DeviceQueueCreateInfo[]
            {
                new DeviceQueueCreateInfo()
                {
                    QueueFamilyIndex = (uint)indices.GraphicsFamily,
                    QueueCount       = 1,
                    QueuePriorities  = new float[] { 1.0f },
                }
            };

            var createInfo = new DeviceCreateInfo()
            {
                EnabledExtensionNames = new string[] { "VK_KHR_swapchain" },
                QueueCreateInfos      = queueCreateInfos,
                EnabledFeatures       = new PhysicalDeviceFeatures(),
            };

            vkDevice = vkPhysicalDevice.CreateDevice(createInfo);

            vkGraphicsQueue = vkDevice.GetQueue((uint)indices.GraphicsFamily, 0);
            vkPresentQueue  = vkDevice.GetQueue((uint)indices.PresentFamily, 0);
        }
コード例 #4
0
        Device CreateDevice(PhysicalDevice physicalDevice, uint queueFamily)
        {
            // Device objects represent logical connections to physical devices. Each device exposes
            // a number of queue families each having one or more queues. All queues in a queue family
            // support the same operations.
            //
            // As described above, a Vulkan application will first query for all physical
            // devices in a system. Each physical device can then be queried for its capabilities,
            // including its queue and queue family properties. Once an acceptable physical device is
            // identified, an application will create a corresponding logical device. An application
            // must create a separate logical device for each physical device it will use. The created
            // logical device is then the primary interface to the physical device.

            String[] enabledLayers = new string[]
            {
                "VK_LAYER_LUNARG_standard_validation"
            };

            var features = new PhysicalDeviceFeatures();

            features.ShaderClipDistance = true;
            features.ShaderCullDistance = true;

            var queueCreateInfo  = new DeviceQueueCreateInfo(queueFamily, new[] { 0f });
            var deviceCreateInfo = new DeviceCreateInfo(new[] { queueCreateInfo }, enabledLayers, null);

            deviceCreateInfo.EnabledFeatures = features;
            return(physicalDevice.CreateDevice(deviceCreateInfo));
        }
コード例 #5
0
        private void CreateDevice()
        {
            QueueFamilyProperties[] queueProps = PhysicalDevice.GetQueueFamilyProperties();
            int computeFamilyIndex             = -1;
            int graphicsFamilyIndex            = -1;
            int sparseBindingFamilyIndex       = -1;
            int transferFamilyIndex            = -1;

            for (var i = 0; i < queueProps.Length; i++)
            {
                QueueFamilyProperties props = queueProps[i];

                if (computeFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.Compute))
                {
                    computeFamilyIndex = i;
                }

                if (graphicsFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.Graphics))
                {
                    graphicsFamilyIndex = i;
                }

                if (sparseBindingFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.SparseBinding))
                {
                    sparseBindingFamilyIndex = i;
                }

                if (transferFamilyIndex == -1 && props.QueueFlags.HasFlag(Queues.Transfer))
                {
                    transferFamilyIndex = i;
                }
            }

            var queueInfos = new[]
            {
                computeFamilyIndex,
                graphicsFamilyIndex,
                sparseBindingFamilyIndex,
                transferFamilyIndex
            }.Distinct().Select(i => new DeviceQueueCreateInfo(i, 1, 1.0f)).ToArray();

            string[] selectExtensions = new[] { Constant.DeviceExtension.ExtDebugMarker }
            .Where(AvailableDeviceExtensions.Contains)
            .ToArray();

            var createInfo = new DeviceCreateInfo(queueInfos, selectExtensions, PhysicalDeviceFeatures);

            Device = PhysicalDevice.CreateDevice(createInfo);

            ComputeQueue       = Device.GetQueue(computeFamilyIndex);
            GraphicsQueue      = Device.GetQueue(graphicsFamilyIndex);
            SparseBindingQueue = Device.GetQueue(sparseBindingFamilyIndex);
            TransferQueue      = Device.GetQueue(transferFamilyIndex);
        }
コード例 #6
0
        public Win32VkContext()
        {
            Instance = Instance.Create(null, new[] { "VK_KHR_surface", "VK_KHR_win32_surface" });

            PhysicalDevice = Instance.EnumeratePhysicalDevices().First();

            Surface = Instance.CreateWin32Surface(Kernel32.CurrentModuleHandle, window.WindowHandle);

            (GraphicsFamily, PresentFamily) = FindQueueFamilies();

            var queueInfos = new[]
            {
                new DeviceQueueCreateInfo {
                    QueueFamilyIndex = GraphicsFamily, QueuePriorities = new[] { 1f }
                },
                new DeviceQueueCreateInfo {
                    QueueFamilyIndex = PresentFamily, QueuePriorities = new[] { 1f }
                },
            };

            Device = PhysicalDevice.CreateDevice(queueInfos, null, null);

            GraphicsQueue = Device.GetQueue(GraphicsFamily, 0);

            PresentQueue = Device.GetQueue(PresentFamily, 0);

            GetProc = (name, instanceHandle, deviceHandle) =>
            {
                if (deviceHandle != IntPtr.Zero)
                {
                    return(Device.GetProcedureAddress(name));
                }

                return(Instance.GetProcedureAddress(name));
            };

            SharpVkGetProc = (name, instance, device) =>
            {
                if (device != null)
                {
                    return(device.GetProcedureAddress(name));
                }
                if (instance != null)
                {
                    return(instance.GetProcedureAddress(name));
                }

                // SharpVk includes the static functions on Instance, but this is not actually correct
                // since the functions are static, they are not tied to an instance. For example,
                // VkCreateInstance is not found on an instance, it is creating said instance.
                // Other libraries, such as VulkanCore, use another type to do this.
                return(Instance.GetProcedureAddress(name));
            };
        }
コード例 #7
0
        public void CreateDevice()
        {
            // Required in order to keep the validation layer happy :)
            PhysicalDevice.GetQueueFamilyProperties();

            var createInfo = new DeviceCreateInfo(new[]
            {
                new DeviceQueueCreateInfo(0, 1, 1.0f)
            });

            using (PhysicalDevice.CreateDevice(createInfo)) { }
            using (PhysicalDevice.CreateDevice(createInfo, CustomAllocator)) { }
        }
コード例 #8
0
        public static Device CreateDevice(PhysicalDevice physicalDevice, bool createDefaultQueue = true, bool includeCommonDebug = false)
        {
            IEnumerable <InitRequest> initRequest = null;

            if (includeCommonDebug)
            {
                initRequest = InitRequestCommonDebug;
            }

            DeviceCreateInfo deviceCreateInfo = VulkanInitUtility.CreateDeviceCreateInfo(physicalDevice, createDefaultQueue, initRequest);

            return(physicalDevice.CreateDevice(deviceCreateInfo));
        }
コード例 #9
0
 public MyDevice CreateDevice(MyQueueFamilyProperties selectedQueue)
 {
     return(new MyDevice(_physicalDevice.CreateDevice(new DeviceCreateInfo {
         QueueCreateInfos = new[] {
             new DeviceQueueCreateInfo {
                 QueueFamilyIndex = selectedQueue.QueueIndex,
                 QueuePriorities = new[] {
                     1.0f
                 }
             },
         }
     })));
 }
コード例 #10
0
ファイル: GraphicsManager.cs プロジェクト: Ciastex/Prisma
        private void InitializeVulkan(PhysicalDevice physDev, SurfaceKhr surface)
        {
            var  queueFamilyProperties = physDev.GetQueueFamilyProperties();
            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physDev.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }
                if (queueFamilyProperties[queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo
            {
                QueuePriorities  = new[] { 1.0f },
                QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo
            {
                EnabledExtensionNames = new[]
                {
                    "VK_KHR_swapchain",
                },
                QueueCreateInfos = new[] { queueInfo }
            };

            _device = physDev.CreateDevice(deviceInfo);

            _queue = _device.GetQueue(0, 0);
            _surfaceCapabilities = physDev.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectSurfaceFormat(physDev, surface);

            _swapchainKhr = CreateSwapchainKhr(surface, surfaceFormat);
            _images       = _device.GetSwapchainImagesKHR(_swapchainKhr);
            _renderPass   = CreateRenderPass(surfaceFormat);
            _framebuffers = CreateFramebuffers(_images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            _fence = _device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            _semaphore      = _device.CreateSemaphore(semaphoreInfo);
            _commandBuffers = CreateCommandBuffers(_images, _framebuffers, _renderPass, _surfaceCapabilities);
        }
コード例 #11
0
        public void CreateLogicalDevice()
        {
            QueueFamilyIndices queueFamilies = helper.FindQueueFamilies(this.physicalDevice, surface);

            this.device = physicalDevice.CreateDevice(queueFamilies.Indices
                                                      .Select(index => new DeviceQueueCreateInfo {
                QueueFamilyIndex = index,
                QueuePriorities  = new[] { 1f }
            }).ToArray(),
                                                      null,
                                                      KhrExtensions.Swapchain);

            this.graphicsQueue = this.device.GetQueue(queueFamilies.GraphicsFamily.Value, 0);
            this.presentQueue  = this.device.GetQueue(queueFamilies.PresentFamily.Value, 0);
        }
コード例 #12
0
ファイル: Program.cs プロジェクト: CloneDeath/Illustrate
 private static Device GetDevice(PhysicalDevice physicalDevice, QueueFamilyPropertiesExt queueFamily)
 {
     return(physicalDevice.CreateDevice(new DeviceCreateInfo
     {
         QueueCreateInfos = new[] {
             new DeviceQueueCreateInfo {
                 QueueFamilyIndex = queueFamily.QueueIndex,
                 QueuePriorities = new[] {
                     1f
                 }
             },
         },
         EnabledExtensionNames = new[] {
             Extension.KhrSwapchain
         }
     }));
 }
コード例 #13
0
        public virtual void Initialize(PhysicalDevice physicalDevice, SurfaceKhr surface)
        {
            var queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();

            uint queueFamilyUsedIndex;

            for (queueFamilyUsedIndex = 0; queueFamilyUsedIndex < queueFamilyProperties.Length; ++queueFamilyUsedIndex)
            {
                if (!physicalDevice.GetSurfaceSupportKHR(queueFamilyUsedIndex, surface))
                {
                    continue;
                }

                if (queueFamilyProperties [queueFamilyUsedIndex].QueueFlags.HasFlag(QueueFlags.Graphics))
                {
                    break;
                }
            }

            var queueInfo = new DeviceQueueCreateInfo {
                QueuePriorities = new float [] { 1.0f }, QueueFamilyIndex = queueFamilyUsedIndex
            };

            var deviceInfo = new DeviceCreateInfo {
                EnabledExtensionNames = new string [] { "VK_KHR_swapchain" },
                QueueCreateInfos      = new DeviceQueueCreateInfo [] { queueInfo }
            };

            device = physicalDevice.CreateDevice(deviceInfo);
            queue  = device.GetQueue(0, 0);
            surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface);
            var surfaceFormat = SelectFormat(physicalDevice, surface);

            swapchain    = CreateSwapchain(surface, surfaceFormat);
            images       = device.GetSwapchainImagesKHR(swapchain);
            renderPass   = CreateRenderPass(surfaceFormat);
            framebuffers = CreateFramebuffers(images, surfaceFormat);
            var fenceInfo = new FenceCreateInfo();

            fence = device.CreateFence(fenceInfo);
            var semaphoreInfo = new SemaphoreCreateInfo();

            semaphore   = device.CreateSemaphore(semaphoreInfo);
            initialized = true;
        }
コード例 #14
0
        private void CreateLogicalDevice()
        {
            QueueFamilyIndices queueFamilies = FindQueueFamilies(physicalDevice);

            device = physicalDevice.CreateDevice(
                queueFamilies.Indices.Select(index => new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = index,
                QueuePriorities  = new[] { 1f }
            }).ToArray(),
                null,
                KhrExtensions.Swapchain
                );

            graphicsQueue = device.GetQueue(queueFamilies.GraphicsFamily.Value, 0);
            presentQueue  = device.GetQueue(queueFamilies.PresentFamily.Value, 0);
            transferQueue = device.GetQueue(queueFamilies.TransferFamily.Value, 0);
        }
コード例 #15
0
ファイル: QueueTest.cs プロジェクト: yongweisun/VulkanCore
        public void PropertiesSet()
        {
            QueueFamilyProperties[] props = PhysicalDevice.GetQueueFamilyProperties();
            int queueFamilyIndex          = props.Length - 1;
            int queueCount       = props[props.Length - 1].QueueCount;
            int queueIndex       = queueCount - 1;
            var deviceCreateInfo = new DeviceCreateInfo(new[]
            {
                new DeviceQueueCreateInfo(queueFamilyIndex, queueCount, Enumerable.Range(0, queueCount).Select(_ => 1.0f).ToArray())
            });

            using (Device device = PhysicalDevice.CreateDevice(deviceCreateInfo))
            {
                Queue queue = device.GetQueue(queueFamilyIndex, queueIndex);

                Assert.Equal(device, queue.Parent);
                Assert.Equal(queueFamilyIndex, queue.FamilyIndex);
                Assert.Equal(queueIndex, queue.Index);
            }
        }
コード例 #16
0
ファイル: Program.cs プロジェクト: CloneDeath/Illustrate
        private static Device CreateAbstractDevice(PhysicalDevice physicalDevice)
        {
            var deviceQueueInfo = new DeviceQueueCreateInfo
            {
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new[] { 1f }
            };

            var deviceInfo = new DeviceCreateInfo
            {
                Flags                 = 0,
                EnabledLayerCount     = 0,
                EnabledLayerNames     = null,
                EnabledExtensionCount = 0,
                EnabledExtensionNames = null,
                QueueCreateInfoCount  = 1,
                QueueCreateInfos      = new[] { deviceQueueInfo }
            };

            return(physicalDevice.CreateDevice(deviceInfo));
        }
コード例 #17
0
ファイル: ExampleBase.cs プロジェクト: jcoder58/Tanagra
        protected Device CreateDevice(PhysicalDevice physicalDevice, uint queueFamily)
        {
            String[] enabledLayers = new string[]
            {
                "VK_LAYER_LUNARG_standard_validation"
            };

            var enabledExtensions = new[]
            {
                VulkanConstant.KhrSwapchainExtensionName,
            };

            var features = new PhysicalDeviceFeatures();

            features.ShaderClipDistance = true;
            features.ShaderCullDistance = true;

            var queueCreateInfo  = new DeviceQueueCreateInfo(queueFamily, new[] { 0f });
            var deviceCreateInfo = new DeviceCreateInfo(new[] { queueCreateInfo }, enabledLayers, enabledExtensions);

            deviceCreateInfo.EnabledFeatures = features;
            return(physicalDevice.CreateDevice(deviceCreateInfo));
        }
コード例 #18
0
        static public MPointArray ComputeData(MPointArray inPos, float angle, float envolope)
        {
            var memorySize = inPos.Count * 4 * sizeof(float);

            float[] ubo = { inPos.Count, angle, envolope };

            // pos to float[]
            float[] allPos = new float[inPos.Count * 4];
            var     i      = 0;

            foreach (var point in inPos)
            {
                allPos[i * 4 + 0] = (float)point.x;
                allPos[i * 4 + 1] = (float)point.y;
                allPos[i * 4 + 2] = (float)point.z;
                allPos[i * 4 + 3] = (float)point.w;
                i++;
            }

            var instance = new Instance(new InstanceCreateInfo {
                ApplicationInfo = new ApplicationInfo {
                    ApplicationName    = "CSharp Vulkan",
                    ApplicationVersion = Vulkan.Version.Make(1, 0, 0),
                    ApiVersion         = Vulkan.Version.Make(1, 0, 0),
                    EngineName         = "CSharp Engine",
                    EngineVersion      = Vulkan.Version.Make(1, 0, 0)
                },
                //EnabledExtensionCount = 0,
                //EnabledLayerCount = 0
                EnabledExtensionNames = new string[] { "VK_EXT_debug_report" },
                EnabledLayerNames     = new string[] { "VK_LAYER_LUNARG_standard_validation" }
            });

            var debugCallback = new Instance.DebugReportCallback(DebugReportCallback);

            instance.EnableDebug(debugCallback, DebugReportFlagsExt.Warning | DebugReportFlagsExt.Error);

            PhysicalDevice physicalDevice = instance.EnumeratePhysicalDevices()[0];

            var queueFamilyIndex = FindBestComputeQueue(physicalDevice);

            DeviceQueueCreateInfo[] deviceQueueCreateInfo =
            {
                new DeviceQueueCreateInfo
                {
                    QueueFamilyIndex = queueFamilyIndex,
                    QueueCount       = 1,
                    QueuePriorities  = new float[] { 1.0f }
                }
            };

            var deviceCreateInfo = new DeviceCreateInfo
            {
                QueueCreateInfos      = deviceQueueCreateInfo,
                EnabledFeatures       = new PhysicalDeviceFeatures(),
                EnabledExtensionCount = 0,
                //EnabledLayerCount = 0
                //EnabledExtensionNames = new string[] { "VK_EXT_debug_report" },
                EnabledLayerNames = new string[] { "VK_LAYER_LUNARG_standard_validation" }
            };

            var device = physicalDevice.CreateDevice(deviceCreateInfo);

            //var memProperties = physicalDevice.GetMemoryProperties();

            var bufferCreateInfo = new BufferCreateInfo
            {
                Size               = memorySize,
                Usage              = BufferUsageFlags.StorageBuffer,
                SharingMode        = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queueFamilyIndex }
            };

            var inBuffer  = device.CreateBuffer(bufferCreateInfo);
            var outBuffer = device.CreateBuffer(bufferCreateInfo);

            var memRequirements = device.GetBufferMemoryRequirements(inBuffer);

            uint memIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent);

            var memoryAllocatInfo = new MemoryAllocateInfo
            {
                AllocationSize  = memRequirements.Size,
                MemoryTypeIndex = memIndex
            };

            var memory = device.AllocateMemory(memoryAllocatInfo);

            var dataPtr = device.MapMemory(memory, 0, memorySize);

            Marshal.Copy(allPos, 0, dataPtr, allPos.Length);

            device.UnmapMemory(memory);

            memRequirements = device.GetBufferMemoryRequirements(outBuffer);
            memoryAllocatInfo.MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent);
            var outMemory = device.AllocateMemory(memoryAllocatInfo);

            device.BindBufferMemory(inBuffer, memory, 0);
            device.BindBufferMemory(outBuffer, outMemory, 0);

            //var uboSize = Marshal.SizeOf(ubo);
            var uboSize             = 3 * sizeof(float);
            var uboBufferCreateInfo = new BufferCreateInfo
            {
                Size               = uboSize,
                Usage              = BufferUsageFlags.UniformBuffer,
                SharingMode        = SharingMode.Exclusive,
                QueueFamilyIndices = new uint[] { queueFamilyIndex }
            };

            var uboBuffer = device.CreateBuffer(uboBufferCreateInfo);

            memRequirements = device.GetBufferMemoryRequirements(uboBuffer);

            var uboMemoryAllocInfo = new MemoryAllocateInfo
            {
                AllocationSize  = memRequirements.Size,
                MemoryTypeIndex = FindMemoryType(physicalDevice, memRequirements.MemoryTypeBits, MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent)
            };

            var uboMemory = device.AllocateMemory(uboMemoryAllocInfo);
            var uboPtr    = device.MapMemory(uboMemory, 0, uboSize);

            Marshal.Copy(ubo, 0, uboPtr, ubo.Length);
            device.UnmapMemory(uboMemory);

            device.BindBufferMemory(uboBuffer, uboMemory, 0);

            //string textureName = string.Format("{0}.comp.spv", typeof(VulankCompute).Namespace);
            //Stream stream = typeof(VulankCompute).GetTypeInfo().Assembly.GetManifestResourceStream(textureName);
            string shaderFile = @"E:\coding\CShape\yTwistCSharpVulkan\comp.spv";
            Stream stream     = File.Open(shaderFile, FileMode.Open);

            byte[] shaderCode = new byte[stream.Length];
            stream.Read(shaderCode, 0, (int)stream.Length);
            stream.Close();
            stream.Dispose();
            var shaderModule = device.CreateShaderModule(shaderCode);

            DescriptorSetLayoutBinding[] descriptorSetLayoutBindings =
            {
                new DescriptorSetLayoutBinding
                {
                    Binding         = 0,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                },

                new DescriptorSetLayoutBinding
                {
                    Binding         = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                },

                new DescriptorSetLayoutBinding
                {
                    Binding         = 2,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    DescriptorCount = 1,
                    StageFlags      = ShaderStageFlags.Compute
                }
            };

            var descriporSetLayoutCreateinfo = new DescriptorSetLayoutCreateInfo
            {
                Bindings = descriptorSetLayoutBindings
            };

            var descriptorSetLayout = device.CreateDescriptorSetLayout(descriporSetLayoutCreateinfo);

            var descriptorPool = device.CreateDescriptorPool(new DescriptorPoolCreateInfo
            {
                MaxSets   = 1,
                PoolSizes = new DescriptorPoolSize[]
                {
                    new DescriptorPoolSize
                    {
                        DescriptorCount = 3
                    }
                }
            });

            var descriptorSet = device.AllocateDescriptorSets(new DescriptorSetAllocateInfo
            {
                DescriptorPool = descriptorPool,
                SetLayouts     = new DescriptorSetLayout[] { descriptorSetLayout }
            })[0];

            var inBufferInfo = new DescriptorBufferInfo
            {
                Buffer = inBuffer,
                Offset = 0,
                Range  = memorySize
            };

            var outBufferInfo = new DescriptorBufferInfo
            {
                Buffer = outBuffer,
                Offset = 0,
                Range  = memorySize
            };

            var uboBufferInfo = new DescriptorBufferInfo
            {
                Buffer = uboBuffer,
                Offset = 0,
                Range  = uboSize
            };

            WriteDescriptorSet[] writeDescriptorSets =
            {
                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 0,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { inBufferInfo }
                },

                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 1,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.StorageBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { outBufferInfo }
                },

                new WriteDescriptorSet
                {
                    DstSet          = descriptorSet,
                    DstBinding      = 2,
                    DstArrayElement = 0,
                    DescriptorCount = 1,
                    DescriptorType  = DescriptorType.UniformBuffer,
                    BufferInfo      = new DescriptorBufferInfo[] { uboBufferInfo }
                }
            };

            device.UpdateDescriptorSets(writeDescriptorSets, null);

            var pipelineLayout = device.CreatePipelineLayout(new PipelineLayoutCreateInfo
            {
                SetLayouts = new DescriptorSetLayout[] { descriptorSetLayout }
            });

            var shaderStage = new PipelineShaderStageCreateInfo
            {
                Stage  = ShaderStageFlags.Compute,
                Module = shaderModule,
                Name   = "main"
            };

            var pipeline = device.CreateComputePipelines(null, new ComputePipelineCreateInfo[]
            {
                new ComputePipelineCreateInfo
                {
                    Stage  = shaderStage,
                    Layout = pipelineLayout
                }
            })[0];

            var commandPool = device.CreateCommandPool(new CommandPoolCreateInfo
            {
                QueueFamilyIndex = queueFamilyIndex
            });

            var cmdBuffer = device.AllocateCommandBuffers(new CommandBufferAllocateInfo
            {
                CommandPool        = commandPool,
                CommandBufferCount = 1,
                Level = CommandBufferLevel.Primary
            })[0];

            cmdBuffer.Begin(new CommandBufferBeginInfo
            {
                Flags = CommandBufferUsageFlags.OneTimeSubmit
            });

            cmdBuffer.CmdBindPipeline(PipelineBindPoint.Compute, pipeline);

            cmdBuffer.CmdBindDescriptorSet(PipelineBindPoint.Compute, pipelineLayout, 0, descriptorSet, null);

            cmdBuffer.CmdDispatch((uint)inPos.Count, 1, 1);

            cmdBuffer.End();

            var queue = device.GetQueue(queueFamilyIndex, 0);

            //var fence = device.CreateFence(new FenceCreateInfo { Flags=0 });
            queue.Submit(new SubmitInfo
            {
                WaitSemaphoreCount = 0,
                CommandBuffers     = new CommandBuffer[] { cmdBuffer },
            });
            queue.WaitIdle();
            //device.WaitForFence(fence, true, UInt64.MaxValue);

            var newDataPtr = device.MapMemory(outMemory, 0, memorySize);

            Marshal.Copy(newDataPtr, allPos, 0, allPos.Length);
            device.UnmapMemory(outMemory);

            var j = 0;

            foreach (var p in inPos)
            {
                p.x = allPos[j * 4 + 0];
                p.y = allPos[j * 4 + 1];
                p.z = allPos[j * 4 + 2];
                p.w = allPos[j * 4 + 3];
                j++;
            }

            //device.DestroyFence(fence);
            device.DestroyShaderModule(shaderModule);
            device.DestroyCommandPool(commandPool);
            device.DestroyDescriptorSetLayout(descriptorSetLayout);
            device.DestroyDescriptorPool(descriptorPool);
            device.DestroyPipelineLayout(pipelineLayout);
            device.DestroyPipeline(pipeline);
            device.DestroyBuffer(inBuffer);
            device.DestroyBuffer(outBuffer);
            device.DestroyBuffer(uboBuffer);
            device.FreeMemory(memory);
            device.FreeMemory(outMemory);
            device.FreeMemory(uboMemory);
            device.Destroy();

            //instance.Destroy();

            return(inPos);
        }
コード例 #19
0
ファイル: Context.cs プロジェクト: meriaizen86/Vulpine
        public Context(GameWindow window)
        {
            Window              = window;
            Instance            = ToDispose(VKHelper.CreateInstance());
            DebugReportCallback = ToDispose(VKHelper.CreateDebugReportCallback(Instance));
            Surface             = ToDispose(VKHelper.CreateSurface(Instance, Window.Handle));

            foreach (PhysicalDevice physicalDevice in Instance.EnumeratePhysicalDevices())
            {
                QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();
                for (int i = 0; i < queueFamilyProperties.Length; i++)
                {
                    if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics))
                    {
                        if (GraphicsQueueFamilyIndex == -1)
                        {
                            GraphicsQueueFamilyIndex = i;
                        }
                        if (ComputeQueueFamilyIndex == -1)
                        {
                            ComputeQueueFamilyIndex = i;
                        }

                        if (physicalDevice.GetSurfaceSupportKhr(i, Surface) &&
                            VKHelper.GetPresentationSupport(physicalDevice, i))
                        {
                            PresentQueueFamilyIndex = i;
                        }

                        if (GraphicsQueueFamilyIndex != -1 &&
                            ComputeQueueFamilyIndex != -1 &&
                            PresentQueueFamilyIndex != -1)
                        {
                            PhysicalDevice = physicalDevice;
                            break;
                        }
                    }
                }
                if (PhysicalDevice != null)
                {
                    break;
                }
            }

            if (PhysicalDevice == null)
            {
                throw new InvalidOperationException("No suitable physical device found.");
            }

            GenerateDepthStencilFormat();

            // Store memory properties of the physical device.
            MemoryProperties = PhysicalDevice.GetMemoryProperties();
            Features         = PhysicalDevice.GetFeatures();
            Properties       = PhysicalDevice.GetProperties();

            // Create a logical device.
            bool sameGraphicsAndPresent = GraphicsQueueFamilyIndex == PresentQueueFamilyIndex;
            var  queueCreateInfos       = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(GraphicsQueueFamilyIndex, 1, 1.0f);
            if (!sameGraphicsAndPresent)
            {
                queueCreateInfos[1] = new DeviceQueueCreateInfo(PresentQueueFamilyIndex, 1, 1.0f);
            }

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.KhrSwapchain, Constant.DeviceExtension.KhrMaintenance1 },
                Features);

            Device = PhysicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            GraphicsQueue = Device.GetQueue(GraphicsQueueFamilyIndex);
            ComputeQueue  = ComputeQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(ComputeQueueFamilyIndex);
            PresentQueue = PresentQueueFamilyIndex == GraphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(PresentQueueFamilyIndex);

            Content = new Content(this);

            GraphicsCommandPool = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(GraphicsQueueFamilyIndex, CommandPoolCreateFlags.ResetCommandBuffer)));
            ComputeCommandPool  = ToDispose(Device.CreateCommandPool(new CommandPoolCreateInfo(ComputeQueueFamilyIndex)));

            Graphics = ToDispose(new Graphics(this));

            Build();
        }
コード例 #20
0
        public VulkanContext(Instance instance, SurfaceKhr surface, Platform platform)
        {
            // Find graphics and presentation capable physical device(s) that support
            // the provided surface for platform.
            int graphicsQueueFamilyIndex = -1;
            int computeQueueFamilyIndex  = -1;
            int presentQueueFamilyIndex  = -1;

            foreach (PhysicalDevice physicalDevice in instance.EnumeratePhysicalDevices())
            {
                QueueFamilyProperties[] queueFamilyProperties = physicalDevice.GetQueueFamilyProperties();
                for (int i = 0; i < queueFamilyProperties.Length; i++)
                {
                    if (queueFamilyProperties[i].QueueFlags.HasFlag(Queues.Graphics))
                    {
                        if (graphicsQueueFamilyIndex == -1)
                        {
                            graphicsQueueFamilyIndex = i;
                        }
                        if (computeQueueFamilyIndex == -1)
                        {
                            computeQueueFamilyIndex = i;
                        }

                        if (physicalDevice.GetSurfaceSupportKhr(i, surface) &&
                            GetPresentationSupport(physicalDevice, i))
                        {
                            presentQueueFamilyIndex = i;
                        }

                        if (graphicsQueueFamilyIndex != -1 &&
                            computeQueueFamilyIndex != -1 &&
                            presentQueueFamilyIndex != -1)
                        {
                            PhysicalDevice = physicalDevice;
                            break;
                        }
                    }
                }
                if (PhysicalDevice != null)
                {
                    break;
                }
            }

            bool GetPresentationSupport(PhysicalDevice physicalDevice, int queueFamilyIndex)
            {
                switch (platform)
                {
                case Platform.Android:
                    return(true);

                case Platform.Win32:
                    return(physicalDevice.GetWin32PresentationSupportKhr(queueFamilyIndex));

                default:
                    throw new NotImplementedException();
                }
            }

            if (PhysicalDevice == null)
            {
                throw new InvalidOperationException("No suitable physical device found.");
            }

            // Store memory properties of the physical device.
            MemoryProperties = PhysicalDevice.GetMemoryProperties();
            Features         = PhysicalDevice.GetFeatures();
            Properties       = PhysicalDevice.GetProperties();

            // Create a logical device.
            bool sameGraphicsAndPresent = graphicsQueueFamilyIndex == presentQueueFamilyIndex;
            var  queueCreateInfos       = new DeviceQueueCreateInfo[sameGraphicsAndPresent ? 1 : 2];

            queueCreateInfos[0] = new DeviceQueueCreateInfo(graphicsQueueFamilyIndex, 1, 1.0f);
            if (!sameGraphicsAndPresent)
            {
                queueCreateInfos[1] = new DeviceQueueCreateInfo(presentQueueFamilyIndex, 1, 1.0f);
            }

            var deviceCreateInfo = new DeviceCreateInfo(
                queueCreateInfos,
                new[] { Constant.DeviceExtension.KhrSwapchain },
                Features);

            Device = PhysicalDevice.CreateDevice(deviceCreateInfo);

            // Get queue(s).
            GraphicsQueue = Device.GetQueue(graphicsQueueFamilyIndex);
            ComputeQueue  = computeQueueFamilyIndex == graphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(computeQueueFamilyIndex);
            PresentQueue = presentQueueFamilyIndex == graphicsQueueFamilyIndex
                ? GraphicsQueue
                : Device.GetQueue(presentQueueFamilyIndex);

            // Create command pool(s).
            GraphicsCommandPool = Device.CreateCommandPool(new CommandPoolCreateInfo(graphicsQueueFamilyIndex));
            ComputeCommandPool  = Device.CreateCommandPool(new CommandPoolCreateInfo(computeQueueFamilyIndex));
        }
コード例 #21
0
ファイル: Sample.cs プロジェクト: jcapellman/SharpVulkan
        protected virtual void CreateDevice()
        {
            uint queuePriorities = 0;
            var  queueCreateInfo = new DeviceQueueCreateInfo
            {
                StructureType    = StructureType.DeviceQueueCreateInfo,
                QueueFamilyIndex = 0,
                QueueCount       = 1,
                QueuePriorities  = new IntPtr(&queuePriorities)
            };

            var enabledLayerNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_LAYER_LUNARG_standard_validation"),
            };

            var enabledExtensionNames = new[]
            {
                Marshal.StringToHGlobalAnsi("VK_KHR_swapchain"),
            };

            try
            {
                fixed(void *enabledLayerNamesPointer = &enabledLayerNames[0])
                fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0])
                {
                    var enabledFeatures = new PhysicalDeviceFeatures
                    {
                        ShaderClipDistance = true,
                    };

                    var deviceCreateInfo = new DeviceCreateInfo
                    {
                        StructureType         = StructureType.DeviceCreateInfo,
                        QueueCreateInfoCount  = 1,
                        QueueCreateInfos      = new IntPtr(&queueCreateInfo),
                        EnabledExtensionCount = (uint)enabledExtensionNames.Length,
                        EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer),
                        EnabledFeatures       = new IntPtr(&enabledFeatures)
                    };

                    if (validate)
                    {
                        deviceCreateInfo.EnabledLayerCount = (uint)enabledLayerNames.Length;
                        deviceCreateInfo.EnabledLayerNames = new IntPtr(enabledLayerNamesPointer);
                    }

                    device = physicalDevice.CreateDevice(ref deviceCreateInfo);
                }
            }
            finally
            {
                foreach (var enabledExtensionName in enabledExtensionNames)
                {
                    Marshal.FreeHGlobal(enabledExtensionName);
                }

                foreach (var enabledLayerName in enabledLayerNames)
                {
                    Marshal.FreeHGlobal(enabledLayerName);
                }
            }

            var queueNodeIndex = physicalDevice.QueueFamilyProperties.
                                 Where((properties, index) => (properties.QueueFlags & QueueFlags.Graphics) != 0 && physicalDevice.GetSurfaceSupport((uint)index, surface)).
                                 Select((properties, index) => index).First();

            queue = device.GetQueue(0, (uint)queueNodeIndex);
        }
コード例 #22
0
 public unsafe void CreateLogicalDevice(DeviceCreateInfo deviceCreateInfo)
 {
     _device = _physicalDevice.CreateDevice(ref deviceCreateInfo);
 }
コード例 #23
0
 /// <summary>
 /// Construct a Graphics object belonging to a window
 /// </summary>
 /// <param name="window"></param>
 public Graphics(WyvernWindow window)
 {
     // Argument checks
     if (window is null)
     {
         throw new ArgumentNullException(nameof(window));
     }
     // Initialize the static part of Graphics if necessary
     InitializeStatic();
     // Store window
     Window = window;
     // Create window surface
     {
         AllocationCallbacks?allocationCallbacks = null;
         Surface = new SurfaceKhr(
             Instance,
             ref allocationCallbacks,
             VkGLFW3.VkGlfw.CreateWindowSurface(Instance.Handle, Window, IntPtr.Zero)
             );
         Surface.PrintDebug();
     }
     // Choose a physical device
     {
         PhysicalDevice = Instance.EnumeratePhysicalDevices()
                          .Where(e => GetDeviceMeetsRequirements(e, Surface))
                          .OrderByDescending(GetDeviceScore)
                          .FirstOrDefault();
         if (PhysicalDevice is null)
         {
             throw new InvalidOperationException("No physical device found that meets the requirements for the application");
         }
         MemoryProperties = PhysicalDevice.GetMemoryProperties();
     }
     // Create default queue families
     {
         ComputeQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(ComputeQueueFamily)}", this, QueueFamily.QueueType.Compute, 2,
             true, ComputeCommandPoolFlags
             );
         GraphicsQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(GraphicsQueueFamily)}", this, QueueFamily.QueueType.Graphics, 2,
             true, GraphicsCommandPoolFlags
             );
         TransferQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(TransferQueueFamily)}", this, QueueFamily.QueueType.Transfer, 2,
             true, TransferCommandPoolFlags
             );
         PresentQueueFamily = new QueueFamily(
             $"{Name}'s {nameof(PresentQueueFamily)}", this, QueueFamily.QueueType.Present, 1,
             false
             );
     }
     // Create a logical device
     {
         // Generate queue create info structs
         var queueCreateInfos = QueueFamilies.Select(queueFamily =>
         {
             // Generate queue priorities
             var priorities = new float[queueFamily.Count];
             for (var i = 0; i < priorities.Length; i++)
             {
                 priorities[i] = 1f - (i / (float)(priorities.Length - 1));
             }
             // Create create info
             var createInfo = new DeviceQueueCreateInfo()
             {
                 QueueFamilyIndex = queueFamily.Index,
                 QueueCount       = queueFamily.Count,
                 QueuePriorities  = priorities
             };
             return(createInfo);
         });
         // Merge multiple queue families' queue create infos
         {
             var alreadyHave       = new List <int>();
             var uniqueCreateInfos = new List <DeviceQueueCreateInfo>();
             foreach (var createInfo in queueCreateInfos.OrderByDescending(e => e.QueueCount))
             {
                 if (!alreadyHave.Contains(createInfo.QueueFamilyIndex))
                 {
                     alreadyHave.Add(createInfo.QueueFamilyIndex);
                     uniqueCreateInfos.Add(createInfo);
                 }
             }
             queueCreateInfos = uniqueCreateInfos;
             foreach (var createInfo in queueCreateInfos)
             {
                 createInfo.PrintDebug();
             }
         }
         // Create device
         Device = PhysicalDevice.CreateDevice(new DeviceCreateInfo()
         {
             EnabledExtensionNames = EnabledDeviceExtensions.ToArray(),
             QueueCreateInfos      = queueCreateInfos.ToArray(),
             EnabledFeatures       = EnabledPhysicalDeviceFeatures
         });
         // Set the queues in the queue families, using those created with the device
         foreach (var family in QueueFamilies)
         {
             var queues = new Queue[family.Count];
             for (var i = 0; i < queues.Length; i++)
             {
                 queues[i] = Device.GetQueue(family.Index, i);
             }
             family.SetQueues(queues);
         }
         // Create and set the command pools in the queue families
         foreach (var family in QueueFamilies)
         {
             // Skip family that shouldn't have a command pool
             if (!family.HasCommandPool)
             {
                 continue;
             }
             // Create command pool
             var commandPool = Device.CreateCommandPool(new CommandPoolCreateInfo()
             {
                 QueueFamilyIndex = family.Index,
                 Flags            = family.CommandPoolFlags
             });
             family.SetCommandPool(commandPool);
         }
     }
     // Create swapchain
     {
         // Query supported capabilities and formats
         var surfaceCapabilities = SurfaceCapabilities;
         var surfaceFormats      = SurfaceFormats;
         var surfacePresentModes = SurfacePresentModes;
         surfaceCapabilities.PrintDebug();
         // Choose the best image format and color space
         {
             var imageFormat = Array.Find(
                 PreferredSwapchainFormats,
                 preferred => surfaceFormats.Any(available => available.Format == preferred)
                 );
             if (imageFormat == Format.Undefined)
             {
                 imageFormat = surfaceFormats.FirstOrDefault().Format;
             }
             if (imageFormat == Format.Undefined)
             {
                 throw new InvalidOperationException("Surface somehow does not support any known image formats");
             }
             SwapchainImageFormat = imageFormat;
             SwapchainColorSpace  = surfaceFormats.First(e => e.Format == SwapchainImageFormat).ColorSpace;
         }
         // Choose the best present mode
         {
             var presentMode = Array.Find(
                 PreferredPresentModes,
                 preferred => surfacePresentModes.Any(available => available == preferred)
                 );
             SwapchainPresentMode = presentMode;
         }
         // Create the swapchain
         SwapchainExtent = surfaceCapabilities.CurrentExtent;
         Swapchain       = Device.CreateSwapchainKhr(new SwapchainCreateInfoKhr(
                                                         surface: Surface,
                                                         imageFormat: SwapchainImageFormat,
                                                         imageExtent: SwapchainExtent,
                                                         preTransform: surfaceCapabilities.CurrentTransform,
                                                         presentMode: SwapchainPresentMode,
                                                         minImageCount: SurfaceCapabilities.MinImageCount,
                                                         imageArrayLayers: SurfaceCapabilities.MaxImageArrayLayers,
                                                         imageSharingMode: SharingMode.Exclusive,
                                                         imageColorSpace: SwapchainColorSpace
                                                         ));
         SwapchainAttachmentImages = Swapchain.GetImages().Select(
             e => new VKImage(
                 e, SwapchainImageFormat,
                 SwapchainExtent,
                 new ImageSubresourceRange(ImageAspects.Color, 0, 1, 0, 1)
                 )
             ).ToArray();
         Swapchain.PrintDebug();
     }
     // Create semaphores & fences
     {
         // Image available semaphore
         ImageAvailableSemaphore = Device.CreateSemaphore();
         ReadyToPresentSemaphore = Device.CreateSemaphore();
         // Swapchain image rendering fences
         RenderToImageFences = new Fence[SwapchainAttachmentImages.Length];
         for (var i = 0; i < RenderToImageFences.Length; i++)
         {
             RenderToImageFences[i] = Device.CreateFence(new FenceCreateInfo(flags: FenceCreateFlags.Signaled));
         }
     }
     // Create content collection
     {
         Content = new ContentCollection(this);
     }
     // Misc
     Stopwatch   = Stopwatch.StartNew();
     CurrentTime = 0.0;
 }
コード例 #24
0
        internal (Device logicalDevice, Queue graphicsQueue, Queue presentQueue, IList <string>) CreateLogicalDevice(
            SurfaceKhr surface, HostDeviceRequirements deviceRequirements)
        {
            if (!AreRequirementsMet(deviceRequirements))
            {
                throw new Exception(
                          $"[{nameof(HostDevice)}] Device '{Name}' does not support all device-requirements");
            }

            string[] requiredExtensions = GetRequiredExtensions(surfaceType);
            if (!AreExtensionsAvailable(requiredExtensions))
            {
                throw new Exception(
                          $"[{nameof(HostDevice)}] Device '{Name}' does not support required extensions");
            }
            var extensionsToEnable = new List <string>(requiredExtensions);

            //Add any optional extensions IF its supported by this host
            string[] optionalExtensions = GetOptionalExtensions(surfaceType);
            for (int i = 0; i < optionalExtensions.Length; i++)
            {
                if (IsExtensionAvailable(optionalExtensions[i]))
                {
                    extensionsToEnable.Add(optionalExtensions[i]);
                }
            }

            int?graphicsQueueFamilyIndex = GetGraphicsQueueFamilyIndex();

            if (graphicsQueueFamilyIndex == null)
            {
                throw new Exception(
                          $"[{nameof(HostDevice)}] Device '{Name}' does not support graphics");
            }

            int?presentQueueFamilyIndex = GetPresentQueueFamilyIndex(surface);

            if (presentQueueFamilyIndex == null)
            {
                throw new Exception(
                          $"[{nameof(HostDevice)}] Device '{Name}' does not support presenting to the given surface");
            }

            List <VulkanCore.DeviceQueueCreateInfo> queueCreateInfos = new List <DeviceQueueCreateInfo>();

            queueCreateInfos.Add(new VulkanCore.DeviceQueueCreateInfo(
                                     graphicsQueueFamilyIndex.Value, queueCount: 1, queuePriorities: 1f));
            //If the present queue and graphics queues are not the same we also need to create a present queue
            if (graphicsQueueFamilyIndex.Value != presentQueueFamilyIndex.Value)
            {
                queueCreateInfos.Add(new VulkanCore.DeviceQueueCreateInfo(
                                         presentQueueFamilyIndex.Value, queueCount: 1, queuePriorities: 1f));
            }

            VulkanCore.DeviceCreateInfo createInfo = new VulkanCore.DeviceCreateInfo(
                queueCreateInfos: queueCreateInfos.ToArray(),
                enabledExtensionNames: extensionsToEnable.ToArray(),
                enabledFeatures: deviceRequirements.GetRequiredFeatures()
                );
            Device logicalDevice = physicalDevice.CreateDevice(createInfo);
            Queue  graphicsQueue = logicalDevice.GetQueue(graphicsQueueFamilyIndex.Value, queueIndex: 0);
            Queue  presentQueue  = logicalDevice.GetQueue(presentQueueFamilyIndex.Value, queueIndex: 0);

            logger?.Log(nameof(HostDevice), $"Created logical-device ({Name})");
            logger?.LogList(nameof(HostDevice), $"Enabled extensions for logical-device:", extensionsToEnable);

            //Note: If we are running on molten-vk then we can set some specific mvk device config
            if (extensionsToEnable.Contains("VK_MVK_moltenvk"))
            {
                var deviceConfig = logicalDevice.GetMVKDeviceConfiguration();
                deviceConfig.DebugMode                    = DebugUtils.IS_DEBUG;
                deviceConfig.PerformanceTracking          = DebugUtils.IS_DEBUG;
                deviceConfig.PerformanceLoggingFrameCount = DebugUtils.IS_DEBUG ? 300 : 0;
                logicalDevice.SetMVKDeviceConfiguration(deviceConfig);
            }

            return(logicalDevice, graphicsQueue, presentQueue, extensionsToEnable);
        }