public FramebufferBuilder(RenderPass pass, VkExtent2D size, Func <TAttachment, uint> map, uint layers = 1)
 {
     _pass          = pass;
     _size          = size;
     _attachmentMap = map;
     _layers        = layers;
 }
        internal void SetNewSwapchain(
            VkSwapchainKHR deviceSwapchain,
            uint width,
            uint height,
            VkSurfaceFormatKHR surfaceFormat,
            VkExtent2D swapchainExtent)
        {
            _desiredWidth  = width;
            _desiredHeight = height;

            // Get the images
            uint     scImageCount = 0;
            VkResult result       = vkGetSwapchainImagesKHR(_gd.Device, deviceSwapchain, ref scImageCount, null);

            CheckResult(result);
            if (_scImages == null)
            {
                _scImages = new VkImage[(int)scImageCount];
            }
            result = vkGetSwapchainImagesKHR(_gd.Device, deviceSwapchain, ref scImageCount, out _scImages[0]);
            CheckResult(result);

            _scImageFormat = surfaceFormat.format;
            _scExtent      = swapchainExtent;

            CreateDepthTexture();
            CreateFramebuffers();

            _outputDescription = OutputDescription.CreateFromFramebuffer(this);
        }
Example #3
0
        public Framebuffer(RenderPass pass, VkExtent2D size, uint layers, IEnumerable <ImageView> views)
        {
            Size   = size;
            Device = pass.Device;
            var imageArray = views.Select(x =>
            {
                x.AssertValid();
                return(x.Handle);
            }).ToArray();

            unsafe
            {
                fixed(VkImageView *view = imageArray)
                {
                    var info = new VkFramebufferCreateInfo()
                    {
                        SType           = VkStructureType.FramebufferCreateInfo,
                        Flags           = 0,
                        PNext           = IntPtr.Zero,
                        RenderPass      = pass.Handle,
                        Width           = size.Width,
                        Height          = size.Height,
                        Layers          = layers,
                        AttachmentCount = (uint)imageArray.Length,
                        PAttachments    = view
                    };

                    Handle = Device.Handle.CreateFramebuffer(&info, Instance.AllocationCallbacks);
                }
            }
        }
 internal SwapchainKHRBuilder(SurfaceKHR surf, Device dev, VkExtent2D size)
 {
     _surf               = surf;
     _dev                = dev;
     _extent             = size;
     _shareMode          = VkSharingMode.Exclusive;
     _preferredTransform = 0;
     _requiredTransform  = VkSurfaceTransformFlagBitsKHR.InheritBitKhr;
 }
        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;
        }
Example #6
0
        public VkResult PresentImage(int imageIndex)
        {
            // TODO: SoftwareSwapchain.PresentImage()

            VkExtent2D imageExtent = new VkExtent2D(
                m_Images[imageIndex].m_imageExtent.width,
                m_Images[imageIndex].m_imageExtent.height);

            return(((BaseSoftwareSurface)m_createInfo.surface).PresentImage(m_Images[imageIndex], imageExtent));
        }
Example #7
0
        void CreateSwapchain()
        {
            var support = GetSwapchainSupport(physicalDevice);
            var cap     = support.cap;

            var surfaceFormat = ChooseSwapSurfaceFormat(support.formats);
            var mode          = ChooseSwapPresentMode(support.modes);
            var extent        = ChooseSwapExtent(ref cap);

            int imageCount = cap.minImageCount + 1;

            if (cap.maxImageCount > 0 && imageCount > cap.maxImageCount)
            {
                imageCount = cap.maxImageCount;
            }

            var oldSwapchain = swapchain;
            var info         = new VkSwapchainCreateInfo();

            info.surface          = surface;
            info.oldSwapchain     = oldSwapchain;
            info.minImageCount    = imageCount;
            info.imageFormat      = surfaceFormat.format;
            info.imageColorSpace  = surfaceFormat.colorSpace;
            info.imageExtent      = extent;
            info.imageArrayLayers = 1;
            info.imageUsage       = VkImageUsageFlags.ColorAttachmentBit;

            var queueFamilyIndices = new List <int> {
                graphicsIndex, presentIndex
            };

            if (graphicsIndex != presentIndex)
            {
                info.imageSharingMode   = VkSharingMode.Concurrent;
                info.queueFamilyIndices = queueFamilyIndices;
            }
            else
            {
                info.imageSharingMode = VkSharingMode.Exclusive;
            }

            info.preTransform   = cap.currentTransform;
            info.compositeAlpha = VkCompositeAlphaFlagsKHR.OpaqueBitKhr;
            info.presentMode    = mode;
            info.clipped        = true;

            swapchain = new VkSwapchain(device, info);
            oldSwapchain?.Dispose();

            swapchainImages = new List <VkImage>(swapchain.Images);

            swapchainImageFormat = surfaceFormat.format;
            swapchainExtent      = extent;
        }
