Пример #1
0
        /// <summary>
        /// Submit an executable command buffer with optional wait and signal semaphores, and an optional fence to be signaled when the commands have been completed.
        /// </summary>
        /// <param name="queue">Queue.</param>
        /// <param name="wait">Wait.</param>
        /// <param name="signal">Signal.</param>
        /// <param name="fence">Fence.</param>
        public void Submit(VkQueue queue, VkSemaphore wait = default, VkSemaphore signal = default, Fence fence = null)
        {
            VkSubmitInfo submit_info = VkSubmitInfo.New();

            IntPtr dstStageMask = Marshal.AllocHGlobal(sizeof(uint));

            Marshal.WriteInt32(dstStageMask, (int)VkPipelineStageFlags.ColorAttachmentOutput);

            using (PinnedObjects pctx = new PinnedObjects()) {
                submit_info.pWaitDstStageMask = dstStageMask;
                if (signal != VkSemaphore.Null)
                {
                    submit_info.signalSemaphoreCount = 1;
                    submit_info.pSignalSemaphores    = signal.Pin(pctx);
                }
                if (wait != VkSemaphore.Null)
                {
                    submit_info.waitSemaphoreCount = 1;
                    submit_info.pWaitSemaphores    = wait.Pin(pctx);
                }

                submit_info.commandBufferCount = 1;
                submit_info.pCommandBuffers    = handle.Pin(pctx);

                Utils.CheckResult(vkQueueSubmit(queue, 1, ref submit_info, fence));
            }
            Marshal.FreeHGlobal(dstStageMask);
        }
Пример #2
0
        public static IntPtr Pin <T> (this T[] obj, PinnedObjects ctx)
        {
            GCHandle hnd = GCHandle.Alloc(obj, GCHandleType.Pinned);

            ctx.Handles.Add(hnd);
            return(hnd.AddrOfPinnedObject());
        }
Пример #3
0
        public static IntPtr Pin(this string obj, PinnedObjects ctx)
        {
            byte[]   n   = System.Text.Encoding.UTF8.GetBytes(obj + '\0');
            GCHandle hnd = GCHandle.Alloc(n, GCHandleType.Pinned);

            ctx.Handles.Add(hnd);
            return(hnd.AddrOfPinnedObject());
        }
Пример #4
0
        /// <summary>
        /// execute the descriptors writes targeting descriptorSets setted on AddWriteInfo call
        /// </summary>
        public void Write(Device dev, params object[] descriptors)
        {
            using (PinnedObjects pinCtx = new PinnedObjects()) {
                int i      = 0;
                int wdsPtr = 0;
                while (i < descriptors.Length)
                {
                    int firstDescriptor      = i;
                    VkWriteDescriptorSet wds = WriteDescriptorSets[wdsPtr];
                    if (dstSetOverride != null)
                    {
                        wds.dstSet = dstSetOverride.Value.Handle;
                    }
                    IntPtr pDescriptors = IntPtr.Zero;

                    if (wds.descriptorCount > 1)
                    {
                        List <IntPtr> descPtrArray = new List <IntPtr> ();
                        for (int d = 0; d < wds.descriptorCount; d++)
                        {
                            descPtrArray.Add(descriptors[i].Pin(pinCtx));
                            i++;
                        }
                        pDescriptors = descPtrArray.Pin(pinCtx);
                    }
                    else
                    {
                        pDescriptors = descriptors[i].Pin(pinCtx);
                        i++;
                    }
                    if (descriptors[firstDescriptor] is VkDescriptorBufferInfo)
                    {
                        wds.pBufferInfo = pDescriptors;
                    }
                    else if (descriptors[firstDescriptor] is VkDescriptorImageInfo)
                    {
                        wds.pImageInfo = pDescriptors;
                    }

                    WriteDescriptorSets[wdsPtr] = wds;
                    wdsPtr++;
                }
                vkUpdateDescriptorSets(dev.VkDev, (uint)WriteDescriptorSets.Count, WriteDescriptorSets.Pin(pinCtx), 0, IntPtr.Zero);
            }
        }
