I am trying to follow Microsoft's official tutorial for DirectX and XAML interop in order to make a C++ runtime library for image primitive drawing for a UWP application. However, the code is riddled with bugs and typos. I have managed to adapt portions of it, but I am getting runtime errors.
I have adapted the code as follows.
Microsoft::WRL::ComPtr<ISurfaceImageSourceNativeWithD2D> m_sisNativeWithD2D;
IInspectable* sisInspectable = (IInspectable*) reinterpret_cast<IInspectable*>(surfaceImageSource);
sisInspectable->QueryInterface(__uuidof(ISurfaceImageSourceNativeWithD2D), (void **)&m_sisNativeWithD2D);
Microsoft::WRL::ComPtr<ID3D11Device> m_d3dDevice;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_d3dContext;
Microsoft::WRL::ComPtr<ID2D1Device> m_d2dDevice;
// Create the DXGI device
D3D11CreateDevice(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
0,
NULL,
NULL,
D3D11_SDK_VERSION,
&m_d3dDevice,
NULL,
&m_d3dContext);
Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
m_d3dDevice.As(&dxgiDevice);
// To enable multi-threaded access (optional)
Microsoft::WRL::ComPtr<ID3D10Multithread> d3dMultiThread;
m_d3dDevice->QueryInterface(__uuidof(ID3D10Multithread), (void **)&d3dMultiThread);
d3dMultiThread->SetMultithreadProtected(TRUE);
// Create the D2D device
HRESULT d2d1 = D2D1CreateDevice(dxgiDevice.Get(), NULL, &m_d2dDevice);
While debugging the code, I can see that the d2d1
handle is returning E_INVALIDARG
. I tried passing device properties instead of NULL
and disabling multi-threaded access, but the error persists. Objects before this line seem to be correctly initialized.
What could be causing this behavior?
Edit
VTT's comment helped in constructing the device, but it seems that the device is not appropriate. My adapted code is as follows.
Microsoft::WRL::ComPtr<ISurfaceImageSourceNativeWithD2D> m_sisNativeWithD2D;
IInspectable* sisInspectable = (IInspectable*) reinterpret_cast<IInspectable*>(surfaceImageSource);
sisInspectable->QueryInterface(__uuidof(ISurfaceImageSourceNativeWithD2D), (void **)&m_sisNativeWithD2D);
Microsoft::WRL::ComPtr<ID3D11Device> m_d3dDevice;
Microsoft::WRL::ComPtr<ID3D11DeviceContext> m_d3dContext;
Microsoft::WRL::ComPtr<ID2D1Device> m_d2dDevice;
D3D_FEATURE_LEVEL array[] = {
D3D_FEATURE_LEVEL_11_1,
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1,
};
D3D_FEATURE_LEVEL selectedFeatureLevel;
// Create the DXGI device
D3D11CreateDevice(
NULL,
D3D_DRIVER_TYPE_HARDWARE,
NULL,
D3D11_CREATE_DEVICE_BGRA_SUPPORT,
array,
sizeof(array)/sizeof(D3D_FEATURE_LEVEL),
D3D11_SDK_VERSION,
&m_d3dDevice,
&selectedFeatureLevel,
&m_d3dContext);
//Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
//m_d3dDevice.As(&dxgiDevice);
Microsoft::WRL::ComPtr<IDXGIDevice> dxgiDevice;
auto hr = m_d3dDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
// To enable multi-threaded access (optional)
Microsoft::WRL::ComPtr<ID3D10Multithread> d3dMultiThread;
m_d3dDevice->QueryInterface(__uuidof(ID3D10Multithread), (void **)&d3dMultiThread);
d3dMultiThread->SetMultithreadProtected(TRUE);
// Create the D2D device
HRESULT d2d1 = D2D1CreateDevice(dxgiDevice.Get(), NULL, &m_d2dDevice);
// Set the D2D device
m_sisNativeWithD2D->SetDevice(m_d2dDevice.Get());
Microsoft::WRL::ComPtr<ID2D1DeviceContext> drawingContext;
RECT rect;
rect.top = 0;
rect.left = 0;
rect.right = 50;
rect.bottom = 50;
POINT offset;
HRESULT beginDrawHR = m_sisNativeWithD2D->BeginDraw(rect, __uuidof(ID2D1DeviceContext), &drawingContext, &offset);
However, here the BeginDraw()
method fails with E_INVALIDARG
. I am assuming it is because of the incorrect device construction.