diff options
Diffstat (limited to 'Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs')
-rw-r--r-- | Ryujinx.Ava/Ui/Backend/Vulkan/Surfaces/VulkanSurfaceRenderTarget.cs | 92 |
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(); + } + } +} |