AppGpu AppGpuInit(uint id, PhysicalDevice obj) { // TODO : Limits AppGpu gpu = new AppGpu { Id = id, Obj = obj, Props = obj.GetProperties(), QueueProps = obj.GetQueueFamilyProperties(), MemoryProps = obj.GetMemoryProperties(), Features = obj.GetFeatures(), Limits = null, }; gpu.QueueReqs = new DeviceQueueCreateInfo[gpu.QueueProps.Length]; for (uint i = 0; i < gpu.QueueProps.Length; i++) { uint queueCount = gpu.QueueProps[i].QueueCount; DeviceQueueCreateInfo queueReq = new DeviceQueueCreateInfo { QueueFamilyIndex = i, QueueCount = queueCount, QueuePriorities = new float[queueCount], }; gpu.QueueReqs[i] = queueReq; } gpu.Device = AppDevInit(gpu); AppDevInitFormats(gpu.Device); return(gpu); }
public void InitializeVulkan() { var devices = Instance.EnumeratePhysicalDevices(); var surface = Instance.CreateAndroidSurfaceKHR(new AndroidSurfaceCreateInfoKhr { Window = aNativeWindow }); var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new float [] { 1.0f } }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new string [] { "VK_KHR_swapchain", "VK_KHR_display_swapchain" }, QueueCreateInfos = new DeviceQueueCreateInfo [] { queueInfo } }; var physicalDevice = devices [0]; device = physicalDevice.CreateDevice(deviceInfo); queue = device.GetQueue(0, 0); var surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectFormat(physicalDevice, surface); swapchain = CreateSwapchain(surface, surfaceCapabilities, surfaceFormat); var images = device.GetSwapchainImagesKHR(swapchain); var renderPass = CreateRenderPass(surfaceFormat); var framebuffers = CreateFramebuffers(images, surfaceFormat, surfaceCapabilities, renderPass); commandBuffers = CreateCommandBuffers(images, framebuffers, renderPass, surfaceCapabilities); var fenceInfo = new FenceCreateInfo(); fences = new Fence [] { device.CreateFence(fenceInfo) }; var semaphoreInfo = new SemaphoreCreateInfo(); semaphore = device.CreateSemaphore(semaphoreInfo); initialized = true; }
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"); }
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)); }
/// <summary> /// Initialize the graphic device. /// </summary> public override void Initialize() { base.Initialize(); // - Take presentation and graphic queue GraphicQueueIndex = GetSuitableQueues(Physical.Handle, QueueFlags.Graphics).First(); PresentQueueIndex = GetPresentQueues(Physical.Handle, Physical.DrawingSurface.Handle).First(); ComputeQueueIndex = GetSuitableQueues(Physical.Handle, QueueFlags.Compute).First(); var queues = new DeviceQueueCreateInfo[] { new DeviceQueueCreateInfo { QueueFamilyIndex = GraphicQueueIndex, QueuePriorities = new[] { 1f } }, new DeviceQueueCreateInfo { QueueFamilyIndex = PresentQueueIndex, QueuePriorities = new[] { 1f } }, new DeviceQueueCreateInfo { QueueFamilyIndex = ComputeQueueIndex, QueuePriorities = new[] { 1f } } }; // - Create logical device Handle = Physical.Handle.CreateDevice(queues, null, new[] { KhrExtensions.Swapchain }); // - Gets the logical queues GraphicQueue = Handle.GetQueue(GraphicQueueIndex, 0); PresentQueue = Handle.GetQueue(PresentQueueIndex, 0); ComputeQueue = Handle.GetQueue(ComputeQueueIndex, 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); }
private Device CreateLogicalDevice(out Queue GraphicsQueue, out Queue PresentQueue) { var queueInfos = stackalloc DeviceQueueCreateInfo[2]; uint infoCount = 1; float queuePriority = 1f; queueInfos[0] = new DeviceQueueCreateInfo(queueFamilyIndex: (uint)this.QueueIndices.GraphicsFamily, queueCount: 1, pQueuePriorities: &queuePriority); if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily) { infoCount = 2; queueInfos[1] = new DeviceQueueCreateInfo(queueFamilyIndex: (uint)this.QueueIndices.PresentFamily, queueCount: 1, pQueuePriorities: &queuePriority); } PhysicalDeviceFeatures features = default; using var extensionNames = SilkMarshal.StringArrayToMemory(RequiredDeviceExtensions); PhysicalDeviceSeparateDepthStencilLayoutsFeatures depthStencilFeature = new PhysicalDeviceSeparateDepthStencilLayoutsFeatures { SType = StructureType.PhysicalDeviceSeparateDepthStencilLayoutsFeatures, SeparateDepthStencilLayouts = true }; DeviceCreateInfo createInfo = new DeviceCreateInfo { SType = StructureType.DeviceCreateInfo, //PNext = &depthStencilFeature, QueueCreateInfoCount = infoCount, PQueueCreateInfos = queueInfos, EnabledExtensionCount = (uint)RequiredDeviceExtensions.Length, PpEnabledExtensionNames = (byte **)extensionNames, PEnabledFeatures = &features }; Device device; var res = VkApi.CreateDevice(this.PhysicalDevice, &createInfo, null, &device); if (res != Result.Success) { throw new VMASharp.VulkanResultException("Logical Device Creation Failed!", res); } Queue queue = default; VkApi.GetDeviceQueue(device, (uint)this.QueueIndices.GraphicsFamily, 0, &queue); GraphicsQueue = queue; if (this.QueueIndices.GraphicsFamily != this.QueueIndices.PresentFamily) { queue = default; VkApi.GetDeviceQueue(device, (uint)this.QueueIndices.PresentFamily, 0, &queue); } PresentQueue = queue; return(device); }
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)); }
public unsafe ReturnSet <bool> InitializeLogicalDevice(VulkanDevice physicalDevice, Logger logger) { uint queuePriorities = 0; var deviceQueueCreateInfo = new DeviceQueueCreateInfo { StructureType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = 0, QueueCount = 1, QueuePriorities = new IntPtr(&queuePriorities) }; var physicalDeviceFeatures = new PhysicalDeviceFeatures { ShaderClipDistance = true, }; var enabledLayerNames = new[] { ExtensionNames.VK_LAYER_LUNARG_standard_validation.ToIntPtr() }; var enabledExtensionNames = new[] { ExtensionNames.VK_KHR_swapchain.ToIntPtr() }; fixed(void *enabledLayerNamesPointer = &enabledLayerNames[0]) fixed(void *enabledExtensionNamesPointer = &enabledExtensionNames[0]) { var deviceCreateInfo = new DeviceCreateInfo { StructureType = StructureType.DeviceCreateInfo, QueueCreateInfoCount = 1, QueueCreateInfos = new IntPtr(&deviceQueueCreateInfo), EnabledExtensionCount = (uint)enabledExtensionNames.Length, EnabledExtensionNames = new IntPtr(enabledExtensionNamesPointer), EnabledFeatures = new IntPtr(&physicalDeviceFeatures), EnabledLayerCount = (uint)enabledLayerNames.Length, EnabledLayerNames = new IntPtr(enabledLayerNamesPointer) }; physicalDevice.CreateLogicalDevice(deviceCreateInfo); logger.AddMessage("Logical Device created successfully"); _queue = physicalDevice.CreateQueue(_surface); logger.AddMessage($"Queue created on {physicalDevice.Name}"); _form.Show(); return(new ReturnSet <bool>(true)); } }
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); }
public void InitializeVulkan() { var devices = Instance.EnumeratePhysicalDevices(); var surface = Instance.CreateAndroidSurfaceKHR(new AndroidSurfaceCreateInfoKhr { Window = aNativeWindow }); var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new float [] { 1.0f } }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new string [] { "VK_KHR_swapchain", "VK_KHR_display_swapchain" }, QueueCreateInfos = new DeviceQueueCreateInfo [] { queueInfo } }; var physicalDevice = devices [0]; device = physicalDevice.CreateDevice(deviceInfo); queue = device.GetQueue(0, 0); surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectFormat(physicalDevice, surface); swapchain = CreateSwapchain(surface, surfaceFormat); var images = device.GetSwapchainImagesKHR(swapchain); renderPass = CreateRenderPass(surfaceFormat); var framebuffers = CreateFramebuffers(images, surfaceFormat); var vertexBuffer = CreateBuffer(physicalDevice, Logo.Vertices, BufferUsageFlags.VertexBuffer, typeof(float)); var indexBuffer = CreateBuffer(physicalDevice, Logo.Indexes, BufferUsageFlags.IndexBuffer, typeof(short)); uniformBuffer = CreateUniformBuffer(physicalDevice); descriptorSetLayout = CreateDescriptorSetLayout(); var pipelines = CreatePipelines(); descriptorSets = CreateDescriptorSets(); UpdateDescriptorSets(); commandBuffers = CreateCommandBuffers(images, framebuffers, pipelines [0], vertexBuffer, indexBuffer, (uint)Logo.Indexes.Length); var fenceInfo = new FenceCreateInfo(); fences = new Fence [] { device.CreateFence(fenceInfo) }; var semaphoreInfo = new SemaphoreCreateInfo(); semaphore = device.CreateSemaphore(semaphoreInfo); initialized = true; }
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; }
private void InitializeVulkan() { var devices = _instance.EnumeratePhysicalDevices(); var surface = _instance.CreateWin32SurfaceKHR( new Win32SurfaceCreateInfoKhr { Hinstance = Instance, Hwnd = Handle }); var queueInfo = new DeviceQueueCreateInfo { QueuePriorities = new [] { 1.0f } }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = new [] { "VK_KHR_swapchain" }, QueueCreateInfos = new [] { queueInfo } }; var physicalDevice = devices [0]; _device = physicalDevice.CreateDevice(deviceInfo); _queue = _device.GetQueue(0, 0); var surfaceCapabilities = physicalDevice.GetSurfaceCapabilitiesKHR(surface); var surfaceFormat = SelectFormat(physicalDevice, surface); _swapchain = CreateSwapchain(surface, surfaceCapabilities, surfaceFormat); var images = _device.GetSwapchainImagesKHR(_swapchain); var renderPass = CreateRenderPass(surfaceFormat); var framebuffers = CreateFramebuffers(images, surfaceFormat, surfaceCapabilities, renderPass); _commandBuffers = CreateCommandBuffers(images, framebuffers, renderPass, surfaceCapabilities); var fenceInfo = new FenceCreateInfo(); _fences = new [] { _device.CreateFence(fenceInfo) }; var semaphoreInfo = new SemaphoreCreateInfo(); _semaphore = _device.CreateSemaphore(semaphoreInfo); _initialized = true; }
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)); }
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)); }
public static Device CreateDevice(Vk api, PhysicalDevice physicalDevice, uint queueFamilyIndex, string[] supportedExtensions, uint queueCount) { if (queueCount > QueuesCount) { queueCount = QueuesCount; } float *queuePriorities = stackalloc float[(int)queueCount]; for (int i = 0; i < queueCount; i++) { queuePriorities[i] = 1f; } var queueCreateInfo = new DeviceQueueCreateInfo() { SType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = queueFamilyIndex, QueueCount = queueCount, PQueuePriorities = queuePriorities }; var features = new PhysicalDeviceFeatures() { DepthBiasClamp = true, DepthClamp = true, DualSrcBlend = true, FragmentStoresAndAtomics = true, GeometryShader = true, ImageCubeArray = true, IndependentBlend = true, LogicOp = true, MultiViewport = true, PipelineStatisticsQuery = true, SamplerAnisotropy = true, ShaderClipDistance = true, ShaderImageGatherExtended = true, // ShaderStorageImageReadWithoutFormat = true, // ShaderStorageImageWriteWithoutFormat = true, VertexPipelineStoresAndAtomics = true }; var featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT() { SType = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt, IndexTypeUint8 = supportedExtensions.Contains("VK_EXT_index_type_uint8") }; var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT() { SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt, PNext = &featuresIndexU8, TransformFeedback = true }; var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT() { SType = StructureType.PhysicalDeviceRobustness2FeaturesExt, PNext = &featuresTransformFeedback, NullDescriptor = true }; var featuresVk12 = new PhysicalDeviceVulkan12Features() { SType = StructureType.PhysicalDeviceVulkan12Features, PNext = &featuresRobustness2, DrawIndirectCount = supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName) }; var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray(); IntPtr *ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length]; for (int i = 0; i < enabledExtensions.Length; i++) { ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]); } var deviceCreateInfo = new DeviceCreateInfo() { SType = StructureType.DeviceCreateInfo, PNext = &featuresVk12, QueueCreateInfoCount = 1, PQueueCreateInfos = &queueCreateInfo, PpEnabledExtensionNames = (byte **)ppEnabledExtensions, EnabledExtensionCount = (uint)enabledExtensions.Length, PEnabledFeatures = &features }; api.CreateDevice(physicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError(); for (int i = 0; i < enabledExtensions.Length; i++) { Marshal.FreeHGlobal(ppEnabledExtensions[i]); } return(device); }
private unsafe void CreateLogicalDevice() { QueueFamilyIndices indices = FindQueueFamilies(_physicalDevice); uint[] uniqueQueueFamilies = new[] { indices.GraphicsFamily.Value, indices.PresentFamily.Value }; var queueCreateInfos = stackalloc DeviceQueueCreateInfo[uniqueQueueFamilies.Length]; float queuePriority = 1.0f; for (int i = 0; i < uniqueQueueFamilies.Length; i++) { uint queueFamily = uniqueQueueFamilies[i]; var queueCreateInfo = new DeviceQueueCreateInfo { SType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = queueFamily, QueueCount = 1, PQueuePriorities = &queuePriority }; queueCreateInfos[i] = queueCreateInfo; } var deviceFeatures = new PhysicalDeviceFeatures(); var createInfo = new DeviceCreateInfo { SType = StructureType.DeviceCreateInfo, PQueueCreateInfos = queueCreateInfos, QueueCreateInfoCount = (uint)uniqueQueueFamilies.Length, PEnabledFeatures = &deviceFeatures, EnabledExtensionCount = 0 }; if (EnableValidationLayers) { createInfo.EnabledLayerCount = (uint)_validationLayers.Length; createInfo.PpEnabledLayerNames = (byte **)SilkMarshal.MarshalStringArrayToPtr(_validationLayers); } else { createInfo.EnabledLayerCount = 0; } fixed(Device *device = &_device) { Result result = _vk.CreateDevice(_physicalDevice, &createInfo, (AllocationCallbacks *)null, device); if (result != Result.Success) { throw new Exception("Failed to create logical device!"); } } fixed(Queue *graphicsQueue = &_graphicsQueue) { _vk.GetDeviceQueue(_device, indices.GraphicsFamily.Value, 0, graphicsQueue); } fixed(Queue *presentQueue = &_presentQueue) { _vk.GetDeviceQueue(_device, indices.PresentFamily.Value, 0, presentQueue); } }
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(); }
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); }
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); }
public virtual void Initialize(InstanceCreateData data) { this.data = data; var graphicsQueue = new DeviceQueueCreateInfo { QueuePriorities = new float[] { 1.0f }, QueueFamilyIndex = (uint)data.queueFamilyIndices.GraphicsFamily }; var presentQueue = new DeviceQueueCreateInfo { QueuePriorities = new float[] { 1.0f }, QueueFamilyIndex = (uint)data.queueFamilyIndices.PresentFamily }; var deviceInfo = new DeviceCreateInfo { EnabledExtensionNames = data.enabledDeviceExtensions, EnabledExtensionCount = (uint)data.enabledDeviceExtensions.Length, EnabledLayerNames = data.enabledLayers, EnabledLayerCount = (data.enabledLayers == null ? 0 : (uint)data.enabledLayers.Length), QueueCreateInfos = new DeviceQueueCreateInfo[] { graphicsQueue, presentQueue }, EnabledFeatures = new PhysicalDeviceFeatures { SamplerAnisotropy = true } }; device = data.physicalDevice.CreateDevice(deviceInfo); this.graphicsQueue = device.GetQueue((uint)data.queueFamilyIndices.GraphicsFamily, 0); this.presentQueue = device.GetQueue((uint)data.queueFamilyIndices.PresentFamily, 0); CreateSwapChain(); CreateImageViews(); CreateRenderPass(); CreateDescriptorSetLayout(); CreateGraphicsPipeline(); CreateFrameBuffers(); CreateCommandPool(); CreateBuffers(); CreateDescriptorPool(); CreateDescriptorSets(); CreateCommandBuffers(); CreateSyncObjects(); submitInfo = new SubmitInfo { WaitSemaphoreCount = 1, WaitDstStageMask = waitStages, CommandBufferCount = 1, SignalSemaphoreCount = 1, }; presentInfo = new PresentInfoKhr { WaitSemaphoreCount = 1, SwapchainCount = 1, }; initialized = running = true; _lastFrame = DateTime.Now; Start(); //data.control.ParentForm.ResizeBegin += ResizeBegin; //data.control.ParentForm.ResizeEnd += ResizeEnd; }
/// <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; }
/// <summary> /// Initializes the specified device. /// </summary> /// <param name="graphicsProfiles">The graphics profiles.</param> /// <param name="deviceCreationFlags">The device creation flags.</param> /// <param name="windowHandle">The window handle.</param> private unsafe void InitializePlatformDevice(GraphicsProfile[] graphicsProfiles, DeviceCreationFlags deviceCreationFlags, object windowHandle) { if (nativeDevice != Device.Null) { // Destroy previous device ReleaseDevice(); } rendererName = Adapter.Description; PhysicalDeviceProperties physicalDeviceProperties; NativePhysicalDevice.GetProperties(out physicalDeviceProperties); ConstantBufferDataPlacementAlignment = (int)physicalDeviceProperties.Limits.MinUniformBufferOffsetAlignment; RequestedProfile = graphicsProfiles.Last(); var queueProperties = NativePhysicalDevice.QueueFamilyProperties; // Command lists are thread-safe and execute deferred IsDeferred = true; // TODO VULKAN // Create Vulkan device based on profile uint queuePriorities = 0; var queueCreateInfo = new DeviceQueueCreateInfo { StructureType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = 0, QueueCount = 1, QueuePriorities = new IntPtr(&queuePriorities) }; var enabledFeature = new PhysicalDeviceFeatures { FillModeNonSolid = true, ShaderClipDistance = true, ShaderCullDistance = true, SamplerAnisotropy = true, DepthClamp = true, }; var extensionProperties = NativePhysicalDevice.GetDeviceExtensionProperties(); var availableExtensionNames = new List <string>(); var desiredExtensionNames = new List <string>(); for (int index = 0; index < extensionProperties.Length; index++) { var namePointer = new IntPtr(Interop.Fixed(ref extensionProperties[index].ExtensionName)); var name = Marshal.PtrToStringAnsi(namePointer); availableExtensionNames.Add(name); } desiredExtensionNames.Add("VK_KHR_swapchain"); if (!availableExtensionNames.Contains("VK_KHR_swapchain")) { throw new InvalidOperationException(); } if (availableExtensionNames.Contains("VK_EXT_debug_marker") && IsDebugMode) { desiredExtensionNames.Add("VK_EXT_debug_marker"); IsProfilingSupported = true; } var enabledExtensionNames = desiredExtensionNames.Select(Marshal.StringToHGlobalAnsi).ToArray(); try { var deviceCreateInfo = new DeviceCreateInfo { StructureType = StructureType.DeviceCreateInfo, QueueCreateInfoCount = 1, QueueCreateInfos = new IntPtr(&queueCreateInfo), EnabledExtensionCount = (uint)enabledExtensionNames.Length, EnabledExtensionNames = enabledExtensionNames.Length > 0 ? new IntPtr(Interop.Fixed(enabledExtensionNames)) : IntPtr.Zero, EnabledFeatures = new IntPtr(&enabledFeature) }; nativeDevice = NativePhysicalDevice.CreateDevice(ref deviceCreateInfo); } finally { foreach (var enabledExtensionName in enabledExtensionNames) { Marshal.FreeHGlobal(enabledExtensionName); } } NativeCommandQueue = nativeDevice.GetQueue(0, 0); //// Prepare copy command list (start it closed, so that every new use start with a Reset) var commandPoolCreateInfo = new CommandPoolCreateInfo { StructureType = StructureType.CommandPoolCreateInfo, QueueFamilyIndex = 0, //device.NativeCommandQueue.FamilyIndex Flags = CommandPoolCreateFlags.ResetCommandBuffer }; NativeCopyCommandPool = NativeDevice.CreateCommandPool(ref commandPoolCreateInfo); var commandBufferAllocationInfo = new CommandBufferAllocateInfo { StructureType = StructureType.CommandBufferAllocateInfo, Level = CommandBufferLevel.Primary, CommandPool = NativeCopyCommandPool, CommandBufferCount = 1 }; CommandBuffer nativeCommandBuffer; NativeDevice.AllocateCommandBuffers(ref commandBufferAllocationInfo, &nativeCommandBuffer); NativeCopyCommandBuffer = nativeCommandBuffer; DescriptorPools = new HeapPool(this); nativeResourceCollector = new NativeResourceCollector(this); graphicsResourceLinkCollector = new GraphicsResourceLinkCollector(this); EmptyTexelBuffer = Buffer.Typed.New(this, 1, PixelFormat.R32G32B32A32_Float); }
void CreateDevice() { PhysicalDevice[] physical_devices = DelegateUtility.EnumerateToArray <PhysicalDevice> (vk.EnumeratePhysicalDevices, (IntPtr)vulkan.Instance); if (physical_devices == null) { //std::cout << "Error occurred during physical devices enumeration!" << std::endl; return; } uint selected_graphics_queue_family_index = uint.MaxValue; uint selected_present_queue_family_index = uint.MaxValue; for (int i = 0; i < physical_devices.Length; ++i) { if (CheckPhysicalDeviceProperties(physical_devices[i], out selected_graphics_queue_family_index, out selected_present_queue_family_index)) { vulkan.PhysicalDevice = physical_devices[i]; } } if (vulkan.PhysicalDevice.IsZero || selected_graphics_queue_family_index == uint.MaxValue || selected_present_queue_family_index == uint.MaxValue) { //std::cout << "Could not select physical device based on the chosen properties!" << std::endl; return; } var queue_create_infos = stackalloc DeviceQueueCreateInfo[2]; uint count = 1; float *queue_priorities = stackalloc float[1]; queue_priorities[0] = 1.0f; queue_create_infos[0] = new DeviceQueueCreateInfo { sType = StructureType.DeviceQueueCreateInfo, // VkStructureType sType pNext = IntPtr.Zero, // const void *pNext flags = 0, // VkDeviceQueueCreateFlagBits flags queueFamilyIndex = selected_graphics_queue_family_index, // uint32_t queueFamilyIndex queueCount = 1, // uint32_t queueCount pQueuePriorities = queue_priorities // const float *pQueuePriorities }; if (selected_graphics_queue_family_index != selected_present_queue_family_index) { queue_create_infos[1] = new DeviceQueueCreateInfo { sType = StructureType.DeviceQueueCreateInfo, // VkStructureType sType pNext = IntPtr.Zero, // const void *pNext flags = 0, // VkDeviceQueueCreateFlagBits flags queueFamilyIndex = selected_present_queue_family_index, // uint32_t queueFamilyIndex queueCount = 1, // uint32_t queueCount pQueuePriorities = queue_priorities // const float *pQueuePriorities }; count++; } const uint exCount = 1; var exPtr = MarshalUtility.AllocateString(new string[] { KhrSwapchain.EXTENSION_NAME }); DeviceCreateInfo device_create_info = new DeviceCreateInfo { sType = StructureType.DeviceCreateInfo, // VkStructureType sType pNext = IntPtr.Zero, // const void *pNext flags = 0, // VkDeviceCreateFlagBits flags queueCreateInfoCount = count, // uint32_t queueCreateInfoCount pQueueCreateInfos = queue_create_infos, // const VkDeviceQueueCreateInfo *pQueueCreateInfos enabledLayerCount = 0, // uint32_t enabledLayerCount ppEnabledLayerNames = (byte *)0, // const char * const *ppEnabledLayerNames enabledExtensionCount = exCount, // uint32_t enabledExtensionCount ppEnabledExtensionNames = (byte *)exPtr, // const char * const *ppEnabledExtensionNames pEnabledFeatures = (PhysicalDeviceFeatures *)0 // const VkPhysicalDeviceFeatures *pEnabledFeatures }; vk.CreateDevice(vulkan.PhysicalDevice, ref device_create_info, (AllocationCallbacks *)0, out vulkan.Device).CheckError(); MarshalUtility.FreeString(exPtr, (int)exCount); }
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)); }
public static Device CreateDevice(Vk api, PhysicalDevice physicalDevice, uint queueFamilyIndex, string[] supportedExtensions, uint queueCount) { if (queueCount > QueuesCount) { queueCount = QueuesCount; } float *queuePriorities = stackalloc float[(int)queueCount]; for (int i = 0; i < queueCount; i++) { queuePriorities[i] = 1f; } var queueCreateInfo = new DeviceQueueCreateInfo() { SType = StructureType.DeviceQueueCreateInfo, QueueFamilyIndex = queueFamilyIndex, QueueCount = queueCount, PQueuePriorities = queuePriorities }; api.GetPhysicalDeviceProperties(physicalDevice, out var properties); bool useRobustBufferAccess = VendorUtils.FromId(properties.VendorID) == Vendor.Nvidia; var supportedFeatures = api.GetPhysicalDeviceFeature(physicalDevice); var features = new PhysicalDeviceFeatures() { DepthBiasClamp = true, DepthClamp = true, DualSrcBlend = true, FragmentStoresAndAtomics = true, GeometryShader = true, ImageCubeArray = true, IndependentBlend = true, LogicOp = true, MultiViewport = true, PipelineStatisticsQuery = true, SamplerAnisotropy = true, ShaderClipDistance = true, ShaderFloat64 = supportedFeatures.ShaderFloat64, ShaderImageGatherExtended = true, // ShaderStorageImageReadWithoutFormat = true, // ShaderStorageImageWriteWithoutFormat = true, TessellationShader = true, VertexPipelineStoresAndAtomics = true, RobustBufferAccess = useRobustBufferAccess }; void *pExtendedFeatures = null; var featuresTransformFeedback = new PhysicalDeviceTransformFeedbackFeaturesEXT() { SType = StructureType.PhysicalDeviceTransformFeedbackFeaturesExt, PNext = pExtendedFeatures, TransformFeedback = true }; pExtendedFeatures = &featuresTransformFeedback; var featuresRobustness2 = new PhysicalDeviceRobustness2FeaturesEXT() { SType = StructureType.PhysicalDeviceRobustness2FeaturesExt, PNext = pExtendedFeatures, NullDescriptor = true }; pExtendedFeatures = &featuresRobustness2; var featuresExtendedDynamicState = new PhysicalDeviceExtendedDynamicStateFeaturesEXT() { SType = StructureType.PhysicalDeviceExtendedDynamicStateFeaturesExt, PNext = pExtendedFeatures, ExtendedDynamicState = supportedExtensions.Contains(ExtExtendedDynamicState.ExtensionName) }; pExtendedFeatures = &featuresExtendedDynamicState; var featuresVk11 = new PhysicalDeviceVulkan11Features() { SType = StructureType.PhysicalDeviceVulkan11Features, PNext = pExtendedFeatures, ShaderDrawParameters = true }; pExtendedFeatures = &featuresVk11; var featuresVk12 = new PhysicalDeviceVulkan12Features() { SType = StructureType.PhysicalDeviceVulkan12Features, PNext = pExtendedFeatures, DescriptorIndexing = supportedExtensions.Contains("VK_EXT_descriptor_indexing"), DrawIndirectCount = supportedExtensions.Contains(KhrDrawIndirectCount.ExtensionName) }; pExtendedFeatures = &featuresVk12; PhysicalDeviceIndexTypeUint8FeaturesEXT featuresIndexU8; if (supportedExtensions.Contains("VK_EXT_index_type_uint8")) { featuresIndexU8 = new PhysicalDeviceIndexTypeUint8FeaturesEXT() { SType = StructureType.PhysicalDeviceIndexTypeUint8FeaturesExt, PNext = pExtendedFeatures, IndexTypeUint8 = true }; pExtendedFeatures = &featuresIndexU8; } PhysicalDeviceFragmentShaderInterlockFeaturesEXT featuresFragmentShaderInterlock; if (supportedExtensions.Contains("VK_EXT_fragment_shader_interlock")) { featuresFragmentShaderInterlock = new PhysicalDeviceFragmentShaderInterlockFeaturesEXT() { SType = StructureType.PhysicalDeviceFragmentShaderInterlockFeaturesExt, PNext = pExtendedFeatures, FragmentShaderPixelInterlock = true }; pExtendedFeatures = &featuresFragmentShaderInterlock; } PhysicalDeviceSubgroupSizeControlFeaturesEXT featuresSubgroupSizeControl; if (supportedExtensions.Contains("VK_EXT_subgroup_size_control")) { featuresSubgroupSizeControl = new PhysicalDeviceSubgroupSizeControlFeaturesEXT() { SType = StructureType.PhysicalDeviceSubgroupSizeControlFeaturesExt, PNext = pExtendedFeatures, SubgroupSizeControl = true }; pExtendedFeatures = &featuresSubgroupSizeControl; } var enabledExtensions = RequiredExtensions.Union(DesirableExtensions.Intersect(supportedExtensions)).ToArray(); IntPtr *ppEnabledExtensions = stackalloc IntPtr[enabledExtensions.Length]; for (int i = 0; i < enabledExtensions.Length; i++) { ppEnabledExtensions[i] = Marshal.StringToHGlobalAnsi(enabledExtensions[i]); } var deviceCreateInfo = new DeviceCreateInfo() { SType = StructureType.DeviceCreateInfo, PNext = pExtendedFeatures, QueueCreateInfoCount = 1, PQueueCreateInfos = &queueCreateInfo, PpEnabledExtensionNames = (byte **)ppEnabledExtensions, EnabledExtensionCount = (uint)enabledExtensions.Length, PEnabledFeatures = &features }; api.CreateDevice(physicalDevice, in deviceCreateInfo, null, out var device).ThrowOnError(); for (int i = 0; i < enabledExtensions.Length; i++) { Marshal.FreeHGlobal(ppEnabledExtensions[i]); } return(device); }