1 /*
2 * Copyright © 2012, 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 /** @file referenced-by-shader.c
25 *
26 * From the GL_ARB_uniform_buffer_object spec and
27 * Section 2.11.4(Uniform Variables) of OpenGL 3.2 Core:
28 *
29 * "If <pname> is UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER,
30 * UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER, or
31 * UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER, then a boolean
32 * value indicating whether the uniform block identified by
33 * <uniformBlockIndex> is referenced by the vertex, geometry, or
34 * fragment programming stage of <program>, respectively, is
35 * returned."
36 */
37
38 #include "piglit-util-gl.h"
39
40 PIGLIT_GL_TEST_CONFIG_BEGIN
41
42 config.supports_gl_compat_version = 10;
43 config.supports_gl_core_version = 31;
44 config.khr_no_error_support = PIGLIT_NO_ERRORS;
45
46 PIGLIT_GL_TEST_CONFIG_END
47
48 void
piglit_init(int argc,char ** argv)49 piglit_init(int argc, char **argv)
50 {
51 bool pass = true;
52 unsigned int i;
53 GLuint vs, gs, fs, prog;
54 const char *vs_source =
55 "%s"
56 "uniform vs { float v; };\n"
57 "uniform vsgs { float vg; };\n"
58 "uniform vsfs { float vf; };\n"
59 "uniform vsgsfs { float vgf; };\n"
60 "void main() {\n"
61 " gl_Position = vec4(v + vg + vf + vgf);\n"
62 "}\n";
63
64 const char *gs_source =
65 "%s"
66 "layout(triangles) in;\n"
67 "layout(triangle_strip, max_vertices=3) out;\n"
68 "uniform gs { float g; };\n"
69 "uniform vsgs { float vg; };\n"
70 "uniform gsfs { float gf; };\n"
71 "uniform vsgsfs { float vgf; };\n"
72 "void main() {\n"
73 " for(int i = 0; i < 3; i++) {\n"
74 " gl_Position = vec4(g + vg + gf + vgf);\n"
75 " EmitVertex();\n"
76 " }\n"
77 "}\n";
78
79 const char *fs_source =
80 "%s"
81 "uniform fs { float f; };\n"
82 "uniform vsfs { float vf; };\n"
83 "uniform gsfs { float gf; };\n"
84 "uniform vsgsfs { float vgf; };\n"
85 "void main() {\n"
86 " gl_FragColor = vec4(f + vf + gf + vgf);\n"
87 "}\n";
88
89 char name[10];
90 bool use_gs = piglit_get_gl_version() >= 32;
91 const char *header;
92 int num_uniforms_used = 0;
93
94 if (use_gs) {
95 header = "#version 150\n";
96 } else {
97 header = "#extension GL_ARB_uniform_buffer_object : enable\n";
98 piglit_require_extension("GL_ARB_uniform_buffer_object");
99 }
100
101 prog = glCreateProgram();
102
103 vs = piglit_compile_shader_formatted(GL_VERTEX_SHADER, vs_source, header);
104 glAttachShader(prog, vs);
105
106 if (use_gs) {
107 gs = piglit_compile_shader_formatted(GL_GEOMETRY_SHADER,
108 gs_source, header);
109 glAttachShader(prog, gs);
110 }
111
112 fs = piglit_compile_shader_formatted(GL_FRAGMENT_SHADER,
113 fs_source, header);
114 glAttachShader(prog, fs);
115
116 glLinkProgram(prog);
117 if (!piglit_link_check_status(prog)) {
118 piglit_report_result(PIGLIT_FAIL);
119 }
120
121 if (use_gs) {
122 num_uniforms_used = 7;
123 printf(" v g f\n");
124 } else {
125 num_uniforms_used = 6;
126 printf(" v f\n");
127 }
128
129 for (i = 0; i < num_uniforms_used; i++) {
130 GLint ref_vs = 0, ref_gs = 0, ref_fs = 0;
131 bool block_fail = false;
132
133 glGetActiveUniformBlockName(prog, i, sizeof(name), NULL, name);
134
135 glGetActiveUniformBlockiv(prog, i,
136 GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER,
137 &ref_vs);
138 if (use_gs) {
139 glGetActiveUniformBlockiv(prog, i,
140 GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER,
141 &ref_gs);
142 }
143 glGetActiveUniformBlockiv(prog, i,
144 GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER,
145 &ref_fs);
146
147 if (use_gs) {
148 printf("%10s: %d %d %d", name, ref_vs, ref_gs, ref_fs);
149 } else {
150 printf("%10s: %d %d", name, ref_vs, ref_fs);
151 }
152
153 if ((strstr(name, "vs") != 0) != ref_vs)
154 block_fail = true;
155 if (use_gs) {
156 if ((strstr(name, "gs") != 0) != ref_gs)
157 block_fail = true;
158 }
159 if ((strstr(name, "fs") != 0) != ref_fs)
160 block_fail = true;
161
162 if (block_fail) {
163 printf(" FAIL");
164 pass = false;
165 }
166
167 printf("\n");
168 }
169
170 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
171 }
172
piglit_display(void)173 enum piglit_result piglit_display(void)
174 {
175 /* UNREACHED */
176 return PIGLIT_FAIL;
177 }
178
179