csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
86 lines
3.3 KiB
86 lines
3.3 KiB
using System;
|
|
using System.Runtime.InteropServices;
|
|
using Avalonia.Platform;
|
|
using Silk.NET.Vulkan;
|
|
using Silk.NET.Vulkan.Extensions.KHR;
|
|
using SilkNetDemo;
|
|
|
|
namespace GpuInterop.VulkanDemo;
|
|
|
|
class VulkanSemaphorePair : IDisposable
|
|
{
|
|
private readonly VulkanContext _resources;
|
|
|
|
public unsafe VulkanSemaphorePair(VulkanContext resources, bool exportable)
|
|
{
|
|
_resources = resources;
|
|
|
|
var semaphoreExportInfo = new ExportSemaphoreCreateInfo
|
|
{
|
|
SType = StructureType.ExportSemaphoreCreateInfo,
|
|
HandleTypes = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
|
|
ExternalSemaphoreHandleTypeFlags.OpaqueWin32Bit :
|
|
ExternalSemaphoreHandleTypeFlags.OpaqueFDBit
|
|
};
|
|
|
|
var semaphoreCreateInfo = new SemaphoreCreateInfo
|
|
{
|
|
SType = StructureType.SemaphoreCreateInfo,
|
|
PNext = exportable ? &semaphoreExportInfo : null
|
|
};
|
|
|
|
resources.Api.CreateSemaphore(resources.Device, semaphoreCreateInfo, null, out var semaphore).ThrowOnError();
|
|
ImageAvailableSemaphore = semaphore;
|
|
|
|
resources.Api.CreateSemaphore(resources.Device, semaphoreCreateInfo, null, out semaphore).ThrowOnError();
|
|
RenderFinishedSemaphore = semaphore;
|
|
}
|
|
|
|
public int ExportFd(bool renderFinished)
|
|
{
|
|
if (!_resources.Api.TryGetDeviceExtension<KhrExternalSemaphoreFd>(_resources.Instance, _resources.Device,
|
|
out var ext))
|
|
throw new InvalidOperationException();
|
|
var info = new SemaphoreGetFdInfoKHR()
|
|
{
|
|
SType = StructureType.SemaphoreGetFDInfoKhr,
|
|
Semaphore = renderFinished ? RenderFinishedSemaphore : ImageAvailableSemaphore,
|
|
HandleType = ExternalSemaphoreHandleTypeFlags.OpaqueFDBit
|
|
};
|
|
ext.GetSemaphoreF(_resources.Device, info, out var fd).ThrowOnError();
|
|
return fd;
|
|
}
|
|
|
|
public IntPtr ExportWin32(bool renderFinished)
|
|
{
|
|
if (!_resources.Api.TryGetDeviceExtension<KhrExternalSemaphoreWin32>(_resources.Instance, _resources.Device,
|
|
out var ext))
|
|
throw new InvalidOperationException();
|
|
var info = new SemaphoreGetWin32HandleInfoKHR()
|
|
{
|
|
SType = StructureType.SemaphoreGetWin32HandleInfoKhr,
|
|
Semaphore = renderFinished ? RenderFinishedSemaphore : ImageAvailableSemaphore,
|
|
HandleType = ExternalSemaphoreHandleTypeFlags.OpaqueWin32Bit
|
|
};
|
|
ext.GetSemaphoreWin32Handle(_resources.Device, info, out var fd).ThrowOnError();
|
|
return fd;
|
|
}
|
|
|
|
public IPlatformHandle Export(bool renderFinished)
|
|
{
|
|
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
|
return new PlatformHandle(ExportWin32(renderFinished),
|
|
KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaqueNtHandle);
|
|
return new PlatformHandle(new IntPtr(ExportFd(renderFinished)),
|
|
KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor);
|
|
}
|
|
|
|
internal Semaphore ImageAvailableSemaphore { get; }
|
|
internal Semaphore RenderFinishedSemaphore { get; }
|
|
|
|
public unsafe void Dispose()
|
|
{
|
|
_resources.Api.DestroySemaphore(_resources.Device, ImageAvailableSemaphore, null);
|
|
_resources.Api.DestroySemaphore(_resources.Device, RenderFinishedSemaphore, null);
|
|
}
|
|
}
|
|
|