aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs')
-rw-r--r--Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs92
1 files changed, 92 insertions, 0 deletions
diff --git a/Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs b/Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs
new file mode 100644
index 00000000..b2b8843d
--- /dev/null
+++ b/Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs
@@ -0,0 +1,92 @@
+using System;
+using Avalonia;
+using Silk.NET.Vulkan;
+
+namespace Ryujinx.Ava.Ui.Vulkan.Surfaces
+{
+ internal class VulkanSurfaceRenderTarget : IDisposable
+ {
+ private readonly VulkanPlatformInterface _platformInterface;
+
+ private readonly Format _format;
+
+ public VulkanImage Image { get; private set; }
+ public bool IsCorrupted { get; private set; } = true;
+
+ public uint MipLevels => Image.MipLevels;
+
+ public VulkanSurfaceRenderTarget(VulkanPlatformInterface platformInterface, VulkanSurface surface)
+ {
+ _platformInterface = platformInterface;
+
+ Display = VulkanDisplay.CreateDisplay(platformInterface.Instance, platformInterface.Device,
+ platformInterface.PhysicalDevice, surface);
+ Surface = surface;
+
+ // Skia seems to only create surfaces from images with unorm format
+
+ IsRgba = Display.SurfaceFormat.Format >= Format.R8G8B8A8Unorm &&
+ Display.SurfaceFormat.Format <= Format.R8G8B8A8Srgb;
+
+ _format = IsRgba ? Format.R8G8B8A8Unorm : Format.B8G8R8A8Unorm;
+ }
+
+ public bool IsRgba { get; }
+
+ public uint ImageFormat => (uint) _format;
+
+ public ulong MemorySize => Image.MemorySize;
+
+ public VulkanDisplay Display { get; }
+
+ public VulkanSurface Surface { get; }
+
+ public uint UsageFlags => Image.UsageFlags;
+
+ public PixelSize Size { get; private set; }
+
+ public void Dispose()
+ {
+ _platformInterface.Device.WaitIdle();
+ DestroyImage();
+ Display?.Dispose();
+ Surface?.Dispose();
+ }
+
+ public VulkanSurfaceRenderingSession BeginDraw(float scaling)
+ {
+ var session = new VulkanSurfaceRenderingSession(Display, _platformInterface.Device, this, scaling);
+
+ if (IsCorrupted)
+ {
+ IsCorrupted = false;
+ DestroyImage();
+ CreateImage();
+ }
+ else
+ {
+ Image.TransitionLayout(ImageLayout.ColorAttachmentOptimal, AccessFlags.AccessNoneKhr);
+ }
+
+ return session;
+ }
+
+ public void Invalidate()
+ {
+ IsCorrupted = true;
+ }
+
+ private void CreateImage()
+ {
+ Size = Display.Size;
+
+ Image = new VulkanImage(_platformInterface.Device, _platformInterface.PhysicalDevice, _platformInterface.Device.CommandBufferPool, ImageFormat, Size);
+ }
+
+ private void DestroyImage()
+ {
+ _platformInterface.Device.WaitIdle();
+ Image?.Dispose();
+ }
+ }
+}