Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

How to render into DirectX context using Vulkan

License

NotificationsYou must be signed in to change notification settings

jack-day/vulkan-interop-directx

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

This repo demonstrates interop between Vulkan and DirectX via embedding the former into WinUI 3 and WPF usingVK_KHR_external_memory_win32 extension. It's basically follows greatAlexander Overvoorde's tutorial for creating resources, but excludes swapchain infrastructure and creates a framebuffer using a shared Direct3D 11 texture.

Whether you are using your own or third party abstractions - it should be easy to adapt the code for use.

The example is written naively, step by step - seeVulkanInterop.Initialize andWindow code behind.

Silk.NET - bindings used for DirectX and Vulkan calls.

Damaged Helmet - model used as an example.SharpGLTF - loader used to read the model.

vulkan-interop-directx.mp4

Interop process

We need to

1. Prepare the back buffer texture

In case of WinUI - create a DXGI swapchain, get the texture and set the swapchain to the WinUI SwapChainPanel.

varswapchainDescription=newSwapChainDesc1{    ...Width=width,Height=height,Format=Format.FormatR8G8B8A8Unorm,SwapEffect=SwapEffect.FlipSequential,SampleDesc=newSampleDesc(1u,0u),BufferUsage=DXGI.UsageBackBuffer};ThrowHResult(dxgiFactory.CreateSwapChainForComposition(dxgiDevice,swapchainDescription,default(ComPtr<IDXGIOutput>),refswapchain));backbufferTexture=swapchain.GetBuffer<ID3D11Texture2D>(0u);target.As<ISwapChainPanelNative>().SetSwapChain(swapchain);

In case of WPF - create a D3D9 texture and get the surface that will be used with WPF D3DImage.

void*d3d9shared=null;ThrowHResult(d3d9device.CreateTexture(width,height,1u,D3D9.UsageRendertarget,Silk.NET.Direct3D9.Format.X8R8G8B8,Pool.Default,refbackbufferTexture,refd3d9shared));ThrowHResult(backbufferTexture.GetSurfaceLevel(0u,refsurface));

2. Create a render target D3D11 texture in shared mode

In case of WinUI - this is regular D3D11 texture.

varrenderTargetDescription=newTexture2DDesc{    ...Width=width,Height=height,BindFlags=(uint)BindFlag.RenderTarget,MiscFlags=(uint)ResourceMiscFlag.Shared};ThrowHResult(d3d11device.CreateTexture2D(renderTargetDescription,null,refrenderTargetTexture));

With WinUI we also need to query both back buffer and render target textures to D3D11 resources for future copy operations.

backbufferResource=backbufferTexture.QueryInterface<ID3D11Resource>();renderTargetResource=renderTargetTexture.QueryInterface<ID3D11Resource>();

In case of WPF, we get the texture using shared handle of the D3D9 texture we created earlier.

renderTargetTexture=d3d11device.OpenSharedResource<ID3D11Texture2D>(d3d9shared);

3. Query D3D11 render target texture to the DXGI resource and get a shared handle

void*handle;varresource=renderTargetTexture.QueryInterface<IDXGIResource>();ThrowHResult(resource.GetSharedHandle(&handle));resource.Dispose();renderTargetSharedHandle=(nint)handle;

4. On the Vulkan side - create an image using the previously obtained shared handle

Then create the view and framebuffer - seeVulkanInterop.CreateImageViews.

varexternalMemoryImageInfo=newExternalMemoryImageCreateInfo(handleTypes:ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit);varimageInfo=newImageCreateInfo(    ...format: targetFormat,usage:ImageUsageFlags.ColorAttachmentBit,pNext:&externalMemoryImageInfo);varimportMemoryInfo=newImportMemoryWin32HandleInfoKHR(handleType:ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit,handle:renderTargetSharedHandle);vk.CreateImage(device,imageInfo,null,outdirectImage).Check();

Note that D3D9X8R8G8B8 texture format map to VulkanB8G8R8A8Unorm

5. Once the framebuffer is created, we are ready to interop

With WinUI we need to call Direct3D 11 to copy data from the render target to the back buffer and present it.

// *rendering*d3d11context.CopyResource(backbufferResource,renderTargetResource);ThrowHResult(swapchain.Present(0u,(uint)SwapChainFlag.None));

With WPF we only need to set the D3D9 surface to the D3DImage, because the back buffer already contains the rendered image.

d3dImage.Lock();// *rendering*d3dImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9,(nint)d3d9surface.Handle);d3dImage.AddDirtyRect(newInt32Rect(0,0,d3dImage.PixelWidth,d3dImage.PixelHeight));d3dImage.Unlock();

Prerequisites and build

The example isdotnet build ready.

About

How to render into DirectX context using Vulkan

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C#98.7%
  • GLSL1.3%

[8]ページ先頭

©2009-2025 Movatter.jp