private void createLogicalDevice() { QueueFamilyIndices indices = findQueueFamilies(physicalDevice); List <VkDeviceQueueCreateInfo> queueCreateInfos = new List <VkDeviceQueueCreateInfo>(); HashSet <int> uniqueQueueFamilies = new HashSet <int>() { indices.graphicsFamily, indices.presentFamily }; float[] queuePriorities = new float[] { 1.0f }; foreach (var queueFamily in uniqueQueueFamilies) { VkDeviceQueueCreateInfo queueCreateInfo = new VkDeviceQueueCreateInfo(); queueCreateInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; queueCreateInfo.queueFamilyIndex = queueFamily; queueCreateInfo.queueCount = 1; queueCreateInfo.pQueuePriorities = queuePriorities; queueCreateInfos.Add(queueCreateInfo); } VkPhysicalDeviceFeatures deviceFeatures = new VkPhysicalDeviceFeatures(); VkDeviceCreateInfo createInfo = new VkDeviceCreateInfo(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; createInfo.queueCreateInfoCount = queueCreateInfos.Count; createInfo.pQueueCreateInfos = queueCreateInfos.ToArray(); createInfo.pEnabledFeatures = new VkPhysicalDeviceFeatures[] { deviceFeatures }; createInfo.enabledExtensionCount = deviceExtensions.Length; createInfo.ppEnabledExtensionNames = deviceExtensions; if (enableValidationLayers) { createInfo.enabledLayerCount = validationLayers.Length; createInfo.ppEnabledLayerNames = validationLayers; } else { createInfo.enabledLayerCount = 0; } VkResult result = Vulkan.vkCreateDevice(physicalDevice, createInfo, null, out device); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create logical device!", result); } Vulkan.vkGetDeviceQueue(device, indices.graphicsFamily, 0, out graphicsQueue); Vulkan.vkGetDeviceQueue(device, indices.presentFamily, 0, out presentQueue); }
private void createCommandPool() { QueueFamilyIndices queueFamilyIndices = findQueueFamilies(physicalDevice); VkCommandPoolCreateInfo poolInfo = new VkCommandPoolCreateInfo(); poolInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; poolInfo.queueFamilyIndex = queueFamilyIndices.graphicsFamily; VkResult result = Vulkan.vkCreateCommandPool(device, poolInfo, null, out commandPool); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create command pool!", result); } }
private bool isDeviceSuitable(VkPhysicalDevice physicalDevice) { QueueFamilyIndices indices = findQueueFamilies(physicalDevice); bool extensionsSupported = checkDeviceExtensionsSupport(physicalDevice); bool swapChainAdequate = false; if (extensionsSupported) { SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); swapChainAdequate = swapChainSupport.formats.Any() && swapChainSupport.presentModes.Any(); } return(indices.isComplete() && extensionsSupported && swapChainAdequate); }
private QueueFamilyIndices findQueueFamilies(VkPhysicalDevice device) { QueueFamilyIndices indices = new QueueFamilyIndices(); int queueFamilyCount = 0; Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, null); VkQueueFamilyProperties[] queueFamilies = new VkQueueFamilyProperties[queueFamilyCount]; Vulkan.vkGetPhysicalDeviceQueueFamilyProperties(device, ref queueFamilyCount, queueFamilies); int i = 0; foreach (var queueFamily in queueFamilies) { if (queueFamily.queueCount > 0 && (queueFamily.queueFlags & VkQueueFlagBits.VK_QUEUE_GRAPHICS_BIT) > 0) { indices.graphicsFamily = i; } bool presentSupport = false; Vulkan.vkGetPhysicalDeviceSurfaceSupportKHR(device, i, surface, out presentSupport); if (queueFamily.queueCount > 0 && presentSupport) { indices.presentFamily = i; } if (indices.isComplete()) { break; } i++; } return(indices); }
private void createSwapChain() { SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice); VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats); VkPresentModeKHR presentMode = chooseSwapPresentMode(swapChainSupport.presentModes); VkExtent2D extent = chooseSwapExtent(swapChainSupport.capabilities); int imageCount = swapChainSupport.capabilities.minImageCount + 1; if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount) { imageCount = swapChainSupport.capabilities.maxImageCount; } VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR(); createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.surface = surface; createInfo.minImageCount = imageCount; createInfo.imageFormat = surfaceFormat.format; createInfo.imageColorSpace = surfaceFormat.colorSpace; createInfo.imageExtent = extent; createInfo.imageArrayLayers = 1; createInfo.imageUsage = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; QueueFamilyIndices indices = findQueueFamilies(physicalDevice); var queueFamilyIndices = new List <int>() { indices.graphicsFamily, indices.presentFamily }; if (indices.graphicsFamily != indices.presentFamily) { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = queueFamilyIndices.Count; createInfo.pQueueFamilyIndices = queueFamilyIndices.ToArray(); } else { createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE; } createInfo.preTransform = (VkSurfaceTransformFlagBitsKHR)swapChainSupport.capabilities.currentTransform; createInfo.compositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = presentMode; createInfo.clipped = VkBool32.VK_TRUE; createInfo.oldSwapchain = null; VkResult result = Vulkan.vkCreateSwapchainKHR(device, createInfo, null, out swapChain); if (result != VkResult.VK_SUCCESS) { throw Program.Throw("failed to create swap chain!", result); } swapChainImages = new VkImage[imageCount]; Vulkan.vkGetSwapchainImagesKHR(device, swapChain, ref imageCount, swapChainImages); swapChainImageFormat = surfaceFormat.format; swapChainExtent = extent; }