Example #8
0
 public Framebuffer(Device dev, VkFramebufferCreateInfo info)
 {
     Device = dev;
     Size   = new VkExtent2D()
     {
         Width = info.Width, Height = info.Height
     };
     unsafe
     {
         Handle = dev.Handle.CreateFramebuffer(&info, Instance.AllocationCallbacks);
     }
 }
        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);
            }
        }
        public VkResult PresentImage(SoftwareImage image, VkExtent2D imageExtent)
        {
            var form = m_Form;

            if (form == null || form.IsDisposed)
            {
                return(VkResult.VK_ERROR_DEVICE_LOST);
            }

            VkResult result;

            if ((imageExtent.width != m_CurrentSurfaceExtents.width) || (imageExtent.height != m_CurrentSurfaceExtents.height))
            {
                InternalDrawUnscaled(image, form);
                return(VkResult.VK_SUBOPTIMAL_KHR);
            }

            /*
             * if ((imageExtent.width < m_CurrentExtents.width) || (imageExtent.height < m_CurrentExtents.height))
             * {
             *      return VkResult.VK_ERROR_OUT_OF_DATE_KHR;
             * } */

            if (form.InvokeRequired)
            {
                result = (VkResult)form.Invoke((Func <VkResult>)(() =>
                {
                    return(InternalPresent(image, form));
                }));
            }
            else
            {
                result = InternalPresent(image, form);
            }

            if ((imageExtent.width != m_CurrentSurfaceExtents.width) || (imageExtent.height != m_CurrentSurfaceExtents.height))
            {
                if (result == VkResult.VK_SUCCESS)
                {
                    result = VkResult.VK_SUBOPTIMAL_KHR;
                }
            }

            return(result);
        }
Example #11
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);
            }
        }
Example #12
0
    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);
        }
    }
Example #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);
            }
        }
Example #14
0
        private VkPipelineViewportStateCreateInfo CreateViewportState()
        {
            VkExtent2D currentExtent = vkctrl.GetCurrentExtent();
            var        viewport      = new VkViewport()
            {
                width    = currentExtent.width,
                height   = currentExtent.height,
                x        = 0,
                y        = 0,
                minDepth = 0.0f,
                maxDepth = 1.0f,
            };
            var scissor = new VkRect2D()
            {
                extent = currentExtent
            };
            var viewportState = new VkPipelineViewportStateCreateInfo();

            viewportState.viewports = new[] { viewport };
            viewportState.scissors  = new[] { scissor };
            return(viewportState);
        }
