3 Replies Latest reply on Oct 18, 2010 4:40 PM by pboudier

    GL_UNIFORM_BLOCK_DATA_SIZE seems to report wrong size.

    nesister

      Hi again,

      using GL_UNIFORM_BLOCK_DATA_SIZE in glGetActiveUniformBlockiv to query the minimum total buffer object size seems to report wrong informations. Querying the following program when successfuly compiled and linked returns 80 bytes for the uniform block named 'Transform'. It should return at least 128 for the two 4x4 floating point matrices it contains.

       

      vertex shader:

      #version 330

      in vec3 position;

      uniform Transform {

        mat4x4 modelview[2];

      };

      void main() {

        gl_Position = modelview[gl_InstanceID] * vec4(position, 1);

      }

       

      fragment shader:

      #version 330

      void main() {

        gl_FragColor = vec4(1, 0, 0, 1);

      }

       

      Querying 'modelview' uniform's array stride using GL_UNIFORM_ARRAY_STRIDE returns the right value with 64 bytes. I can provide a simple test case for this issue if you want.

       

      Is there an OpenGL specific bugtracker somewhere we can use to search and eventually report issues ?

      Thanks.

       

          • GL_UNIFORM_BLOCK_DATA_SIZE seems to report wrong size.
            nesister

             

             

            Hi Pierre,

            I'm not sure of what you meant but given this piece of code:

             

            GLuint index = glGetUniformBlockIndex(prg, "Transform");

            GLint value;

            glGetActiveUniformBlockiv(prg, index, GL_UNIFORM_BLOCK_DATA_SIZE, &value);

            std::cout << "'Transform' block at index=" << index << " size=" << value << std::endl;



             

            Output using the example shader given in my first post is : 'Transform' block at index=0 size=80.

            80 is not in hexadecimal notation.

             

            FYI here's the complete test case I used:

             

            #include <GL/glut.h>

            #include <GL/glext.h>

            #include <wingdi.h>

            #include <cstdio>

            #include <sstream>

            #include <iostream>

             

            #define WIDTH 640

            #define HEIGHT 480

             

            PFNGLCREATESHADERPROC glCreateShader;

            PFNGLSHADERSOURCEPROC glShaderSource;

            PFNGLCOMPILESHADERPROC glCompileShader;

            PFNGLATTACHSHADERPROC glAttachShader;

            PFNGLCREATEPROGRAMPROC glCreateProgram;

            PFNGLLINKPROGRAMPROC glLinkProgram;

            PFNGLLINKPROGRAMPROC glUseProgram;

            PFNGLGETSHADERIVPROC glGetShaderiv;

            PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;

            PFNGLGETPROGRAMIVPROC glGetProgramiv;

            PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;

            PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation;

            PFNGLGETACTIVEUNIFORMBLOCKIVPROC glGetActiveUniformBlockiv;

            PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glGetActiveUniformBlockName;

            PFNGLGETUNIFORMBLOCKINDEXPROC glGetUniformBlockIndex;

            PFNGLGETACTIVEUNIFORMSIVPROC glGetActiveUniformsiv;

            PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;

             

            static const char *vp =

                "#version 330\n"

                "in vec3 position;\n"

                "uniform Transform {\n"

                " mat4x4 modelview[2];\n"

                "};\n"

                "void main() {\n"

                "    gl_Position = modelview[gl_InstanceID] * vec4(position, 1);\n"

                "}\n";

             

            static const char *fp =

                "#version 330\n"

                "\n"

                "void main() {\n"

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

                "}\n";

             

            template

            bool load_gl_proc(const char *name, T &ptr);

            GLuint create_shader(GLenum type, const char *src);

            GLuint create_program(GLuint vp, GLuint fp);

            std::string enum_name(GLenum value);

             

            int

            main(int argc, char **argv)

            {

                glutInit(&argc, argv);

                glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);

                glutInitWindowSize(WIDTH, HEIGHT);

             

                int window = glutCreateWindow(argv[0]);

             

                std::cout << "GL_VENDOR=" << glGetString(GL_VENDOR) << std::endl;

                std::cout << "GL_RENDERER=" << glGetString(GL_RENDERER) << std::endl;

                std::cout << "GL_VERSION=" << glGetString(GL_VERSION) << std::endl;

             

            #define LOAD_GL_PROC(proc) load_gl_proc(#proc, proc);

                LOAD_GL_PROC(glCreateShader);

                LOAD_GL_PROC(glShaderSource);

                LOAD_GL_PROC(glCompileShader);

                LOAD_GL_PROC(glAttachShader);

                LOAD_GL_PROC(glCreateProgram);

                LOAD_GL_PROC(glLinkProgram);

                LOAD_GL_PROC(glUseProgram);

                LOAD_GL_PROC(glGetShaderiv);

                LOAD_GL_PROC(glGetShaderInfoLog);

                LOAD_GL_PROC(glGetProgramiv);

                LOAD_GL_PROC(glGetProgramInfoLog);

                LOAD_GL_PROC(glGetAttribLocation);

                LOAD_GL_PROC(glGetActiveUniformBlockiv);

                LOAD_GL_PROC(glGetActiveUniformBlockName);

                LOAD_GL_PROC(glGetUniformBlockIndex);

                LOAD_GL_PROC(glGetActiveUniformsiv);

                LOAD_GL_PROC(glGetActiveUniform);

            #undef LOAD_PROC

             

                GLuint vtx = create_shader(GL_VERTEX_SHADER, vp);

                GLuint frg = create_shader(GL_FRAGMENT_SHADER, fp);

                GLuint prg = create_program(vtx, frg);

             

                GLuint index = glGetUniformBlockIndex(prg, "Transform");

                GLint value;

                glGetActiveUniformBlockiv(prg, index, GL_UNIFORM_BLOCK_DATA_SIZE, &value);

                std::cout << "'Transform' block at index=" << index << " size=" << value << std::endl;

             

                GLint uniforms;

                glGetProgramiv(prg, GL_ACTIVE_UNIFORMS, &uniforms);

                for (GLuint i = 0; i < static_cast(uniforms); ++i) {

                    GLenum type;

                    GLint  count, block_index, offset, stride;

                    GLchar name[128];

             

                    glGetActiveUniformsiv(prg, 1, &i, GL_UNIFORM_BLOCK_INDEX, &block_index);

                    glGetActiveUniformsiv(prg, 1, &i, GL_UNIFORM_OFFSET, &offset);

                    glGetActiveUniformsiv(prg, 1, &i, GL_UNIFORM_ARRAY_STRIDE, &stride);

                    glGetActiveUniform(prg, i, 128, NULL, &count, &type, name);

             

                    std::cout << "Found uniform named '" << name << "' in block " << block_index << " type=" << enum_name(type) << " count=" << count << " offset=" << offset << " stride=" << stride << std::endl;

                }

             

                glutDestroyWindow(window);

                getchar();

             

                return 0;

            }

             

            template

            bool

            load_gl_proc(const char *name, T &ptr)

            {

                ptr = reinterpret_cast(wglGetProcAddress(name));

                if (ptr == 0)

                    std::cerr << "Couldn't load " << name << std::endl;

                return ptr != 0;

            }

             

            GLuint

            create_shader(GLenum type, const char *src)

            {

                GLuint shader = glCreateShader(type);

                glShaderSource(shader, 1, &src, 0);

                glCompileShader(shader);

                GLint compile;

                glGetShaderiv(shader, GL_COMPILE_STATUS, &compile);

                if (compile != GL_TRUE) {

                    GLint len;

                    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);

             

                    GLchar *output = new GLchar[len];

                    glGetShaderInfoLog(shader, len, 0, output);

                    std::cerr << "Shader compilation failed: " << output << std::endl;

                    delete[] output;

                    shader = 0;

                }

                return shader;

            }

             

            GLuint

            create_program(GLuint vp, GLuint fp)

            {

                GLuint program = glCreateProgram();

                glAttachShader(program, vp);

                glAttachShader(program, fp);

                glLinkProgram(program);

                GLint link;

                glGetProgramiv(program, GL_LINK_STATUS, &link);

                if (link != GL_TRUE) {

                    GLint len;

                    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);

                    GLchar *output = new GLchar[len];

                    glGetProgramInfoLog(program, len, 0, output);

                    std::cerr << "Program link failed: " << output << std::endl;

                    delete[] output;

                    program = 0;

                }

                return program;

            }

             

            std::string

            enum_name(GLenum value)

            {

            #define ENUM_NAME(x) case x: return #x;

                switch (value) {

                ENUM_NAME(GL_NO_ERROR);

                ENUM_NAME(GL_INVALID_ENUM);

                ENUM_NAME(GL_INVALID_VALUE);

                ENUM_NAME(GL_INVALID_OPERATION);

                ENUM_NAME(GL_STACK_OVERFLOW);

                ENUM_NAME(GL_STACK_UNDERFLOW);

                ENUM_NAME(GL_OUT_OF_MEMORY);

                ENUM_NAME(GL_TABLE_TOO_LARGE);

                ENUM_NAME(GL_INVALID_FRAMEBUFFER_OPERATION);

                ENUM_NAME(GL_FLOAT);

                ENUM_NAME(GL_FLOAT_VEC2);

                ENUM_NAME(GL_FLOAT_VEC3);

                ENUM_NAME(GL_FLOAT_VEC4);

                ENUM_NAME(GL_INT);

                ENUM_NAME(GL_INT_VEC2);

                ENUM_NAME(GL_INT_VEC3);

                ENUM_NAME(GL_INT_VEC4);

                ENUM_NAME(GL_UNSIGNED_INT);

                ENUM_NAME(GL_UNSIGNED_INT_VEC2);

                ENUM_NAME(GL_UNSIGNED_INT_VEC3);

                ENUM_NAME(GL_UNSIGNED_INT_VEC4);

                ENUM_NAME(GL_BOOL);

                ENUM_NAME(GL_BOOL_VEC2);

                ENUM_NAME(GL_BOOL_VEC3);

                ENUM_NAME(GL_BOOL_VEC4);

                ENUM_NAME(GL_FLOAT_MAT2);

                ENUM_NAME(GL_FLOAT_MAT3);

                ENUM_NAME(GL_FLOAT_MAT4);

                ENUM_NAME(GL_FLOAT_MAT2x3);

                ENUM_NAME(GL_FLOAT_MAT2x4);

                ENUM_NAME(GL_FLOAT_MAT3x2);

                ENUM_NAME(GL_FLOAT_MAT3x4);

                ENUM_NAME(GL_FLOAT_MAT4x2);

                ENUM_NAME(GL_FLOAT_MAT4x3);

                default:;

                }

             

                std::stringstream unknown;

                unknown << "unknown enum (0x" << std::hex << value << ')';

                return unknown.str();

            }



             

            Test case output is :

             

            GL_VENDOR=ATI Technologies Inc.

            GL_RENDERER=ATI Radeon HD 5600 Series

            GL_VERSION=4.0.10188 Compatibility Profile Context

            'Transform' block at index=0 size=80

            Found uniform named 'modelview' in block 0 type=GL_FLOAT_MAT4 count=2 offset=0 stride=64



             

            I initialy found this issue with another shader whose uniform block size was supposed to be 256 but for which glGetActiveUniformBlockiv returned 208. 48 bytes were missing here too. Shader source was (uniform block is 'Transform'):

             

            static const std::string vp =

                "#version 330\n"

                "in vec3 position;\n"

                "in vec2 tex_coords;\n"

                "out vec2 texCoords;\n"

                "uniform Transform {\n"

                "    mat4 texTransfo[2];\n"

                "    mat4 modelview[2];\n"

                "};\n"

                "\n"

                "void main() {\n"

                "    texCoords = (texTransfo[gl_InstanceID] * vec4(tex_coords, 0, 0)).xy;\n"

                "    gl_Position = modelview[gl_InstanceID] * vec4(position, 1);\n"

                "}\n";

            static const std::string fp =

                "#version 330\n"

                "uniform sampler2D tex;\n"

                "in vec2 texCoords;\n"

                "out vec4 out_color;\n"

                "\n"

                "void main() {\n"

                "    vec4 color = texture(tex, texCoords);\n"

                "    out_color = color;\n"

                "}\n";