示例#1
0
        private void CreateLogicalDevice()
        {
            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            float priority         = 1f;
            var   queueCreateInfos = stackalloc VkDeviceQueueCreateInfo[]
            {
                new VkDeviceQueueCreateInfo()
                {
                    sType            = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
                    queueFamilyIndex = (uint)indices.GraphicsFamily,
                    queueCount       = 1,
                    pQueuePriorities = &priority,
                }
            };

            int     extensionsCount         = 1;
            IntPtr *extensionsToEnableArray = stackalloc IntPtr[extensionsCount];

            for (int i = 0; i < extensionsCount; i++)
            {
                string extension = "VK_KHR_swapchain";
                extensionsToEnableArray[i] = Marshal.StringToHGlobalAnsi(extension);
            }

            VkPhysicalDeviceFeatures deviceFeatures = new VkPhysicalDeviceFeatures();

            var createInfo = new VkDeviceCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
                ppEnabledExtensionNames = (byte **)extensionsToEnableArray,
                enabledExtensionCount   = (uint)extensionsCount,
                pQueueCreateInfos       = queueCreateInfos,
                queueCreateInfoCount    = 1,
                pEnabledFeatures        = &deviceFeatures,
            };

            VkDevice newDevice;
            var      result = VulkanNative.vkCreateDevice(this.vkPhysicalDevice, &createInfo, null, &newDevice);

            this.vkDevice = newDevice;
            Helpers.CheckErrors(result);

            for (int i = 0; i < extensionsCount; i++)
            {
                Marshal.FreeHGlobal(extensionsToEnableArray[i]);
            }

            VkQueue newGraphicsQueue;

            VulkanNative.vkGetDeviceQueue(vkDevice, (uint)indices.GraphicsFamily, 0, &newGraphicsQueue);
            this.vkGraphicsQueue = newGraphicsQueue;

            VkQueue newPresentQueue;

            VulkanNative.vkGetDeviceQueue(vkDevice, (uint)indices.PresentFamily, 0, &newPresentQueue);
            this.vkPresentQueue = newPresentQueue;
        }
示例#2
0
        public unsafe Device(VkPhysicalDevice physicalDevice)
        {
            _physicalDevice = physicalDevice;

            //get physical device information
            VulkanNative.vkGetPhysicalDeviceProperties(
                _physicalDevice,
                out _properties
                );
            VulkanNative.vkGetPhysicalDeviceMemoryProperties(
                _physicalDevice,
                out _memoryProperties
                );
            VulkanNative.vkGetPhysicalDeviceFeatures(
                _physicalDevice,
                out _features
                );

            //get family queue properties
            uint familyQueuePropertiesCount;

            VulkanNative.vkGetPhysicalDeviceQueueFamilyProperties(
                _physicalDevice,
                &familyQueuePropertiesCount,
                null
                );
            var familyQueueProperties = new NativeList <VkQueueFamilyProperties>(
                familyQueuePropertiesCount
                );

            familyQueueProperties.Count = familyQueuePropertiesCount;
            VulkanNative.vkGetPhysicalDeviceQueueFamilyProperties(
                _physicalDevice,
                &familyQueuePropertiesCount,
                (VkQueueFamilyProperties *)familyQueueProperties.Data.ToPointer()
                );

            //setup queue families
            _queueFamilies = new List <QueueFamily>();
            for (uint i = 0; i < familyQueuePropertiesCount; i++)
            {
                var familyQueueProperty = familyQueueProperties[i];
                _queueFamilies.Add(new QueueFamily(
                                       i,
                                       familyQueueProperty.queueCount,
                                       (QueueFamilyType)familyQueueProperty.queueFlags
                                       ));
            }

            //get queue create infos
            var queueCreateInfos = new NativeList <VkDeviceQueueCreateInfo>(
                familyQueuePropertiesCount
                );

            queueCreateInfos.Count = familyQueuePropertiesCount;
            for (int i = 0; i < familyQueuePropertiesCount; i++)
            {
                queueCreateInfos[i] = _queueFamilies[i].QueueCreateInfo;
            }

            //enable extra device features
            var enabledFeatures = new VkPhysicalDeviceFeatures()
            {
                samplerAnisotropy = true,
                dualSrcBlend      = true
            };

            //enable swapchain extension for window support
            var enabledExtensions = new NativeList <IntPtr>();

            enabledExtensions.Add(GraphicsApiConstants.VK_KHR_SWAPCHAIN_EXTENSION_NAME);

            var deviceInfo = new VkDeviceCreateInfo
            {
                sType                   = VkStructureType.DeviceCreateInfo,
                pEnabledFeatures        = &enabledFeatures,
                enabledExtensionCount   = enabledExtensions.Count,
                ppEnabledExtensionNames = (byte **)enabledExtensions.Data,
                enabledLayerCount       = 0,
                ppEnabledLayerNames     = null,
                queueCreateInfoCount    = queueCreateInfos.Count,
                pQueueCreateInfos       = (VkDeviceQueueCreateInfo *)queueCreateInfos.Data.ToPointer()
            };

            //setup device
            VkDevice device;

            if (VulkanNative.vkCreateDevice(
                    _physicalDevice,
                    &deviceInfo,
                    null,
                    &device
                    ) != VkResult.Success)
            {
                throw new Exception("failed to initialize device");
            }
            _handle = device;

            //setup device queues
            foreach (var queueFamily in _queueFamilies)
            {
                queueFamily.GetQueuesFromDevice(this);
            }

            //calculate device score
            _score = 0;
            if (_properties.deviceType == VkPhysicalDeviceType.DiscreteGpu)
            {
                _score += 10;
            }
            else if (_properties.deviceType == VkPhysicalDeviceType.IntegratedGpu)
            {
                _score += 5;
            }
            else if (_properties.deviceType == VkPhysicalDeviceType.VirtualGpu)
            {
                _score += 3;
            }
            else if (_properties.deviceType == VkPhysicalDeviceType.Cpu)
            {
                _score += 1;
            }

            _score += (
                //1073741824 = 1024 * 1024 * 1024
                _properties.limits.maxMemoryAllocationCount / 1073741824.0f
                );
        }
