VulkanSurfaceRenderTarget.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using System;
  2. using Avalonia;
  3. using Silk.NET.Vulkan;
  4. namespace Ryujinx.Ava.Ui.Vulkan.Surfaces
  5. {
  6. internal class VulkanSurfaceRenderTarget : IDisposable
  7. {
  8. private readonly VulkanPlatformInterface _platformInterface;
  9. private readonly Format _format;
  10. public VulkanImage Image { get; private set; }
  11. public bool IsCorrupted { get; private set; } = true;
  12. public uint MipLevels => Image.MipLevels;
  13. public VulkanSurfaceRenderTarget(VulkanPlatformInterface platformInterface, VulkanSurface surface)
  14. {
  15. _platformInterface = platformInterface;
  16. Display = VulkanDisplay.CreateDisplay(platformInterface.Instance, platformInterface.Device,
  17. platformInterface.PhysicalDevice, surface);
  18. Surface = surface;
  19. // Skia seems to only create surfaces from images with unorm format
  20. IsRgba = Display.SurfaceFormat.Format >= Format.R8G8B8A8Unorm &&
  21. Display.SurfaceFormat.Format <= Format.R8G8B8A8Srgb;
  22. _format = IsRgba ? Format.R8G8B8A8Unorm : Format.B8G8R8A8Unorm;
  23. }
  24. public bool IsRgba { get; }
  25. public uint ImageFormat => (uint) _format;
  26. public ulong MemorySize => Image.MemorySize;
  27. public VulkanDisplay Display { get; }
  28. public VulkanSurface Surface { get; }
  29. public uint UsageFlags => Image.UsageFlags;
  30. public PixelSize Size { get; private set; }
  31. public void Dispose()
  32. {
  33. _platformInterface.Device.WaitIdle();
  34. DestroyImage();
  35. Display?.Dispose();
  36. Surface?.Dispose();
  37. }
  38. public VulkanSurfaceRenderingSession BeginDraw(float scaling)
  39. {
  40. var session = new VulkanSurfaceRenderingSession(Display, _platformInterface.Device, this, scaling);
  41. if (IsCorrupted)
  42. {
  43. IsCorrupted = false;
  44. DestroyImage();
  45. CreateImage();
  46. }
  47. else
  48. {
  49. Image.TransitionLayout(ImageLayout.ColorAttachmentOptimal, AccessFlags.AccessNoneKhr);
  50. }
  51. return session;
  52. }
  53. public void Invalidate()
  54. {
  55. IsCorrupted = true;
  56. }
  57. private void CreateImage()
  58. {
  59. Size = Display.Size;
  60. Image = new VulkanImage(_platformInterface.Device, _platformInterface.PhysicalDevice, _platformInterface.Device.CommandBufferPool, ImageFormat, Size);
  61. }
  62. private void DestroyImage()
  63. {
  64. _platformInterface.Device.WaitIdle();
  65. Image?.Dispose();
  66. }
  67. }
  68. }