[Mesa-users] GL_ACTIVE_UNIFORMS returns unexpected value

Lascha Lagidse laschalagidse at triumphstudios.com
Fri Mar 20 03:39:46 PDT 2015


On 3/19/2015 6:32 PM, Brian Paul wrote:
> On 03/19/2015 11:20 AM, Lascha Lagidse wrote:
>> 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?
>
> Yeah, link time is when we determine the location of each uniform.  If 
> the linker determines that a uniform isn't actually used, it's not 
> considered "active" and not reported (and gets location -1).  IIRC, 
> OpenGL doesn't let you query which shader(s) a uniform variable is 
> used in.
>
>
>> 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
>
> -Brian
>

I've changed the code to avoid using a shader program with only one
shader type attached. Instead I parse each type separately and cross-
reference it to the shader program with all shaders linked. This way I
can tell which uniform belongs to which shader type. The game
renders nicely now.

Thank you very much, Brian.

-Lascha


More information about the mesa-users mailing list