cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

nilsk
Journeyman III

glsl clipPlane bugs

Using geometry shaders results in all kinds of strange behaviour regarding clip planes. I cobbled together a small test case demonstrating the issues.

First in case 0 it looks like gl_ClipVertex gets ignored completely if it is written in the geometry shader. If only a vertex shader is used or if neither the vertex shader nor the geometry shader write to ClipVertex clipping works as expected.

In case 1 writing to gl_ClipDistance fails for all indices but 0, unrolling the loop works though.

Case 2 shouldn't work at all, pos should be vec4[3] but the program compiles, links and is validated but visual studio reports two access violations while debugging and following draw calls with that shader fail and generate errors.

I experimented with different #version settings but got buggy results whatever i tried.

Os: Windows 7 64

Graphics Chipset    ATI Radeon HD 5800 Series

Device ID    6898

Driver Packaging Version    8.982-120727a-145524C-ATI

Catalyst Version: 12.8

OpenGL Version: 6.14.10.11762

Header 1

#include "stdafx.h"

#include "GL/glew.h"

#include "GL/glut.h"

#include <vector>

GLuint program;

#define CASE_0

//#define CASE_1

//#define CASE_2

#define WORKING

//#define BUGED

//adding a geometry shader and writing gl_ClipVertex will be ignored

#ifdef CASE_0

#ifdef WORKING

#define USE_GEOMETRY_SHADER

const char *vs_source =

"#version 120\n"

"void main(void) {                        "

"  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"

"}";

const char *gs_source =

"//#extension GL_EXT_geometry_shader4 : require\n"

"void main(void) {\n        "

"    for(int i = 0; i < 3; ++i){\n"

"        gl_Position = gl_PositionIn;\n"

"    EmitVertex();\n"

"    }"

"}\n";

#endif

#ifdef BUGED

#define USE_GEOMETRY_SHADER

const char *vs_source =

"#version 120\n"

"void main(void) {                        "

"  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;"

"  gl_ClipVertex = gl_ModelViewMatrix*gl_Vertex;\n"

"}";

const char *gs_source =

"//#extension GL_EXT_geometry_shader4 : require\n"

"void main(void) {\n        "

"    for(int i = 0; i < 3; ++i){\n"

"        gl_Position = gl_PositionIn;\n"

"        gl_ClipVertex = gl_ClipVertexIn;\n"

"    EmitVertex();\n"

"    }"

"}\n";

#endif

#endif

//writing gl_ClipDistance in a loop ignores the ClipDistance[1], unrolling the loop works as expected

#ifdef CASE_1

#define USE_GEOMETRY_SHADER

const char *vs_source =

"#version 120\n"

"varying vec4 pos\n;"

"void main(void) {"

"  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"

"  pos = gl_ModelViewMatrix * gl_Vertex;\n"

"}\n";

#ifdef WORKING

const char *gs_source =

"//#version 150\n"

"#extension GL_EXT_geometry_shader4 : require\n"

"varying in vec4 pos[3];\n"

"void main(void) {\n"

"    for(int i = 0; i < 3; ++i){\n"

"        gl_Position = gl_PositionIn;\n"

"        gl_ClipDistance[0] = dot(pos, gl_ClipPlane[0]);\n"

"        gl_ClipDistance[1] = dot(pos, gl_ClipPlane[1]);\n"

"        EmitVertex();\n"

"    }"

"}\n";

#endif

#ifdef BUGED

#define USE_GEOMETRY_SHADER

const char *gs_source =

"//#version 150\n"

"#extension GL_EXT_geometry_shader4 : require\n"

"varying in vec4 pos[3];\n"

"void main(void) {\n"

"    for(int i = 0; i < 3; ++i){\n"

"        gl_Position = gl_PositionIn;\n"

"        for(int k = 0; k < 2; ++k){\n"

"            gl_ClipDistance = dot(pos, gl_ClipPlane);\n"

"        }\n"

"        EmitVertex();\n"

"    }"

"}\n";

#endif

#endif

//pos should be vec4[3] but it compiles, links and validates but genaretes access violation at runtime and drawing fails afterwards

#ifdef CASE_2

#define USE_GEOMETRY_SHADER

const char *vs_source =

"#version 120\n"

"varying vec4 pos\n;"

"void main(void) {"

"  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"

"  pos = gl_ModelViewMatrix * gl_Vertex;\n"

"}\n";

#ifdef BUGED

const char *gs_source =

"//#version 150\n"

"#extension GL_EXT_geometry_shader4 : require\n"

"varying in vec4 pos;\n"

"void main(void) {\n"

