Exemple #1
0
        internal static VulkanDisplay CreateDisplay(VulkanInstance instance, VulkanDevice device,
                                                    VulkanPhysicalDevice physicalDevice, VulkanSurface surface)
        {
            var swapchain = CreateSwapchain(instance, device, physicalDevice, surface, out var extent, null, true);

            return(new VulkanDisplay(instance, device, physicalDevice, surface, swapchain, extent));
        }
Exemple #2
0
        private static unsafe PresentModeKHR GetSuitablePresentMode(VulkanPhysicalDevice physicalDevice, VulkanSurface surface, bool vsyncEnabled)
        {
            uint presentModesCount;

            VulkanSurface.SurfaceExtension.GetPhysicalDeviceSurfacePresentModes(physicalDevice.InternalHandle,
                                                                                surface.ApiHandle,
                                                                                &presentModesCount, null);

            var presentModes = new PresentModeKHR[presentModesCount];

            fixed(PresentModeKHR *pPresentModes = presentModes)
            {
                VulkanSurface.SurfaceExtension.GetPhysicalDeviceSurfacePresentModes(physicalDevice.InternalHandle,
                                                                                    surface.ApiHandle, &presentModesCount, pPresentModes);
            }

            var modes = presentModes.ToList();

            if (!vsyncEnabled && modes.Contains(PresentModeKHR.PresentModeImmediateKhr))
            {
                return(PresentModeKHR.PresentModeImmediateKhr);
            }
            else if (modes.Contains(PresentModeKHR.PresentModeMailboxKhr))
            {
                return(PresentModeKHR.PresentModeMailboxKhr);
            }
            else if (modes.Contains(PresentModeKHR.PresentModeFifoKhr))
            {
                return(PresentModeKHR.PresentModeFifoKhr);
            }
            else
            {
                return(PresentModeKHR.PresentModeImmediateKhr);
            }
        }
Exemple #3
0
        public VulkanDevice(Device apiHandle, VulkanPhysicalDevice physicalDevice, Vk api)
        {
            InternalHandle = apiHandle;
            Api            = api;

            api.GetDeviceQueue(apiHandle, physicalDevice.QueueFamilyIndex, 0, out var queue);

            Queue = new VulkanQueue(this, queue);

            PresentQueue = Queue;
        }
        internal static int FindSuitableMemoryTypeIndex(VulkanPhysicalDevice physicalDevice, uint memoryTypeBits,
                                                        MemoryPropertyFlags flags)
        {
            physicalDevice.Api.GetPhysicalDeviceMemoryProperties(physicalDevice.InternalHandle, out var properties);

            for (var i = 0; i < properties.MemoryTypeCount; i++)
            {
                var type = properties.MemoryTypes[i];

                if ((memoryTypeBits & (1 << i)) != 0 && type.PropertyFlags.HasFlag(flags))
                {
                    return(i);
                }
            }

            return(-1);
        }
Exemple #5
0
        private VulkanDisplay(VulkanInstance instance, VulkanDevice device,
                              VulkanPhysicalDevice physicalDevice, VulkanSurface surface, SwapchainKHR swapchain,
                              Extent2D swapchainExtent)
        {
            _instance        = instance;
            _device          = device;
            _physicalDevice  = physicalDevice;
            _swapchain       = swapchain;
            _swapchainExtent = swapchainExtent;
            _surface         = surface;

            CreateSwapchainImages();

            _semaphorePair = new VulkanSemaphorePair(_device);

            CommandBufferPool = new VulkanCommandBufferPool(device, physicalDevice);
        }
Exemple #6
0
        public VulkanSurfaceRenderTarget CreateRenderTarget(IVulkanPlatformSurface platformSurface)
        {
            var surface = VulkanSurface.CreateSurface(Instance, platformSurface);

            if (PhysicalDevice == null)
            {
                PhysicalDevice = VulkanPhysicalDevice.FindSuitablePhysicalDevice(Instance, surface, _options.PreferDiscreteGpu, _options.PreferredDevice);
            }

            var renderTarget = new VulkanSurfaceRenderTarget(this, surface);

            if (MainSurface == null && surface != null)
            {
                MainSurface = renderTarget;
            }

            return(renderTarget);
        }
Exemple #7
0
        public VulkanImage(
            VulkanDevice device,
            VulkanPhysicalDevice physicalDevice,
            VulkanCommandBufferPool commandBufferPool,
            uint format,
            PixelSize size,
            uint mipLevels = 0)
        {
            _device            = device;
            _physicalDevice    = physicalDevice;
            _commandBufferPool = commandBufferPool;
            Format             = (Format)format;
            Size             = size;
            MipLevels        = mipLevels;
            _imageUsageFlags =
                ImageUsageFlags.ImageUsageColorAttachmentBit | ImageUsageFlags.ImageUsageTransferDstBit |
                ImageUsageFlags.ImageUsageTransferSrcBit | ImageUsageFlags.ImageUsageSampledBit;

            Initialize();
        }
Exemple #8
0
        internal SurfaceFormatKHR GetSurfaceFormat(VulkanPhysicalDevice physicalDevice)
        {
            Span <uint> surfaceFormatsCount = stackalloc uint[1];

            SurfaceExtension.GetPhysicalDeviceSurfaceFormats(physicalDevice.InternalHandle, ApiHandle, surfaceFormatsCount, Span <SurfaceFormatKHR> .Empty);
            Span <SurfaceFormatKHR> surfaceFormats = stackalloc SurfaceFormatKHR[(int)surfaceFormatsCount[0]];

            SurfaceExtension.GetPhysicalDeviceSurfaceFormats(physicalDevice.InternalHandle, ApiHandle, surfaceFormatsCount, surfaceFormats);

            if (surfaceFormats.Length == 1 && surfaceFormats[0].Format == Format.Undefined)
            {
                return(new SurfaceFormatKHR(Format.B8G8R8A8Unorm, ColorSpaceKHR.ColorspaceSrgbNonlinearKhr));
            }

            foreach (var format in surfaceFormats)
            {
                if (format.Format == Format.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.ColorspaceSrgbNonlinearKhr)
                {
                    return(format);
                }
            }

            return(surfaceFormats[0]);
        }
Exemple #9
0
        private static unsafe SwapchainKHR CreateSwapchain(VulkanInstance instance, VulkanDevice device,
                                                           VulkanPhysicalDevice physicalDevice, VulkanSurface surface, out Extent2D swapchainExtent,
                                                           SwapchainKHR?oldswapchain = null, bool vsyncEnabled = true)
        {
            if (_swapchainExtension == null)
            {
                instance.Api.TryGetDeviceExtension(instance.InternalHandle, device.InternalHandle, out _swapchainExtension);
            }

            while (!surface.CanSurfacePresent(physicalDevice))
            {
                Thread.Sleep(16);
            }

            VulkanSurface.SurfaceExtension.GetPhysicalDeviceSurfaceCapabilities(physicalDevice.InternalHandle,
                                                                                surface.ApiHandle, out var capabilities);

            var imageCount = capabilities.MinImageCount + 1;

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

            var surfaceFormat = surface.GetSurfaceFormat(physicalDevice);

            bool supportsIdentityTransform = capabilities.SupportedTransforms.HasFlag(SurfaceTransformFlagsKHR.SurfaceTransformIdentityBitKhr);
            bool isRotated = capabilities.CurrentTransform.HasFlag(SurfaceTransformFlagsKHR.SurfaceTransformRotate90BitKhr) ||
                             capabilities.CurrentTransform.HasFlag(SurfaceTransformFlagsKHR.SurfaceTransformRotate270BitKhr);

            swapchainExtent = GetSwapchainExtent(surface, capabilities);

            CompositeAlphaFlagsKHR compositeAlphaFlags = GetSuitableCompositeAlphaFlags(capabilities);

            PresentModeKHR presentMode = GetSuitablePresentMode(physicalDevice, surface, vsyncEnabled);

            var swapchainCreateInfo = new SwapchainCreateInfoKHR
            {
                SType           = StructureType.SwapchainCreateInfoKhr,
                Surface         = surface.ApiHandle,
                MinImageCount   = imageCount,
                ImageFormat     = surfaceFormat.Format,
                ImageColorSpace = surfaceFormat.ColorSpace,
                ImageExtent     = swapchainExtent,
                ImageUsage      =
                    ImageUsageFlags.ImageUsageColorAttachmentBit | ImageUsageFlags.ImageUsageTransferDstBit,
                ImageSharingMode = SharingMode.Exclusive,
                ImageArrayLayers = 1,
                PreTransform     = supportsIdentityTransform && isRotated ?
                                   SurfaceTransformFlagsKHR.SurfaceTransformIdentityBitKhr :
                                   capabilities.CurrentTransform,
                CompositeAlpha = compositeAlphaFlags,
                PresentMode    = presentMode,
                Clipped        = true,
                OldSwapchain   = oldswapchain ?? new SwapchainKHR()
            };

            _swapchainExtension.CreateSwapchain(device.InternalHandle, swapchainCreateInfo, null, out var swapchain)
            .ThrowOnError();

            if (oldswapchain != null)
            {
                _swapchainExtension.DestroySwapchain(device.InternalHandle, oldswapchain.Value, null);
            }

            return(swapchain);
        }
Exemple #10
0
        internal bool CanSurfacePresent(VulkanPhysicalDevice physicalDevice)
        {
            SurfaceExtension.GetPhysicalDeviceSurfaceSupport(physicalDevice.InternalHandle, physicalDevice.QueueFamilyIndex, ApiHandle, out var isSupported);

            return(isSupported);
        }