Пример #5
0
        /// <summary>
        /// execute the descriptors writes targeting descriptorSets setted on AddWriteInfo call
        /// </summary>
        public void Push(PrimaryCommandBuffer cmd, PipelineLayout plLayout, params object[] descriptors)
        {
            using (PinnedObjects pinCtx = new PinnedObjects()) {
                int i      = 0;
                int wdsPtr = 0;
                while (i < descriptors.Length)
                {
                    int firstDescriptor      = i;
                    VkWriteDescriptorSet wds = WriteDescriptorSets[wdsPtr];
                    wds.dstSet = 0;
                    IntPtr pDescriptors = IntPtr.Zero;

                    if (wds.descriptorCount > 1)
                    {
                        List <IntPtr> descPtrArray = new List <IntPtr> ();
                        for (int d = 0; d < wds.descriptorCount; d++)
                        {
                            descPtrArray.Add(descriptors[i].Pin(pinCtx));
                            i++;
                        }
                        pDescriptors = descPtrArray.Pin(pinCtx);
                    }
                    else
                    {
                        pDescriptors = descriptors[i].Pin(pinCtx);
                        i++;
                    }
                    if (descriptors[firstDescriptor] is VkDescriptorBufferInfo)
                    {
                        wds.pBufferInfo = pDescriptors;
                    }
                    else if (descriptors[firstDescriptor] is VkDescriptorImageInfo)
                    {
                        wds.pImageInfo = pDescriptors;
                    }

                    WriteDescriptorSets[wdsPtr] = wds;
                    wdsPtr++;
                }
                vkCmdPushDescriptorSetKHR(cmd.Handle, VkPipelineBindPoint.Graphics, plLayout.handle, 0,
                                          (uint)WriteDescriptorSets.Count, WriteDescriptorSets.Pin(pinCtx));
            }
        }
Пример #6
0
        protected void init(GraphicPipelineConfig cfg)
        {
            if (state != ActivableState.Activated)
            {
                Layout.Activate();
                RenderPass.Activate();
                Cache?.Activate();

                List <VkPipelineShaderStageCreateInfo> shaderStages = new List <VkPipelineShaderStageCreateInfo> ();
                foreach (ShaderInfo shader in cfg.Shaders)
                {
                    shaderStages.Add(shader.Info);
                }

                using (PinnedObjects pctx = new PinnedObjects()) {
                    VkPipelineColorBlendStateCreateInfo colorBlendInfo = VkPipelineColorBlendStateCreateInfo.New();
                    colorBlendInfo.logicOpEnable = cfg.ColorBlendLogicOpEnable;
                    colorBlendInfo.logicOp       = cfg.ColorBlendLogicOp;
                    unsafe {
                        colorBlendInfo.blendConstants[0] = cfg.ColorBlendConstants.X;
                        colorBlendInfo.blendConstants[1] = cfg.ColorBlendConstants.Y;
                        colorBlendInfo.blendConstants[2] = cfg.ColorBlendConstants.Z;
                        colorBlendInfo.blendConstants[3] = cfg.ColorBlendConstants.W;
                    }
                    colorBlendInfo.attachmentCount = (uint)cfg.blendAttachments.Count;
                    colorBlendInfo.pAttachments    = cfg.blendAttachments.Pin(pctx);

                    VkPipelineDynamicStateCreateInfo dynStatesInfo = VkPipelineDynamicStateCreateInfo.New();
                    dynStatesInfo.dynamicStateCount = (uint)cfg.dynamicStates.Count;
                    dynStatesInfo.pDynamicStates    = cfg.dynamicStates.Cast <int> ().ToArray().Pin(pctx);

                    VkPipelineVertexInputStateCreateInfo vertInputInfo = VkPipelineVertexInputStateCreateInfo.New();
                    vertInputInfo.vertexBindingDescriptionCount   = (uint)cfg.vertexBindings.Count;
                    vertInputInfo.pVertexBindingDescriptions      = cfg.vertexBindings.Pin(pctx);
                    vertInputInfo.vertexAttributeDescriptionCount = (uint)cfg.vertexAttributes.Count;
                    vertInputInfo.pVertexAttributeDescriptions    = cfg.vertexAttributes.Pin(pctx);

                    VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.New();
                    if (cfg.Viewports.Count > 0)
                    {
                        viewportState.viewportCount = (uint)cfg.Viewports.Count;
                        viewportState.pViewports    = cfg.Viewports.Pin(pctx);
                    }
                    else
                    {
                        viewportState.viewportCount = 1;
                    }

                    if (cfg.Scissors.Count > 0)
                    {
                        viewportState.scissorCount = (uint)cfg.Scissors.Count;
                        viewportState.pScissors    = cfg.Scissors.Pin(pctx);
                    }
                    else
                    {
                        viewportState.scissorCount = 1;
                    }

                    VkGraphicsPipelineCreateInfo info = VkGraphicsPipelineCreateInfo.New();
                    info.renderPass          = RenderPass.handle;
                    info.layout              = Layout.handle;
                    info.pVertexInputState   = vertInputInfo.Pin(pctx);
                    info.pInputAssemblyState = cfg.inputAssemblyState.Pin(pctx);
                    info.pRasterizationState = cfg.rasterizationState.Pin(pctx);
                    info.pColorBlendState    = colorBlendInfo.Pin(pctx);
                    info.pMultisampleState   = cfg.multisampleState.Pin(pctx);
                    info.pViewportState      = viewportState.Pin(pctx);
                    info.pDepthStencilState  = cfg.depthStencilState.Pin(pctx);
                    info.pDynamicState       = dynStatesInfo.Pin(pctx);
                    info.stageCount          = (uint)cfg.Shaders.Count;
                    info.pStages             = shaderStages.Pin(pctx);
                    info.subpass             = cfg.SubpassIndex;

                    Utils.CheckResult(vkCreateGraphicsPipelines(Dev.VkDev, Cache == null ? VkPipelineCache.Null : Cache.handle, 1, ref info, IntPtr.Zero, out handle));
                }
            }
            base.Activate();
        }
