1 /* Copyright © 2013 Intel Corporation
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice (including the next
11 * paragraph) shall be included in all copies or substantial portions of the
12 * Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 * IN THE SOFTWARE.
21 */
22 #include "piglit-util-gl.h"
23 #include "piglit-glx-util.h"
24 #include "query-renderer-common.h"
25
26 struct test_vector {
27 const char *name_string;
28 int attribute;
29 int value_count;
30 };
31
32 #define ENUM(name, count) { # name, name, count }
33
34 static const struct test_vector all_valid_integer_enums[] = {
35 ENUM(GLX_RENDERER_VENDOR_ID_MESA, 1),
36 ENUM(GLX_RENDERER_DEVICE_ID_MESA, 1),
37 ENUM(GLX_RENDERER_VERSION_MESA, 3),
38 ENUM(GLX_RENDERER_ACCELERATED_MESA, 1),
39 ENUM(GLX_RENDERER_VIDEO_MEMORY_MESA, 1),
40 ENUM(GLX_RENDERER_UNIFIED_MEMORY_ARCHITECTURE_MESA, 1),
41 ENUM(GLX_RENDERER_PREFERRED_PROFILE_MESA, 1),
42 ENUM(GLX_RENDERER_OPENGL_CORE_PROFILE_VERSION_MESA, 2),
43 ENUM(GLX_RENDERER_OPENGL_COMPATIBILITY_PROFILE_VERSION_MESA, 2),
44 ENUM(GLX_RENDERER_OPENGL_ES_PROFILE_VERSION_MESA, 2),
45 ENUM(GLX_RENDERER_OPENGL_ES2_PROFILE_VERSION_MESA, 2),
46 };
47
48 static const struct test_vector all_valid_string_enums[] = {
49 ENUM(GLX_RENDERER_VENDOR_ID_MESA, 0),
50 ENUM(GLX_RENDERER_DEVICE_ID_MESA, 0),
51 };
52
53 static bool
verify_integer_values(const char * name,Bool success,const struct test_vector * test,const unsigned * buffer,unsigned buffer_size,bool silent)54 verify_integer_values(const char *name, Bool success,
55 const struct test_vector *test,
56 const unsigned *buffer, unsigned buffer_size,
57 bool silent)
58 {
59 char text[512];
60 unsigned text_size;
61 bool pass = true;
62 unsigned j;
63
64 if (!success) {
65 fprintf(stderr, "%s(%s) failed.\n", name, test->name_string);
66
67 /* If the call failed, don't bother checking that the correct
68 * number of values were written.
69 */
70 return false;
71 }
72
73 if (!silent) {
74 text_size = snprintf(text, sizeof(text), "%s(%s) values:\n ",
75 name,
76 test->name_string);
77 for (j = 0; j < test->value_count; j++) {
78 text_size += snprintf(&text[text_size],
79 sizeof(text) - text_size,
80 "%d ",
81 buffer[j]);
82 }
83
84 printf("%s\n", text);
85 }
86
87 for (j = 0; j < test->value_count; j++) {
88 if (buffer[j] == 0xDEADBEEF) {
89 fprintf(stderr,
90 "%s(%s) only wrote %d values, expected %d.\n",
91 name,
92 test->name_string,
93 j,
94 test->value_count);
95 pass = false;
96 break;
97 }
98 }
99
100 for (j = test->value_count; j < buffer_size; j++) {
101 if (buffer[j] != 0xDEADBEEF) {
102 fprintf(stderr,
103 "%s(%s) wrote at least %d values, expected "
104 "only %d.\n",
105 name,
106 test->name_string,
107 j + 1,
108 test->value_count);
109 pass = false;
110 break;
111 }
112 }
113
114 /* value sanity check */
115 switch (test->attribute) {
116 case GLX_RENDERER_PREFERRED_PROFILE_MESA: {
117 unsigned legal = GLX_CONTEXT_CORE_PROFILE_BIT_ARB |
118 GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB |
119 GLX_CONTEXT_ES_PROFILE_BIT_EXT |
120 GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
121 if (buffer[0] & ~legal) {
122 fprintf(stderr, "Unknown bits set in preferred profile "
123 "bitmask: 0x%x\n", buffer[0] & ~legal);
124 pass = false;
125 }
126 if (!buffer[0]) {
127 fprintf(stderr, "No preferred API profile!\n");
128 pass = false;
129 } else if (buffer[0] & (buffer[0] - 1)) {
130 fprintf(stderr, "More than one preferred API profile\n");
131 pass = false;
132 }
133 break;
134 }
135 default:
136 break;
137 }
138
139 return pass;
140 }
141
142 static bool
subtest_QueryRendererInteger(Display * dpy)143 subtest_QueryRendererInteger(Display *dpy)
144 {
145 static const char subtest_name[] =
146 "glXQueryRendererIntegerMESA and "
147 "glXQueryCurrentRendererIntegerMESA";
148
149 bool pass = true;
150 unsigned i;
151
152 for (i = 0; i < ARRAY_SIZE(all_valid_integer_enums); i++) {
153 unsigned buffer_a[16];
154 unsigned buffer_b[ARRAY_SIZE(buffer_a)];
155 Bool success;
156 unsigned j;
157
158 for (j = 0; j < ARRAY_SIZE(buffer_a); j++) {
159 buffer_a[j] = 0xDEADBEEF;
160 buffer_b[j] = 0xDEADBEEF;
161 }
162
163 success =
164 glXQueryRendererIntegerMESA(dpy, 0, 0,
165 all_valid_integer_enums[i].attribute,
166 buffer_a);
167 pass = verify_integer_values("glXQueryRendererIntegerMESA",
168 success,
169 &all_valid_integer_enums[i],
170 buffer_a,
171 ARRAY_SIZE(buffer_a),
172 false)
173 && pass;
174
175 success =
176 glXQueryCurrentRendererIntegerMESA(
177 all_valid_integer_enums[i].attribute,
178 buffer_b);
179 pass = verify_integer_values("glXQueryCurrentRendererIntegerMESA",
180 success,
181 &all_valid_integer_enums[i],
182 buffer_b,
183 ARRAY_SIZE(buffer_b),
184 true)
185 && pass;
186
187 for (j = 0; j < all_valid_integer_enums[i].value_count; j++) {
188 if (buffer_a[j] != buffer_b[j]) {
189 fprintf(stderr,
190 "glXQueryRendererIntegerMESA and "
191 "glXQueryCurrentRendererIntegerMESA "
192 "disagree about %s value %d: "
193 "%d != %d\n",
194 all_valid_integer_enums[i].name_string,
195 j,
196 buffer_a[j],
197 buffer_b[j]);
198 pass = false;
199 }
200 }
201 }
202
203 piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
204 subtest_name);
205 return pass;
206 }
207
208 static bool
subtest_QueryRendererString(Display * dpy)209 subtest_QueryRendererString(Display *dpy)
210 {
211 static const char subtest_name[] =
212 "glXQueryRendererStringMESA and "
213 "glXQueryCurrentRendererStringMESA";
214
215 bool pass = true;
216 unsigned i;
217
218 for (i = 0; i < ARRAY_SIZE(all_valid_string_enums); i++) {
219 const char *string_a;
220 const char *string_b;
221
222 string_a =
223 glXQueryRendererStringMESA(dpy, 0, 0,
224 all_valid_string_enums[i].attribute);
225 if (string_a == NULL) {
226 fprintf(stderr,
227 "glXQueryRendererStringMESA(%s) failed.\n",
228 all_valid_string_enums[i].name_string);
229 pass = false;
230 } else {
231 printf("glXQueryRendererStringMESA(%s) value:\n"
232 " %s\n",
233 all_valid_string_enums[i].name_string,
234 string_a);
235 }
236
237 string_b = glXQueryCurrentRendererStringMESA(all_valid_string_enums[i].attribute);
238 if (string_b == NULL) {
239 fprintf(stderr,
240 "glXQueryRendererStringMESA(%s) failed.\n",
241 all_valid_string_enums[i].name_string);
242 pass = false;
243 }
244
245 if (string_a != NULL && string_b != NULL
246 && strcmp(string_a, string_b) != 0) {
247 fprintf(stderr,
248 "glXQueryRendererIntegerMESA and "
249 "glXQueryCurrentRendererIntegerMESA "
250 "disagree about %s: %s != %s\n",
251 all_valid_string_enums[i].name_string,
252 string_a,
253 string_b);
254 pass = false;
255 }
256 }
257
258 piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
259 subtest_name);
260 return pass;
261 }
262
main(int argc,char ** argv)263 int main(int argc, char **argv)
264 {
265 bool pass = true;
266 Display *dpy = NULL;
267 GLXFBConfig fbconfig = None;
268 XVisualInfo *visinfo = NULL;
269 Window win = None;
270 GLXWindow glxWin = None;
271 GLXContext ctx;
272
273 dpy = piglit_get_glx_display();
274
275 piglit_require_glx_version(dpy, 1, 4);
276
277 initialize_function_pointers(dpy);
278
279 visinfo = piglit_get_glx_visual(dpy);
280 fbconfig = piglit_glx_get_fbconfig_for_visinfo(dpy, visinfo);
281
282 win = piglit_get_glx_window_unmapped(dpy, visinfo);
283 glxWin = glXCreateWindow(dpy, fbconfig, win, NULL);
284
285 ctx = glXCreateNewContext(dpy, fbconfig, GLX_RGBA_TYPE, NULL, True);
286 if (ctx == NULL) {
287 fprintf(stderr, "Unable to create OpenGL context!\n");
288 piglit_report_result(PIGLIT_FAIL);
289 }
290
291 glXMakeContextCurrent(dpy, glxWin, glxWin, ctx);
292 piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
293
294 pass = subtest_QueryRendererInteger(dpy) && pass;
295 pass = subtest_QueryRendererString(dpy) && pass;
296
297 glXMakeContextCurrent(dpy, 0, 0, 0);
298
299 piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
300 return 0;
301 }
302