Browse Source

vulkan - fix display out of date error (#16887)

pull/16896/head
Emmanuel Hansen 2 years ago
committed by GitHub
parent
commit
77fe0400fc
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 33
      src/Avalonia.Vulkan/Interop/VulkanDisplay.cs
  2. 8
      src/Avalonia.Vulkan/VulkanKhrSurfaceRenderTarget.cs

33
src/Avalonia.Vulkan/Interop/VulkanDisplay.cs

@ -13,22 +13,24 @@ internal class VulkanDisplay : IDisposable
private IVulkanPlatformGraphicsContext _context; private IVulkanPlatformGraphicsContext _context;
private VulkanSemaphorePair _semaphorePair; private VulkanSemaphorePair _semaphorePair;
private uint _nextImage; private uint _nextImage;
private readonly VulkanKhrSurface _surface; private VulkanKhrSurface _surface;
private VkSurfaceFormatKHR _surfaceFormat; private VkSurfaceFormatKHR _surfaceFormat;
private VkSwapchainKHR _swapchain; private VkSwapchainKHR _swapchain;
private VkExtent2D _swapchainExtent; private VkExtent2D _swapchainExtent;
private readonly IVulkanKhrSurfacePlatformSurface _platformSurface;
private VkImage[] _swapchainImages = Array.Empty<VkImage>(); private VkImage[] _swapchainImages = Array.Empty<VkImage>();
private VkImageView[] _swapchainImageViews = Array.Empty<VkImageView>(); private VkImageView[] _swapchainImageViews = Array.Empty<VkImageView>();
public VulkanCommandBufferPool CommandBufferPool { get; private set; } public VulkanCommandBufferPool CommandBufferPool { get; private set; }
public PixelSize Size { get; private set; } public PixelSize Size { get; private set; }
private VulkanDisplay(IVulkanPlatformGraphicsContext context, VulkanKhrSurface surface, VkSwapchainKHR swapchain, private VulkanDisplay(IVulkanPlatformGraphicsContext context, VulkanKhrSurface surface, VkSwapchainKHR swapchain,
VkExtent2D swapchainExtent) VkExtent2D swapchainExtent, IVulkanKhrSurfacePlatformSurface platformSurface)
{ {
_context = context; _context = context;
_surface = surface; _surface = surface;
_swapchain = swapchain; _swapchain = swapchain;
_swapchainExtent = swapchainExtent; _swapchainExtent = swapchainExtent;
_platformSurface = platformSurface;
_semaphorePair = new VulkanSemaphorePair(_context); _semaphorePair = new VulkanSemaphorePair(_context);
CommandBufferPool = new VulkanCommandBufferPool(_context); CommandBufferPool = new VulkanCommandBufferPool(_context);
CreateSwapchainImages(); CreateSwapchainImages();
@ -135,10 +137,11 @@ internal class VulkanDisplay : IDisposable
_swapchain = default; _swapchain = default;
} }
internal static VulkanDisplay CreateDisplay(IVulkanPlatformGraphicsContext context, VulkanKhrSurface surface) internal static VulkanDisplay CreateDisplay(IVulkanPlatformGraphicsContext context, IVulkanKhrSurfacePlatformSurface surface)
{ {
var swapchain = CreateSwapchain(context, surface, out var extent); var khrSurface = new VulkanKhrSurface(context, surface);
return new VulkanDisplay(context, surface, swapchain, extent); var swapchain = CreateSwapchain(context, khrSurface, out var extent);
return new VulkanDisplay(context, khrSurface, swapchain, extent, surface);
} }
private void DestroyCurrentImageViews() private void DestroyCurrentImageViews()
@ -188,19 +191,27 @@ internal class VulkanDisplay : IDisposable
return imageView; return imageView;
} }
private void Recreate() private void RecreateSwapchain()
{ {
_context.DeviceApi.DeviceWaitIdle(_context.DeviceHandle); _context.DeviceApi.DeviceWaitIdle(_context.DeviceHandle);
_swapchain = CreateSwapchain(_context, _surface, out var extent, this); _swapchain = CreateSwapchain(_context, _surface, out var extent, this);
_swapchainExtent = extent; _swapchainExtent = extent;
CreateSwapchainImages(); CreateSwapchainImages();
} }
private void RecreateSurface()
{
_surface?.Dispose();
_surface = new VulkanKhrSurface(_context, _platformSurface);
DestroySwapchain();
RecreateSwapchain();
}
public bool EnsureSwapchainAvailable() public bool EnsureSwapchainAvailable()
{ {
if (Size != _surface.Size) if (Size != _surface.Size)
{ {
Recreate(); RecreateSwapchain();
return true; return true;
} }
return false; return false;
@ -218,7 +229,9 @@ internal class VulkanDisplay : IDisposable
_semaphorePair.ImageAvailableSemaphore.Handle, _semaphorePair.ImageAvailableSemaphore.Handle,
default, out _nextImage); default, out _nextImage);
if (acquireResult is VkResult.VK_ERROR_OUT_OF_DATE_KHR or VkResult.VK_SUBOPTIMAL_KHR) if (acquireResult is VkResult.VK_ERROR_OUT_OF_DATE_KHR or VkResult.VK_SUBOPTIMAL_KHR)
Recreate(); RecreateSwapchain();
else if (acquireResult is VkResult.VK_ERROR_SURFACE_LOST_KHR)
RecreateSurface();
else else
{ {
acquireResult.ThrowOnError("vkAcquireNextImageKHR"); acquireResult.ThrowOnError("vkAcquireNextImageKHR");
@ -323,6 +336,8 @@ internal class VulkanDisplay : IDisposable
DestroySwapchain(); DestroySwapchain();
CommandBufferPool?.Dispose(); CommandBufferPool?.Dispose();
CommandBufferPool = null!; CommandBufferPool = null!;
_surface?.Dispose();
_surface = null!;
} }
} }