Пример #7
0
        /// <summary>
        /// Create a new vulkan instance with enabled extensions given as argument.
        /// </summary>
        /// <param name="extensions">List of extension to enable if supported</param>
        public Instance(params string[] extensions)
        {
            List <IntPtr> instanceExtensions = new List <IntPtr> ();
            List <IntPtr> enabledLayerNames  = new List <IntPtr> ();

            string[] supportedExts = SupportedExtensions(IntPtr.Zero);

            using (PinnedObjects pctx = new PinnedObjects()) {
                for (int i = 0; i < extensions.Length; i++)
                {
                    if (supportedExts.Contains(extensions [i]))
                    {
                        instanceExtensions.Add(extensions [i].Pin(pctx));
                        if (extensions [i] == Ext.I.VK_EXT_debug_utils)
                        {
                            debugUtilsEnabled = true;
                        }
                    }
                    else
                    {
                        Console.WriteLine($"Vulkan initialisation: Unsupported extension: {extensions [i]}");
                    }
                }


                if (VALIDATION)
                {
                    enabledLayerNames.Add(strValidationLayer.Pin(pctx));
                }
                if (RENDER_DOC_CAPTURE)
                {
                    enabledLayerNames.Add(strRenderDocLayer.Pin(pctx));
                }


                VkApplicationInfo appInfo = new VkApplicationInfo()
                {
                    sType            = VkStructureType.ApplicationInfo,
                    apiVersion       = new Vulkan.Version(VK_MAJOR, VK_MINOR, 0),
                    pApplicationName = ENGINE_NAME.Pin(pctx),
                    pEngineName      = APPLICATION_NAME.Pin(pctx),
                };

                VkInstanceCreateInfo instanceCreateInfo = VkInstanceCreateInfo.New();
                instanceCreateInfo.pApplicationInfo = appInfo.Pin(pctx);

                if (instanceExtensions.Count > 0)
                {
                    instanceCreateInfo.enabledExtensionCount   = (uint)instanceExtensions.Count;
                    instanceCreateInfo.ppEnabledExtensionNames = instanceExtensions.Pin(pctx);
                }
                if (enabledLayerNames.Count > 0)
                {
                    instanceCreateInfo.enabledLayerCount   = (uint)enabledLayerNames.Count;
                    instanceCreateInfo.ppEnabledLayerNames = enabledLayerNames.Pin(pctx);
                }

                VkResult result = vkCreateInstance(ref instanceCreateInfo, IntPtr.Zero, out inst);
                if (result != VkResult.Success)
                {
                    throw new InvalidOperationException("Could not create Vulkan instance. Error: " + result);
                }

                Vk.LoadInstanceFunctionPointers(inst);
            }
        }