[Mesa-users] GL_ACTIVE_UNIFORMS returns unexpected value

Lascha Lagidse laschalagidse at triumphstudios.com
Thu Mar 19 10:20:42 PDT 2015


On 3/19/2015 3:34 PM, Brian Paul wrote:
> On 03/19/2015 08:20 AM, Brian Paul wrote:
>> On 03/19/2015 04:16 AM, Lascha Lagidse wrote:
>>> On 3/18/2015 6:12 PM, Brian Paul wrote:
>>>> On 03/18/2015 09:37 AM, Lascha Lagidse wrote:
>>>>> Hello :)
>>>>>
>>>>> I am Lascha, new to linux and first time subscribing to a mailing 
>>>>> list.
>>>>> I heard you were great guys ;)
>>>>
>>>> We try to be. :)
>>>>
>>>>
>>>>> So, I am currently in the process of porting the game Age of 
>>>>> Wonders 3
>>>>> to Linux. The game is currently in open-beta on Steam, and people
>>>>> reported issues with the specifically the Mesa graphics driver. I 
>>>>> had a
>>>>> look and it looks like this driver behaves differently on this driver
>>>>> when using glGetProgramiv and glGetActiveUniform.
>>>>>
>>>>> The vertex shader (see bottom) is attached to a program. The 
>>>>> program is
>>>>> then linked. Note: Only this vertex shader is attached to the 
>>>>> program;
>>>>> there is no other shader attached. Now using glGetProgramiv with
>>>>> GL_ACTIVE_UNIFORMS will return 2, but I expect it to be 3 like on the
>>>>> other drivers. According to glGetActiveUniform it is the variable 
>>>>> 'c24'
>>>>> which is missing. My guess is that it's optimized away, for some
>>>>> reason.
>>>>> If I also link the fragment shader, then 'c24' is listed correctly.
>>>>>
>>>>> My goal is to retrieve the active uniforms from specifically the 
>>>>> vertex
>>>>> shader. If I link both the vertex AND the fragment program, then 
>>>>> there
>>>>> is no way to distinguish which uniforms belong to the vertex program
>>>>> and
>>>>> which belong to the fragment program (or is there?).
>>>>>
>>>>> I can't think of a nice work-around; but since this is only
>>>>> initialization code the only work-around that comes to mind is to
>>>>> serialize the info I get from glGetActiveUniform on another driver 
>>>>> and
>>>>> use that info instead of calling glGetActiveUniform at 
>>>>> initialization.
>>>>>
>>>>> #version 140
>>>>> uniform mat4 c20;
>>>>> uniform vec4 c24;
>>>>> uniform vec4 c25;
>>>>> in vec3 POSITION0;
>>>>> in vec2 TEXCOORD0;
>>>>> out vec2 xlv_TEXCOORD0;
>>>>> void main ()
>>>>> {
>>>>>    vec4 PosWS_1;
>>>>>    PosWS_1.xy = (c25.xy + (POSITION0.xy * c25.zw));
>>>>>    PosWS_1.z = POSITION0.z;
>>>>>    PosWS_1.w = 1.0;
>>>>>    gl_Position = (c20 * PosWS_1);
>>>>>    xlv_TEXCOORD0 = (c24.xy + (TEXCOORD0 * c24.zw));
>>>>> }
>>>>
>>>> Which version of Mesa are you using?  Would it be possible to get a
>>>> simple glut/piglit test program?
>>>>
>>>> -Brian
>>>>
>>> Sorry if you're receiving this multiple times. I think I should have
>>> used 'Reply All' instead of 'Reply'. Realized this too late.
>>>
>>> I'm using "3.3 (Core profile) Mesa 10.3.2" (according to GL_VERSION).
>>>
>>> Here is a simple test program. It uses freeglut and glew. I hope that's
>>> okay.
>>>
>>> #include <GL/glew.h>
>>> #include <GL/freeglut.h>
>>> #include <stdlib.h>
>>> #include <cstdio>
>>> #include <cstring>
>>>
>>> int main(int argc, char *argv[])
>>> {
>>>    glutInit(&argc, argv);
>>>    glutInitWindowSize(128,128);
>>>    glutInitWindowPosition(10,10);
>>>    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
>>>    glutInitContextVersion(3, 3);
>>>    glutInitContextFlags(GLUT_CORE_PROFILE);
>>>    glutCreateWindow("LinuxShaderBug");
>>>    glewInit();
>>>
>>>    printf("version: %s\n", glGetString(GL_VERSION));
>>>
>>>    const GLchar* shader_code = "#version 140\n\
>>>      uniform mat4 c20;\n\
>>>      uniform vec4 c24;\n\
>>>      uniform vec4 c25;\n\
>>>      in vec3 POSITION0;\n\
>>>      in vec2 TEXCOORD0;\n\
>>>      out vec2 xlv_TEXCOORD0;\n\
>>>      void main ()\n\
>>>      {\n\
>>>        vec4 PosWS_1;\n\
>>>        PosWS_1.xy = (c25.xy + (POSITION0.xy * c25.zw));\n\
>>>        PosWS_1.z = POSITION0.z;\n\
>>>        PosWS_1.w = 1.0;\n\
>>>        gl_Position = (c20 * PosWS_1);\n\
>>>        xlv_TEXCOORD0 = (c24.xy + (TEXCOORD0 * c24.zw));\n\
>>>      }\n";
>>>
>>>    const GLchar* shader_code_array[1] = { shader_code };
>>>    const GLint shader_size_array[1] = { strlen(shader_code) };
>>>    GLuint shader_handle = glCreateShader(GL_VERTEX_SHADER);
>>>    glShaderSource(shader_handle, 1, shader_code_array,
>>> shader_size_array);
>>>    glCompileShader(shader_handle);
>>>
>>>    GLuint program_handle = glCreateProgram();
>>>    glAttachShader(program_handle, shader_handle);
>>>    glLinkProgram(program_handle);
>>>
>>>    GLint num_uniforms = 0;
>>>    glGetProgramiv(program_handle, GL_ACTIVE_UNIFORMS, &num_uniforms);
>>>    printf("num_uniforms: %i\n", num_uniforms);
>>>
>>>    char u_name[32];
>>>    GLsizei u_name_len = 0;
>>>    GLint u_size = 0;
>>>    GLenum u_type = GL_NONE;
>>>    GLint u_idx = 0;
>>>
>>>    for (u_idx = 0; u_idx < num_uniforms; ++u_idx)
>>>    {
>>>      glGetActiveUniform(program_handle, u_idx, 31, &u_name_len, 
>>> &u_size,
>>> &u_type, &u_name[0]);
>>>      printf("u_name: %s\n", u_name);
>>>    }
>>>
>>>    return EXIT_SUCCESS;
>>> }
>>
>> Thanks.  Looks like it's the same with current Mesa from git. Seems
>> like a bug to me.  I'll probably convert your test to a piglit test. Not
>> sure if I'll have time to debug this, bug I can file a bug anyway.
>
> Actually, this may not be a bug.  Since there's no fragment shader, 
> the xlv_TEXCOORD0 output variable is unused.  Therefore, the uniform 
> c24 is unused also.  So that's why it's not considered active.
>
> Does your actual program have a fragment shader that uses xlv_TEXCOORD0?
>
> -Brian
>

That's what I thought too, but wasn't sure since other drivers do report is
as active with the same sample code. Then again, I don't know how the
'standard' behavior is documented. If it is not documented, then I feel
like I should stay away from using it like this.

Yes, it does have a fragment shader that uses xlv_TEXCOORD0, but the
reason it is not linked here is because I want to retrieve specifically the
uniform variables in the vertex shader. If I link the fragment shader as
well, then I don't think there's a way to tell which active uniform 
variables
originate from the vertex shader, because they're grouped. Am I taking
the wrong approach here?

I suppose I could also filter out the uniforms in the vertex shader by
parsing over it myself, and then cross-reference with the program that
has both the vertex /and/ the fragment shader linked.

-Lascha


More information about the mesa-users mailing list