aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Vulkan/Window.cs
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.Graphics.Vulkan/Window.cs
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'Ryujinx.Graphics.Vulkan/Window.cs')
-rw-r--r--Ryujinx.Graphics.Vulkan/Window.cs603
1 files changed, 0 insertions, 603 deletions
diff --git a/Ryujinx.Graphics.Vulkan/Window.cs b/Ryujinx.Graphics.Vulkan/Window.cs
deleted file mode 100644
index 075d1b30..00000000
--- a/Ryujinx.Graphics.Vulkan/Window.cs
+++ /dev/null
@@ -1,603 +0,0 @@
-using Ryujinx.Graphics.GAL;
-using Ryujinx.Graphics.Vulkan.Effects;
-using Silk.NET.Vulkan;
-using Silk.NET.Vulkan.Extensions.KHR;
-using System;
-using System.Linq;
-using VkFormat = Silk.NET.Vulkan.Format;
-
-namespace Ryujinx.Graphics.Vulkan
-{
- class Window : WindowBase, IDisposable
- {
- private const int SurfaceWidth = 1280;
- private const int SurfaceHeight = 720;
-
- private readonly VulkanRenderer _gd;
- private readonly SurfaceKHR _surface;
- private readonly PhysicalDevice _physicalDevice;
- private readonly Device _device;
- private SwapchainKHR _swapchain;
-
- private Image[] _swapchainImages;
- private Auto<DisposableImageView>[] _swapchainImageViews;
-
- private Semaphore _imageAvailableSemaphore;
- private Semaphore _renderFinishedSemaphore;
-
- private int _width;
- private int _height;
- private bool _vsyncEnabled;
- private bool _vsyncModeChanged;
- private VkFormat _format;
- private AntiAliasing _currentAntiAliasing;
- private bool _updateEffect;
- private IPostProcessingEffect _effect;
- private IScalingFilter _scalingFilter;
- private bool _isLinear;
- private float _scalingFilterLevel;
- private bool _updateScalingFilter;
- private ScalingFilter _currentScalingFilter;
-
- public unsafe Window(VulkanRenderer gd, SurfaceKHR surface, PhysicalDevice physicalDevice, Device device)
- {
- _gd = gd;
- _physicalDevice = physicalDevice;
- _device = device;
- _surface = surface;
-
- CreateSwapchain();
-
- var semaphoreCreateInfo = new SemaphoreCreateInfo()
- {
- SType = StructureType.SemaphoreCreateInfo
- };
-
- gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _imageAvailableSemaphore).ThrowOnError();
- gd.Api.CreateSemaphore(device, semaphoreCreateInfo, null, out _renderFinishedSemaphore).ThrowOnError();
- }
-
- private void RecreateSwapchain()
- {
- var oldSwapchain = _swapchain;
- _vsyncModeChanged = false;
-
- for (int i = 0; i < _swapchainImageViews.Length; i++)
- {
- _swapchainImageViews[i].Dispose();
- }
-
- // Destroy old Swapchain.
- _gd.Api.DeviceWaitIdle(_device);
- _gd.SwapchainApi.DestroySwapchain(_device, oldSwapchain, Span<AllocationCallbacks>.Empty);
-
- CreateSwapchain();
- }
-
- private unsafe void CreateSwapchain()
- {
- _gd.SurfaceApi.GetPhysicalDeviceSurfaceCapabilities(_physicalDevice, _surface, out var capabilities);
-
- uint surfaceFormatsCount;
-
- _gd.SurfaceApi.GetPhysicalDeviceSurfaceFormats(_physicalDevice, _surface, &surfaceFormatsCount, null);
-
- var surfaceFormats = new SurfaceFormatKHR[surfaceFormatsCount];
-
- fixed (SurfaceFormatKHR* pSurfaceFormats = surfaceFormats)
- {
- _gd.SurfaceApi.GetPhysicalDeviceSurfaceFormats(_physicalDevice, _surface, &surfaceFormatsCount, pSurfaceFormats);
- }
-
- uint presentModesCount;
-
- _gd.SurfaceApi.GetPhysicalDeviceSurfacePresentModes(_physicalDevice, _surface, &presentModesCount, null);
-
- var presentModes = new PresentModeKHR[presentModesCount];
-
- fixed (PresentModeKHR* pPresentModes = presentModes)
- {
- _gd.SurfaceApi.GetPhysicalDeviceSurfacePresentModes(_physicalDevice, _surface, &presentModesCount, pPresentModes);
- }
-
- uint imageCount = capabilities.MinImageCount + 1;
- if (capabilities.MaxImageCount > 0 && imageCount > capabilities.MaxImageCount)
- {
- imageCount = capabilities.MaxImageCount;
- }
-
- var surfaceFormat = ChooseSwapSurfaceFormat(surfaceFormats);
-
- var extent = ChooseSwapExtent(capabilities);
-
- _width = (int)extent.Width;
- _height = (int)extent.Height;
- _format = surfaceFormat.Format;
-
- var oldSwapchain = _swapchain;
-
- var swapchainCreateInfo = new SwapchainCreateInfoKHR()
- {
- SType = StructureType.SwapchainCreateInfoKhr,
- Surface = _surface,
- MinImageCount = imageCount,
- ImageFormat = surfaceFormat.Format,
- ImageColorSpace = surfaceFormat.ColorSpace,
- ImageExtent = extent,
- ImageUsage = ImageUsageFlags.ColorAttachmentBit | ImageUsageFlags.TransferDstBit | ImageUsageFlags.StorageBit,
- ImageSharingMode = SharingMode.Exclusive,
- ImageArrayLayers = 1,
- PreTransform = capabilities.CurrentTransform,
- CompositeAlpha = ChooseCompositeAlpha(capabilities.SupportedCompositeAlpha),
- PresentMode = ChooseSwapPresentMode(presentModes, _vsyncEnabled),
- Clipped = true
- };
-
- _gd.SwapchainApi.CreateSwapchain(_device, swapchainCreateInfo, null, out _swapchain).ThrowOnError();
-
- _gd.SwapchainApi.GetSwapchainImages(_device, _swapchain, &imageCount, null);
-
- _swapchainImages = new Image[imageCount];
-
- fixed (Image* pSwapchainImages = _swapchainImages)
- {
- _gd.SwapchainApi.GetSwapchainImages(_device, _swapchain, &imageCount, pSwapchainImages);
- }
-
- _swapchainImageViews = new Auto<DisposableImageView>[imageCount];
-
- for (int i = 0; i < _swapchainImageViews.Length; i++)
- {
- _swapchainImageViews[i] = CreateSwapchainImageView(_swapchainImages[i], surfaceFormat.Format);
- }
- }
-
- private unsafe Auto<DisposableImageView> CreateSwapchainImageView(Image swapchainImage, VkFormat format)
- {
- var componentMapping = new ComponentMapping(
- ComponentSwizzle.R,
- ComponentSwizzle.G,
- ComponentSwizzle.B,
- ComponentSwizzle.A);
-
- var aspectFlags = ImageAspectFlags.ColorBit;
-
- var subresourceRange = new ImageSubresourceRange(aspectFlags, 0, 1, 0, 1);
-
- var imageCreateInfo = new ImageViewCreateInfo()
- {
- SType = StructureType.ImageViewCreateInfo,
- Image = swapchainImage,
- ViewType = ImageViewType.Type2D,
- Format = format,
- Components = componentMapping,
- SubresourceRange = subresourceRange
- };
-
- _gd.Api.CreateImageView(_device, imageCreateInfo, null, out var imageView).ThrowOnError();
- return new Auto<DisposableImageView>(new DisposableImageView(_gd.Api, _device, imageView));
- }
-
- private static SurfaceFormatKHR ChooseSwapSurfaceFormat(SurfaceFormatKHR[] availableFormats)
- {
- if (availableFormats.Length == 1 && availableFormats[0].Format == VkFormat.Undefined)
- {
- return new SurfaceFormatKHR(VkFormat.B8G8R8A8Unorm, ColorSpaceKHR.PaceSrgbNonlinearKhr);
- }
-
- foreach (var format in availableFormats)
- {
- if (format.Format == VkFormat.B8G8R8A8Unorm && format.ColorSpace == ColorSpaceKHR.PaceSrgbNonlinearKhr)
- {
- return format;
- }
- }
-
- return availableFormats[0];
- }
-
- private static CompositeAlphaFlagsKHR ChooseCompositeAlpha(CompositeAlphaFlagsKHR supportedFlags)
- {
- if (supportedFlags.HasFlag(CompositeAlphaFlagsKHR.OpaqueBitKhr))
- {
- return CompositeAlphaFlagsKHR.OpaqueBitKhr;
- }
- else if (supportedFlags.HasFlag(CompositeAlphaFlagsKHR.PreMultipliedBitKhr))
- {
- return CompositeAlphaFlagsKHR.PreMultipliedBitKhr;
- }
- else
- {
- return CompositeAlphaFlagsKHR.InheritBitKhr;
- }
- }
-
- private static PresentModeKHR ChooseSwapPresentMode(PresentModeKHR[] availablePresentModes, bool vsyncEnabled)
- {
- if (!vsyncEnabled && availablePresentModes.Contains(PresentModeKHR.ImmediateKhr))
- {
- return PresentModeKHR.ImmediateKhr;
- }
- else if (availablePresentModes.Contains(PresentModeKHR.MailboxKhr))
- {
- return PresentModeKHR.MailboxKhr;
- }
- else
- {
- return PresentModeKHR.FifoKhr;
- }
- }
-
- public static Extent2D ChooseSwapExtent(SurfaceCapabilitiesKHR capabilities)
- {
- if (capabilities.CurrentExtent.Width != uint.MaxValue)
- {
- return capabilities.CurrentExtent;
- }
- else
- {
- uint width = Math.Max(capabilities.MinImageExtent.Width, Math.Min(capabilities.MaxImageExtent.Width, SurfaceWidth));
- uint height = Math.Max(capabilities.MinImageExtent.Height, Math.Min(capabilities.MaxImageExtent.Height, SurfaceHeight));
-
- return new Extent2D(width, height);
- }
- }
-
- public unsafe override void Present(ITexture texture, ImageCrop crop, Action swapBuffersCallback)
- {
- _gd.PipelineInternal.AutoFlush.Present();
-
- uint nextImage = 0;
-
- while (true)
- {
- var acquireResult = _gd.SwapchainApi.AcquireNextImage(
- _device,
- _swapchain,
- ulong.MaxValue,
- _imageAvailableSemaphore,
- new Fence(),
- ref nextImage);
-
- if (acquireResult == Result.ErrorOutOfDateKhr ||
- acquireResult == Result.SuboptimalKhr ||
- _vsyncModeChanged)
- {
- RecreateSwapchain();
- }
- else
- {
- acquireResult.ThrowOnError();
- break;
- }
- }
-
- var swapchainImage = _swapchainImages[nextImage];
-
- _gd.FlushAllCommands();
-
- var cbs = _gd.CommandBufferPool.Rent();
-
- Transition(
- cbs.CommandBuffer,
- swapchainImage,
- 0,
- AccessFlags.TransferWriteBit,
- ImageLayout.Undefined,
- ImageLayout.General);
-
- var view = (TextureView)texture;
-
- UpdateEffect();
-
- if (_effect != null)
- {
- view = _effect.Run(view, cbs, _width, _height);
- }
-
- int srcX0, srcX1, srcY0, srcY1;
- float scale = view.ScaleFactor;
-
- if (crop.Left == 0 && crop.Right == 0)
- {
- srcX0 = 0;
- srcX1 = (int)(view.Width / scale);
- }
- else
- {
- srcX0 = crop.Left;
- srcX1 = crop.Right;
- }
-
- if (crop.Top == 0 && crop.Bottom == 0)
- {
- srcY0 = 0;
- srcY1 = (int)(view.Height / scale);
- }
- else
- {
- srcY0 = crop.Top;
- srcY1 = crop.Bottom;
- }
-
- if (scale != 1f)
- {
- srcX0 = (int)(srcX0 * scale);
- srcY0 = (int)(srcY0 * scale);
- srcX1 = (int)Math.Ceiling(srcX1 * scale);
- srcY1 = (int)Math.Ceiling(srcY1 * scale);
- }
-
- if (ScreenCaptureRequested)
- {
- if (_effect != null)
- {
- _gd.CommandBufferPool.Return(
- cbs,
- null,
- stackalloc[] { PipelineStageFlags.ColorAttachmentOutputBit },
- null);
- _gd.FlushAllCommands();
- cbs.GetFence().Wait();
- cbs = _gd.CommandBufferPool.Rent();
- }
-
- CaptureFrame(view, srcX0, srcY0, srcX1 - srcX0, srcY1 - srcY0, view.Info.Format.IsBgr(), crop.FlipX, crop.FlipY);
-
- ScreenCaptureRequested = false;
- }
-
- float ratioX = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _height * crop.AspectRatioX / (_width * crop.AspectRatioY));
- float ratioY = crop.IsStretched ? 1.0f : MathF.Min(1.0f, _width * crop.AspectRatioY / (_height * crop.AspectRatioX));
-
- int dstWidth = (int)(_width * ratioX);
- int dstHeight = (int)(_height * ratioY);
-
- int dstPaddingX = (_width - dstWidth) / 2;
- int dstPaddingY = (_height - dstHeight) / 2;
-
- int dstX0 = crop.FlipX ? _width - dstPaddingX : dstPaddingX;
- int dstX1 = crop.FlipX ? dstPaddingX : _width - dstPaddingX;
-
- int dstY0 = crop.FlipY ? dstPaddingY : _height - dstPaddingY;
- int dstY1 = crop.FlipY ? _height - dstPaddingY : dstPaddingY;
-
- if (_scalingFilter != null)
- {
- _scalingFilter.Run(
- view,
- cbs,
- _swapchainImageViews[nextImage],
- _format,
- _width,
- _height,
- new Extents2D(srcX0, srcY0, srcX1, srcY1),
- new Extents2D(dstX0, dstY0, dstX1, dstY1)
- );
- }
- else
- {
- _gd.HelperShader.BlitColor(
- _gd,
- cbs,
- view,
- _swapchainImageViews[nextImage],
- _width,
- _height,
- 1,
- _format,
- false,
- new Extents2D(srcX0, srcY0, srcX1, srcY1),
- new Extents2D(dstX0, dstY1, dstX1, dstY0),
- _isLinear,
- true);
- }
-
- Transition(
- cbs.CommandBuffer,
- swapchainImage,
- 0,
- 0,
- ImageLayout.General,
- ImageLayout.PresentSrcKhr);
-
- _gd.CommandBufferPool.Return(
- cbs,
- stackalloc[] { _imageAvailableSemaphore },
- stackalloc[] { PipelineStageFlags.ColorAttachmentOutputBit },
- stackalloc[] { _renderFinishedSemaphore });
-
- // TODO: Present queue.
- var semaphore = _renderFinishedSemaphore;
- var swapchain = _swapchain;
-
- Result result;
-
- var presentInfo = new PresentInfoKHR()
- {
- SType = StructureType.PresentInfoKhr,
- WaitSemaphoreCount = 1,
- PWaitSemaphores = &semaphore,
- SwapchainCount = 1,
- PSwapchains = &swapchain,
- PImageIndices = &nextImage,
- PResults = &result
- };
-
- lock (_gd.QueueLock)
- {
- _gd.SwapchainApi.QueuePresent(_gd.Queue, presentInfo);
- }
- }
-
- public override void SetAntiAliasing(AntiAliasing effect)
- {
- if (_currentAntiAliasing == effect && _effect != null)
- {
- return;
- }
-
- _currentAntiAliasing = effect;
-
- _updateEffect = true;
- }
-
- public override void SetScalingFilter(ScalingFilter type)
- {
- if (_currentScalingFilter == type && _effect != null)
- {
- return;
- }
-
- _currentScalingFilter = type;
-
- _updateScalingFilter = true;
- }
-
- private void UpdateEffect()
- {
- if (_updateEffect)
- {
- _updateEffect = false;
-
- switch (_currentAntiAliasing)
- {
- case AntiAliasing.Fxaa:
- _effect?.Dispose();
- _effect = new FxaaPostProcessingEffect(_gd, _device);
- break;
- case AntiAliasing.None:
- _effect?.Dispose();
- _effect = null;
- break;
- case AntiAliasing.SmaaLow:
- case AntiAliasing.SmaaMedium:
- case AntiAliasing.SmaaHigh:
- case AntiAliasing.SmaaUltra:
- var quality = _currentAntiAliasing - AntiAliasing.SmaaLow;
- if (_effect is SmaaPostProcessingEffect smaa)
- {
- smaa.Quality = quality;
- }
- else
- {
- _effect?.Dispose();
- _effect = new SmaaPostProcessingEffect(_gd, _device, quality);
- }
- break;
- }
- }
-
- if (_updateScalingFilter)
- {
- _updateScalingFilter = false;
-
- switch (_currentScalingFilter)
- {
- case ScalingFilter.Bilinear:
- case ScalingFilter.Nearest:
- _scalingFilter?.Dispose();
- _scalingFilter = null;
- _isLinear = _currentScalingFilter == ScalingFilter.Bilinear;
- break;
- case ScalingFilter.Fsr:
- if (_scalingFilter is not FsrScalingFilter)
- {
- _scalingFilter?.Dispose();
- _scalingFilter = new FsrScalingFilter(_gd, _device);
- }
-
- _scalingFilter.Level = _scalingFilterLevel;
- break;
- }
- }
- }
-
- public override void SetScalingFilterLevel(float level)
- {
- _scalingFilterLevel = level;
- _updateScalingFilter = true;
- }
-
- private unsafe void Transition(
- CommandBuffer commandBuffer,
- Image image,
- AccessFlags srcAccess,
- AccessFlags dstAccess,
- ImageLayout srcLayout,
- ImageLayout dstLayout)
- {
- var subresourceRange = new ImageSubresourceRange(ImageAspectFlags.ColorBit, 0, 1, 0, 1);
-
- var barrier = new ImageMemoryBarrier()
- {
- SType = StructureType.ImageMemoryBarrier,
- SrcAccessMask = srcAccess,
- DstAccessMask = dstAccess,
- OldLayout = srcLayout,
- NewLayout = dstLayout,
- SrcQueueFamilyIndex = Vk.QueueFamilyIgnored,
- DstQueueFamilyIndex = Vk.QueueFamilyIgnored,
- Image = image,
- SubresourceRange = subresourceRange
- };
-
- _gd.Api.CmdPipelineBarrier(
- commandBuffer,
- PipelineStageFlags.TopOfPipeBit,
- PipelineStageFlags.AllCommandsBit,
- 0,
- 0,
- null,
- 0,
- null,
- 1,
- barrier);
- }
-
- private void CaptureFrame(TextureView texture, int x, int y, int width, int height, bool isBgra, bool flipX, bool flipY)
- {
- byte[] bitmap = texture.GetData(x, y, width, height);
-
- _gd.OnScreenCaptured(new ScreenCaptureImageInfo(width, height, isBgra, bitmap, flipX, flipY));
- }
-
- public override void SetSize(int width, int height)
- {
- // Not needed as we can get the size from the surface.
- }
-
- public override void ChangeVSyncMode(bool vsyncEnabled)
- {
- _vsyncEnabled = vsyncEnabled;
- _vsyncModeChanged = true;
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- unsafe
- {
- _gd.Api.DestroySemaphore(_device, _renderFinishedSemaphore, null);
- _gd.Api.DestroySemaphore(_device, _imageAvailableSemaphore, null);
-
- for (int i = 0; i < _swapchainImageViews.Length; i++)
- {
- _swapchainImageViews[i].Dispose();
- }
-
- _gd.SwapchainApi.DestroySwapchain(_device, _swapchain, null);
- }
-
- _effect?.Dispose();
- _scalingFilter?.Dispose();
- }
- }
-
- public override void Dispose()
- {
- Dispose(true);
- }
- }
-}