зеркало из https://github.com/AvaloniaUI/Avalonia.git
Use NT shared handles for Vulkan interop on Windows
This commit is contained in:
Родитель
dbeea393d6
Коммит
fc0ddcb320
|
@ -47,7 +47,7 @@ public class D3DMemoryHelper
|
|||
MipLevels = 1,
|
||||
SampleDescription = new SampleDescription { Count = 1, Quality = 0 },
|
||||
CpuAccessFlags = default,
|
||||
OptionFlags = ResourceOptionFlags.SharedKeyedmutex,
|
||||
OptionFlags = ResourceOptionFlags.SharedKeyedmutex|ResourceOptionFlags.SharedNthandle,
|
||||
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource
|
||||
});
|
||||
}
|
||||
|
|
|
@ -173,7 +173,7 @@ public unsafe class VulkanContext : IDisposable
|
|||
api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyCount, familyProperties);
|
||||
for (uint queueFamilyIndex = 0; queueFamilyIndex < queueFamilyCount; queueFamilyIndex++)
|
||||
{
|
||||
var family = familyProperties[c];
|
||||
var family = familyProperties[queueFamilyIndex];
|
||||
if (!family.QueueFlags.HasAllFlags(QueueFlags.GraphicsBit))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -4,10 +4,13 @@ using System.Runtime.InteropServices;
|
|||
using Avalonia;
|
||||
using Avalonia.Platform;
|
||||
using Avalonia.Vulkan;
|
||||
using SharpDX.DXGI;
|
||||
using Silk.NET.Vulkan;
|
||||
using Silk.NET.Vulkan.Extensions.KHR;
|
||||
using SilkNetDemo;
|
||||
using SkiaSharp;
|
||||
using Device = Silk.NET.Vulkan.Device;
|
||||
using Format = Silk.NET.Vulkan.Format;
|
||||
|
||||
namespace GpuInterop.VulkanDemo;
|
||||
|
||||
|
@ -24,7 +27,6 @@ public unsafe class VulkanImage : IDisposable
|
|||
private ImageView? _imageView { get; set; }
|
||||
private DeviceMemory _imageMemory { get; set; }
|
||||
private SharpDX.Direct3D11.Texture2D? _d3dTexture2D;
|
||||
private IntPtr _win32ShareHandle;
|
||||
|
||||
internal Image? InternalHandle { get; private set; }
|
||||
internal Format Format { get; }
|
||||
|
@ -108,14 +110,14 @@ public unsafe class VulkanImage : IDisposable
|
|||
if (exportable && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
_d3dTexture2D = D3DMemoryHelper.CreateMemoryHandle(vk.D3DDevice, size, Format);
|
||||
using var dxgi = _d3dTexture2D.QueryInterface<SharpDX.DXGI.Resource>();
|
||||
_win32ShareHandle = dxgi.SharedHandle;
|
||||
using var dxgi = _d3dTexture2D.QueryInterface<SharpDX.DXGI.Resource1>();
|
||||
|
||||
handleImport = new ImportMemoryWin32HandleInfoKHR
|
||||
{
|
||||
PNext = &dedicatedAllocation,
|
||||
SType = StructureType.ImportMemoryWin32HandleInfoKhr,
|
||||
HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit,
|
||||
Handle = _win32ShareHandle,
|
||||
HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureBit,
|
||||
Handle = dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -185,11 +187,19 @@ public unsafe class VulkanImage : IDisposable
|
|||
return fd;
|
||||
}
|
||||
|
||||
public IPlatformHandle Export() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
|
||||
new PlatformHandle(_win32ShareHandle,
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle) :
|
||||
new PlatformHandle(new IntPtr(ExportFd()),
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor);
|
||||
public IPlatformHandle Export()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
using var dxgi = _d3dTexture2D!.QueryInterface<Resource1>();
|
||||
return new PlatformHandle(
|
||||
dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write),
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle);
|
||||
}
|
||||
else
|
||||
return new PlatformHandle(new IntPtr(ExportFd()),
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor);
|
||||
}
|
||||
|
||||
public ImageTiling Tiling => ImageTiling.Optimal;
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
@clr-map DXGI_SHARED_RESOURCE void*
|
||||
@clr-map LUID ulong
|
||||
@clr-map LPSTR ushort*
|
||||
@clr-map LPWSTR ushort*
|
||||
@clr-map LPCWSTR ushort*
|
||||
|
||||
|
||||
enum DXGI_FORMAT
|
||||
|
@ -501,6 +503,44 @@ interface ID3D11Device : IUnknown
|
|||
UINT GetExceptionMode();
|
||||
}
|
||||
|
||||
[uuid(a04bfb29-08ef-43d6-a49c-a9bdbdcbe686)]
|
||||
interface ID3D11Device1 : ID3D11Device
|
||||
{
|
||||
void GetImmediateContext1( void** ppImmediateContext );
|
||||
|
||||
HRESULT CreateDeferredContext1(
|
||||
UINT ContextFlags, // Reserved parameter; must be 0
|
||||
[out, retval] IUnknown** ppDeferredContext );
|
||||
|
||||
HRESULT CreateBlendState1(
|
||||
void* pBlendStateDesc,
|
||||
[out, retval] IUnknown** ppBlendState );
|
||||
|
||||
HRESULT CreateRasterizerState1(
|
||||
void* pRasterizerDesc,
|
||||
[out, retval] IUnknown** ppRasterizerState );
|
||||
|
||||
HRESULT CreateDeviceContextState(
|
||||
UINT Flags,
|
||||
void* pFeatureLevels,
|
||||
UINT FeatureLevels,
|
||||
UINT SDKVersion,
|
||||
GUID* EmulatedInterface,
|
||||
void* pChosenFeatureLevel,
|
||||
[out, retval] IUnknown** ppContextState);
|
||||
|
||||
HRESULT OpenSharedResource1(
|
||||
IntPtr hResource,
|
||||
Guid* ReturnedInterface,
|
||||
[out, retval] IUnknown** ppResource);
|
||||
|
||||
HRESULT OpenSharedResourceByName(
|
||||
LPCWSTR lpName,
|
||||
DWORD dwDesiredAccess,
|
||||
REFIID returnedInterface,
|
||||
void** ppResource);
|
||||
};
|
||||
|
||||
|
||||
[uuid( 6f15aaf2-d208-4e89-9ab4-489535d34f9c)]
|
||||
interface ID3D11Texture2D : IUnknown
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Avalonia.Controls.Documents;
|
||||
using Avalonia.OpenGL;
|
||||
|
@ -15,12 +16,14 @@ internal class AngleExternalObjectsFeature : IGlContextExternalObjectsFeature, I
|
|||
{
|
||||
private readonly EglContext _context;
|
||||
private readonly ID3D11Device _device;
|
||||
private readonly ID3D11Device1 _device1;
|
||||
|
||||
public AngleExternalObjectsFeature(EglContext context)
|
||||
{
|
||||
_context = context;
|
||||
var angle = (AngleWin32EglDisplay)context.Display;
|
||||
_device = MicroComRuntime.CreateProxyFor<ID3D11Device>(angle.GetDirect3DDevice(), false).CloneReference();
|
||||
_device1 = _device.QueryInterface<ID3D11Device1>();
|
||||
using var dxgiDevice = _device.QueryInterface<IDXGIDevice>();
|
||||
using var adapter = dxgiDevice.Adapter;
|
||||
DeviceLuid = BitConverter.GetBytes(adapter.Desc.AdapterLuid);
|
||||
|
@ -28,7 +31,8 @@ internal class AngleExternalObjectsFeature : IGlContextExternalObjectsFeature, I
|
|||
|
||||
public IReadOnlyList<string> SupportedImportableExternalImageTypes { get; } = new[]
|
||||
{
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle,
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle,
|
||||
};
|
||||
|
||||
public IReadOnlyList<string> SupportedExportableExternalImageTypes => SupportedImportableExternalImageTypes;
|
||||
|
@ -72,13 +76,17 @@ internal class AngleExternalObjectsFeature : IGlContextExternalObjectsFeature, I
|
|||
|
||||
public unsafe IGlExternalImageTexture ImportImage(IPlatformHandle handle, PlatformGraphicsExternalImageProperties properties)
|
||||
{
|
||||
if (handle.HandleDescriptor != KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle)
|
||||
if (!SupportedImportableExternalImageTypes.Contains(handle.HandleDescriptor))
|
||||
throw new NotSupportedException("Unsupported external memory type");
|
||||
|
||||
using (_context.EnsureCurrent())
|
||||
{
|
||||
var guid = MicroComRuntime.GetGuidFor(typeof(ID3D11Texture2D));
|
||||
using var opened = _device.OpenSharedResource(handle.Handle, &guid);
|
||||
using var opened =
|
||||
handle.HandleDescriptor ==
|
||||
KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle ?
|
||||
_device.OpenSharedResource(handle.Handle, &guid) :
|
||||
_device1.OpenSharedResource1(handle.Handle, &guid);
|
||||
using var texture = opened.QueryInterface<ID3D11Texture2D>();
|
||||
return new AngleExternalMemoryD3D11Texture2D(_context, texture, properties);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче