private HostDevice FindSuitableDevice( SurfaceKhr surface, HostDeviceRequirements deviceRequirements, bool preferDiscreteDevice = true) { ThrowIfDisposed(); List <HostDevice> supportedDevices = new List <HostDevice>(); //Find all devices that support the given surface for (int i = 0; i < hostDevices.Length; i++) { if (hostDevices[i].IsSurfaceSupported(surface) && hostDevices[i].AreRequirementsMet(deviceRequirements)) { supportedDevices.Add(hostDevices[i]); } } if (supportedDevices.IsEmpty()) { throw new Exception($"[{nameof(Host)}] Unable to find a supported device"); } //If we have a supported discreate gpu and we prefer a discrete one then we pick that for (int i = 0; i < supportedDevices.Count; i++) { if (supportedDevices[i].IsDiscreteGPU == preferDiscreteDevice) { return(supportedDevices[i]); } } return(supportedDevices[0]); }
internal Window( string title, INativeWindow nativeWindow, SurfaceKhr surface, HostDevice hostDevice, HostDeviceRequirements deviceRequirements, Logger logger = null) { if (nativeWindow == null) { throw new ArgumentNullException(nameof(nativeWindow)); } if (surface == null) { throw new ArgumentNullException(nameof(surface)); } if (hostDevice == null) { throw new ArgumentNullException(nameof(hostDevice)); } this.title = title; this.nativeWindow = nativeWindow; this.surface = surface; this.hostDevice = hostDevice; this.logger = logger; //Subscribe to callbacks for the native window nativeWindow.CloseRequested += OnNativeWindowCloseRequested; nativeWindow.Resized += OnNativeWindowResized; //Create a logical device (and queues on the device) IList <string> enabledExtensions; (logicalDevice, graphicsQueue, presentQueue, enabledExtensions) = hostDevice.CreateLogicalDevice( surface: surface, deviceRequirements: deviceRequirements); hasDebugMarkerExtension = enabledExtensions.Contains("VK_EXT_debug_marker"); if (hasDebugMarkerExtension) { logger?.Log(nameof(Window), "Enabled debug-markers"); } //Get a presentmode to use presentMode = hostDevice.GetPresentMode(surface); //Get the surfaceformat to use (surfaceFormat, surfaceColorspace) = hostDevice.GetSurfaceFormat(surface); //Gets how many swapchain images we should use swapchainCount = hostDevice.GetSwapchainCount(surface); //Create a command-pool attached to this device commandPool = logicalDevice.CreateCommandPool(new CommandPoolCreateInfo( queueFamilyIndex: graphicsQueue.FamilyIndex, flags: CommandPoolCreateFlags.None )); //Create the swapchain (images to present to the screen) CreateSwapchain(swapchainCount); //Synchronization objects are used to sync the rendering and presenting CreateSynchronizationObjects(); }
public Window CreateWindow( Int2 windowSize, HostDeviceRequirements deviceRequirements, bool preferDiscreteDevice = true) { ThrowIfDisposed(); INativeWindow nativeWindow = nativeApp.CreateWindow( size: windowSize, minSize: (x: 150, y: 150), title: string.Empty); SurfaceKhr surface = CreateSurface(nativeWindow); HostDevice graphicsDevice = FindSuitableDevice( surface, deviceRequirements, preferDiscreteDevice); return(new Window( title: $"{appName} - {appVersion}", nativeWindow, surface, graphicsDevice, deviceRequirements, logger)); }
internal bool AreRequirementsMet(HostDeviceRequirements requirements) => requirements.DoesSupportRequirements(supportedFeatures);
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); }