minetest / irrlicht

Minetest's fork of Irrlicht
Other
115 stars 87 forks source link

Fix Windows/SDL builds #250

Closed numberZero closed 1 year ago

numberZero commented 1 year ago

This PR replaces all direct calls to the OpenGL library from the unified driver with calls via OpenGLProcedures. There are also a few fixes required for it to compile.

This is inspired by #232 but is much simpler. Also not all calls are replaced, those in e.g. COpenGLCoreTexture (shared with other drivers) remain. That shouldn’t be a problem as these drivers do that too and work (it might be the cause of some obscure bugs though).

I can’t test whether this Windows/SDL build actually works but given that it didn’t even compile, it is definitely better than before ;)

grorp commented 1 year ago

I tested this PR on Windows together with minetest/minetest#13321, it crashed on startup. I hope this output from "Microsoft (R) Windows Debugger" helps a bit. I had to skip through tons of "Debug Assertion Failed!" before it got to the actual crash.

windows.debugger.txt

Output:

8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
GL_INVALID_VALUE: 851
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
GL_INVALID_VALUE: 851
PNG warning: Interlace handling should be turned on when using png_read_image
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
GL_INVALID_VALUE: 597
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
8246 824c 501 9146 Error has been generated. GL error GL_INVALID_VALUE in VertexAttribPointer: (ID: 3708630069) Generic error
2023-10-08 19:25:13: [Main]:  >> === FATAL ERROR ===
2023-10-08 19:25:13: [Main]:  >> Access violation (Exception 0xC0000005) at 0x00007FFAE246AAB1

Stacktrace:

[0x0]   ig11icd64!RegisterProcTableCallback+0x2ca841   0xea1bbc7a80   0x7ffae1caf26c   
[0x1]   ig11icd64 + 0xcf26c!ig11icd64+0xcf26c   0xea1bbc8f90   0x7ffae1c1a238   
[0x2]   ig11icd64 + 0x3a238!ig11icd64+0x3a238   0xea1bbcb330   0x7ffae21b8213   
[0x3]   ig11icd64!RegisterProcTableCallback+0x17fa3   0xea1bbcbb00   0x7ffae260e03b   
[0x4]   ig11icd64!RegisterProcTableCallback+0x46ddcb   0xea1bbcbb50   0x7ffae24de78e   
[0x5]   ig11icd64!RegisterProcTableCallback+0x33e51e   0xea1bbcbbc0   0x7ffae26ace6e   
[0x6]   ig11icd64!RegisterProcTableCallback+0x50cbfe   0xea1bbcbc00   0x7ffae26adc2d   
[0x7]   ig11icd64!RegisterProcTableCallback+0x50d9bd   0xea1bbcbc40   0x7ffae24fe59d   
[0x8]   ig11icd64!RegisterProcTableCallback+0x35e32d   0xea1bbcbcd0   0x7ffae25b3cc0   
[0x9]   ig11icd64!RegisterProcTableCallback+0x413a50   0xea1bbcbd20   0x7ff65a66d405   
[0xa]   minetest!irr::video::COpenGL3DriverBase::drawElements+0x65   0xea1bbcbd70   0x7ff65a666b76   
[0xb]   minetest!irr::video::COpenGL3DriverBase::draw2DImageBatch+0x756   0xea1bbcbdc0   0x7ff65a0d8fea   
[0xc]   minetest!irr::gui::CGUITTFont::draw+0xfba   0xea1bbcc030   0x7ff65a0d7ff4   
[0xd]   minetest!irr::gui::CGUITTFont::draw+0xd4   0xea1bbcc5d0   0x7ff65a6b535c   
[0xe]   minetest!irr::gui::CGUITabControl::draw+0x60c   0xea1bbcc6d0   0x7ff65a02dbc2   
[0xf]   minetest!GUIFormSpecMenu::drawMenu+0x612   0xea1bbcca50   0x7ff65a0ce48d   
[0x10]   minetest!GUIModalMenu::draw+0xdd   0xea1bbccfc0   0x7ff65a003ab3   
[0x11]   minetest!irr::gui::IGUIElement::draw+0xb3   0xea1bbcd020   0x7ff65a6a5dfe   
[0x12]   minetest!irr::gui::CGUIStaticText::draw+0x87e   0xea1bbcd0a0   0x7ff65a003ab3   
[0x13]   minetest!irr::gui::IGUIElement::draw+0xb3   0xea1bbcd300   0x7ff65a624c17   
[0x14]   minetest!irr::gui::CGUIEnvironment::drawAll+0x177   0xea1bbcd380   0x7ff65a024d12   
[0x15]   minetest!GUIEngine::run+0x402   0xea1bbcd420   0x7ff65a0242cf   
[0x16]   minetest!GUIEngine::GUIEngine+0xa2f   0xea1bbcd6e0   0x7ff659da0b89   
[0x17]   minetest!ClientLauncher::main_menu+0x349   0xea1bbcda20   0x7ff659d9faad   
[0x18]   minetest!ClientLauncher::launch_game+0x50d   0xea1bbcdca0   0x7ff659d9e9ed   
[0x19]   minetest!ClientLauncher::run+0x14cd   0xea1bbce580   0x7ff65a3ebbdb   
[0x1a]   minetest!main+0xcdb   0xea1bbceff0   0x7ff65a7522e9   
[0x1b]   minetest!invoke_main+0x39   0xea1bbcf890   0x7ff65a7521ce   
[0x1c]   minetest!__scrt_common_main_seh+0x12e   0xea1bbcf8e0   0x7ff65a75208e   
[0x1d]   minetest!__scrt_common_main+0xe   0xea1bbcf950   0x7ff65a75237e   
[0x1e]   minetest!mainCRTStartup+0xe   0xea1bbcf980   0x7ffb26747344   
[0x1f]   KERNEL32!BaseThreadInitThunk+0x14   0xea1bbcf9b0   0x7ffb26da26b1   
[0x20]   ntdll!RtlUserThreadStart+0x21   0xea1bbcf9e0   0x0   
numberZero commented 1 year ago

