/// <summary> /// To query the extensions available to a given physical device, call: /// </summary> /// <param name="layerName">is either `NULL` or a pointer to a null-terminated UTF-8 string naming the layer to retrieve extensions from.</param> /// <returns>array of <see cref="VkExtensionProperties"/> structures</returns> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorOutOfHostMemory"></exception> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorOutOfDeviceMemory"></exception> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorLayerNotPresent"></exception> public VkExtensionProperties[] EnumerateExtensionProperties(string layerName) { unsafe { var layerNamePtr = (byte *)0; try { if (layerName != null) { layerNamePtr = (byte *)Marshal.StringToHGlobalAnsi(layerName).ToPointer(); } VkExtensionProperties[] props; uint count = 0; do { props = new VkExtensionProperties[count]; fixed(VkExtensionProperties *pptr = props) VkException.Check(vkEnumerateDeviceExtensionProperties(this, layerNamePtr, &count, pptr)); } while (props.Length != count); return(props); } finally { if (layerNamePtr != (byte *)0) { Marshal.FreeHGlobal(new IntPtr(layerNamePtr)); } } } }
public void Submit(CommandBuffer buffer, VkSemaphore?wait = null, VkPipelineStageFlag waitStage = 0, VkSemaphore?signal = null, VkFence?submit = null) { buffer.AssertBuilt(); var buff = buffer.Handle; unsafe { var waitH = wait ?? VkSemaphore.Null; var signalH = signal ?? VkSemaphore.Null; var submitH = submit ?? VkFence.Null; var info = new VkSubmitInfo() { SType = VkStructureType.SubmitInfo, PNext = IntPtr.Zero, CommandBufferCount = 1, PCommandBuffers = &buff, SignalSemaphoreCount = signalH != VkSemaphore.Null ? 1u : 0u, PSignalSemaphores = &signalH, WaitSemaphoreCount = waitH != VkSemaphore.Null ? 1u : 0u, PWaitSemaphores = &waitH, PWaitDstStageMask = &waitStage, }; if (buffer is CommandBufferPooledExclusiveUse peu) { Debug.Assert(submitH == VkFence.Null, "Can't use a submit fence on a pooled handle"); peu.DoSubmit(Handle, info); } else { VkException.Check(VkQueue.vkQueueSubmit(Handle, 1, &info, submitH)); } } }
public void PresentKHR(SwapchainKHR swapchain, uint imageIndex, VkSemaphore[] waitSemaphores) { AssertValid(); unsafe { swapchain.AssertValid(); var swapHandle = swapchain.Handle; fixed(VkSemaphore *waitPtr = waitSemaphores) { var result = VkResult.ErrorDeviceLost; var info = new VkPresentInfoKHR() { SType = VkStructureType.PresentInfoKhr, PNext = IntPtr.Zero, SwapchainCount = 1, PSwapchains = &swapHandle, PImageIndices = &imageIndex, WaitSemaphoreCount = (uint)(waitSemaphores?.Length ?? 0), PWaitSemaphores = waitPtr, PResults = &result }; Handle.QueuePresentKHR(&info); VkException.Check(result); } } }
/// <summary> /// Waits for this fence. /// </summary> /// <param name="timeout">Timeout in ns</param> /// <returns><see cref="VkResult.Success"/> or <see cref="VkResult.Timeout"/></returns> public VkResult WaitFor(ulong timeout) { unsafe { var handle = Handle; return(VkException.Check(VkDevice.vkWaitForFences(Device.Handle, 1, &handle, true, timeout))); } }
/// <summary> /// Resets this fence /// </summary> public void Reset() { unsafe { var handle = Handle; VkException.Check(VkDevice.vkResetFences(Device.Handle, 1, &handle)); } }
public void Submit(CommandBuffer[] buffers, VkSemaphore[] wait, VkPipelineStageFlag[] waitStages, VkSemaphore[] signal, VkFence submit) { unsafe { // ReSharper disable once PossibleNullReferenceException Debug.Assert((waitStages == null && wait == null) || waitStages.Length == wait.Length); var arrayBuffers = buffers.Where(x => !(x is CommandBufferPooledExclusiveUse)).Select(x => { x.AssertBuilt(); return(x.Handle); }).ToArray(); var pooledBuffers = buffers.OfType <CommandBufferPooledExclusiveUse>().ToArray(); Debug.Assert(pooledBuffers.Length == 0 || submit == VkFence.Null, "Can't use custom submit fence on pooled buffers"); fixed(VkSemaphore *waitPtr = wait) fixed(VkPipelineStageFlag * waitStagePtr = waitStages) fixed(VkSemaphore * signalPtr = signal) { if (arrayBuffers.Length > 0) fixed(VkCommandBuffer *buffer = arrayBuffers) { var info = new VkSubmitInfo() { SType = VkStructureType.SubmitInfo, PNext = IntPtr.Zero, CommandBufferCount = (uint)arrayBuffers.Length, PCommandBuffers = buffer, SignalSemaphoreCount = (uint)(signal?.Length ?? 0), PSignalSemaphores = signalPtr, WaitSemaphoreCount = (uint)(wait?.Length ?? 0), PWaitSemaphores = waitPtr, PWaitDstStageMask = waitStagePtr, }; VkException.Check(VkQueue.vkQueueSubmit(Handle, 1, &info, submit)); } foreach (var pooled in pooledBuffers) { var handle = pooled.Handle; var info = new VkSubmitInfo() { SType = VkStructureType.SubmitInfo, PNext = IntPtr.Zero, CommandBufferCount = 1, PCommandBuffers = &handle, SignalSemaphoreCount = (uint)(signal?.Length ?? 0), PSignalSemaphores = signalPtr, WaitSemaphoreCount = (uint)(wait?.Length ?? 0), PWaitSemaphores = waitPtr, PWaitDstStageMask = waitStagePtr, }; pooled.DoSubmit(Handle, info); } } } }
public VkImage[] GetSwapchainImagesKHR(VkSwapchainKHR swapchain) { unsafe { VkImage[] props; uint count = 0; do { props = new VkImage[count]; fixed(VkImage *pptr = props) VkException.Check(vkGetSwapchainImagesKHR(this, swapchain, &count, pptr)); } while (props.Length != count); return(props); } }
public VkSurfaceFormatKHR[] GetPhysicalDeviceSurfaceFormatsKHR(VkSurfaceKHR surface) { unsafe { VkSurfaceFormatKHR[] props; uint count = 0; do { props = new VkSurfaceFormatKHR[count]; fixed(VkSurfaceFormatKHR *pptr = props) VkException.Check(vkGetPhysicalDeviceSurfaceFormatsKHR(this, surface, &count, pptr)); } while (props.Length != count); return(props); } }
/// <summary> /// To enumerate device layers, call: /// </summary> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorOutOfHostMemory"></exception> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorOutOfDeviceMemory"></exception> /// <returns>array of <see cref="VkLayerProperties"/> structures</returns> public VkLayerProperties[] EnumerateLayerProperties() { unsafe { VkLayerProperties[] props; uint count = 0; do { props = new VkLayerProperties[count]; fixed(VkLayerProperties *pptr = props) VkException.Check(vkEnumerateDeviceLayerProperties(this, &count, pptr)); } while (props.Length != count); return(props); } }
/// <summary> /// To retrieve a list of physical device objects representing the physical devices installed in the system, call: /// </summary> /// <param name="pPhysicalDevices">is either `NULL` or a pointer to an array of <see cref="VkPhysicalDevice"/> handles.</param> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorOutOfHostMemory"></exception> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorOutOfDeviceMemory"></exception> /// <exception cref="VulkanLibrary.Unmanaged.VkErrorInitializationFailed"></exception> public VkPhysicalDevice[] EnumeratePhysicalDevices() { unsafe { VkPhysicalDevice[] props; uint count = 0; do { props = new VkPhysicalDevice[count]; fixed(VkPhysicalDevice *pptr = props) VkException.Check(vkEnumeratePhysicalDevices(this, &count, pptr)); } while (props.Length != count); return(props); } }
public DescriptorSet(DescriptorPool pool, DescriptorSetLayout layout) { unsafe { var layoutHandle = layout.Handle; var info = new VkDescriptorSetAllocateInfo() { SType = VkStructureType.DescriptorSetAllocateInfo, PNext = IntPtr.Zero, DescriptorPool = pool.Handle, DescriptorSetCount = 1, PSetLayouts = &layoutHandle }; VkDescriptorSet result; VkException.Check(VkDevice.vkAllocateDescriptorSets(pool.Device.Handle, &info, &result)); DescriptorPool = pool; Handle = result; } }
public CommandBuffer(CommandPool pool, VkCommandBufferLevel level) { CommandPool = pool; unsafe { VkCommandBuffer handle = VkCommandBuffer.Null; VkCommandBufferAllocateInfo info = new VkCommandBufferAllocateInfo() { SType = VkStructureType.CommandBufferAllocateInfo, PNext = IntPtr.Zero, CommandPool = pool.Handle, CommandBufferCount = 1, Level = level }; VkException.Check(VkDevice.vkAllocateCommandBuffers(Device.Handle, &info, &handle)); Debug.Assert(handle != VkCommandBuffer.Null); Handle = handle; _state = State.Allocated; } }
public Pipeline Build() { var stages = _stages.ToArray(); var vertexBindings = new VkVertexInputBindingDescription[_vertexBindingDescriptions.Count]; { var i = 0; foreach (var kv in _vertexBindingDescriptions) { vertexBindings[i++] = kv.Value; } } var attributeBindings = new VkVertexInputAttributeDescription[_vertexAttributeDescriptions.Count]; { var i = 0; foreach (var kv in _vertexAttributeDescriptions) { attributeBindings[i++] = kv.Value; } } var blendStates = new VkPipelineColorBlendAttachmentState[_blendAttachmentStates.Count]; foreach (var kv in _blendAttachmentStates) { blendStates[kv.Key] = kv.Value; } var viewports = _viewports.ToArray(); var scissors = _viewportScissors.ToArray(); var dynamicStates = _dynamicStates.ToArray(); try { unsafe { fixed(VkViewport *viewportPtr = viewports) fixed(VkRect2D * scissorPtr = scissors) fixed(VkDynamicState * dynamicPtr = dynamicStates) fixed(VkPipelineColorBlendAttachmentState * blendPtr = blendStates) fixed(VkVertexInputBindingDescription * vertexPtr = vertexBindings) fixed(VkVertexInputAttributeDescription * attributePtr = attributeBindings) fixed(VkPipelineShaderStageCreateInfo * stagePtr = stages) { if (_basePipeline != null) { _flags |= VkPipelineCreateFlag.Derivative; } else { _flags &= ~VkPipelineCreateFlag.Derivative; } var vertexInputState = new VkPipelineVertexInputStateCreateInfo() { SType = VkStructureType.PipelineVertexInputStateCreateInfo, PNext = IntPtr.Zero, Flags = 0, VertexBindingDescriptionCount = (uint)vertexBindings.Length, PVertexBindingDescriptions = vertexPtr, VertexAttributeDescriptionCount = (uint)attributeBindings.Length, PVertexAttributeDescriptions = attributePtr }; var assemblyState = _asmInfo; var tessState = _tessInfo; var viewportState = new VkPipelineViewportStateCreateInfo() { SType = VkStructureType.PipelineViewportStateCreateInfo, PNext = IntPtr.Zero, Flags = 0, ViewportCount = (uint)viewports.Length, PViewports = viewportPtr, ScissorCount = (uint)scissors.Length, PScissors = scissorPtr }; var rasterState = _rasterInfo; var multisampleState = _multisampleInfo; var depthStencilState = _depthStencilInfo; var colorBlendState = _colorBlendInfo; colorBlendState.AttachmentCount = (uint)blendStates.Length; colorBlendState.PAttachments = blendPtr; var dynamicState = new VkPipelineDynamicStateCreateInfo() { SType = VkStructureType.PipelineDynamicStateCreateInfo, PNext = IntPtr.Zero, Flags = 0, DynamicStateCount = (uint)dynamicStates.Length, PDynamicStates = dynamicPtr }; var info = new VkGraphicsPipelineCreateInfo() { SType = VkStructureType.GraphicsPipelineCreateInfo, PNext = IntPtr.Zero, Flags = _flags, StageCount = (uint)stages.Length, PStages = stagePtr, PVertexInputState = &vertexInputState, PInputAssemblyState = &assemblyState, PTessellationState = &tessState, PViewportState = &viewportState, PRasterizationState = &rasterState, PMultisampleState = &multisampleState, PDepthStencilState = &depthStencilState, PColorBlendState = &colorBlendState, PDynamicState = dynamicStates.Length > 0 ? &dynamicState : (VkPipelineDynamicStateCreateInfo *)0, Layout = _pipelineLayout.Handle, RenderPass = _pass.Handle, Subpass = _subpassId, BasePipelineHandle = _basePipeline?.Handle ?? VkPipeline.Null, BasePipelineIndex = _basePipelineIndex }; VkPipeline result = VkPipeline.Null; VkException.Check(VkDevice.vkCreateGraphicsPipelines(_pass.Device.Handle, VkPipelineCache.Null, 1, &info, _pass.Instance.AllocationCallbacks, &result)); Debug.Assert(result != VkPipeline.Null); return(new Pipeline(_pass.Device, VkPipelineBindPoint.Graphics, _pipelineLayout, result)); } } } finally { foreach (var pin in _pins) { pin.Free(); } foreach (var strPin in _strPins) { Marshal.FreeHGlobal(strPin); } } }