I'm not 100% sure, but wxLogMessage uses a mutex internally itself, so it's possible that the entries appear out of order when they come from different threads.
Use wxLogDebug. If your debugger doesn't display its output, use DebugView: https://docs.microsoft.com/en-us/sysint ... /debugview
It uses Windows' OutputDebugString and outputs the string immediately.
Program spontaneously closes: OpenGL and threads on Win10 Topic is solved
Re: Program spontaneously closes: OpenGL and threads on Win10
Use the source, Luke!
Re: Program spontaneously closes: OpenGL and threads on Win10
The stack after crash you showed reveals that something wrong is happening in the graphics card driver (ATI). I deduce the issue is not related to wxWidgets. Perhaps in a OpenGL forum you may get more help.
Anyhow, I see some topics to be aware of.
As doublemax told, OpenGL multithread is confusing. No, OGL is not "multithread" in the sense of handling different threads, some of they rendering at once. The very very point is that a gl-context must be set as current in the thread (your app threads) where gl-commands are used, and that only one gl-context can be set as current to a thread, no several gl-contexts at once.
You currently do it right calling SetCurrent(*m_context) in the paint-event handler. What I don't understand is why you use the static version wxGLCanvas::SetCurrent(*m_context) instead of just SetCurrent(*m_context) if your BasicGLPane derives from wxGLCanvas (it does, right?).
I don't know if this event handler is called ONLY from the main thread. It should, otherwise problems arise.
In the OGL part, does your shaders accept double types? Do you really need them? Likely the GPU is faster with floats than with doubles. I see this in your buffer filling:
Also
I hope vertices1 is an array not a pointer, or sizeof will return a different value.
To be able to find out your issue all your GL-related code (shaders included) must be in sight.
Anyhow, I see some topics to be aware of.
As doublemax told, OpenGL multithread is confusing. No, OGL is not "multithread" in the sense of handling different threads, some of they rendering at once. The very very point is that a gl-context must be set as current in the thread (your app threads) where gl-commands are used, and that only one gl-context can be set as current to a thread, no several gl-contexts at once.
You currently do it right calling SetCurrent(*m_context) in the paint-event handler. What I don't understand is why you use the static version wxGLCanvas::SetCurrent(*m_context) instead of just SetCurrent(*m_context) if your BasicGLPane derives from wxGLCanvas (it does, right?).
I don't know if this event handler is called ONLY from the main thread. It should, otherwise problems arise.
In the OGL part, does your shaders accept double types? Do you really need them? Likely the GPU is faster with floats than with doubles. I see this in your buffer filling:
Code: Select all
glBufferData(GL_ARRAY_BUFFER, sizeof(double)*4*parent->N, parent->nodeArray.data(), GL_DYNAMIC_DRAW);
Code: Select all
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
To be able to find out your issue all your GL-related code (shaders included) must be in sight.
Re: Program spontaneously closes: OpenGL and threads on Win10
Manolo's post gave me an idea: Do both machines you're testing on have the same GPU type? If it only crashes on AMD and the other PC has an NVidia card, it could also be that there is an error in your OpenGL code, but one driver (NVidia) is more forgiving that the other (AMD).
Use the source, Luke!
-
- Earned a small fee
- Posts: 11
- Joined: Tue Jun 26, 2018 3:06 pm
Re: Program spontaneously closes: OpenGL and threads on Win10
To doublemax: yes, the working one has an NVidia while the crashing one has AMD.
Also, I ran the DebugView application with wxLogDebug() and it still looks like the program is breaking mutex and program order:
I think the thumbnail cache lines were from another program. The buffer events for arrays 3/2 at the end shouldn't be sent until after the thread finished the code surrounded by enter/exit thread lock (final). Even if the events are sent, it shouldn't enter the mutex (the enter/exit messages are generated inside the mutex).
To Manolo, the class is indeed derived from wxGLCanvas; I switched the call you mentioned. But yes, it is the only place OGL commands are called and only the main frame asks it to do things. The thread just sends events to the main frame. I used doubles since doubles was what I was working with on the computation side, but I could try converting them to floats when I prepare the buffers on the host side. Also, yes the vertices1 is just the array for a triangle I show on startup, left over from when I was following the learnopengl.com tutorial.
Also, I ran the DebugView application with wxLogDebug() and it still looks like the program is breaking mutex and program order:
Code: Select all
00000001 0.00000000 [2588] Hello.
00000002 0.27686408 [2588] Enter buffer lock, 0
00000003 0.27712435 [2588] Exit buffer lock, 0
00000004 16.61983681 [2588] Enter buffer lock, 1
00000005 16.62022018 [2588] Exit buffer lock, 1
00000006 21.00772095 [2588] Enter thread lock (init)
00000007 21.00916290 [2588] Exit thread lock (init)
00000008 21.00925636 [2588] Enter buffer lock, 2
00000009 21.00947762 [2588] Exit buffer lock, 2
00000010 21.02763939 [2588] Plotting VAO2 with n=12000
<CRASH>
<NEW PROGRAM>
00000011 35.90525436 [8572] Hello.
00000012 36.18479919 [8572] Enter buffer lock, 0
00000013 36.18504715 [8572] Exit buffer lock, 0
00000014 47.67440033 [8572] Enter buffer lock, 1
00000015 47.67475891 [8572] Exit buffer lock, 1
00000016 47.94973755 [5336] Thumbnail Cache: Attempting to replace an entry that is in use
00000017 47.95830154 [5336] Thumbnail Cache: Attempting to replace an entry that is in use
00000018 58.22648621 [8572] Enter thread lock (init)
00000019 58.22684479 [8572] Exit thread lock (init)
00000020 58.22694397 [8572] Enter buffer lock, 2
00000021 58.22705841 [8572] Exit buffer lock, 2
00000022 58.24670029 [8572] Plotting VAO2 with n=4560
00000023 58.24800873 [8572] Plotting succeeded.
00000024 58.27142334 [8572] Enter thread lock (final)
00000025 58.29844666 [8572] Enter buffer lock, 3
00000026 58.29858780 [8572] Exit buffer lock, 3
00000027 58.29864883 [8572] Enter buffer lock, 2
00000028 58.29887009 [8572] Exit buffer lock, 2
00000029 58.31067657 [8572] Plotting VAO2 with n=4560
00000030 58.31549072 [8572] Plotting succeeded.
00000031 58.31618500 [8572] Exit thread lock (final)
00000032 58.31624603 [8572] Is this even in order?
00000034 245.07139587 [8572] Plotting VAO2 with n=4560
00000035 245.07165527 [8572] Plotting succeeded.
00000036 245.15139771 [8572] Plotting VAO2 with n=4560
00000037 245.15156555 [8572] Plotting succeeded.
00000038 245.53451538 [8572] Plotting VAO2 with n=4560
00000039 245.53468323 [8572] Plotting succeeded.
00000040 245.61656189 [8572] Plotting VAO2 with n=4560
00000041 245.61672974 [8572] Plotting succeeded.
To Manolo, the class is indeed derived from wxGLCanvas; I switched the call you mentioned. But yes, it is the only place OGL commands are called and only the main frame asks it to do things. The thread just sends events to the main frame. I used doubles since doubles was what I was working with on the computation side, but I could try converting them to floats when I prepare the buffers on the host side. Also, yes the vertices1 is just the array for a triangle I show on startup, left over from when I was following the learnopengl.com tutorial.
-
- Earned a small fee
- Posts: 11
- Joined: Tue Jun 26, 2018 3:06 pm
Re: Program spontaneously closes: OpenGL and threads on Win10
UPDATE: It looks like sending floats fixed the problem; I was using float types in the shader (below). Apparently it tries to convert the doubles on the fly and sometimes succeeds, but not reliably. The shaders:
I'll mark this thread as solved, though I'm still curious as to why the mutex doesn't seem to be working. That, and the apparent out-of-order code execution within a single thread. I'd like to know what's going on there since it could be important in the future.
Code: Select all
// The vertex shader
#version 440 core
layout (location = 0) in vec3 inPos;
layout (location = 1) in float funcVal;
out float funcVal_;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
gl_Position = projection * view * model * vec4(inPos, 1.0);
funcVal_ = funcVal;
}
// The fragment shader
#version 440 core
in vec3 vertexColor;
in float funcVal_;
out vec4 FragColor;
uniform sampler1D colormap;
void main(){
FragColor = vec4(texture(colormap,funcVal_).rgb,1.0f);
};