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; }
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 ); }
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 ?¿?¿ } }