Re: GL_ACTIVE_UNIFORMS returns unexpected value

Lascha Lagidse <[email protected]>
Newsgroups gmane.comp.video.mesa3d.user
Message-ID <[email protected]>
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
_______________________________________________
mesa-users mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/mesa-users
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.