Example #15
0
        private void CreateSwapChain()
        {
            var swapChainSupport = QuerySwapChainSupport(physicalDevice, surface);
            var surfaceFormat    = ChooseSwapSurfaceFormat(swapChainSupport.Formats);
            var presentMode      = ChooseSwapPresentMode(swapChainSupport.PresentModes);
            var extent           = ChooseSwapExtent(swapChainSupport.Capabilities);
            var minImages        = swapChainSupport.Capabilities.MinImageCount;
            var maxImages        = swapChainSupport.Capabilities.MaxImageCount > 0
                ? swapChainSupport.Capabilities.MaxImageCount
                : int.MaxValue;
            var imageCount     = Math.Max(minImages, Math.Min(maxImages, 2));
            var indices        = FindQueueFamilies(physicalDevice, surface).Value;
            var separateQueues = indices.GraphicsFamily != indices.PresentFamily;
            var createInfo     = new VkSwapchainCreateInfoKHR
            {
                Surface            = surface,
                MinImageCount      = imageCount,
                ImageFormat        = surfaceFormat.Format,
                ImageColorSpace    = surfaceFormat.ColorSpace,
                ImageExtent        = extent,
                ImageArrayLayers   = 1,
                ImageUsage         = VkImageUsageFlags.ColorAttachment,
                ImageSharingMode   = separateQueues ? VkSharingMode.Concurrent : VkSharingMode.Exclusive,
                QueueFamilyIndices = separateQueues ? new[] { indices.GraphicsFamily, indices.PresentFamily } : null,
                PreTransform       = swapChainSupport.Capabilities.CurrentTransform,
                CompositeAlpha     = VkCompositeAlphaFlagsKHR.Opaque,
                PresentMode        = presentMode,
                Clipped            = true,
                OldSwapchain       = null
            };

            swapChain            = device.CreateSwapchainKHR(createInfo, null).Object;
            swapChainImages      = swapChain.GetImagesKHR().Object;
            swapchainImageFormat = surfaceFormat.Format;
            swapChainExtent      = extent;
        }
Example #16
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();
        }
Example #17
0
    public unsafe Window(string title, int width, int height, WindowFlags flags = WindowFlags.None)
    {
        Title = title;

        bool         fullscreen = false;
        GLFWmonitor *monitor    = null;

        if ((flags & WindowFlags.Fullscreen) != WindowFlags.None)
        {
            monitor    = glfwGetPrimaryMonitor();
            fullscreen = true;
        }

        if ((flags & WindowFlags.FullscreenDesktop) != WindowFlags.None)
        {
            monitor = glfwGetPrimaryMonitor();
            //auto mode = glfwGetVideoMode(monitor);
            //
            //glfwWindowHint(GLFW_RED_BITS, mode->redBits);
            //glfwWindowHint(GLFW_GREEN_BITS, mode->greenBits);
            //glfwWindowHint(GLFW_BLUE_BITS, mode->blueBits);
            //glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate);

            glfwWindowHint(WindowHintBool.Decorated, false);
            fullscreen = true;
        }

        if (!fullscreen)
        {
            if ((flags & WindowFlags.Borderless) != WindowFlags.None)
            {
                glfwWindowHint(WindowHintBool.Decorated, false);
            }
            else
            {
                glfwWindowHint(WindowHintBool.Decorated, true);
            }

            if ((flags & WindowFlags.Resizable) != WindowFlags.None)
            {
                glfwWindowHint(WindowHintBool.Resizable, true);
            }

            if ((flags & WindowFlags.Hidden) != WindowFlags.None)
            {
                glfwWindowHint(WindowHintBool.Visible, false);
            }

            if ((flags & WindowFlags.Minimized) != WindowFlags.None)
            {
                glfwWindowHint(WindowHintBool.Iconified, true);
            }

            if ((flags & WindowFlags.Maximized) != WindowFlags.None)
            {
                glfwWindowHint(WindowHintBool.Maximized, true);
            }
        }

        _window = glfwCreateWindow(width, height, title, monitor, null);
        //Handle = hwnd;

        glfwGetWindowSize(_window, out width, out height);
        Extent = new VkExtent2D(width, height);
    }
Example #18
0
 public static extern void GetRenderAreaGranularity(
     VkDevice device,
     VkRenderPass renderPass,
     out VkExtent2D pGranularity
     );
