Hello hpx-users,
I'm still working on my parallel rendering project and can't find a
solution for an error for over a month now.
Whenever i call my rendering routine through an action (component- or
plain action), i get a Segfault at glLinkProgram().
If i call it in hpx_main() as a normal method or through std::async, it
works fine, so my method is not faulty (correct image, no glErrors).
I want to call it in a component action to render 16 images on 16
components of a 16-core node/locality simultaneously, but the simplified
version of just calling it once on a 1-core locality in a plain action
in the hpx_main() gives the same segmentation fault.
I know this most likely is an error on the interaction of OpenGL and
asynchronous actions in general, but maybe someone on this list has an
idea or has used OpenGL with HPX.
Thanks in advance for any hints.
Best,
Jan
Code snippets:
- in readable order
- single core version with OSMesa
- interesting lines marked with ++++++++++++++++++++++++++++++++++)
- can provide more if necessary
the call: +++++++++++++++++++++++++++++++++++++++++++++++
hpx::async<process_context_action>(hpx::find_here(), locID, locnum,
m_currentImage).get();
int process_context(GLuint offset, GLuint groups, Image image)
{
const GLint z = 32, stencil = 0, accum = 0;
OSMesaContext ctx;
void *buffer;
GLint cBits;
GLenum type = GL_UNSIGNED_BYTE;
GLint bits = 8;
setenv( "MESA_GL_VERSION_OVERRIDE", "3.3", 0 );
setenv( "MESA_GLSL_VERSION_OVERRIDE", "330", 0);
ctx = OSMesaCreateContextExt(OSMESA_RGBA, z, stencil, accum, NULL );
if (!ctx) {
printf("OSMesaCreateContextExt() failed!\n");
return 0;
}
// Allocate the image buffer
buffer = malloc(width * height * 4);
if (!buffer) {
printf("Alloc image buffer failed!\n");
return 0;
}
// Bind the buffer to the context and make it current
if (!OSMesaMakeCurrent( ctx, buffer, type, width, height )) {
printf("OSMesaMakeCurrent (%d bits/channel) failed!\n", bits);
free(buffer);
OSMesaDestroyContext(ctx);
return 0;
}
/* sanity checks */
glGetIntegerv(GL_RED_BITS, &cBits);
if (cBits != bits) {
fprintf(stderr, "Unable to create %d-bit/channel
renderbuffer.\n", bits);
fprintf(stderr, "May need to recompile Mesa with CHAN_BITS=16
or 32.\n");
return 0;
}
OSMesaColorClamp(GL_TRUE);
// ++++++++++++++++++++ go in next method ++++++++++++++++++++++
if (!render_image(offset,groups))
{
return 0;
}
OSMesaDestroyContext(ctx);
free(buffer);
return 1;
}
HPX_PLAIN_ACTION(process_context, process_context_action);
int render_image(GLuint offs, GLuint grps)
{
// Enable depth test
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Initialize VAO
GLuint VertexArray;
glGenVertexArrays(1, &VertexArray);
glBindVertexArray(VertexArray);
// Load and compile shaders +++++++++++ go in next method
++++++++++++++++
GLuint program = LoadShaders();
// Get indices of shader-uniforms
GLint MVPShaderID = glGetUniformLocation(program, "MVP");
if (MVPShaderID == -1){
fprintf(stderr, "FAILED: MVP misspelled or not used in shader.\n");
return 0;
}
GLint ModelMatrixID = glGetUniformLocation(program, "M");
if (ModelMatrixID == -1){
fprintf(stderr, "FAILED: M misspelled or not used in shader.\n");
return 0;
}
GLint ViewMatrixID = glGetUniformLocation(program, "V");
if (ViewMatrixID == -1){
fprintf(stderr, "FAILED: V misspelled or not used in shader.\n");
return 0;
}
GLint LightPosID = glGetUniformLocation(program,
"LightPosition_worldspace");
if (LightPosID == -1){
fprintf(stderr, "FAILED: LightPosition_worldspace misspelled or
not used in shader.\n");
return 0;
}
// Projection matrix
glm::mat4 P = glm::perspective(80.0f, // FoV
(float)width / (float)height, // Aspect Ratio
0.1f, 4.0f*std::max(std::max(camPos.x, camPos.y),
camPos.z)); // Display Range
// Camera matrix
glm::mat4 V = glm::lookAt(
camPos, // Camera-Position
glm::vec3(0,0,0), // Looks at Point
glm::vec3(0,-1,0)); // Up-Vector
// Model matrix
glm::mat4 M =
glm::translate(glm::mat4(1.0f),glm::vec3(0.0f,0.0f,0.0f));
// Compute MVP-Matrix
glm::mat4 MVP = P * V * M;
// Load Data
std::vector<glm::vec3> VertexBufferData;
std::vector<glm::vec3> ColorBufferData;
std::vector<glm::vec3> NormalBufferData;
std::vector<unsigned int> IndexBufferData;
loadOBJ("../src/suzanne.obj", VertexBufferData, ColorBufferData,
NormalBufferData, IndexBufferData, offs, grps);
// Create VertexBuffer
GLuint VBO;
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, VertexBufferData.size() *
sizeof(glm::vec3),
&VertexBufferData[0], GL_STATIC_DRAW);
// Create ColorBuffer
GLuint CBO;
glGenBuffers(1, &CBO);
glBindBuffer(GL_ARRAY_BUFFER, CBO);
glBufferData(GL_ARRAY_BUFFER, ColorBufferData.size() *
sizeof(glm::vec3),
&ColorBufferData[0], GL_STATIC_DRAW);
// Create NormalBuffer
GLuint NBO;
glGenBuffers(1, &NBO);
glBindBuffer(GL_ARRAY_BUFFER, NBO);
glBufferData(GL_ARRAY_BUFFER, NormalBufferData.size() *
sizeof(glm::vec3),
&NormalBufferData[0], GL_STATIC_DRAW);
// Create IndexBuffer
GLuint IBO;
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexBufferData.size() *
sizeof(unsigned int), &IndexBufferData[0], GL_STATIC_DRAW);
// Set clear color
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
//glClearDepth(0.5f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Use shader
glUseProgram(program);
// Give shader Matrices & Light
glUniformMatrix4fv(MVPShaderID, 1, GL_FALSE, &MVP[0][0]);
glUniformMatrix4fv(ModelMatrixID, 1, GL_FALSE, &M[0][0]);
glUniformMatrix4fv(ViewMatrixID, 1, GL_FALSE, &V[0][0]);
glUniform3f(LightPosID, lightPos.x, lightPos.y, lightPos.z);
// Vertices atrribute buffer
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(
0, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized
0, // stride
(void*)0 // array buffer offset
);
// Color attribute buffer
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, CBO);
glVertexAttribPointer(
1, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized
0, // stride
(const GLvoid*)0 // array buffer offset
);
// Normal attribute buffer
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, NBO);
glVertexAttribPointer(
2, // attribute
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized
0, // stride
(const GLvoid*)0 // array buffer offset
);
// Index Buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
// Draw triangles (mode, size, type,
offset)
glDrawElements(GL_TRIANGLES, IndexBufferData.size(),
GL_UNSIGNED_INT, 0);
// Cleanup VAO-Attributes
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
/* Make sure buffered commands are finished! */
glFinish();
// Cleanup VBO and shader
glDeleteBuffers(1, &VBO);
glDeleteBuffers(1, &CBO);
glDeleteBuffers(1, &NBO);
glDeleteBuffers(1, &IBO);
glDeleteProgram(program);
glDeleteVertexArrays(1, &VertexArray);
return 1;
}
GLuint LoadShaders(){
// Create the shaders
GLuint VertexShader = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
// Vertex Shader code
const char* VertexShaderCode = "\
#version 330 core\n\
layout(location = 0) in vec3 vertexPosition_modelspace;\
layout(location = 1) in vec3 color;\
layout(location = 2) in vec3 vertexNormal_modelspace;\
out vec3 col;\
out vec3 vertexNormal_cameraspace;\
out vec3 EyeDirection_cameraspace;\
out vec3 LightDirection_cameraspace;\
uniform mat4 MVP;\
uniform mat4 M;\
uniform mat4 V;\
uniform vec3 LightPosition_worldspace;\
void main(){\
gl_Position = MVP * vec4(vertexPosition_modelspace,1.0);\
vec3 vertexPosition_cameraspace = (V * M *
vec4(vertexPosition_modelspace,1)).xyz;\
EyeDirection_cameraspace = vec3(0,0,0) - vertexPosition_cameraspace;\
vec3 LightPosition_cameraspace = ( V *
vec4(LightPosition_worldspace,1)).xyz;\
LightDirection_cameraspace = LightPosition_cameraspace +
EyeDirection_cameraspace;\
col = color;\
vertexNormal_cameraspace = (V * M *
vec4(vertexNormal_modelspace,0.0)).xyz;\
}";
// Fragment Shader code
const char* FragmentShaderCode = "\
#version 330 core\n\
in vec3 col;\
in vec3 vertexNormal_cameraspace;\
in vec3 EyeDirection_cameraspace;\
in vec3 LightDirection_cameraspace;\
out vec4 FragColor;\
void main(){\
vec3 MaterialDiffuseColor = col;\
vec3 MaterialAmbientColor = vec3(0.3,0.3,0.3) * MaterialDiffuseColor;\
vec3 MaterialSpecularColor = vec3(0.3,0.3,0.3);\
vec3 n = normalize(vertexNormal_cameraspace);\
vec3 l = normalize(LightDirection_cameraspace);\
float cosTheta = clamp(dot(n,l), 0, 1);\
vec3 E = normalize(EyeDirection_cameraspace);\
vec3 R = reflect(-l,n);\
float cosAlpha = clamp(dot(E,R), 0, 1);\
FragColor = \
vec4(MaterialAmbientColor +\
MaterialDiffuseColor * cosTheta +\
MaterialSpecularColor * pow(cosAlpha,5), 1.0);\
}";
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
glShaderSource(VertexShader, 1, &VertexShaderCode, NULL);
glCompileShader(VertexShader);
// Check Vertex Shader
glGetShaderiv(VertexShader, GL_COMPILE_STATUS, &Result);
if (!Result) {
printf("VertexShader compilation failed:\n");
}
glGetShaderiv(VertexShader, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> VertexShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(VertexShader, InfoLogLength, NULL,
&VertexShaderErrorMessage[0]);
printf("%s", &VertexShaderErrorMessage[0]);
}
// Compile Fragment Shader
glShaderSource(FragmentShader, 1, &FragmentShaderCode, NULL);
glCompileShader(FragmentShader);
// Check Fragment Shader
glGetShaderiv(FragmentShader, GL_COMPILE_STATUS, &Result);
if (!Result) {
printf("FragmentShader compilation failed:\n");
}
glGetShaderiv(FragmentShader, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1);
glGetShaderInfoLog(FragmentShader, InfoLogLength, NULL,
&FragmentShaderErrorMessage[0]);
printf("%s", &FragmentShaderErrorMessage[0]);
}
// Link the program
GLuint program = glCreateProgram();
glAttachShader(program, VertexShader);
glAttachShader(program, FragmentShader);
GLenum glErr;
glErr = glGetError();
if (glErr != 0){
std::cout << "OpenGL error: " << glErr << endl;
}
printf("Linking Program...\n");
glLinkProgram(program); +++++++++++++++++ SEGFAULT HERE ++++++++++++++
printf("Program linked\n");
// Check the program
glGetProgramiv(program, GL_LINK_STATUS, &Result);
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &InfoLogLength);
if ( InfoLogLength > 0 ){
std::vector<char> ProgramErrorMessage(InfoLogLength+1);
glGetProgramInfoLog(program, InfoLogLength, NULL,
&ProgramErrorMessage[0]);
printf("%s", &ProgramErrorMessage[0]);
}
// Detach & delete shaders
glDetachShader(program, VertexShader);
glDetachShader(program, FragmentShader);
glDeleteShader(VertexShader);
glDeleteShader(FragmentShader);
return program;
}
_______________________________________________
hpx-users mailing list
[email protected]
https://mail.cct.lsu.edu/mailman/listinfo/hpx-users