8
src/Avalonia.Vulkan/VulkanKhrSurfaceRenderTarget.cs

@ -7,7 +7,6 @@ namespace Avalonia.Vulkan;
internal class VulkanKhrRenderTarget : IVulkanRenderTarget internal class VulkanKhrRenderTarget : IVulkanRenderTarget
{ {
private VulkanKhrSurface _khrSurface;
private readonly IVulkanPlatformGraphicsContext _context; private readonly IVulkanPlatformGraphicsContext _context;
private VulkanDisplay _display; private VulkanDisplay _display;
private VulkanImage? _image; private VulkanImage? _image;
@ -18,8 +17,7 @@ internal class VulkanKhrRenderTarget : IVulkanRenderTarget
public VulkanKhrRenderTarget(IVulkanKhrSurfacePlatformSurface surface, IVulkanPlatformGraphicsContext context) public VulkanKhrRenderTarget(IVulkanKhrSurfacePlatformSurface surface, IVulkanPlatformGraphicsContext context)
{ {
_platformSurface = surface; _platformSurface = surface;
_khrSurface = new(context, surface); _display = VulkanDisplay.CreateDisplay(context, surface);
_display = VulkanDisplay.CreateDisplay(context, _khrSurface);
_context = context; _context = context;
IsRgba = _display.SurfaceFormat.format >= VkFormat.VK_FORMAT_R8G8B8A8_UNORM && IsRgba = _display.SurfaceFormat.format >= VkFormat.VK_FORMAT_R8G8B8A8_UNORM &&
_display.SurfaceFormat.format <= VkFormat.VK_FORMAT_R8G8B8A8_SRGB; _display.SurfaceFormat.format <= VkFormat.VK_FORMAT_R8G8B8A8_SRGB;
@ -46,8 +44,6 @@ internal class VulkanKhrRenderTarget : IVulkanRenderTarget
DestroyImage(); DestroyImage();
_display?.Dispose(); _display?.Dispose();
_display = null!; _display = null!;
_khrSurface?.Dispose();
_khrSurface = null!;
} }
@ -104,4 +100,4 @@ internal class VulkanKhrRenderTarget : IVulkanRenderTarget
} }
} }
} }
} }

Loading…
Cancel
Save