Example #19
0
        public SwapchainKHR(SurfaceKHR surface, Device device, uint minImageCount,
                            uint layerCount, VkImageUsageFlag usageFlag,
                            VkFormat imageFormat, VkColorSpaceKHR colorSpace,
                            VkExtent2D dimensions,
                            VkCompositeAlphaFlagBitsKHR compositeAlpha,
                            VkPresentModeKHR presentMode,
                            bool clipped = true,
                            VkSurfaceTransformFlagBitsKHR transform = VkSurfaceTransformFlagBitsKHR.IdentityBitKhr,
                            VkSharingMode sharing     = VkSharingMode.Exclusive, uint[] sharedQueueFamily = null,
                            SwapchainKHR oldSwapchain = null)
        {
            SurfaceKHR = surface;
            Device     = device;

            {
                var surfSupported = false;
                foreach (var family in Device.Queues.Select(x => x.FamilyIndex).Distinct())
                {
                    if (PhysicalDevice.Handle.GetPhysicalDeviceSurfaceSupportKHR(family, SurfaceKHR.Handle))
                    {
                        surfSupported = true;
                        break;
                    }
                }
                if (!surfSupported)
                {
                    throw new NotSupportedException($"No queues on device support the surface");
                }
            }

            _sharingQueueInfo = sharedQueueFamily;

            unsafe
            {
                if (sharing == VkSharingMode.Concurrent)
                {
                    Debug.Assert(sharedQueueFamily != null);
                }
                var hasPinnedSharedQueue    = sharedQueueFamily != null && sharedQueueFamily.Length > 0;
                var pinnedSharedQueueFamily = hasPinnedSharedQueue
                    ? GCHandle.Alloc(sharedQueueFamily, GCHandleType.Pinned)
                    : default(GCHandle);
                try
                {
                    var info = new VkSwapchainCreateInfoKHR()
                    {
                        SType                 = VkStructureType.SwapchainCreateInfoKhr,
                        PNext                 = IntPtr.Zero,
                        Flags                 = 0, // reserved VkSwapchainCreateFlagBitsKHR
                        Surface               = surface.Handle,
                        MinImageCount         = minImageCount,
                        ImageFormat           = imageFormat,
                        ImageColorSpace       = colorSpace,
                        ImageExtent           = dimensions,
                        ImageArrayLayers      = layerCount,
                        ImageUsage            = usageFlag,
                        ImageSharingMode      = sharing,
                        QueueFamilyIndexCount = (uint)(sharedQueueFamily?.Length ?? 0),
                        PQueueFamilyIndices   = hasPinnedSharedQueue
                            ? (uint *)Marshal.UnsafeAddrOfPinnedArrayElement(sharedQueueFamily, 0).ToPointer()
                            : (uint *)0,
                        PreTransform   = transform,
                        CompositeAlpha = compositeAlpha,
                        PresentMode    = presentMode,
                        Clipped        = clipped,
                        OldSwapchain   = oldSwapchain?.Handle ?? VkSwapchainKHR.Null
                    };
                    _info  = info;
                    Handle = Device.Handle.CreateSwapchainKHR(&info, Instance.AllocationCallbacks);
                    if (oldSwapchain != null)
                    {
                        foreach (var img in oldSwapchain._swapchainImages)
                        {
                            img.Dispose();
                        }
                        oldSwapchain.Dispose();
                    }
                }
                finally
                {
                    if (hasPinnedSharedQueue)
                    {
                        pinnedSharedQueueFamily.Free();
                    }
                }
            }

            var images = Device.Handle.GetSwapchainImagesKHR(Handle);

            _swapchainImages.Clear();
            _swapchainImages.Capacity = images.Length;
            foreach (var img in images)
            {
                _swapchainImages.Add(new SwapchainImage(this, img));
            }
        }
