예제 #1
0
        /// <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));
                    }
                }
            }
        }
예제 #2
0
        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));
                }
            }
        }
예제 #3
0
        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);
                }
            }
        }
예제 #4
0
 /// <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)));
     }
 }
예제 #5
0
 /// <summary>
 /// Resets this fence
 /// </summary>
 public void Reset()
 {
     unsafe
     {
         var handle = Handle;
         VkException.Check(VkDevice.vkResetFences(Device.Handle, 1, &handle));
     }
 }
예제 #6
0
        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);
                    }
                }
            }
        }
예제 #7
0
        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);
            }
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
        /// <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);
            }
        }
예제 #10
0
        /// <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);
            }
        }
예제 #11
0
 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;
     }
 }
예제 #12
0
 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;
     }
 }
예제 #13
0
        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);
                }
            }
        }