"    for(int i = 0; i < 3; ++i){\n"

"        gl_Position = gl_PositionIn;\n"

"        gl_ClipDistance[0] = dot(pos, gl_ClipPlane[0]);\n"

"        EmitVertex();\n"

"    }"

"}\n";

#endif

#endif

const char *fs_source =

"#version 120\n"

"void main(void) {\n"

"  gl_FragColor = vec4(1.0, 0,0,1);\n"

"}\n";

void printCompileError(GLuint obj){

    GLint logLength;

    glGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &logLength);

    std::vector<GLcharARB> errorLog(logLength,0);

    glGetInfoLogARB(obj, logLength,0,&errorLog[0]);

    fprintf(stderr, &errorLog[0]);

}

int init_resources(){

    GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;

    program = glCreateProgram();

    GLuint vs = glCreateShader(GL_VERTEX_SHADER);

    glShaderSource(vs, 1, &vs_source, NULL);

    glCompileShader(vs);

    glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_ok);

    if (0 == compile_ok){

        fprintf(stderr, "Error in vertex shader\n");

        printCompileError(vs);

        return 0;

    }

    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(fs, 1, &fs_source, NULL);

    glCompileShader(fs);

    glGetShaderiv(fs, GL_COMPILE_STATUS, &compile_ok);

    if (!compile_ok){

        fprintf(stderr, "Error in fragment shader\n");

        printCompileError(fs);

        return 0;

    }

    glAttachShader(program, vs);

    glAttachShader(program, fs);

#ifdef USE_GEOMETRY_SHADER

    GLuint gs = glCreateShader(GL_GEOMETRY_SHADER);

    glShaderSource(gs, 1, &gs_source, NULL);

    glCompileShader(gs);

    glGetShaderiv(gs, GL_COMPILE_STATUS, &compile_ok);

    if (!compile_ok){

        fprintf(stderr, "Error in geometry shader\n");

        printCompileError(gs);

        return 0;

    }

    glAttachShader(program, gs);

    glProgramParameteriARB(program, GL_GEOMETRY_INPUT_TYPE_ARB, GL_TRIANGLES);

    glProgramParameteriARB(program, GL_GEOMETRY_OUTPUT_TYPE_ARB, GL_TRIANGLE_STRIP);

    glProgramParameteriARB(program, GL_GEOMETRY_VERTICES_OUT_ARB, 3);

#endif

    glLinkProgram(program);

    glGetProgramiv(program, GL_LINK_STATUS, &link_ok);

    if (!link_ok) {

        fprintf(stderr, "glLinkProgram:");

        printCompileError(program);

        return 0;

    }           

    glutReportErrors();

    return 1;

}

void onDisplay()

{

    glClearColor(0.0, 0.0, 0.0, 1.0);

    glClear(GL_COLOR_BUFFER_BIT);

    double plane0[4] = {1.0, 0.0, 0.0, 0.3};

    double plane1[4] = {-1.0, 0.0, 0.0, 0.3};

    glEnable(GL_CLIP_PLANE0);

    glClipPlane(GL_CLIP_PLANE0, plane0);

    glEnable(GL_CLIP_PLANE1);

    glClipPlane(GL_CLIP_PLANE1, plane1);

    glUseProgram(program);

    glValidateProgram(program);

    int valid;

    glGetObjectParameterivARB(program, GL_OBJECT_VALIDATE_STATUS_ARB, &valid);

    if(!valid){

        fprintf(stderr, "validation failed");

        return;

    }

    glutSolidOctahedron();

    glutReportErrors();

    glutSwapBuffers();

}

int main(int argc, char** argv)

{

    glutInit(&argc, argv);

    glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);

    glutInitWindowSize(640, 480);

    glutCreateWindow("gltestcase");

    GLenum glew_status = glewInit();

    if (glew_status != GLEW_OK)

    {

        fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));

        return EXIT_FAILURE;

    }

    if (1 == init_resources())    {

        glutDisplayFunc(onDisplay);

        glutMainLoop();

    }

    return 0;

}

0 Likes
3 Replies
gsellers
Staff

Hi,

Thanks for the reports and detailed test cases. It looks like you have hit at least one bug here, though I suspect the issues are all related. I've forwarded your test cases to our shader compiler team and will let you know what they find.

Cheers,

Graham

0 Likes
gsellers
Staff

Hi,

Our engineers have been looking at these issues. We've found the root cause. The access violations have been fixed and the other issues are being worked on. Expect fixes in an upcoming driver. Thanks again for the report - it was very helpful.

Thanks,

Graham

0 Likes

This is good news, I like how quick this issue got resolved.

0 Likes