Example #20
0
        void CreateSwapchain()
        {
            var support = GetSwapchainSupport(physicalDevice);
            var cap     = support.cap.Value;

            var surfaceFormat = ChooseSwapSurfaceFormat(support.formats);
            var mode          = ChooseSwapPresentMode(support.modes);
            var extent        = ChooseSwapExtent(ref cap);

            uint imageCount = cap.minImageCount + 1;

            if (cap.maxImageCount > 0 && imageCount > cap.maxImageCount)
            {
                imageCount = cap.maxImageCount;
            }

            var info = new VkSwapchainCreateInfoKHR();

            info.sType            = CSGL.Vulkan.VkStructureType.SwapchainCreateInfoKhr;
            info.surface          = surface;
            info.minImageCount    = imageCount;
            info.imageFormat      = surfaceFormat.format;
            info.imageColorSpace  = surfaceFormat.colorSpace;
            info.imageExtent      = extent;
            info.imageArrayLayers = 1;
            info.imageUsage       = CSGL.Vulkan.VkImageUsageFlags.ColorAttachmentBit;

            var queueFamilyIndices = new NativeArray <uint>(2);

            queueFamilyIndices[0] = graphicsIndex;
            queueFamilyIndices[1] = presentIndex;

            if (graphicsIndex != presentIndex)
            {
                info.imageSharingMode      = CSGL.Vulkan.VkSharingMode.Concurrent;
                info.queueFamilyIndexCount = 2;
                info.pQueueFamilyIndices   = queueFamilyIndices.Address;
            }
            else
            {
                info.imageSharingMode = CSGL.Vulkan.VkSharingMode.Exclusive;
            }

            info.preTransform   = cap.currentTransform;
            info.compositeAlpha = CSGL.Vulkan.VkCompositeAlphaFlagsKHR.OpaqueBitKhr;
            info.presentMode    = mode;
            info.clipped        = 1;

            var oldSwapchain = swapchain;

            info.oldSwapchain = oldSwapchain;

            VkSwapchainKHR newSwapchain;
            var            result = createSwapchain(device, ref info, alloc, out newSwapchain);

            if (swapchain != VkSwapchainKHR.Null)
            {
                destroySwapchain(device, swapchain, alloc);
            }
            swapchain = newSwapchain;

            getSwapchainImages(device, swapchain, ref imageCount, IntPtr.Zero);
            var swapchainImagesNative = new NativeArray <VkImage>(imageCount);

            getSwapchainImages(device, swapchain, ref imageCount, swapchainImagesNative.Address);

            swapchainImages = new List <VkImage>(swapchainImagesNative.Count);

            for (int i = 0; i < imageCount; i++)
            {
                swapchainImages.Add(swapchainImagesNative[i]);
            }

            swapchainImageFormat = surfaceFormat.format;
            swapchainExtent      = extent;

            support.cap.Dispose();
            queueFamilyIndices.Dispose();
        }
Example #21
0
        //private readonly WindowStyles _windowFullscreenStyle = WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_GROUP | WindowStyles.WS_TABSTOP;

        public unsafe Window(string title, int width, int height, WindowFlags flags = WindowFlags.None)
        {
            Title = title;

            int  x         = CW_USEDEFAULT;
            int  y         = CW_USEDEFAULT;
            bool resizable = (flags & WindowFlags.Resizable) != WindowFlags.None;

            _windowWindowedStyle = WindowStyles.WS_CAPTION | WindowStyles.WS_SYSMENU | WindowStyles.WS_MINIMIZEBOX | WindowStyles.WS_CLIPSIBLINGS | WindowStyles.WS_BORDER | WindowStyles.WS_DLGFRAME | WindowStyles.WS_THICKFRAME | WindowStyles.WS_GROUP | WindowStyles.WS_TABSTOP;

            if (resizable)
            {
                _windowWindowedStyle |= WindowStyles.WS_SIZEBOX | WindowStyles.WS_MAXIMIZEBOX;
            }

            _windowStyle = _windowWindowedStyle;

            RawRect windowRect = new RawRect(0, 0, width, height);

            // Adjust according to window styles
            AdjustWindowRectEx(ref windowRect, _windowStyle, false, WindowExStyles.WS_EX_OVERLAPPEDWINDOW);

            int windowWidth  = windowRect.Right - windowRect.Left;
            int windowHeight = windowRect.Bottom - windowRect.Top;

            bool centerWindow = true;

            if (centerWindow)
            {
                if (windowWidth > 0 && windowHeight > 0)
                {
                    int screenWidth  = GetSystemMetrics(SystemMetrics.SM_CXSCREEN);
                    int screenHeight = GetSystemMetrics(SystemMetrics.SM_CYSCREEN);

                    // Place the window in the middle of the screen.WS_EX_APPWINDOW
                    x = (screenWidth - windowWidth) / 2;
                    y = (screenHeight - windowHeight) / 2;
                }
            }

            IntPtr hwnd;

            fixed(char *lpWndClassName = WndClassName)
            {
                fixed(char *lpWindowName = Title)
                {
                    hwnd = CreateWindowExW(
                        (uint)WindowExStyles.WS_EX_OVERLAPPEDWINDOW,
                        (ushort *)lpWndClassName,
                        (ushort *)lpWindowName,
                        (uint)_windowStyle,
                        x,
                        y,
                        windowWidth,
                        windowHeight,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        IntPtr.Zero,
                        null);
                }
            }

            if (hwnd == IntPtr.Zero)
            {
                return;
            }

            ShowWindow(hwnd, ShowWindowCommand.Normal);
            Handle = hwnd;

            GetClientRect(hwnd, out windowRect);
            Extent = new VkExtent2D(windowRect.Right - windowRect.Left, windowRect.Bottom - windowRect.Top);
        }
