Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 4 of 4

Thread: OpenGL 4.1 : did i misunderstood separate programs ?

  1. #1
    Newbie Newbie
    Join Date
    Oct 2012
    Posts
    3

    Question OpenGL 4.1 : did i misunderstood separate programs ?

    Hello everyone,

    I am trying to use a ProgramPipelineObject and I have not been able to make it work the way I want.
    Maybe I am trying something that is not possible.
    I have a "basic" example which works, and a "little bit more complexe" example which does not.

    This is the example which works :
    ProgramObject 1 :
    • load vertex shader, compile, set separable true, link

    ProgramObject 2 :
    • load fragment shader, compile, set separable true, link

    ProgramPipeline :
    • generate, bind ProgramPipeline
    • useStage(ProgramPipeline, Vertex, ProgramObject 1)
    • useStage(ProgramPipeline, Fragment, ProgramObject 2)
    • unbind ProgramPipeline

    Render pass :
    • programuniform(ProgramObject 1, "matrix etc...")
    • programuniform(ProgramObject 2, "color etc...")
    • bind ProgramPipeline
    • draw object
    • unbind ProgramPipeline




    This is the example which doest not work (the only modification is bold) :
    ProgramObject 1 :
    • load vertex shader, load fragment shader, compile both, set separable true, link (so this is not a simple program with a vertex shader, but a program with a vertex and a fragment shader)

    ProgramObject 2 :
    • load fragment shader, compile, set separable true, link

    ProgramPipeline :
    • generate, bind ProgramPipeline
    • useStage(ProgramPipeline, Vertex, ProgramObject 1)
    • useStage(ProgramPipeline, Fragment, ProgramObject 2)
    • unbind ProgramPipeline

    Render pass :
    • programuniform(ProgramObject 1, "matrix etc...")
    • programuniform(ProgramObject 2, "color etc...")
    • bind ProgramPipeline
    • draw object
    • unbind ProgramPipeline


    My result is : no object on screen : maybe a uniform problem ?

    ->Is it possible to create a pipeline taking only one stage of a shaderprogram that contains many stages?
    ->Do you see any reason that can make it fail ?

    Thanks you very much.

    PS : I am under linux ubuntu 12.04, nvidia 304 drivers, gtx 480, glew 1.9

  2. #2
    Senior Member OpenGL Guru
    Join Date
    May 2009
    Posts
    4,948
    Is it possible to create a pipeline taking only one stage of a shaderprogram that contains many stages?
    According to the specification, yes.

    Do you see any reason that can make it fail ?
    Yes.

    The whole point of separable programs is to not have programs linked together. At all. Indeed, they created a whole new entrypoint dedicated to creating single-stage programs.

    NVIDIA's drivers certainly should allow this by the specification, so it's probably a driver bug (assuming your code isn't wrong in some other way), so feel free to file a report on it. But it's not exactly a surprise that this doesn't work.

    In short, I wouldn't rely on being able to replace one program's stage with another program's stage. It could and should work, but it's a corner case that most users of this functionality (people who want D3D-like shaders) would never touch. So it doesn't get as extensive testing in the field as the other cases.

  3. #3
    Newbie Newbie
    Join Date
    Oct 2012
    Posts
    3
    Thanks you for that quick answer.

    Quote Originally Posted by Alfonse Reinheart View Post
    In short, I wouldn't rely on being able to replace one program's stage with another program's stage. It could and should work, but it's a corner case that most users of this functionality (people who want D3D-like shaders) would never touch. So it doesn't get as extensive testing in the field as the other cases.
    I could have been so amazing ...


    To make sure this is not a wrong code and a real driver problem, this is what I tested :
    On the OpenGL Samples Pack 4.3.0.2 (http://www.g-truc.net/post-0503.html#menu) I changed initSeparateProgram() of gl-410-program-separate.cpp.

    This is the diff :

    < std::string VertexSourceContent = glf::loadFile(VERTEX_SHADER_SOURCE);
    < char const * VertexSourcePointer = VertexSourceContent.c_str();
    < SeparateProgramName[program::VERTEX] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &VertexSourcePointer);
    ---
    > // create a shaderprogram containing 2 shader stages
    > GLuint VertShaderName = glf::createShader(GL_VERTEX_SHADER, VERTEX_SHADER_SOURCE);
    > GLuint FragShaderName = glf::createShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE);
    >
    > SeparateProgramName[program::VERTEX] = glCreateProgram();
    > glAttachShader(SeparateProgramName[program::VERTEX], VertShaderName);
    > glAttachShader(SeparateProgramName[program::VERTEX], FragShaderName); // If you comment this line, it works. If you do not (and the program has 2 shaders) it does not.
    > glProgramParameteri(SeparateProgramName[program::VERTEX], GL_PROGRAM_SEPARABLE, GL_TRUE);
    > glLinkProgram(SeparateProgramName[program::VERTEX]);

    Consequently the following line should have taken only one stage :
    glUseProgramStages(PipelineName, GL_VERTEX_SHADER_BIT, SeparateProgramName[program::VERTEX]);
    // Check program id
    int program_id = 0;
    glGetProgramPipelineiv(PipelineName, GL_VERTEX_SHADER, &program_id);
    std::cout << "Used (vertex) program id : " << program_id << std::endl; // display the correct program id
    glGetProgramPipelineiv(PipelineName, GL_FRAGMENT_SHADER, &program_id);
    std::cout << "Used (fragment) program id : " << program_id << std::endl; // display 0 which is what we want

    So, the use stage "seems" to work, but the display does not work anymore :
    glBindProgramPipeline(PipelineName);
    glDrawElementsInstancedBaseVertex(GL_TRIANGLES, ElementCount, GL_UNSIGNED_INT, NULL, 1, 0); // crash here
    glBindProgramPipeline(0);

    OpenGL: error(high) 1282: GL_INVALID_OPERATION error generated. State(s) are invalid: program pipeline config.


    If somebody can confirm me that I did not do wrong code, I will report the bug.
    Thanks.

  4. #4
    Newbie Newbie
    Join Date
    Oct 2012
    Posts
    3
    Thanks you for that quick answer.

    Quote Originally Posted by Alfonse Reinheart View Post
    In short, I wouldn't rely on being able to replace one program's stage with another program's stage. It could and should work, but it's a corner case that most users of this functionality (people who want D3D-like shaders) would never touch. So it doesn't get as extensive testing in the field as the other cases.
    I could have been so amazing ...


    To make sure this is not a wrong code and a real driver problem, this is what I tested :
    On the OpenGL Samples Pack 4.3.0.2 (http://www.g-truc.net/post-0503.html#menu) I changed initSeparateProgram() of gl-410-program-separate.cpp.

    This is the diff :

    < std::string VertexSourceContent = glf::loadFile(VERTEX_SHADER_SOURCE);
    < char const * VertexSourcePointer = VertexSourceContent.c_str();
    < SeparateProgramName[program::VERTEX] = glCreateShaderProgramv(GL_VERTEX_SHADER, 1, &VertexSourcePointer);
    ---
    > // create a shaderprogram containing 2 shader stages
    > GLuint VertShaderName = glf::createShader(GL_VERTEX_SHADER, VERTEX_SHADER_SOURCE);
    > GLuint FragShaderName = glf::createShader(GL_FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE);
    >
    > SeparateProgramName[program::VERTEX] = glCreateProgram();
    > glAttachShader(SeparateProgramName[program::VERTEX], VertShaderName);
    > glAttachShader(SeparateProgramName[program::VERTEX], FragShaderName); // If you comment this line, it works. If you do not (and the program has 2 shaders) it does not.
    > glProgramParameteri(SeparateProgramName[program::VERTEX], GL_PROGRAM_SEPARABLE, GL_TRUE);
    > glLinkProgram(SeparateProgramName[program::VERTEX]);

    Consequently the following line should have taken only one stage :
    glUseProgramStages(PipelineName, GL_VERTEX_SHADER_BIT, SeparateProgramName[program::VERTEX]);
    // Check program id
    int program_id = 0;
    glGetProgramPipelineiv(PipelineName, GL_VERTEX_SHADER, &program_id);
    std::cout << "Used (vertex) program id : " << program_id << std::endl; // display the correct program id
    glGetProgramPipelineiv(PipelineName, GL_FRAGMENT_SHADER, &program_id);
    std::cout << "Used (fragment) program id : " << program_id << std::endl; // display 0 which is what we want

    So, the use stage "seems" to work, but the display does not work anymore :
    glBindProgramPipeline(PipelineName);
    glDrawElementsInstancedBaseVertex(GL_TRIANGLES, ElementCount, GL_UNSIGNED_INT, NULL, 1, 0); // crash here
    glBindProgramPipeline(0);

    OpenGL: error(high) 1282: GL_INVALID_OPERATION error generated. State(s) are invalid: program pipeline config.


    If somebody can confirm me that I did not do wrong code, I will report the bug.
    Thanks.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •