Ejemplo n.º 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));
        }
Ejemplo n.º 2
0
        internal static void SelectAvailableDevices(VulkanInstance instance,
                                                    VulkanSurface surface, bool preferDiscreteGpu, string preferredDevice)
        {
            uint physicalDeviceCount;

            instance.Api.EnumeratePhysicalDevices(instance.InternalHandle, &physicalDeviceCount, null).ThrowOnError();

            var physicalDevices = new PhysicalDevice[physicalDeviceCount];

            fixed(PhysicalDevice *pPhysicalDevices = physicalDevices)
            {
                instance.Api.EnumeratePhysicalDevices(instance.InternalHandle, &physicalDeviceCount, pPhysicalDevices)
                .ThrowOnError();
            }

            PhysicalDevices = new Dictionary <PhysicalDevice, PhysicalDeviceProperties>();

            foreach (var physicalDevice in physicalDevices)
            {
                instance.Api.GetPhysicalDeviceProperties(physicalDevice, out var properties);
                PhysicalDevices.Add(physicalDevice, properties);
            }

            SuitableDevices = PhysicalDevices.Where(x => IsSuitableDevice(
                                                        instance.Api,
                                                        x.Key,
                                                        x.Value,
                                                        surface.ApiHandle,
                                                        out _,
                                                        out _));
        }
Ejemplo n.º 3
0
        private static VulkanPlatformInterface TryCreate()
        {
            _options = AvaloniaLocator.Current.GetService <VulkanOptions>() ?? new VulkanOptions();

            var instance = VulkanInstance.Create(_options);

            return(new VulkanPlatformInterface(instance));
        }
Ejemplo n.º 4
0
        internal static VulkanSurface CreateSurface(VulkanInstance instance, IVulkanPlatformSurface vulkanPlatformSurface)
        {
            if (SurfaceExtension == null)
            {
                instance.Api.TryGetInstanceExtension(instance.InternalHandle, out KhrSurface extension);

                SurfaceExtension = extension;
            }

            return(new VulkanSurface(vulkanPlatformSurface, instance));
        }
Ejemplo n.º 5
0
        internal static VulkanPhysicalDevice FindSuitablePhysicalDevice(VulkanInstance instance,
                                                                        VulkanSurface surface, bool preferDiscreteGpu, string preferredDevice)
        {
            SelectAvailableDevices(instance, surface, preferDiscreteGpu, preferredDevice);

            uint queueFamilyIndex = 0;
            uint queueCount       = 0;

            if (!string.IsNullOrWhiteSpace(preferredDevice))
            {
                var physicalDevice = SuitableDevices.FirstOrDefault(x => VulkanInitialization.StringFromIdPair(x.Value.VendorID, x.Value.DeviceID) == preferredDevice);

                queueFamilyIndex = FindSuitableQueueFamily(instance.Api, physicalDevice.Key,
                                                           surface.ApiHandle, out queueCount);
                if (queueFamilyIndex != int.MaxValue)
                {
                    return(new VulkanPhysicalDevice(physicalDevice.Key, instance.Api, queueCount, queueFamilyIndex));
                }
            }

            if (preferDiscreteGpu)
            {
                var discreteGpus = SuitableDevices.Where(p => p.Value.DeviceType == PhysicalDeviceType.DiscreteGpu);

                foreach (var gpu in discreteGpus)
                {
                    queueFamilyIndex = FindSuitableQueueFamily(instance.Api, gpu.Key,
                                                               surface.ApiHandle, out queueCount);
                    if (queueFamilyIndex != int.MaxValue)
                    {
                        return(new VulkanPhysicalDevice(gpu.Key, instance.Api, queueCount, queueFamilyIndex));
                    }
                }
            }

            foreach (var physicalDevice in SuitableDevices)
            {
                queueFamilyIndex = FindSuitableQueueFamily(instance.Api, physicalDevice.Key,
                                                           surface.ApiHandle, out queueCount);
                if (queueFamilyIndex != int.MaxValue)
                {
                    return(new VulkanPhysicalDevice(physicalDevice.Key, instance.Api, queueCount, queueFamilyIndex));
                }
            }

            throw new Exception("No suitable physical device found");
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
 private VulkanPlatformInterface(VulkanInstance instance)
 {
     Instance = instance;
     Api      = instance.Api;
 }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
0
 private VulkanSurface(IVulkanPlatformSurface vulkanPlatformSurface, VulkanInstance instance)
 {
     _vulkanPlatformSurface = vulkanPlatformSurface;
     _instance = instance;
     ApiHandle = vulkanPlatformSurface.CreateSurface(instance);
 }