I am receiving IDirect3DSurface
s from a FrameReader and wish to render them to a SwapChain in a WinUI3 desktop app.
I have followed DirectX and XAML interop to implement the SwapChain, including this fix.
My research suggests I need to create a Bitmap from the surface returned from the frame and use Direct2D to render that bitmap on the SwapChain back-buffer. Here is the code with the two approaches I have tried, selected via preprocessor for the moment.
winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DSurface surface =
frameRef.VideoMediaFrame().Direct3DSurface();
winrt::com_ptr<::Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess> dxgiInterfaceAccess{
surface.as<::Windows::Graphics::DirectX::Direct3D11::IDirect3DDxgiInterfaceAccess>()
};
winrt::com_ptr<::IDXGISurface> nativeSurface;
winrt::check_hresult(
dxgiInterfaceAccess->GetInterface(__uuidof(nativeSurface), nativeSurface.put_void())
);
#if 0
winrt::com_ptr<::ID2D1Bitmap> frameBitmap;
winrt::check_hresult(
d2dDeviceContext->CreateSharedBitmap(
__uuidof(nativeSurface),
nativeSurface.get(),
nullptr,
frameBitmap.put())
);
#else
winrt::com_ptr<::ID2D1Bitmap1> frameBitmap;
winrt::check_hresult(
d2dDeviceContext->CreateBitmapFromDxgiSurface(
nativeSurface.get(),
nullptr,
frameBitmap.put()
)
);
#endif
// Both approaches fail before getting here!
winrt::com_ptr<::IDXGISurface> dxgiBackBuffer;
swapChain->GetBuffer(0, __uuidof(dxgiBackBuffer), dxgiBackBuffer.put_void());
winrt::com_ptr<::ID2D1Bitmap1> targetBitmap;
winrt::check_hresult(
d2dDeviceContext->CreateBitmapFromDxgiSurface(
dxgiBackBuffer.get(),
nullptr,
targetBitmap.put()
)
);
d2dDeviceContext->SetTarget(targetBitmap.get());
d2dDeviceContext->BeginDraw();
d2dDeviceContext->DrawBitmap(frameBitmap.get());
d2dDeviceContext->EndDraw();
Both most often fail with "pixel format not supported". As per the guide, the d3dDevice
is created with D3D11_CREATE_DEVICE_BGRA_SUPPORT
. I have tried creating the frame reader with MediaEncodingSubtypes::Bgra8()
as well as testing many other formats with no luck.
As a final note, the second approach sometimes fails with "0x88990003 : The requested operation is not supported." for certain MediaEncodingSubtypes
, for example Argb32.