cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

nesister
Journeyman III

GL_UNIFORM_BLOCK_DATA_SIZE seems to report wrong size.

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.

 

0 Likes
3 Replies
pboudier
Staff

0x80==128 ?

Pierre B.

0 Likes

 

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";





 

0 Likes

seems like the value is off by 48 bytes each time; weird.

 

anyway, thanks for the report, we will look into it.

 

Pierre B.

 

0 Likes