-
Task
-
Resolution: Won't Do
-
P3: Somewhat important
-
None
-
None
-
None
This task is intended to document the issues surrounding the possible addition of hardware acceleration to Chromium when using Direct3D 12 as the RHI backend in a Qt application.
On Windows, all rendering is done via the ANGLE graphics layer, which supports rendering via Direct3D 11 only. We want to be able to have hardware-accelerated rendering in Chromium, and then take the rendered texture and pass it forward to the Direct3D 12 RHI backend. Unfortunately, there seems to be no API support at all for accessing resources created in a Direct3D 11 device through a Direct3D 12 device; only the opposite path is supported. Currently, in such a case we simply default Chromium to software rendering.
A partial solution does exist, however: a translation layer called D3D11On12. Instead of providing real interoperability, this layer creates a fake Direct3D 11 device which translates (most) calls to Direct3D 12 equivalents. As per its documentation, this comes at the cost of some increased CPU usage and a large memory footprint. Chromium/ANGLE experimentally supports this layer, and an attempt at hooking that functionality up to WebEngine was succesful: https://codereview.qt-project.org/c/qt/qtwebengine/+/540908 Unfortunately, this causes a driver crash whenever a video is played; the issue occurs both in WebEngine, as well as in upstream Chromium (though curiously, it does not in Chrome itself). Thus, this is a viable solution only in case the upstream issue is ever fixed; and even then, it'd need to be benchmarked to make sure the added overhead isn't more costly than just doing software rendering.
However, it is not impossible to have proper texture sharing between Direct3D versions, we only need to make the necessary adjustments to ensure that it's the Direct3D 12 device that creates them. From my understanding of the code, the gist of what needs to be done is the following:
- gpu::SharedContextState needs to be provided with the Direct3D 12 device as well as the Direct3D 11 one; an appropriate accessor needs to be added as well
- gpu::D3DImageBackingFactory (or better, a subclass), needs to be made aware of both devices as well
- gpu::D3DImageBackingFactory::CreateSharedImage() needs to be modified to check for the presence of both devices. If it detects a Direct3D 12 one, it needs to make sure it is used to called CreateSharedHandle(); otherwise, the normal logic should apply
The outline above should be doable, but it still requires some heavy-handed changes to Chromium code which could be a pain to support going forward.