bboguni Posted October 22, 2025 Posted October 22, 2025 I’m currently testing Unigine 2.20.0.1 on Windows 11 using an NVIDIA GeForce RTX 4070. I’m running the engine through a CustomSystemProxy window implementation. The engine initializes successfully and loads the world, but when using Direct3D 12, the viewport remains black most of the time — it occasionally flashes for a single frame and then goes black again. There are no crash logs or explicit GPU errors, but the rendering output is unstable. If I launch the same project with -video_app vk or -video_app dx, the following error message appears, but rendering itself works correctly: ERROR: Engine::init(): using D3D12 without Agility SDK is not supported. Please export `D3D12SDKVersion` and `D3D12SDKPath` in your executable. Falling back to Vulkan. I have already checked and applied the recommendations described in the following documentation: https://developer.unigine.com/en/docs/latest/troubleshooting/engine_issues So it seems that this issue is specific to the Direct3D 12 backend. Could you please confirm: Whether this is a known issue with Direct3D 12 in Unigine 2.20, and If there are any recommended settings, patches, or configuration changes to ensure proper rendering under D3D12 on Windows 11? Thank you very much for your help.
arizmenda Posted October 22, 2025 Posted October 22, 2025 Hi, That’s an interesting issue. First, please check if the following files are present at this path <project>\bin\D3D12: The resulting file structure should look like this: Second, update the GPU driver to the latest version, just to rule out any driver-level issues. And finally, please share (you can PM me) your main.csproj file from the VSCsharpCore folder: ...\sdks\<your_sdk_version>\utils\project\ide\VSCSharpCore - we’ll take a look on our side. Thanks.
bboguni Posted October 23, 2025 Author Posted October 23, 2025 I’ve sent the main.csproj file via private message. The GPU driver is already updated to the latest version. When building and running with the default Unigine base project, everything works fine. However, we are currently using only the Engine SDK, and in our MFC-based project, we pass an HWND to the engine for rendering. Could this integration approach be the cause of the issue?
arizmenda Posted October 23, 2025 Posted October 23, 2025 Thanks for sending the file. Unfortunately, our current theory hasn’t been confirmed yet. Did this setup work on a previous version, for example 2.19? If so, please send us your minimal working sample project from that version. We can migrate it on our side and try to figure out where and why things went wrong.
bboguni Posted October 24, 2025 Author Posted October 24, 2025 It seems that the issue is not related to D3D12. I’ve been analyzing and using the SystemProxyQt example, and I noticed that the example doesn’t call registerExternalWindow anywhere. Docs: https://developer.unigine.com/en/docs/2.20/code/cpp/usage/unigine_app/proxy?highlighted=externalwindow,externalwindowlll,externalwindowll Location: Unigine\browser\sdks\engineering_windows_2.20.0.1_bin\source\apps\main_qt So, I added a call to registerExternalWindow inside SystemProxyQt::createWindow for testing, but the same issue still occurs. When I call registerExternalWindow after the engine initialization, onExternalWindowRender is never triggered. Could this be due to calling registerExternalWindow at the wrong time?
arizmenda Posted October 27, 2025 Posted October 27, 2025 Thanks for the details so far. We haven’t managed to trigger the same behavior on our side. There should be exported symbols D3D12SDKVersion and D3D12SDKPath somewhere in the sources - maybe they’re just missing in your setup, since you’re creating the window in a custom way. Please, check them on your side. In our projects, these symbols are usually exported by including UnigineInit.h in one of the main source files (e.g. main.cpp): About registerExternalWindow: in the SystemProxyQt example, that function is meant for registering user-created windows, not those created by the engine itself. When the engine calls createWindow, it already initializes all the necessary buffers for that window internally. So you don’t need to call registerExternalWindow from inside createWindow. You mentioned that when you don’t specify -video_app, rendering fails, but when you run with -video_app dx or -video_app vk, it works, even though you get the Agility SDK warning and it falls back to Vulkan. Could you please check what video app is actually being used when you don’t pass the parameter? You can print it from the console or via getVideoApp(). Could you also please send your CustomSystemProxy source? We’ll compile it here and see if we can reproduce the same problem. Thanks.
arizmenda Posted October 27, 2025 Posted October 27, 2025 We think we’ve found the cause of the problem. After migrating the project from previous versions, there’s a section like this In F:\_SDK\proj\unigine_project\source\main.cpp: After migration, the #include <UnigineInit.h> line ended up inside the #ifdef block, so it wasn’t included on Windows builds. Try moving this line outside the #ifdef block (to the other includes), rebuild the project, and D3D12 should start working correctly.
bboguni Posted October 28, 2025 Author Posted October 28, 2025 I have created two sample projects: CustomSystemProxyC++.zip – Unigine project using main.cpp. CustomSystemProxyMFC.zip – MFC-based project importing the SDK. When UnigineInit.h is declared, it uses DirectX 12. When UnigineInit.h is not declared, it defaults to vk. I understand that. When using vk, registerExternalWindow() works fine and rendering is normal. However, with DX12, the behavior is different. I’d like to know if this difference is expected or normal. Also, I want to receive the onExternalWindowRender event. If I don’t call registerExternalWindow(), the onExternalWindowRender event never triggers. As an alternative, is it acceptable to use the on_connection_event() registration in the sample source instead? CustomSystemProxyC++.zip CustomSystemProxyMFC.zip
arizmenda Posted October 29, 2025 Posted October 29, 2025 Thank you for the samples. We checked both projects you provided. The different behavior between Vulkan and D3D12 is not expected - Vulkan was simply more forgiving in this case. The underlying issue is the timing of when the external window is registered and when its buffers are initialized. The key point here is initExternalWindowBuffers() should not be called inside createWindow(). At that point, the rendering backend is not fully initialized yet under D3D12, which leads to issues mentioned. When engine calls the createWindow() callback it initializes the needed resources on its own. Instead of the SystemProxy::onExternalWindowRender callback (which is intended for windows created by user, i.e. not via createWindow()) you can alternatively use the SystemProxy::mainUpdate (or similar preferable Engine callback) https://developer.unigine.com/en/docs/2.20/api/library/engine/class.customsystemproxy#mainUpdate_void.
Recommended Posts