aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs')
-rw-r--r--Ryujinx.Ava/Ui/Backend/Vulkan/VulkanDisplay.cs456
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);
- }
- }
-}