/// <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); }
public static IntPtr Pin <T> (this T[] obj, PinnedObjects ctx) { GCHandle hnd = GCHandle.Alloc(obj, GCHandleType.Pinned); ctx.Handles.Add(hnd); return(hnd.AddrOfPinnedObject()); }
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()); }
/// <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); } }
/// <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)); } }
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(); }
/// <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); } }