Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        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);
 }
Exemple #5
0
        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;
        }
Exemple #7
0
        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);
        }
Exemple #8
0
        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));
        }
Exemple #9
0
        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);
        }
    }
Exemple #12
0
        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);
            }
        }
Exemple #13
0
        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);
            }
        }
Exemple #14
0
 public virtual VkResult GetSurfaceCapabilities(VkSurfaceKHR surface, out VkSurfaceCapabilitiesKHR capabilities)
 {
     return(GetSurface(surface).GetCapabilities(out capabilities));
 }
Exemple #15
0
        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);
        }
Exemple #16
0
        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);
        }
Exemple #17
0
        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();
        }
Exemple #18
0
 public SwapchainSupport(VkSurfaceCapabilitiesKHR cap, List <VkSurfaceFormatKHR> formats, List <VkPresentModeKHR> modes)
 {
     this.cap     = cap;
     this.formats = formats;
     this.modes   = modes;
 }
Exemple #19
0
        /// <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");
            }
        }