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

Reply via email to