Example #22
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VkRect2D"/> structure.
 /// </summary>
 /// <param name="width">The width component of the extent.</param>
 /// <param name="height">The height component of the extent.</param>
 public VkRect2D(int width, int height)
 {
     offset = default;
     extent = new VkExtent2D(width, height);
 }
Example #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VkRect2D"/> structure.
 /// </summary>
 /// <param name="x">The X component of the offset.</param>
 /// <param name="y">The Y component of the offset.</param>
 /// <param name="width">The width component of the extent.</param>
 /// <param name="height">The height component of the extent.</param>
 public VkRect2D(int x, int y, int width, int height)
 {
     offset = new VkOffset2D(x, y);
     extent = new VkExtent2D(width, height);
 }
Example #24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VkRect2D"/> structure.
 /// </summary>
 /// <param name="extent">The extent component of the rectangle.</param>
 public VkRect2D(VkExtent2D extent)
 {
     offset      = default;
     this.extent = extent;
 }
Example #25
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VkRect2D"/> structure.
 /// </summary>
 /// <param name="offset">The offset component of the rectangle.</param>
 /// <param name="extent">The extent component of the rectangle.</param>
 public VkRect2D(VkOffset2D offset, VkExtent2D extent)
 {
     this.offset = offset;
     this.extent = extent;
 }
Example #26
0
            private void OnDraw(VkCommandBuffer commandBuffer, VkFramebuffer framebuffer, VkExtent2D size)
            {
                float g = _green + 0.001f;

                if (g > 1.0f)
                {
                    g = 0.0f;
                }
                _green = g;

                VkClearValue clearValue = new VkClearValue(1.0f, _green, 0.0f, 1.0f);

                // Begin the render pass.
                VkRenderPassBeginInfo renderPassBeginInfo = new VkRenderPassBeginInfo
                {
                    sType           = VkStructureType.RenderPassBeginInfo,
                    renderPass      = _graphicsDevice !.Swapchain.RenderPass,
                    framebuffer     = framebuffer,
                    renderArea      = new VkRect2D(size),
                    clearValueCount = 1,
                    pClearValues    = &clearValue
                };

                vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VkSubpassContents.Inline);
                vkCmdEndRenderPass(commandBuffer);
            }
        }
