mosra / magnum

Lightweight and modular C++11 graphics middleware for games and data visualization
https://magnum.graphics/
Other
4.76k stars 438 forks source link

DirectX 12 backend #262

Closed TheAifam5 closed 3 years ago

TheAifam5 commented 6 years ago

Hey,

What do you think about it, to add the support for DirectX from version 9 to 12 (especially DX 12).

Regards, TheAifam5

mosra commented 6 years ago

Hi,

as far as I see it now, starting support for DirectX < 12 is not worth doing anymore. There's OpenGL and/or ANGLE that can cover all features DirectX 9/10/11 has.

For DirectX 12, this is together with Vulkan and Metal on the roadmap, right after animation support (#191). Vulkan would be the first iteration (because there are already compatibility layers that can translate it to Metal and DX12), the others might come later. Searching for funding :)

mosra commented 3 years ago

Because there's always more things to do than there's time, I have decided to not invest into APIs that are available only on a single platform, thus Metal (#254) and D3D is currently out of question. The time will be spent on Vulkan and WebGPU instead.

alanjfs commented 2 years ago

Hello! I'm investigating Magnum for a mixed OpenGL/DirectX project and stumbled upon this issue. Perfectly understandable that one must pick their battles, YOLO and all that. But if one really liked Magnum and wanted to use it with DirectX, what would such a person be up against if he was to tackle this burden himself? Like, is it a complete rewrite of Magnum, not-worth-it it kind of deal, or is there some layer missing that one could "easily" fill in? Like implementing a new backend for ImGui, say. Where would one begin, so as to try and build some intuition for the amount of work that would lie ahead?

EDIT: Oh and I should add, this involves DirectX 11 specifically. :S

mosra commented 2 years ago

Oh, hello again, Alan! :)

Hm, what kind of mix is this? Is it, say, a "native DirectX" project and then you're combining it with some libraries / plugins / tools that use OpenGL instead? Or is it the inverse, where you'd have an OpenGL base but then some 3rd party libraries use DirectX for I don't know, doing heavy calculations on the GPU? Or is it a DirectX-only project and Magnum is the only part that would require OpenGL? Or is OpenGL the fallback path for non-Windows platforms and on Windows it should be DirectX only?

if one really liked Magnum and wanted to use it with DirectX

The "I don't want to deal with any OpenGL at all" approach would be building Magnum without the Magnum::GL library and everything else that relies on it, which is ... basically mostly just builtin shaders and the ImGui integration. Which means you'd end up with a math library, assert import, export and processing, the application classes and the scene graph, and for shaders, meshes, framebuffers and whatnot you'd use DirectX directly. But I never used it myself so I don't know how bad it is to use directly. At this point the question is what you plan to use Magnum for -- if it's mainly for math, asset management and OS interfaces, then it's a good option. But if it's mainly because its GL wrapper was convenient and you didn't use much else, then not really :)

About ImGui, one thing I wanted to do but didn't get to yet is splitting the renderer and event processing code so you could keep the integration with application classes but supply your own renderer. And if I'm not mistaken, ImGui itself should have a D3D backend implementation somewhere already. So that part could be reasonably effortless.

or is there some layer missing that one could "easily" fill in?

No, at this point there isn't. Maybe it would materialize with the WebGPU backend, but that's still quite far ahead.


Another idea I have is that you could have the project DirectX-based and then use ANGLE for the OpenGL part, if it could work in such restricted context (no compute, no bindless and other fancy features). Magnum can run with ANGLE, and ANGLE would act here as a convenience layer sitting on top of a DirectX base, with an ability to share surfaces between the two (such as with this extension). I think that would be even faster (and less prone to hitting driver bugs, heh) than having two completely independent DX/GL parts fighting over the GPU resources.

alanjfs commented 2 years ago

Heya. 👋 😄

Hm, what kind of mix is this?

It'll be running one or the other, not both at once. Which I expect simplifies things somewhat.

It's a plug-in to an application (Autodesk Maya), whereby I share graphics state with the application and the user is free to choose whether that graphics state should be DirectX or OpenGL (once, at startup). So whatever I do graphically would need to run equally well with either backend. I'm already writing separate GLSL and HLSL shaders, so there already some bespoke project structure for each backend.

Which means you'd end up with a math library, assert import, export and processing, the application classes and the scene graph

That is true, good point. I keep forgetting about the modular nature of Magnum.

At this point the question is what you plan to use Magnum for -- if it's mainly for math, asset management and OS interfaces, then it's a good option.

Ultimately I'd like to use as much Magnum as possible. My past experience with Magnum was stellar and I'd like to rekindle that. Aside from this plug-in, there'll be a standalone version of it, and that will leverage much if not most of Magnum.

So this little exploration is to figure out how much overlap I can establish for the source code; the more the merrier.

Another idea I have is that you could have the project DirectX-based and then use ANGLE for the OpenGL part

This breaks my brain a little. Given an existing application, with both window and either DirectX or OpenGL context already established and me borrowing it for my own drawing, is ANGLE useful here? 🤔

mosra commented 2 years ago

Given an existing application, with both window and either DirectX or OpenGL context already established and me borrowing it for my own drawing, is ANGLE useful here?

ANGLE could make DirectX "look like" OpenGL, so your code could be just GL, with no need to worry about DirectX except for sharing the final framebuffer / swapchain / surface / howeverisitcalled with DirectX somehow. So, once, at startup, if the user chooses OpenGL, then your code would directly use the GL context; and if they choose DirectX, you load a variant of that code that relies on ANGLE to build the OpenGL context on top of DirectX. Actually, scratch the complexity, ANGLE can run on top of OpenGL as well, so you'd just have one code and then only pick an appropriate ANGLE backend at startup. Plus that makes it far easier in case running on Mac (and Metal) would be desired as well. Then for the standalone version you could either keep using ANGLE, or go directly.

In other words, you could think of ANGLE as being a GPU-API-agnostic abstraction that provides an unified interface over GL/Vulkan/D3D/Metal, it's just that the unified interface is GL (ES) and not some completely new API.

What I'm not 100% sure about is the way how to create an ANGLE context using an existing D3D/GL context, instead of ANGLE creating its own and then sharing resources (which is slightly slower). A cursory search didn't reveal anything, but it would be silly if this was not possible. There's EGL_ANGLE_device_creation_d3d11 for creating ANGLE on top of existing D3D context. No idea about GL, but worst case you could go directly if it was not possible.

alanjfs commented 2 years ago

That is interesting, thanks @mosra, investigating this.