internal SurfaceKhr(Instance parent, XlibSurfaceCreateInfoKhr *createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; long handle; createInfo->Prepare(); Result result = vkCreateXlibSurfaceKHR(Parent, createInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
internal Device(PhysicalDevice parent, ref DeviceCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; createInfo.ToNative(out DeviceCreateInfo.Native nativeCreateInfo); IntPtr handle; Result result = vkCreateDevice(Parent.Handle, &nativeCreateInfo, NativeAllocator, &handle); nativeCreateInfo.Free(); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
internal DescriptorSetLayout(Device parent, ref DescriptorSetLayoutCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; createInfo.ToNative(out DescriptorSetLayoutCreateInfo.Native nativeCreateInfo); long handle; Result result = vkCreateDescriptorSetLayout(Parent, &nativeCreateInfo, NativeAllocator, &handle); nativeCreateInfo.Free(); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
internal Semaphore(Device parent, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; var createInfo = new SemaphoreCreateInfo(); createInfo.Prepare(); long handle; Result result = vkCreateSemaphore(Parent, &createInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
internal ShaderModule(Device parent, ref ShaderModuleCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(byte *codePtr = createInfo.Code) { createInfo.ToNative(out ShaderModuleCreateInfo.Native nativeCreateInfo, codePtr); long handle; Result result = vkCreateShaderModule(Parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
internal IndirectCommandsLayoutNvx(Device parent, ref IndirectCommandsLayoutCreateInfoNvx createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(IndirectCommandsLayoutTokenNvx *tokensPtr = createInfo.Tokens) { createInfo.ToNative(out IndirectCommandsLayoutCreateInfoNvx.Native nativeCreateInfo, tokensPtr); long handle; Result result = vkCreateIndirectCommandsLayoutNVX(Parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
internal Image(Device parent, ref ImageCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(int *queueFamilyIndicesPtr = createInfo.QueueFamilyIndices) { createInfo.ToNative(out ImageCreateInfo.Native nativeCreateInfo, queueFamilyIndicesPtr); long handle; Result result = vkCreateImage(parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
internal DescriptorPool(Device parent, ref DescriptorPoolCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(DescriptorPoolSize *poolSizesPtr = createInfo.PoolSizes) { createInfo.ToNative(out DescriptorPoolCreateInfo.Native nativeCreateInfo, poolSizesPtr); long handle; Result result = vkCreateDescriptorPool(Parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
/// <summary> /// Create a new Vulkan instance. /// </summary> /// <param name="createInfo"> /// An instance of <see cref="InstanceCreateInfo"/> controlling creation of the instance. /// </param> /// <param name="allocator">Controls host memory allocation.</param> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public Instance(InstanceCreateInfo createInfo = default(InstanceCreateInfo), AllocationCallbacks?allocator = null) { Allocator = allocator; createInfo.ToNative(out InstanceCreateInfo.Native nativeCreateInfo); IntPtr handle; Result result = vkCreateInstance(&nativeCreateInfo, NativeAllocator, &handle); nativeCreateInfo.Free(); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
internal PipelineCache(Device parent, ref PipelineCacheCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(byte *initialDataPtr = createInfo.InitialData) { createInfo.ToNative(out PipelineCacheCreateInfo.Native nativeCreateInfo, initialDataPtr); long handle; Result result = vkCreatePipelineCache(Parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
internal SwapchainKhr(Device parent, ref SwapchainCreateInfoKhr createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; Format = createInfo.ImageFormat; long handle; createInfo.ToNative(out SwapchainCreateInfoKhr.Native nativeCreateInfo); Result result = vkCreateSwapchainKHR(Parent, &nativeCreateInfo, NativeAllocator, &handle); nativeCreateInfo.Free(); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
internal DescriptorUpdateTemplateKhr(Device parent, ref DescriptorUpdateTemplateCreateInfoKhr createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(DescriptorUpdateTemplateEntryKhr *nativeDescriptorUpdateEntries = createInfo.DescriptorUpdateEntries) { createInfo.ToNative(out var nativeCreateInfo, nativeDescriptorUpdateEntries); long handle; Result result = vkCreateDescriptorUpdateTemplateKHR(parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
internal RenderPass(Device parent, ref RenderPassCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(AttachmentDescription *attachmentsPtr = createInfo.Attachments) fixed(SubpassDependency * dependenciesPtr = createInfo.Dependencies) { createInfo.ToNative(out RenderPassCreateInfo.Native nativeCreateInfo, attachmentsPtr, dependenciesPtr); long handle; Result result = vkCreateRenderPass(Parent, &nativeCreateInfo, NativeAllocator, &handle); nativeCreateInfo.Free(); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
internal Framebuffer(Device parent, RenderPass renderPass, ref FramebufferCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; RenderPass = renderPass; Allocator = allocator; fixed(long *attachmentsPtr = createInfo.Attachments) { createInfo.ToNative(out FramebufferCreateInfo.Native nativeCreateInfo, attachmentsPtr, renderPass); long handle; Result result = vkCreateFramebuffer(Parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
internal ObjectTableNvx(Device parent, ref ObjectTableCreateInfoNvx createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; fixed(ObjectEntryTypeNvx *objEntryTypesPtr = createInfo.ObjectEntryTypes) fixed(int *objEntryCountsPtr = createInfo.ObjectEntryCounts) fixed(ObjectEntryUsagesNvx * objEntryUsagesPtr = createInfo.ObjectEntryUsageFlags) { createInfo.ToNative(out ObjectTableCreateInfoNvx.Native nativeCreateInfo, objEntryTypesPtr, objEntryCountsPtr, objEntryUsagesPtr); long handle; Result result = vkCreateObjectTableNVX(this)(Parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
/// <summary> /// Signal a fence when a device event occurs. /// </summary> /// <param name="device">A logical device on which the event may occur.</param> /// <param name="deviceEventInfo">A structure describing the event of interest to the application.</param> /// <param name="allocator">Controls host memory allocation.</param> /// <returns>The resulting fence object.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static Fence RegisterDeviceEventExt(this Device device, DeviceEventInfoExt deviceEventInfo, AllocationCallbacks? allocator = null) { deviceEventInfo.Prepare(); AllocationCallbacks.Native* nativeAllocator = null; if (allocator.HasValue) { nativeAllocator = (AllocationCallbacks.Native*)Interop.Alloc<AllocationCallbacks.Native>(); allocator.Value.ToNative(nativeAllocator); } long handle; Result result = vkRegisterDeviceEventEXT(device)(device, &deviceEventInfo, nativeAllocator, &handle); Interop.Free(nativeAllocator); VulkanException.ThrowForInvalidResult(result); return new Fence(device, ref allocator, handle); }
internal DebugReportCallbackExt(Instance parent, ref DebugReportCallbackCreateInfoExt createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; var createDelegate = Parent.GetProc <CreateDebugReportCallbackExt>("vkCreateDebugReportCallbackEXT"); if (createDelegate == null) { throw new InvalidOperationException(nameof(DebugReportCallbackExt) + " is not supported."); } Func <DebugReportCallbackInfo, bool> createInfoCallback = createInfo.Callback; IntPtr callbackHandle = IntPtr.Zero; if (createInfoCallback != null) { _callback = (flags, objectType, @object, location, messageCode, layerPrefix, message, userData) => createInfoCallback(new DebugReportCallbackInfo { Flags = flags, ObjectType = objectType, Object = @object, Location = location, MessageCode = messageCode, LayerPrefix = Interop.String.FromPointer(layerPrefix), Message = Interop.String.FromPointer(message), UserData = userData }); callbackHandle = Interop.GetFunctionPointerForDelegate(_callback); } createInfo.ToNative(out DebugReportCallbackCreateInfoExt.Native nativeCreateInfo, callbackHandle); long handle; Result result = createDelegate( Parent.Handle, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; }
/// <summary> /// Create a <see cref="SurfaceKhr"/> object for a VI layer. /// <para> /// During the lifetime of a surface created using a particular `NativeWindowHandle`, any /// attempts to create another surface for the same `Layer` and any attempts to connect to /// the same layer through other platform mechanisms will have undefined results. /// </para> /// <para> /// The <see cref="SurfaceCapabilitiesKhr.CurrentExtent"/> of a VI surface is always /// undefined. Applications are expected to choose an appropriate size for the swapchain's /// <see cref="SwapchainCreateInfoKhr.ImageExtent"/> (e.g., by matching the the result of a /// call to `GetDisplayResolution`). /// </para> /// </summary> /// <param name="instance">The <see cref="Instance"/> to associate with the surface.</param> /// <param name="createInfo"> /// The structure containing the parameters affecting the creation of the surface object. /// </param> /// <param name="allocator"> /// The allocator used for host memory allocated for the surface object. /// </param> /// <returns>The resulting surface object handle.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static SurfaceKhr CreateVISurfaceNN(this Instance instance, VISurfaceCreateInfoNN createInfo, AllocationCallbacks?allocator = null) { createInfo.Prepare(); AllocationCallbacks.Native *nativeAllocator = null; if (allocator.HasValue) { nativeAllocator = (AllocationCallbacks.Native *)Interop.Alloc <AllocationCallbacks.Native>(); allocator.Value.ToNative(nativeAllocator); } long handle; Result result = vkCreateViSurfaceNN(instance)(instance, &createInfo, nativeAllocator, &handle); Interop.Free(nativeAllocator); VulkanException.ThrowForInvalidResult(result); return(new SurfaceKhr(instance, ref allocator, handle)); }
internal void CreateWindowSurface(Window wnd) { //create window surface IntPtr surfaceHandle; Result result = (Result)Vulkan.CreateWindowSurface( mInstance.GetInstance().Handle, wnd, IntPtr.Zero, out surfaceHandle); if (result != Result.Success) { ErrorSpew("Window surface creation failed: " + result.ToString()); return; } AllocationCallbacks?superAnnoyingParameter = null; mSurface = new SurfaceKhr(mInstance.GetInstance(), ref superAnnoyingParameter, surfaceHandle.ToInt64()); }
internal PipelineLayout(Device parent, ref PipelineLayoutCreateInfo createInfo, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; int setLayoutCount = createInfo.SetLayouts?.Length ?? 0; var layoutsPtr = stackalloc long[setLayoutCount]; for (int i = 0; i < setLayoutCount; i++) layoutsPtr[i] = createInfo.SetLayouts[i]; fixed(PushConstantRange *pushConstantRangesPtr = createInfo.PushConstantRanges) { createInfo.ToNative(out PipelineLayoutCreateInfo.Native nativeCreateInfo, layoutsPtr, pushConstantRangesPtr); long handle; Result result = vkCreatePipelineLayout(Parent, &nativeCreateInfo, NativeAllocator, &handle); VulkanException.ThrowForInvalidResult(result); Handle = handle; } }
/// <summary> /// Creates a new validation cache. /// </summary> /// <param name="device">The logical device that creates the validation cache object.</param> /// <param name="createInfo">The initial parameters for the validation cache object.</param> /// <param name="allocator">Controls host memory allocation.</param> /// <returns>Handle in which the resulting validation cache object is returned.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static ValidationCacheExt CreateValidationCacheExt(this Device device, ValidationCacheCreateInfoExt createInfo, AllocationCallbacks?allocator) { return(new ValidationCacheExt(device, &createInfo, ref allocator)); }
internal SurfaceKhr(Instance parent, ref AllocationCallbacks?allocator, long handle) { Parent = parent; Allocator = allocator; Handle = handle; }
/// <summary> /// Create a debug report callback object. /// </summary> /// <param name="instance">The instance the callback will be logged on.</param> /// <param name="createInfo"> /// The structure which defines the conditions under which this callback will be called. /// </param> /// <param name="allocator">Controls host memory allocation.</param> /// <returns>A <see cref="DebugReportCallbackExt"/> handle.</returns> /// <exception cref="InvalidOperationException">Vulkan command not found.</exception> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public static DebugReportCallbackExt CreateDebugReportCallbackExt(this Instance instance, DebugReportCallbackCreateInfoExt createInfo, AllocationCallbacks?allocator = null) { return(new DebugReportCallbackExt(instance, ref createInfo, ref allocator)); }
internal SwapchainKhr(Device parent, long handle, ref AllocationCallbacks?allocator) { Parent = parent; Allocator = allocator; Handle = handle; }
internal Fence(Device parent, ref AllocationCallbacks?allocator, long handle) { Parent = parent; Allocator = allocator; Handle = handle; }
/// <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> /// Create a new buffer view object. /// </summary> /// <param name="createInfo"> /// The structure containing parameters to be used to create the buffer. /// </param> /// <param name="allocator">Controls host memory allocation.</param> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public BufferView CreateView(BufferViewCreateInfo createInfo, AllocationCallbacks?allocator = null) { return(new BufferView(Parent, this, &createInfo, ref allocator)); }
/// <summary> /// Create a new Vulkan instance. /// </summary> /// <param name="flags"> /// Reserved for future use. /// </param> /// <param name="applicationInfo"> /// Null or an instance of ApplicationInfo. If not Null, this /// information helps implementations recognize behavior inherent to /// classes of applications. ApplicationInfo is defined in detail /// below. /// </param> /// <param name="enabledLayerNames"> /// An array of enabledLayerCount strings containing the names of /// layers to enable for the created instance. See the Layers section /// for further details. /// </param> /// <param name="enabledExtensionNames"> /// An array of enabledExtensionCount strings containing the names of /// extensions to enable. /// </param> /// <param name="debugReportCallbackCreateInfoExt"> /// </param> /// <param name="validationFlagsExt"> /// </param> /// <param name="allocator"> /// An optional AllocationCallbacks instance that controls host memory /// allocation. /// </param> public static unsafe SharpVk.Instance Create(ArrayProxy <string>?enabledLayerNames, ArrayProxy <string>?enabledExtensionNames, SharpVk.InstanceCreateFlags?flags = null, SharpVk.ApplicationInfo?applicationInfo = null, SharpVk.Multivendor.DebugReportCallbackCreateInfo?debugReportCallbackCreateInfoExt = null, SharpVk.Multivendor.ValidationFlags?validationFlagsExt = null, AllocationCallbacks?allocator = null) { return(Instance.Create(new CommandCache(new SharpVk.Interop.NativeLibrary(), "", null), enabledLayerNames, enabledExtensionNames, flags, applicationInfo, debugReportCallbackCreateInfoExt, validationFlagsExt, allocator)); }
/// <summary> /// Create a new framebuffer object. /// </summary> /// <param name="createInfo"> /// The structure which describes additional information about framebuffer creation. /// </param> /// <param name="allocator">Controls host memory allocation.</param> /// <returns>The resulting framebuffer object.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public Framebuffer CreateFramebuffer(FramebufferCreateInfo createInfo, AllocationCallbacks?allocator = null) { return(new Framebuffer(Parent, this, ref createInfo, ref allocator)); }
/// <summary> /// Create a new query pool object. /// </summary> /// <param name="createInfo"> /// Structure containing the number and type of queries to be managed by the pool. /// </param> /// <param name="allocator">Controls host memory allocation.</param> /// <returns>The resulting query pool object.</returns> /// <exception cref="VulkanException">Vulkan returns an error code.</exception> public QueryPool CreateQueryPool(QueryPoolCreateInfo createInfo, AllocationCallbacks?allocator = null) { return(new QueryPool(this, &createInfo, ref allocator)); }