Example #27
0
 public FramebufferBuilder <uint> FramebufferBuilder(VkExtent2D size, uint layers = 1)
 {
     return(new FramebufferBuilder <uint>(this, size, (x) => x, layers));
 }
        private void CreateSwapChain()
        {
            // Create SwapChain
            SwapChainSupportDetails swapChainSupport = this.QuerySwapChainSupport(this.physicalDevice);

            VkSurfaceFormatKHR surfaceFormat = this.ChooseSwapSurfaceFormat(swapChainSupport.formats);
            VkPresentModeKHR   presentMode   = this.ChooseSwapPresentMode(swapChainSupport.presentModes);
            VkExtent2D         extent        = this.ChooseSwapExtent(swapChainSupport.capabilities);

            uint imageCount = swapChainSupport.capabilities.minImageCount + 1;

            if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount)
            {
                imageCount = swapChainSupport.capabilities.maxImageCount;
            }

            VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR();

            createInfo.sType            = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
            createInfo.surface          = surface;
            createInfo.minImageCount    = imageCount;
            createInfo.imageFormat      = surfaceFormat.format;
            createInfo.imageColorSpace  = surfaceFormat.colorSpace;
            createInfo.imageExtent      = extent;
            createInfo.imageArrayLayers = 1;
            createInfo.imageUsage       = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

            QueueFamilyIndices indices = this.FindQueueFamilies(this.physicalDevice);
            uint *queueFamilyIndices   = stackalloc uint[] { indices.graphicsFamily.Value, indices.presentFamily.Value };

            if (indices.graphicsFamily != indices.presentFamily)
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_CONCURRENT;
                createInfo.queueFamilyIndexCount = 2;
                createInfo.pQueueFamilyIndices   = queueFamilyIndices;
            }
            else
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE;
                createInfo.queueFamilyIndexCount = 0;    //Optional
                createInfo.pQueueFamilyIndices   = null; //Optional
            }
            createInfo.preTransform   = swapChainSupport.capabilities.currentTransform;
            createInfo.compositeAlpha = VkCompositeAlphaFlagsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
            createInfo.presentMode    = presentMode;
            createInfo.clipped        = true;
            createInfo.oldSwapchain   = 0;

            fixed(VkSwapchainKHR *swapChainPtr = &swapChain)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateSwapchainKHR(device, &createInfo, null, swapChainPtr));
            }

            // SwapChain Images
            VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, null);
            this.swapChainImages = new VkImage[imageCount];
            fixed(VkImage *swapChainImagesPtr = &this.swapChainImages[0])
            {
                VulkanNative.vkGetSwapchainImagesKHR(device, swapChain, &imageCount, swapChainImagesPtr);
            }

            this.swapChainImageFormat = surfaceFormat.format;
            this.swapChainExtent      = extent;
        }
Example #29
0
        private void CreateSwapChain()
        {
            var swapChainSupport = new SwapChainSupportDetails(vkPhysicalDevice, vkSurface);

            VkSurfaceFormatKHR surfaceFormat = ChooseSwapSurfaceFormat(swapChainSupport.formats);
            VkPresentModeKHR   presentMode   = ChooseSwapPresentMode(swapChainSupport.presentModes);
            VkExtent2D         extent        = ChooseSwapExtent(swapChainSupport.capabilities);

            uint imageCount = swapChainSupport.capabilities.minImageCount + 1;

            if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount)
            {
                imageCount = Math.Min(imageCount, swapChainSupport.capabilities.maxImageCount);
            }

            var createInfo = new VkSwapchainCreateInfoKHR()
            {
                sType            = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR,
                surface          = vkSurface,
                minImageCount    = imageCount,
                imageFormat      = surfaceFormat.format,
                imageColorSpace  = surfaceFormat.colorSpace,
                imageExtent      = extent,
                imageArrayLayers = 1,
                imageUsage       = VkImageUsageFlagBits.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
                preTransform     = swapChainSupport.capabilities.currentTransform,
                compositeAlpha   = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR,
                presentMode      = presentMode,
                clipped          = true,
            };

            var indices = new QueueFamilyIndices(vkPhysicalDevice, vkSurface);

            uint *QueueFamilyIndicesPtr = stackalloc uint[]
            {
                (uint)indices.GraphicsFamily,
                (uint)indices.PresentFamily,
            };

            if (indices.GraphicsFamily != indices.PresentFamily)
            {
                createInfo.imageSharingMode    = VkSharingMode.VK_SHARING_MODE_CONCURRENT;
                createInfo.pQueueFamilyIndices = QueueFamilyIndicesPtr;
            }
            else
            {
                createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE;
            }

            VkSwapchainKHR newSwapChain;
            var            result = VulkanNative.vkCreateSwapchainKHR(vkDevice, &createInfo, null, &newSwapChain);

            vkSwapChain = newSwapChain;
            Helpers.CheckErrors(result);

            VulkanNative.vkGetSwapchainImagesKHR(vkDevice, vkSwapChain, &imageCount, null);
            VkImage *images = stackalloc VkImage[(int)imageCount];

            result = VulkanNative.vkGetSwapchainImagesKHR(vkDevice, vkSwapChain, &imageCount, images);
            Helpers.CheckErrors(result);

            vkSwapChainImages = new VkImage[imageCount];
            for (int i = 0; i < imageCount; i++)
            {
                vkSwapChainImages[i] = images[i];
            }

            vkSwapChainImageFormat = surfaceFormat.format;
            vkSwapChainExtent      = extent;
        }
