[Mesa-users] GL_ACTIVE_UNIFORMS returns unexpected value
Brian Paul
brianp at vmware.com
Thu Mar 19 10:32:55 PDT 2015
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
More information about the mesa-users
mailing list