| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- using System;
- using Avalonia;
- using Ryujinx.Graphics.Vulkan;
- using Silk.NET.Vulkan;
- namespace Ryujinx.Ava.Ui.Vulkan.Surfaces
- {
- internal class VulkanSurfaceRenderTarget : IDisposable
- {
- private readonly VulkanPlatformInterface _platformInterface;
- private readonly Format _format;
- private VulkanCommandBufferPool.VulkanCommandBuffer _commandBuffer;
- private VulkanImage Image { get; set; }
- private object _lock = new object();
- public uint MipLevels => Image.MipLevels;
- public VulkanDevice Device { get; }
- public VulkanSurfaceRenderTarget(VulkanPlatformInterface platformInterface, VulkanSurface surface)
- {
- _platformInterface = platformInterface;
- var device = VulkanInitialization.CreateDevice(platformInterface.Api,
- platformInterface.PhysicalDevice.InternalHandle,
- platformInterface.PhysicalDevice.QueueFamilyIndex,
- VulkanInitialization.GetSupportedExtensions(platformInterface.Api, platformInterface.PhysicalDevice.InternalHandle),
- platformInterface.PhysicalDevice.QueueCount);
- Device = new VulkanDevice(device, platformInterface.PhysicalDevice, platformInterface.Api);
- Display = VulkanDisplay.CreateDisplay(
- platformInterface.Instance,
- 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; private set; }
- public VulkanSurface Surface { get; private set; }
- public uint UsageFlags => Image.UsageFlags;
- public PixelSize Size { get; private set; }
- public void Dispose()
- {
- lock (_lock)
- {
- DestroyImage();
- Display?.Dispose();
- Surface?.Dispose();
- Device?.Dispose();
- Display = null;
- Surface = null;
- }
- }
- public VulkanSurfaceRenderingSession BeginDraw(float scaling)
- {
- if (Image == null)
- {
- RecreateImage();
- }
- _commandBuffer?.WaitForFence();
- _commandBuffer = null;
- var session = new VulkanSurfaceRenderingSession(Display, Device, this, scaling);
- Image.TransitionLayout(ImageLayout.ColorAttachmentOptimal, AccessFlags.AccessNoneKhr);
- return session;
- }
- public void RecreateImage()
- {
- DestroyImage();
- CreateImage();
- }
- private void CreateImage()
- {
- Size = Display.Size;
- Image = new VulkanImage(Device, _platformInterface.PhysicalDevice, Display.CommandBufferPool, ImageFormat, Size);
- }
- private void DestroyImage()
- {
- _commandBuffer?.WaitForFence();
- _commandBuffer = null;
- Image?.Dispose();
- Image = null;
- }
- public VulkanImage GetImage()
- {
- return Image;
- }
- public void EndDraw()
- {
- lock (_lock)
- {
- if (Display == null)
- {
- return;
- }
- _commandBuffer = Display.StartPresentation();
- Display.BlitImageToCurrentImage(this, _commandBuffer.InternalHandle);
- Display.EndPresentation(_commandBuffer);
- }
- }
- }
- }
|