@grorp GL_INVALID_VALUE isn’t something in any way expected here. Maybe there is some subtlety in VertexType initialization (did I read that lifetime extension clause carefully enough?). Can you retest with the following debug patch, please? The expected output is lots of beginDraw({36, {0, 3, 0x1406, 0, 0}, {2, 4, 0x1401, 1, 24}, {3, 2, 0x1406, 0, 28}}, some-pointer-value-here) and beginDraw({36, {0, 3, 0x1406, 0, 0}, {2, 4, 0x1401, 1, 24}}, some-pointer-value-here).

diff --git a/source/Irrlicht/OpenGL/Driver.cpp b/source/Irrlicht/OpenGL/Driver.cpp
index 6a8217e6..5294e481 100644
--- a/source/Irrlicht/OpenGL/Driver.cpp
+++ b/source/Irrlicht/OpenGL/Driver.cpp
@@ -1106,14 +1106,17 @@ COpenGL3DriverBase::~COpenGL3DriverBase()

        void COpenGL3DriverBase::beginDraw(const VertexType &vertexType, uintptr_t verticesBase)
        {
+               printf("beginDraw({%d", vertexType.VertexSize);
                for (auto attr: vertexType) {
                        GL.EnableVertexAttribArray(attr.Index);
+                       printf(", {%d, %d, %#04x, %d, %d}", attr.Index, attr.ComponentCount, attr.ComponentType, attr.mode, attr.Offset);
                        switch (attr.mode) {
                        case VertexAttribute::Mode::Regular: GL.VertexAttribPointer(attr.Index, attr.ComponentCount, attr.ComponentType, GL_FALS>
                        case VertexAttribute::Mode::Normalized: GL.VertexAttribPointer(attr.Index, attr.ComponentCount, attr.ComponentType, GL_T>
                        case VertexAttribute::Mode::Integral: GL.VertexAttribIPointer(attr.Index, attr.ComponentCount, attr.ComponentType, verte>
                        }
                }
+               printf("}, %p)\n", (void*)verticesBase);
        }

        void COpenGL3DriverBase::endDraw(const VertexType &vertexType)
numberZero commented 1 year ago

Also am I right you’re testing an MSVC build? MinGW build may behave differently.

grorp commented 1 year ago

Also am I right you’re testing an MSVC build? MinGW build may behave differently.

Yes, I am.

Can you retest with the following debug patch, please?

Debug build (window opens, but stays all black): Debug_output.txt

RelWithDebInfo build (window opens and is filled with sky blue): RelWithDebInfo.txt

numberZero commented 1 year ago

Thanks. Now it’s clear what happens: the Attributes list in the VertexType is not valid by the time it is used. I have several suggestions but not sure which one is needed to make this work on MSVC:

  1. In VertexType, replace initializer_list with vector. Should work, but may be an overkill.
  2. In initialization of VertexType vt..., remove the equals sign. Shouldn’t matter but who knows...
  3. Try my gl3-vertex-type-literal branch, it has a slightly different approach.
numberZero commented 1 year ago

I replaced initializer_list with vector. Now lifetime shouldn’t be a problem. VertexType became heavier though.

grorp commented 1 year ago

Works 👍