public unsafe SwapChainSupportDetails(VkPhysicalDevice device, VkSurfaceKHR surface) { VkSurfaceCapabilitiesKHR capabilitiesKHR; VulkanNative.vkGetPhysicalDeviceSurfaceCapabilitiesKHR(device, surface, &capabilitiesKHR); capabilities = capabilitiesKHR; formats = null; presentModes = null; uint formatCount; VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, null); if (formatCount > 0) { formats = new VkSurfaceFormatKHR[formatCount]; fixed(VkSurfaceFormatKHR *formatsPtr = formats) { VulkanNative.vkGetPhysicalDeviceSurfaceFormatsKHR(device, surface, &formatCount, formatsPtr); } } uint presentModeCount; VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, null); if (presentModeCount > 0) { presentModes = new VkPresentModeKHR[presentModeCount]; fixed(VkPresentModeKHR *presentsPtr = presentModes) { VulkanNative.vkGetPhysicalDeviceSurfacePresentModesKHR(device, surface, &presentModeCount, presentsPtr); } } }
protected VkSwapchainKHR CreateSwapchain(VkDevice device, VkSurfaceKHR surface, VkSurfaceFormatKHR surfaceFormat, VkSurfaceCapabilitiesKHR surfaceCapabilities) { var compositeAlpha = surfaceCapabilities.supportedCompositeAlpha.HasFlag( VkCompositeAlphaFlagBitsKHR.InheritKHR) ? VkCompositeAlphaFlagBitsKHR.InheritKHR : VkCompositeAlphaFlagBitsKHR.OpaqueKHR; UInt32 index = 0; var info = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR }; info.surface = surface; info.minImageCount = surfaceCapabilities.minImageCount; info.imageFormat = surfaceFormat.format; info.imageColorSpace = surfaceFormat.colorSpace; info.imageExtent = surfaceCapabilities.currentExtent; info.imageUsage = VkImageUsageFlagBits.ColorAttachment; info.preTransform = VkSurfaceTransformFlagBitsKHR.IdentityKHR; info.imageArrayLayers = 1; info.imageSharingMode = VkSharingMode.Exclusive; info.queueFamilyIndices = index; info.presentMode = VkPresentModeKHR.FifoKHR; info.compositeAlpha = compositeAlpha; //return device.CreateSwapchainKHR(ref info, null); VkSwapchainKHR swapchain; vkAPI.vkCreateSwapchainKHR(device, &info, null, &swapchain).Check(); return(swapchain); }
static VkSwapchainKHR CreateSwapchain(VkSwapchainKHR oldSwapchain, VkInstance instance, VkDevice device, VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, uint queueFamilyIndex) { vkDestroySwapchainKHR(device, oldSwapchain, null);//Does nothing if oldswapchain is null VkSurfaceCapabilitiesKHR capabilities = new VkSurfaceCapabilitiesKHR(); Assert(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, surface, &capabilities)); GetSwapchainFormat(physicalDevice, surface); VkSwapchainKHR swapchain = VkSwapchainKHR.Null; VkSwapchainCreateInfoKHR pCreateInfo = VkSwapchainCreateInfoKHR.New(); pCreateInfo.surface = surface; pCreateInfo.minImageCount = capabilities.minImageCount; pCreateInfo.imageFormat = surfaceFormat.format;//SHORTCUT: Some devices might not support pCreateInfo.imageColorSpace = surfaceFormat.colorSpace; pCreateInfo.imageExtent = capabilities.currentExtent; pCreateInfo.imageArrayLayers = 1; pCreateInfo.imageUsage = VkImageUsageFlags.ColorAttachment; pCreateInfo.queueFamilyIndexCount = 1; pCreateInfo.pQueueFamilyIndices = &queueFamilyIndex; pCreateInfo.preTransform = VkSurfaceTransformFlagsKHR.IdentityKHR; pCreateInfo.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR; pCreateInfo.presentMode = VkPresentModeKHR.MailboxKHR; Assert(vkCreateSwapchainKHR(device, &pCreateInfo, null, &swapchain)); return(swapchain); }
public VkResult GetCapabilities(out VkSurfaceCapabilitiesKHR capabilities) { capabilities = m_Capabilities; capabilities.currentExtent = m_CurrentSurfaceExtents; capabilities.maxImageExtent = capabilities.currentExtent; capabilities.minImageExtent = capabilities.currentExtent; return(VkResult.VK_SUCCESS); }
public void Create() { if (state != ActivableState.Activated) { Activate(); } Dev.WaitIdle(); VkSurfaceCapabilitiesKHR capabilities = Dev.phy.GetSurfaceCapabilities(presentQueue.Surface); createInfos.minImageCount = capabilities.minImageCount; createInfos.preTransform = capabilities.currentTransform; createInfos.oldSwapchain = handle; if (capabilities.currentExtent.width == 0xFFFFFFFF) { if (createInfos.imageExtent.width < capabilities.minImageExtent.width) { createInfos.imageExtent.width = capabilities.minImageExtent.width; } else if (createInfos.imageExtent.width > capabilities.maxImageExtent.width) { createInfos.imageExtent.width = capabilities.maxImageExtent.width; } if (createInfos.imageExtent.height < capabilities.minImageExtent.height) { createInfos.imageExtent.height = capabilities.minImageExtent.height; } else if (createInfos.imageExtent.height > capabilities.maxImageExtent.height) { createInfos.imageExtent.height = capabilities.maxImageExtent.height; } } else { createInfos.imageExtent = capabilities.currentExtent; } VkSwapchainKHR newSwapChain = Dev.CreateSwapChain(createInfos); if (handle.Handle != 0) { _destroy(); } handle = newSwapChain; VkImage[] tmp = Dev.GetSwapChainImages(handle); images = new Image[tmp.Length]; for (int i = 0; i < tmp.Length; i++) { images[i] = new Image(Dev, tmp[i], ColorFormat, ImageUsage, Width, Height); images[i].CreateView(); images[i].SetName("SwapChain Img" + i); images[i].Descriptor.imageView.SetDebugMarkerName(Dev, "SwapChain Img" + i + " view"); } }
public SoftwareFormSurface(SoftwareInstance instance, VkWin32SurfaceCreateInfoKHR createInfo) { this.m_Formats = new List <VkSurfaceFormatKHR>() { VkSurfaceFormatKHR.Create(VkFormat.VK_FORMAT_B8G8R8A8_UNORM, VkColorSpaceKHR.VK_COLOR_SPACE_SRGB_NONLINEAR_KHR) }; this.m_PresentModes = new List <VkPresentModeKHR>() { VkPresentModeKHR.VK_PRESENT_MODE_IMMEDIATE_KHR }; this.m_instance = instance; this.m_createInfo = createInfo; foreach (Form form in Application.OpenForms) { if (form.Handle == createInfo.hwnd) { m_Form = form; } } if (m_Form == null) { throw new ArgumentException(string.Format("Form not found for the handle informed on the field {0}.{1}", nameof(VkWin32SurfaceCreateInfoKHR), nameof(VkWin32SurfaceCreateInfoKHR.hwnd))); } var m_OriginalExtents = VkExtent2D.Create(GetWidth(), GetHeight()); m_CurrentSurfaceExtents = m_OriginalExtents; this.m_Capabilities = new VkSurfaceCapabilitiesKHR(); this.m_Capabilities.currentExtent = m_OriginalExtents; this.m_Capabilities.maxImageExtent = m_OriginalExtents; this.m_Capabilities.minImageExtent = m_OriginalExtents; this.m_Capabilities.minImageCount = 1; this.m_Capabilities.maxImageCount = 8; this.m_Capabilities.maxImageArrayLayers = 1; this.m_Capabilities.supportedTransforms = VkSurfaceTransformFlagBitsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; this.m_Capabilities.currentTransform = VkSurfaceTransformFlagBitsKHR.VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; this.m_Capabilities.supportedCompositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; this.m_Capabilities.supportedUsageFlags = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; this.m_SurfacePresentMode = FormSurfacePresentMode.DibBitmapBitBlt; InternalResize(); m_Form.Resize += Form_Resize; }
protected VkFramebuffer[] CreateFramebuffers(VkDevice device, VkImage[] images, VkSurfaceFormatKHR surfaceFormat, VkRenderPass renderPass, VkSurfaceCapabilitiesKHR surfaceCapabilities) { var displayViews = new VkImageView[images.Length]; var viewInfo = new VkImageViewCreateInfo { sType = VkStructureType.ImageViewCreateInfo }; viewInfo.viewType = VkImageViewType._2d; viewInfo.format = surfaceFormat.format; viewInfo.components = new VkComponentMapping { r = VkComponentSwizzle.R, g = VkComponentSwizzle.G, b = VkComponentSwizzle.B, a = VkComponentSwizzle.A }; viewInfo.subresourceRange = new VkImageSubresourceRange { aspectMask = VkImageAspectFlagBits.Color, levelCount = 1, layerCount = 1 }; for (int i = 0; i < images.Length; i++) { viewInfo.image = images[i]; //displayViews[i] = device.CreateImageView(ref info); VkImageView view; vkAPI.vkCreateImageView(device, &viewInfo, null, &view).Check(); displayViews[i] = view; } var framebuffers = new VkFramebuffer[images.Length]; var fbInfo = new VkFramebufferCreateInfo { sType = VkStructureType.FramebufferCreateInfo }; fbInfo.layers = 1; fbInfo.renderPass = renderPass; fbInfo.width = surfaceCapabilities.currentExtent.width; fbInfo.height = surfaceCapabilities.currentExtent.height; for (int i = 0; i < images.Length; i++) { fbInfo.attachments = displayViews[i]; //framebuffers[i] = device.CreateFramebuffer(ref info); VkFramebuffer framebuffer; vkAPI.vkCreateFramebuffer(device, &fbInfo, null, &framebuffer).Check(); framebuffers[i] = framebuffer; } fbInfo.Free(); return(framebuffers); }
private VkExtent2D ChooseSwapExtent(VkSurfaceCapabilitiesKHR capabilities) { const int special = -1; if (capabilities.CurrentExtent.Width != special) { return(capabilities.CurrentExtent); } var width = Math.Max(capabilities.MinImageExtent.Width, Math.Min(capabilities.MaxImageExtent.Width, form.Width)); var height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, form.Height)); return(new VkExtent2D(width, height)); }
private VkExtent2D ChooseSwapExtent(VkSurfaceCapabilitiesKHR capabilities) { if (capabilities.currentExtent.width != uint.MaxValue) { return(capabilities.currentExtent); } return(new VkExtent2D() { width = Math.Max(capabilities.minImageExtent.width, Math.Min(capabilities.maxImageExtent.width, (uint)this.width)), height = Math.Max(capabilities.minImageExtent.height, Math.Min(capabilities.maxImageExtent.height, (uint)this.height)), }); }
VkExtent2D ChooseSwapExtent(VkSurfaceCapabilitiesKHR capabilities) { if (capabilities.currentExtent.width != uint.MaxValue) { return(capabilities.currentExtent); } else { VkExtent2D actualExtent = new VkExtent2D(WIDTH, HEIGHT); actualExtent.width = Math.Max(capabilities.minImageExtent.width, Math.Min(capabilities.maxImageExtent.width, actualExtent.width)); actualExtent.height = Math.Max(capabilities.minImageExtent.height, Math.Min(capabilities.maxImageExtent.height, actualExtent.height)); return(actualExtent); } }
private VkExtent2D ChooseSwapExtent(VkSurfaceCapabilitiesKHR capabilities) { if (capabilities.currentExtent.width > 0) { return(capabilities.currentExtent); } else { VkExtent2D actualExtent = Window.Extent; actualExtent = new VkExtent2D( Math.Max(capabilities.minImageExtent.width, Math.Min(capabilities.maxImageExtent.width, actualExtent.width)), Math.Max(capabilities.minImageExtent.height, Math.Min(capabilities.maxImageExtent.height, actualExtent.height)) ); return(actualExtent); } }
VkExtent2D ChooseSwapExtent(ref VkSurfaceCapabilitiesKHR cap) { if (cap.currentExtent.width != -1) { return(cap.currentExtent); } else { var extent = new VkExtent2D(); extent.width = width; extent.height = height; extent.width = Math.Max(cap.minImageExtent.width, Math.Min(cap.maxImageExtent.width, extent.width)); extent.height = Math.Max(cap.minImageExtent.height, Math.Min(cap.maxImageExtent.height, extent.height)); return(extent); } }
private VkExtent2D chooseSwapExtent(VkSurfaceCapabilitiesKHR capabilities) { if (capabilities.currentExtent.width != Int32.MaxValue) { return(capabilities.currentExtent); } else { int width, height; GLFW.glfwGetWindowSize(window, out width, out height); VkExtent2D actualExtent = VkExtent2D.Create(width, height); actualExtent.width = Math.Max(capabilities.minImageExtent.width, Math.Min(capabilities.maxImageExtent.width, actualExtent.width)); actualExtent.height = Math.Max(capabilities.minImageExtent.height, Math.Min(capabilities.maxImageExtent.height, actualExtent.height)); return(actualExtent); } }
public virtual VkResult GetSurfaceCapabilities(VkSurfaceKHR surface, out VkSurfaceCapabilitiesKHR capabilities) { return(GetSurface(surface).GetCapabilities(out capabilities)); }
VkPipeline CreatePipeline(VkDevice device, VkSurfaceCapabilitiesKHR surfaceCapabilities, VkRenderPass renderPass, VkPipelineLayout pipelineLayout) { //VkShaderModule vertexShaderModule = device.CreateShaderModule(LoadResource(@"Shaders\shader.vert.spv")); VkShaderModule vsModule; { var info = new VkShaderModuleCreateInfo { sType = VkStructureType.ShaderModuleCreateInfo }; byte[] bytes = LoadResource(@"Shaders\shader.vert.spv"); info.code = bytes; //vkAPI.vkCreateShaderModule(device, bytes); vkAPI.vkCreateShaderModule(device, &info, null, &vsModule).Check(); info.Free(); } //VkShaderModule fragmentShaderModule = device.CreateShaderModule(LoadResource(@"Shaders\shader.frag.spv")); VkShaderModule fsModule; { var info = new VkShaderModuleCreateInfo { sType = VkStructureType.ShaderModuleCreateInfo }; byte[] bytes = LoadResource(@"Shaders\shader.frag.spv"); info.code = bytes; //vkAPI.vkCreateShaderModule(device, bytes); vkAPI.vkCreateShaderModule(device, &info, null, &fsModule).Check(); info.Free(); } var shaderStages = new VkPipelineShaderStageCreateInfo[2]; { shaderStages[0].sType = VkStructureType.PipelineShaderStageCreateInfo; shaderStages[0].stage = VkShaderStageFlagBits.Vertex; shaderStages[0].module = vsModule; //"main".Set(ref shaderStages[0].pName); shaderStages[0].pName = "main"; shaderStages[1].sType = VkStructureType.PipelineShaderStageCreateInfo; shaderStages[1].stage = VkShaderStageFlagBits.Fragment; shaderStages[1].module = fsModule; //"main".Set(ref shaderStages[1].pName); shaderStages[1].pName = "main"; } var viewport = new VkPipelineViewportStateCreateInfo { sType = VkStructureType.PipelineViewportStateCreateInfo }; viewport.viewports = new VkViewport(surfaceCapabilities.currentExtent, 0.0f, 1.0f); viewport.scissors = new VkRect2D(surfaceCapabilities.currentExtent); var multisample = new VkPipelineMultisampleStateCreateInfo { sType = VkStructureType.PipelineMultisampleStateCreateInfo }; multisample.rasterizationSamples = VkSampleCountFlagBits._1; var colorBlend = new VkPipelineColorBlendStateCreateInfo { sType = VkStructureType.PipelineColorBlendStateCreateInfo }; colorBlend.logicOp = VkLogicOp.Copy; var blend = new VkPipelineColorBlendAttachmentState( colorWriteMask: VkColorComponentFlagBits.R | VkColorComponentFlagBits.G | VkColorComponentFlagBits.B | VkColorComponentFlagBits.A, blendEnable: false); colorBlend.attachments = blend; var rasterization = new VkPipelineRasterizationStateCreateInfo { sType = VkStructureType.PipelineRasterizationStateCreateInfo }; rasterization.polygonMode = VkPolygonMode.Fill; rasterization.cullMode = VkCullModeFlagBits.None; rasterization.frontFace = VkFrontFace.Clockwise; rasterization.lineWidth = 1.0f; var inputAssem = new VkPipelineInputAssemblyStateCreateInfo { sType = VkStructureType.PipelineInputAssemblyStateCreateInfo }; inputAssem.topology = VkPrimitiveTopology.TriangleList; var input = new VkPipelineVertexInputStateCreateInfo { sType = VkStructureType.PipelineVertexInputStateCreateInfo }; // static readonly float[] Vertices = { .. } input.vertexBindingDescriptions = new VkVertexInputBindingDescription( binding: 0, stride: 2 * sizeof(float), inputRate: VkVertexInputRate.Vertex); // layout(location = 0) in vec2 inPos; input.vertexAttributeDescriptions = new VkVertexInputAttributeDescription( location: 0, binding: 0, format: VkFormat.R32g32Sfloat, offset: 0); //VkPipelineCache cache = device.CreatePipelineCache(ref cacheInfo); VkPipelineCache cache; { var info = VkPipelineCacheCreateInfo.Alloc(); vkAPI.vkCreatePipelineCache(device, info, null, &cache).Check(); Marshal.FreeHGlobal((IntPtr)info); } //var infos = new VkGraphicsPipelineCreateInfo[] { pipelineCreateInfo }; //return device.CreateGraphicsPipelines(ref cache, infos); VkPipeline pipeline; { var info = new VkGraphicsPipelineCreateInfo { sType = VkStructureType.GraphicsPipelineCreateInfo }; info.layout = pipelineLayout; info.pViewportState = &viewport; info.stages = shaderStages; info.pMultisampleState = &multisample; info.pColorBlendState = &colorBlend; info.pRasterizationState = &rasterization; info.pInputAssemblyState = &inputAssem; info.pVertexInputState = &input; info.renderPass = renderPass; vkAPI.vkCreateGraphicsPipelines(device, cache, 1, &info, null, &pipeline).Check(); info.Free(); } shaderStages[0].Free(); shaderStages[1].Free(); viewport.Free(); colorBlend.Free(); input.Free(); return(pipeline); }
VkCommandBuffer[] CreateCommandBuffers( VkDevice device, VkRenderPass renderPass, VkSurfaceCapabilitiesKHR surfaceCapabilities, VkImage[] images, VkFramebuffer[] framebuffers, VkPipeline pipeline, VkBuffer vertexBuffer, VkBuffer indexBuffer, uint indexLength, VkPipelineLayout pipelineLayout, VkDescriptorSet descriptorSet) { VkCommandBuffer[] buffers; { VkCommandPool pool; { var info = new VkCommandPoolCreateInfo { sType = VkStructureType.CommandPoolCreateInfo }; info.flags = VkCommandPoolCreateFlagBits.ResetCommandBuffer; //var commandPool = device.CreateCommandPool(ref poolInfo); vkCreateCommandPool(device, &info, null, &pool).Check(); } { var info = new VkCommandBufferAllocateInfo { sType = VkStructureType.CommandBufferAllocateInfo }; info.level = VkCommandBufferLevel.Primary; info.commandPool = pool; info.commandBufferCount = (uint)images.Length; //buffers = device.AllocateCommandBuffers(ref info); buffers = new VkCommandBuffer[info.commandBufferCount]; fixed(VkCommandBuffer *pointer = buffers) { vkAPI.vkAllocateCommandBuffers(device, &info, pointer).Check(); } } } var cmdBeginInfo = new VkCommandBufferBeginInfo { sType = VkStructureType.CommandBufferBeginInfo }; var clearValue = new VkClearValue { color = new VkClearColorValue(0.9f, 0.87f, 0.75f, 1.0f) }; var begin = new VkRenderPassBeginInfo { sType = VkStructureType.RenderPassBeginInfo }; begin.renderPass = renderPass; begin.clearValues = clearValue; begin.renderArea = new VkRect2D { extent = surfaceCapabilities.currentExtent }; for (int i = 0; i < images.Length; i++) { VkCommandBuffer cmds = buffers[i]; //cmds.Begin(ref cmdBeginInfo); vkAPI.vkBeginCommandBuffer(cmds, &cmdBeginInfo).Check(); begin.framebuffer = framebuffers[i]; vkAPI.vkCmdBeginRenderPass(cmds, &begin, VkSubpassContents.Inline); vkAPI.vkCmdBindDescriptorSets(cmds, VkPipelineBindPoint.Graphics, pipelineLayout, 0, 1, &descriptorSet, 0, null); vkAPI.vkCmdBindPipeline(cmds, VkPipelineBindPoint.Graphics, pipeline); VkDeviceSize offset = 0; vkAPI.vkCmdBindVertexBuffers(cmds, 0, 1, &vertexBuffer, &offset); vkAPI.vkCmdBindIndexBuffer(cmds, indexBuffer, offset, VkIndexType.Uint16); vkAPI.vkCmdDrawIndexed(cmds, indexLength, 1, 0, 0, 0); vkAPI.vkCmdEndRenderPass(cmds); vkAPI.vkEndCommandBuffer(cmds).Check(); } begin.Free(); return(buffers); }
public unsafe Swapchain(Device device, NativeWindow window) { _device = device; _window = window; //get present queue _presentQueueFamily = GetQueueFamilyWithPresentationSupport( device, window ); //get surface capabilities _surfaceCapabilities = GetSurfaceCapabilities( device, window ); //get surface format support _supportedSurfaceFormats = GetSupportedSurfaceFormats( device, window ); //get present mode support _supportedPresentModes = GetSupportedPresentModes( device, window ); //choose best surface format #region Surface Format if ( _supportedSurfaceFormats.Count == 1 && _supportedSurfaceFormats[0].format == VkFormat.Undefined ) { _surfaceFormat = new VkSurfaceFormatKHR { colorSpace = VkColorSpaceKHR.SrgbNonlinearKHR, format = VkFormat.R8g8b8Unorm }; } else { bool choosenFormat = false; foreach (var format in _supportedSurfaceFormats) { if ( format.format == VkFormat.R8g8b8Unorm && format.colorSpace == VkColorSpaceKHR.SrgbNonlinearKHR ) { _surfaceFormat = format; choosenFormat = true; break; } } if (choosenFormat == false) { _surfaceFormat = _supportedSurfaceFormats[0]; } } #endregion #region Surface Present Mode _surfacePresentMode = VkPresentModeKHR.FifoKHR; foreach (var presentMode in _supportedPresentModes) { if (presentMode == VkPresentModeKHR.MailboxKHR) { _surfacePresentMode = presentMode; break; } else if (presentMode == VkPresentModeKHR.ImmediateKHR) { _surfacePresentMode = presentMode; } } #endregion #region Surface Extent if (_surfaceCapabilities.currentExtent.width != uint.MaxValue) { _surfaceExtent = _surfaceCapabilities.currentExtent; } else { _surfaceExtent = new VkExtent2D { width = Math.Clamp( Convert.ToUInt32(window.Width), _surfaceCapabilities.minImageExtent.width, _surfaceCapabilities.maxImageExtent.width ), height = Math.Clamp( Convert.ToUInt32(window.Height), _surfaceCapabilities.minImageExtent.height, _surfaceCapabilities.maxImageExtent.height ) }; } #endregion #region Images Count var imagesCount = _surfaceCapabilities.minImageCount + 1; if (_surfaceCapabilities.maxImageCount > 0) { if (imagesCount > _surfaceCapabilities.maxImageCount) { imagesCount = Math.Min(_surfaceCapabilities.maxImageCount, 2); } } #endregion var queueFamilyIndices = new NativeList <uint>(); foreach (var queueFamily in device.QueueFamilies) { queueFamilyIndices.Add(queueFamily.Index); } var swapchainInfo = new VkSwapchainCreateInfoKHR { sType = VkStructureType.SwapchainCreateInfoKHR, compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueKHR, minImageCount = imagesCount, imageFormat = _surfaceFormat.format, imageColorSpace = _surfaceFormat.colorSpace, imageExtent = _surfaceExtent, imageArrayLayers = 1, imageUsage = ( VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.TransferDst ), imageSharingMode = VkSharingMode.Concurrent, preTransform = _surfaceCapabilities.currentTransform, presentMode = _surfacePresentMode, surface = window.Surface, clipped = true, queueFamilyIndexCount = queueFamilyIndices.Count, pQueueFamilyIndices = (uint *)queueFamilyIndices.Data.ToPointer() }; VkSwapchainKHR swapchain; if (VulkanNative.vkCreateSwapchainKHR( device.Handle, &swapchainInfo, null, &swapchain ) != VkResult.Success) { throw new Exception("failed to create swapchain"); } _handle = swapchain; SetupSwapchainImages(); }
public SwapchainSupport(VkSurfaceCapabilitiesKHR cap, List <VkSurfaceFormatKHR> formats, List <VkPresentModeKHR> modes) { this.cap = cap; this.formats = formats; this.modes = modes; }
/// <summary> /// Create/recreate swapchain and populate images array /// </summary> public void Create() { Dev.WaitIdle(); VkSurfaceCapabilitiesKHR capabilities = Dev.phy.GetSurfaceCapabilities(presentQueue.Surface); createInfos.minImageCount = capabilities.minImageCount; createInfos.preTransform = capabilities.currentTransform; createInfos.oldSwapchain = Handle; if (capabilities.currentExtent.width == 0xFFFFFFFF) { if (createInfos.imageExtent.width < capabilities.minImageExtent.width) { createInfos.imageExtent.width = capabilities.minImageExtent.width; } else if (createInfos.imageExtent.width > capabilities.maxImageExtent.width) { createInfos.imageExtent.width = capabilities.maxImageExtent.width; } if (createInfos.imageExtent.height < capabilities.minImageExtent.height) { createInfos.imageExtent.height = capabilities.minImageExtent.height; } else if (createInfos.imageExtent.height > capabilities.maxImageExtent.height) { createInfos.imageExtent.height = capabilities.maxImageExtent.height; } } else { createInfos.imageExtent = capabilities.currentExtent; } Utils.CheckResult(vkCreateSwapchainKHR(Dev.VkDev, ref createInfos, IntPtr.Zero, out VkSwapchainKHR newSwapChain)); if (Handle.Handle != 0) { _destroy(); } presentComplete = Dev.CreateSemaphore(); presentComplete.SetDebugMarkerName(Dev, "Semaphore PresentComplete"); Handle = newSwapChain; Utils.CheckResult(vkGetSwapchainImagesKHR(Dev.VkDev, Handle, out uint imageCount, IntPtr.Zero)); if (imageCount == 0) { throw new Exception("Swapchain image count is 0."); } VkImage[] imgs = new VkImage[imageCount]; Utils.CheckResult(vkGetSwapchainImagesKHR(Dev.VkDev, Handle, out imageCount, imgs.Pin())); imgs.Unpin(); images = new Image[imgs.Length]; for (int i = 0; i < imgs.Length; i++) { images[i] = new Image(Dev, imgs[i], ColorFormat, ImageUsage, Width, Height); images[i].CreateView(); images[i].SetName("SwapChain Img" + i); images[i].Descriptor.imageView.SetDebugMarkerName(Dev, "SwapChain Img" + i + " view"); } }