AnsweredAssumed Answered

glMapBuffer and secondary thread problem

Question asked by maxis11 on Jul 15, 2014
Latest reply on Aug 20, 2014 by leonmaxx

glDrawArray doesn't draw anything when using secondary thread + glMapBuffer(thread receive pointer and use it as a buffer) to update data in VBO. Example code:

 

#include <thread>
#include <GL/glew.h>
#include <GLFW/glfw3.h>


const char vsource [] = "#version 330 core\nin vec3 position;\nvoid main(void){gl_Position = vec4(position,1.0f);}\0";
const char fsource [] = "#version 330 core\nvoid main(void){gl_FragColor = vec4(1.0f,0.0f,0.0f,1.0f);}\0";


bool ext = 0;


void gen_function(float *data, unsigned count)
{
    srand(time(NULL));
    while (!ext)
    {
        for (unsigned i = 0; i < (count/3)*3; i+=3)
        {
            data[i] = ((rand() % 2001) * 0.001f) - 1.0f;
            data[i+1] = ((rand() % 2001) * 0.001f) - 1.0f;
            data[i+2] = 0.0f;
        }
    }
}


int main()
{
    if (!glfwInit())
        return 1;
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
    GLFWwindow* window = glfwCreateWindow(640, 480, "Test", NULL, NULL);
    glfwMakeContextCurrent(window);
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    glewExperimental = GL_TRUE;
    glewInit();
    GLuint vshader = glCreateShader(GL_VERTEX_SHADER);
    char const* source_pointer = vsource;
    glShaderSource (vshader,1,&source_pointer,NULL);
    glCompileShader(vshader);
    GLuint fshader = glCreateShader(GL_FRAGMENT_SHADER);
    source_pointer = fsource;
    glShaderSource (fshader,1,&source_pointer,NULL);
    glCompileShader(fshader);
    GLuint program = glCreateProgram();
    glAttachShader(program,vshader);
    glAttachShader(program,fshader);
    glLinkProgram(program);
    GLuint VAO;
    glGenVertexArrays(1,&VAO);
    glBindVertexArray(VAO);
    GLuint VBO;
    glGenBuffers(1,&VBO);
    glBindBuffer(GL_ARRAY_BUFFER,VBO);
    glBufferData(GL_ARRAY_BUFFER,300*sizeof(float),NULL,GL_DYNAMIC_DRAW);
    void* ptr = glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY | GL_MAP_UNSYNCHRONIZED_BIT);
    GLint pos = glGetAttribLocation(program,"position\0");
    glVertexAttribPointer(pos,3,GL_FLOAT,GL_FALSE,0,0);
    glEnableVertexAttribArray(pos);
    glUseProgram(program);
    std::thread thread1(gen_function,(float*)ptr,300);
    glPointSize(2.0f);
    do
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glDrawArrays(GL_POINTS,0,100);
        glfwSwapBuffers(window);
        glfwPollEvents();
    } while (glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
             glfwWindowShouldClose(window) == 0);
    ext = 1;
    thread1.join();
    glDisableVertexAttribArray(pos);
    glUnmapBuffer(GL_ARRAY_BUFFER);
    glDeleteBuffers(1,&VBO);
    glDeleteVertexArrays(1,&VAO);
    glDeleteProgram(program);
    glDeleteShader(vshader);
    glDeleteShader(fshader);
    glfwTerminate();
    return 0;
}


 

If I use open source driver(mesa(r600g)) then program draws without problems.
Hardware: 6480G + 7470M
OS: Kubuntu 14.10 daily
Driver: AMD Catalyst 14.6 jul11

Outcomes