Example #30
0
        private void createSwapChain()
        {
            SwapChainSupportDetails swapChainSupport = querySwapChainSupport(physicalDevice);

            VkSurfaceFormatKHR surfaceFormat = chooseSwapSurfaceFormat(swapChainSupport.formats);
            VkPresentModeKHR   presentMode   = chooseSwapPresentMode(swapChainSupport.presentModes);
            VkExtent2D         extent        = chooseSwapExtent(swapChainSupport.capabilities);

            int imageCount = swapChainSupport.capabilities.minImageCount + 1;

            if (swapChainSupport.capabilities.maxImageCount > 0 && imageCount > swapChainSupport.capabilities.maxImageCount)
            {
                imageCount = swapChainSupport.capabilities.maxImageCount;
            }

            VkSwapchainCreateInfoKHR createInfo = new VkSwapchainCreateInfoKHR();

            createInfo.sType   = VkStructureType.VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR;
            createInfo.surface = surface;

            createInfo.minImageCount    = imageCount;
            createInfo.imageFormat      = surfaceFormat.format;
            createInfo.imageColorSpace  = surfaceFormat.colorSpace;
            createInfo.imageExtent      = extent;
            createInfo.imageArrayLayers = 1;
            createInfo.imageUsage       = VkImageUsageFlags.VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;

            QueueFamilyIndices indices = findQueueFamilies(physicalDevice);
            var queueFamilyIndices     = new List <int>()
            {
                indices.graphicsFamily, indices.presentFamily
            };

            if (indices.graphicsFamily != indices.presentFamily)
            {
                createInfo.imageSharingMode      = VkSharingMode.VK_SHARING_MODE_CONCURRENT;
                createInfo.queueFamilyIndexCount = queueFamilyIndices.Count;
                createInfo.pQueueFamilyIndices   = queueFamilyIndices.ToArray();
            }
            else
            {
                createInfo.imageSharingMode = VkSharingMode.VK_SHARING_MODE_EXCLUSIVE;
            }

            createInfo.preTransform   = (VkSurfaceTransformFlagBitsKHR)swapChainSupport.capabilities.currentTransform;
            createInfo.compositeAlpha = VkCompositeAlphaFlagBitsKHR.VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR;
            createInfo.presentMode    = presentMode;
            createInfo.clipped        = VkBool32.VK_TRUE;

            createInfo.oldSwapchain = null;

            VkResult result = Vulkan.vkCreateSwapchainKHR(device, createInfo, null, out swapChain);

            if (result != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to create swap chain!", result);
            }

            swapChainImages = new VkImage[imageCount];
            Vulkan.vkGetSwapchainImagesKHR(device, swapChain, ref imageCount, swapChainImages);

            swapChainImageFormat = surfaceFormat.format;
            swapChainExtent      = extent;
        }