Swift and Direct2D

I have worked with Swift in Xcode for a couple of years now. I deeply enjoyed the language experience and so turned my attention toward Swift on Windows. I recently started investigating Direct2D and Swift. I attempted to follow this tutorial from MSDN using the Swift 5.10.1 Windows toolchain. However, I was unable to get very far due to certain APIs being unavailable, namely the D2D1CreateFactory function. My understanding is that this API is exposed to C++, but not to C.

I tried the Direct3D demo linked in this thread which worked fantastically (thanks @compnerd!). This makes me wonder why Direct2D support seems to be lacking.

As someone just getting their feet wet in the world of DirectX and Windows COM, I have struggled to find a workaround. Has anyone here found a solution?

1 Like

I would need to look at the API surface, but if the D2D API is like the D3D APIs and require COM, we will need to create the Swift interfaces for the COM types to expose them and to be able to use them. The C++ interop approach is possible to use, but that might have some additional complexity as I've not yet tried the C++ interop for the DX APIs. This would certainly be an interesting exploration and could possibly be an avenue to contribute to the ongoing C++ interop work as well!

@compnerd Thank you for that information.

Could creating these Swift interfaces be done with a Swift wrapper, or would it require a modification of the Windows Swift toolchain?

I tried enabling C++ interoperability, but I then could not access the Release() method of the OpenFileDialog component (see screenshot).

The Swift interfaces would be manual wrapping in Swift code (see GitHub - compnerd/DXSample: Sample Program for DirectX 12 + Swift for how I wrapped the D3D interfaces). The virtual method dispatch in C++ interop mode would require that you manually write some thunks in C++ to bridge those as the virtual dispatch is not yet available.

This may be a result my misunderstanding of Direct2D, but I am not certain how I can wrap the D2D interfaces. I do not appear to have access to the D2D interfaces. For example, there are a number of Direct3D APIs available such as WinSDK.ID3D12Resource. However, there does not seem to be any of the ID2D- APIs available. For example, I would expect to be able to access WinSDK.ID2D1Resource (see this MSDN page). However, it is unavailable.

Based upon the comments in this Stack Overflow post, it appears that Direct2D is missing proper C support. Can you think of any way around that, or is using thunks in C++ the only way forward?

Thanks for your assistance @compnerd!

It is possible that we are missing the module definition for the D2D interfaces. You would need to help get that modularised (see swift/stdlib/public/Platform/winsdk.modulemap at main · swiftlang/swift · GitHub). Once that is modularised properly, import WinSDK should expose the declarations to Swift allowing the Swift bindings similar to D3D. The modularisation can require C++, which would only expose the interfaces when C++ interop is enabled. As an example the XAudio APIs are only available with C++ interop enabled.

@compnerd Thank you for that info. This gives me a potential starting point.