Program spontaneously closes: OpenGL and threads on Win10 Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Program spontaneously closes: OpenGL and threads on Win10

Post by doublemax »

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.
Use the source, Luke!
Manolo
Can't get richer than this
Can't get richer than this
Posts: 827
Joined: Mon Apr 30, 2012 11:07 pm

Re: Program spontaneously closes: OpenGL and threads on Win10

Post by Manolo »

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:

Code: Select all

glBufferData(GL_ARRAY_BUFFER, sizeof(double)*4*parent->N, parent->nodeArray.data(), GL_DYNAMIC_DRAW);
Also

Code: Select all

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices1), vertices1, GL_STATIC_DRAW);
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.
User avatar
doublemax
Moderator
Moderator
Posts: 19115
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Program spontaneously closes: OpenGL and threads on Win10

Post by doublemax »

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!
dcoffm5261
Earned a small fee
Earned a small fee
Posts: 11
Joined: Tue Jun 26, 2018 3:06 pm

Re: Program spontaneously closes: OpenGL and threads on Win10

Post by dcoffm5261 »

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:

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. 	
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.
dcoffm5261
Earned a small fee
Earned a small fee
Posts: 11
Joined: Tue Jun 26, 2018 3:06 pm

Re: Program spontaneously closes: OpenGL and threads on Win10

Post by dcoffm5261 »

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:

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);
};
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.
Post Reply