diff options
Diffstat (limited to 'Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs')
-rw-r--r-- | Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs b/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs deleted file mode 100644 index f3116fbd..00000000 --- a/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs +++ /dev/null @@ -1,456 +0,0 @@ -using System; -using System.Linq; -using System.Threading; -using Avalonia; -using Ryujinx.Ava.Ui.Vulkan.Surfaces; -using Silk.NET.Vulkan; -using Silk.NET.Vulkan.Extensions.KHR; - -namespace Ryujinx.Ava.Ui.Vulkan -{ - internal class VulkanDisplay : IDisposable - { - private static KhrSwapchain _swapchainExtension; - private readonly VulkanInstance _instance; - private readonly VulkanPhysicalDevice _physicalDevice; - private readonly VulkanSemaphorePair _semaphorePair; - private readonly VulkanDevice _device; - private uint _nextImage; - private readonly VulkanSurface _surface; - private SurfaceFormatKHR _surfaceFormat; - private SwapchainKHR _swapchain; - private Extent2D _swapchainExtent; - private Image[] _swapchainImages; - private ImageView[] _swapchainImageViews = Array.Empty<ImageView>(); - private bool _vsyncStateChanged; - private bool _vsyncEnabled; - private bool _surfaceChanged; - - public event EventHandler Presented; - - public VulkanCommandBufferPool CommandBufferPool { get; set; } - - public object Lock => _device.Lock; - - 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); - } - - public PixelSize Size { get; private set; } - public uint QueueFamilyIndex => _physicalDevice.QueueFamilyIndex; - - internal SurfaceFormatKHR SurfaceFormat - { - get - { - if (_surfaceFormat.Format == Format.Undefined) - { - _surfaceFormat = _surface.GetSurfaceFormat(_physicalDevice); - } - - return _surfaceFormat; - } - } - - public void Dispose() - { - _device.WaitIdle(); - _semaphorePair?.Dispose(); - DestroyCurrentImageViews(); - _swapchainExtension.DestroySwapchain(_device.InternalHandle, _swapchain, Span<AllocationCallbacks>.Empty); - CommandBufferPool.Dispose(); - } - - public bool IsSurfaceChanged() - { - var changed = _surfaceChanged; - _surfaceChanged = false; - - return changed; - } - - 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; - } - - private static unsafe Extent2D GetSwapchainExtent(VulkanSurface surface, SurfaceCapabilitiesKHR capabilities) - { - Extent2D swapchainExtent; - if (capabilities.CurrentExtent.Width != uint.MaxValue) - { - swapchainExtent = capabilities.CurrentExtent; - } - else - { - var surfaceSize = surface.SurfaceSize; - - var width = Math.Clamp((uint)surfaceSize.Width, capabilities.MinImageExtent.Width, capabilities.MaxImageExtent.Width); - var height = Math.Clamp((uint)surfaceSize.Height, capabilities.MinImageExtent.Height, capabilities.MaxImageExtent.Height); - - swapchainExtent = new Extent2D(width, height); - } - - return swapchainExtent; - } - - private static unsafe CompositeAlphaFlagsKHR GetSuitableCompositeAlphaFlags(SurfaceCapabilitiesKHR capabilities) - { - var compositeAlphaFlags = CompositeAlphaFlagsKHR.CompositeAlphaOpaqueBitKhr; - - if (capabilities.SupportedCompositeAlpha.HasFlag(CompositeAlphaFlagsKHR.CompositeAlphaPostMultipliedBitKhr)) - { - compositeAlphaFlags = CompositeAlphaFlagsKHR.CompositeAlphaPostMultipliedBitKhr; - } - else if (capabilities.SupportedCompositeAlpha.HasFlag(CompositeAlphaFlagsKHR.CompositeAlphaPreMultipliedBitKhr)) - { - compositeAlphaFlags = CompositeAlphaFlagsKHR.CompositeAlphaPreMultipliedBitKhr; - } - - return compositeAlphaFlags; - } - - 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; - } - } - - 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); - } - - private unsafe void CreateSwapchainImages() - { - DestroyCurrentImageViews(); - - Size = new PixelSize((int)_swapchainExtent.Width, (int)_swapchainExtent.Height); - - uint imageCount = 0; - - _swapchainExtension.GetSwapchainImages(_device.InternalHandle, _swapchain, &imageCount, null); - - _swapchainImages = new Image[imageCount]; - - fixed (Image* pSwapchainImages = _swapchainImages) - { - _swapchainExtension.GetSwapchainImages(_device.InternalHandle, _swapchain, &imageCount, pSwapchainImages); - } - - _swapchainImageViews = new ImageView[imageCount]; - - var surfaceFormat = SurfaceFormat; - - for (var i = 0; i < imageCount; i++) - { - _swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format); - } - } - - private void DestroyCurrentImageViews() - { - for (var i = 0; i < _swapchainImageViews.Length; i++) - { - _instance.Api.DestroyImageView(_device.InternalHandle, _swapchainImageViews[i], Span<AllocationCallbacks>.Empty); - } - } - - internal void ChangeVSyncMode(bool vsyncEnabled) - { - _vsyncStateChanged = true; - _vsyncEnabled = vsyncEnabled; - } - - private void Recreate() - { - _device.WaitIdle(); - _swapchain = CreateSwapchain(_instance, _device, _physicalDevice, _surface, out _swapchainExtent, _swapchain, _vsyncEnabled); - - CreateSwapchainImages(); - - _surfaceChanged = true; - } - - private unsafe ImageView CreateSwapchainImageView(Image swapchainImage, Format format) - { - var componentMapping = new ComponentMapping( - ComponentSwizzle.Identity, - ComponentSwizzle.Identity, - ComponentSwizzle.Identity, - ComponentSwizzle.Identity); - - var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ImageAspectColorBit, 0, 1, 0, 1); - - var imageCreateInfo = new ImageViewCreateInfo - { - SType = StructureType.ImageViewCreateInfo, - Image = swapchainImage, - ViewType = ImageViewType.ImageViewType2D, - Format = format, - Components = componentMapping, - SubresourceRange = subresourceRange - }; - - _instance.Api.CreateImageView(_device.InternalHandle, imageCreateInfo, null, out var imageView).ThrowOnError(); - return imageView; - } - - public bool EnsureSwapchainAvailable() - { - if (Size != _surface.SurfaceSize || _vsyncStateChanged) - { - _vsyncStateChanged = false; - - Recreate(); - - return false; - } - - return true; - } - - internal VulkanCommandBufferPool.VulkanCommandBuffer StartPresentation() - { - _nextImage = 0; - while (true) - { - var acquireResult = _swapchainExtension.AcquireNextImage( - _device.InternalHandle, - _swapchain, - ulong.MaxValue, - _semaphorePair.ImageAvailableSemaphore, - new Fence(), - ref _nextImage); - - if (acquireResult == Result.ErrorOutOfDateKhr || - acquireResult == Result.SuboptimalKhr) - { - Recreate(); - } - else - { - acquireResult.ThrowOnError(); - break; - } - } - - var commandBuffer = CommandBufferPool.CreateCommandBuffer(); - commandBuffer.BeginRecording(); - - VulkanMemoryHelper.TransitionLayout(_device, commandBuffer.InternalHandle, - _swapchainImages[_nextImage], ImageLayout.Undefined, - AccessFlags.AccessNoneKhr, - ImageLayout.TransferDstOptimal, - AccessFlags.AccessTransferWriteBit, - 1); - - return commandBuffer; - } - - internal void BlitImageToCurrentImage(VulkanSurfaceRenderTarget renderTarget, CommandBuffer commandBuffer) - { - var image = renderTarget.GetImage(); - - VulkanMemoryHelper.TransitionLayout(_device, commandBuffer, - image.InternalHandle.Value, (ImageLayout)image.CurrentLayout, - AccessFlags.AccessNoneKhr, - ImageLayout.TransferSrcOptimal, - AccessFlags.AccessTransferReadBit, - renderTarget.MipLevels); - - var srcBlitRegion = new ImageBlit - { - SrcOffsets = new ImageBlit.SrcOffsetsBuffer - { - Element0 = new Offset3D(0, 0, 0), - Element1 = new Offset3D(renderTarget.Size.Width, renderTarget.Size.Height, 1), - }, - DstOffsets = new ImageBlit.DstOffsetsBuffer - { - Element0 = new Offset3D(0, 0, 0), - Element1 = new Offset3D(Size.Width, Size.Height, 1), - }, - SrcSubresource = new ImageSubresourceLayers - { - AspectMask = ImageAspectFlags.ImageAspectColorBit, - BaseArrayLayer = 0, - LayerCount = 1, - MipLevel = 0 - }, - DstSubresource = new ImageSubresourceLayers - { - AspectMask = ImageAspectFlags.ImageAspectColorBit, - BaseArrayLayer = 0, - LayerCount = 1, - MipLevel = 0 - } - }; - - _device.Api.CmdBlitImage(commandBuffer, image.InternalHandle.Value, - ImageLayout.TransferSrcOptimal, - _swapchainImages[_nextImage], - ImageLayout.TransferDstOptimal, - 1, - srcBlitRegion, - Filter.Linear); - - VulkanMemoryHelper.TransitionLayout(_device, commandBuffer, - image.InternalHandle.Value, ImageLayout.TransferSrcOptimal, - AccessFlags.AccessTransferReadBit, - (ImageLayout)image.CurrentLayout, - AccessFlags.AccessNoneKhr, - renderTarget.MipLevels); - } - - internal unsafe void EndPresentation(VulkanCommandBufferPool.VulkanCommandBuffer commandBuffer) - { - VulkanMemoryHelper.TransitionLayout(_device, commandBuffer.InternalHandle, - _swapchainImages[_nextImage], ImageLayout.TransferDstOptimal, - AccessFlags.AccessNoneKhr, - ImageLayout.PresentSrcKhr, - AccessFlags.AccessNoneKhr, - 1); - - commandBuffer.Submit( - stackalloc[] { _semaphorePair.ImageAvailableSemaphore }, - stackalloc[] { PipelineStageFlags.PipelineStageColorAttachmentOutputBit }, - stackalloc[] { _semaphorePair.RenderFinishedSemaphore }); - - var semaphore = _semaphorePair.RenderFinishedSemaphore; - var swapchain = _swapchain; - var nextImage = _nextImage; - - Result result; - - var presentInfo = new PresentInfoKHR - { - SType = StructureType.PresentInfoKhr, - WaitSemaphoreCount = 1, - PWaitSemaphores = &semaphore, - SwapchainCount = 1, - PSwapchains = &swapchain, - PImageIndices = &nextImage, - PResults = &result - }; - - lock (_device.Lock) - { - _swapchainExtension.QueuePresent(_device.PresentQueue.InternalHandle, presentInfo); - } - - CommandBufferPool.FreeUsedCommandBuffers(); - - Presented?.Invoke(this, null); - } - } -} |