示例#3
0
        private void CreateLogicalDevice()
        {
            QueueFamilyIndices indices = this.FindQueueFamilies(physicalDevice);

            List <VkDeviceQueueCreateInfo> queueCreateInfos = new List <VkDeviceQueueCreateInfo>();
            HashSet <uint> uniqueQueueFamilies = new HashSet <uint>()
            {
                indices.graphicsFamily.Value, indices.presentFamily.Value
            };

            float queuePriority = 1.0f;

            foreach (uint queueFamily in uniqueQueueFamilies)
            {
                VkDeviceQueueCreateInfo queueCreateInfo = new VkDeviceQueueCreateInfo()
                {
                    sType            = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
                    queueFamilyIndex = queueFamily,
                    queueCount       = 1,
                    pQueuePriorities = &queuePriority,
                };
                queueCreateInfos.Add(queueCreateInfo);
            }

            VkPhysicalDeviceFeatures deviceFeatures = default;

            // Raytracing extensions
            VkPhysicalDeviceRayTracingFeaturesKHR deviceRayTracingFeatures = new VkPhysicalDeviceRayTracingFeaturesKHR()
            {
                sType      = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_FEATURES_KHR,
                pNext      = null,
                rayTracing = true,
            };

            VkPhysicalDeviceVulkan12Features deviceVulkan12Features = new VkPhysicalDeviceVulkan12Features()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES,
                pNext = &deviceRayTracingFeatures,
                bufferDeviceAddress = true,
            };

            int     deviceExtensionsCount = deviceExtensions.Length;
            IntPtr *deviceExtensionsArray = stackalloc IntPtr[deviceExtensionsCount];

            for (int i = 0; i < deviceExtensionsCount; i++)
            {
                string extension = deviceExtensions[i];
                deviceExtensionsArray[i] = Marshal.StringToHGlobalAnsi(extension);
            }

            VkDeviceCreateInfo createInfo = new VkDeviceCreateInfo();

            createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
            createInfo.pNext = &deviceVulkan12Features;

            VkDeviceQueueCreateInfo[] queueCreateInfosArray = queueCreateInfos.ToArray();
            fixed(VkDeviceQueueCreateInfo *queueCreateInfosArrayPtr = &queueCreateInfosArray[0])
            {
                createInfo.queueCreateInfoCount = (uint)queueCreateInfos.Count;
                createInfo.pQueueCreateInfos    = queueCreateInfosArrayPtr;
            }

            createInfo.pEnabledFeatures        = &deviceFeatures;
            createInfo.enabledExtensionCount   = (uint)deviceExtensions.Length;
            createInfo.ppEnabledExtensionNames = (byte **)deviceExtensionsArray;

            fixed(VkDevice *devicePtr = &device)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateDevice(physicalDevice, &createInfo, null, devicePtr));
            }

            fixed(VkQueue *graphicsQueuePtr = &graphicsQueue)
            {
                VulkanNative.vkGetDeviceQueue(device, indices.graphicsFamily.Value, 0, graphicsQueuePtr);
            }

            fixed(VkQueue *presentQueuePtr = &presentQueue)
            {
                VulkanNative.vkGetDeviceQueue(device, indices.presentFamily.Value, 0, presentQueuePtr); // TODO queue index 0 ?¿?¿
            }
        }