Reputation: 493
I created following class and set it as content of the MainWindow.
public class DXControl : Control{
static IDXGIFactory7 DXGIFactory = DXGI.CreateDXGIFactory1<IDXGIFactory7>();
static ID2D1Factory D2D1Factory = D2D1.D2D1CreateFactory<ID2D1Factory>();
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) {
int imageWidth = 1024;
int imageHeight = 1024;
ID3D11Device3 d3d11Device = D3D11.D3D11CreateDevice(DriverType.Hardware, DeviceCreationFlags.BgraSupport, Vortice.Direct3D.FeatureLevel.Level_11_1).QueryInterface<ID3D11Device3>();
ID3D11Texture2D texture = d3d11Device.CreateTexture2D1(new() {
Format = Format.R8G8B8A8_UNorm,
Width = (uint)imageWidth,
Height = (uint)imageHeight,
ArraySize = 1,
MipLevels = 1,
SampleDescription = SampleDescription.Default,
BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
Usage = ResourceUsage.Default,
CPUAccessFlags = CpuAccessFlags.None,
MiscFlags = ResourceOptionFlags.SharedNTHandle | ResourceOptionFlags.SharedKeyedMutex,
TextureLayout = TextureLayout.Undefined
});
IDXGIDevice dxgiDevice = d3d11Device.QueryInterface<IDXGIDevice>();
ID2D1RenderTarget renderTarget = D2D1Factory.CreateDxgiSurfaceRenderTarget(
texture.QueryInterface<IDXGISurface>(),
new() {
Type = RenderTargetType.Hardware,
PixelFormat = new(Format.Unknown, Vortice.DCommon.AlphaMode.Ignore),
Usage = RenderTargetUsage.None,
MinLevel = Vortice.Direct2D1.FeatureLevel.Default,
DpiX = 0,
DpiY = 0
}
);
renderTarget.BeginDraw();
renderTarget.Clear(new(0xFF0000FF));
renderTarget.EndDraw();
IDXGIResource1 dxgiResource1 = texture.QueryInterface<IDXGIResource1>();
IntPtr ptr = dxgiResource1.CreateSharedHandle(null, Vortice.DXGI.SharedResourceFlags.Read, null);
PlatformHandle platformHandle = new(ptr, KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle);
Compositor compositor = ElementComposition.GetElementVisual(this)!.Compositor;
var task = compositor.TryGetCompositionGpuInterop();
ICompositionGpuInterop? gpuInterop = task.Result;
if (gpuInterop is null) return;
ICompositionImportedGpuImage importedImage = gpuInterop.ImportImage(
platformHandle,
new() {
Format = PlatformGraphicsExternalImageFormat.R8G8B8A8UNorm,
Width = imageWidth,
Height = imageHeight,
MemoryOffset = 0,
MemorySize = (ulong)(imageWidth * imageHeight * sizeof(uint)),
TopLeftOrigin = true
}
);
CompositionSurfaceVisual visual = compositor.CreateSurfaceVisual();
visual.Size = new(Bounds.Width, Bounds.Height);
CompositionDrawingSurface compositionDrawingSurface = compositor.CreateDrawingSurface();
visual.Surface = compositionDrawingSurface;
compositionDrawingSurface.UpdateAsync(importedImage).ContinueWith(task => Debug.WriteLine("Update Completed"));
ElementComposition.SetElementChildVisual(this, visual);
}
}
The window can startup without any exception. However, the texture which was fill with red color wasn't present. I checked the example provided in https://github.com/AvaloniaUI/Avalonia/tree/master/samples/GpuInterop/D3DDemo and I cannot figure out where is problem of my code.
Upvotes: 0
Views: 54