README: recommend Ninja by default and switch to cmake --build
[piglit.git] / tests / glx / glx-tfp.c
blob58fd8b2c6ef1a49696fe747df38b8452461bf06e
1 /*
2 * Copyright © 2009 Intel Corporation
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:
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.
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 DEALINGS
21 * IN THE SOFTWARE.
23 * Authors:
24 * Eric Anholt <eric@anholt.net>
28 /** @file glx-tfp.c
29 * Tests the GLX_EXT_texture_from_pixmap extension, in particular the bug
30 * reported in https://bugs.freedesktop.org/show_bug.cgi?id=19910 in which
31 * the RGB/RGBA attribute of the drawable was misplaced, resulting in always
32 * acting as if the pixmap had the alpha channel present.
34 * This test is based loosely on the testcase attached to that bug, by
35 * Neil Roberts <neil@linux.intel.com>.
38 #include "piglit-util-gl.h"
39 #include "piglit-glx-util.h"
40 #include "GL/glx.h"
41 #include "X11/extensions/Xrender.h"
43 GLfloat tex_data[4][4] = {
44 { 1.0, 0.5, 0.0, 1.0 },
45 { 1.0, 0.5, 0.0, 0.5 },
46 { 0.0, 1.0, 0.0, 1.0 },
47 { 0.0, 1.0, 0.0, 0.5 },
50 #define WIN_WIDTH 256
51 #define WIN_HEIGHT 128
53 static GLXPixmap rgb_pixmap, rgba_pixmap;
54 static Display *dpy;
55 static Window win;
56 int piglit_width = WIN_WIDTH;
57 int piglit_height = WIN_HEIGHT;
59 static PFNGLXBINDTEXIMAGEEXTPROC pglXBindTexImageEXT;
60 static PFNGLXRELEASETEXIMAGEEXTPROC pglXReleaseTexImageEXT;
62 static GLboolean
63 check_pixel(GLboolean has_alpha, GLfloat *tex_color, int x, int y)
65 GLfloat color[3];
67 if (has_alpha) {
68 color[0] = tex_color[0] * tex_color[3];
69 color[1] = tex_color[1] * tex_color[3];
70 color[2] = tex_color[2] * tex_color[3];
71 } else {
72 color[0] = tex_color[0];
73 color[1] = tex_color[1];
74 color[2] = tex_color[2];
77 return piglit_probe_pixel_rgb(x, y, color);
80 static GLboolean
81 check_results(GLboolean has_alpha, int x, int y, int w, int h)
83 GLboolean pass = GL_TRUE;
85 pass &= check_pixel(has_alpha, tex_data[0],
86 x + w * 1 / 4, y + h * 1 / 4);
87 pass &= check_pixel(has_alpha, tex_data[1],
88 x + w * 3 / 4, y + h * 1 / 4);
89 pass &= check_pixel(has_alpha, tex_data[2],
90 x + w * 1 / 4, y + h * 3 / 4);
91 pass &= check_pixel(has_alpha, tex_data[3],
92 x + w * 3 / 4, y + h * 3 / 4);
94 return pass;
97 static void
98 draw_pixmap(GLXPixmap pixmap, int x, int y, int w, int h)
100 GLuint texname;
101 GLfloat tex_coords[] = {
102 0.0f, 0.0f,
103 1.0f, 0.0f,
104 1.0f, 1.0f,
105 0.0f, 1.0f,
107 GLfloat vertex_coords[4][2];
109 vertex_coords[0][0] = x;
110 vertex_coords[0][1] = y;
111 vertex_coords[1][0] = x + w;
112 vertex_coords[1][1] = y;
113 vertex_coords[2][0] = x + w;
114 vertex_coords[2][1] = y + h;
115 vertex_coords[3][0] = x;
116 vertex_coords[3][1] = y + h;
118 /* Create the texture. */
119 glGenTextures(1, &texname);
120 glBindTexture(GL_TEXTURE_2D, texname);
121 glEnable(GL_TEXTURE_2D);
123 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
124 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
125 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
126 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
128 /* Set the texture combiner to give {r*a, g*a, b*a, a} so we can see
129 * the effect of the alpha channel in terms of color.
131 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
132 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
133 glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
135 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
136 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
137 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
139 glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_ALPHA);
140 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_TEXTURE);
141 glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE); /* ignored */
143 pglXBindTexImageEXT(dpy, pixmap, GLX_FRONT_LEFT_EXT, NULL);
145 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
146 glTexCoordPointer(2, GL_FLOAT, 0, tex_coords);
148 glEnableClientState(GL_VERTEX_ARRAY);
149 glVertexPointer(2, GL_FLOAT, 0, vertex_coords);
151 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
153 pglXReleaseTexImageEXT(dpy, pixmap, GLX_FRONT_LEFT_EXT);
154 glDeleteTextures(1, &texname);
155 glDisableClientState(GL_VERTEX_ARRAY);
156 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
157 glDisable(GL_TEXTURE_2D);
160 static enum piglit_result
161 draw(Display *dpy)
163 GLboolean pass = GL_TRUE;
164 int draw_w = piglit_width / 4;
165 int draw_h = piglit_height / 2;
166 int rgb_x = piglit_width / 8;
167 int rgb_y = piglit_height / 4;
168 int rgba_x = piglit_width * 5 / 8;
169 int rgba_y = piglit_height / 4;
171 /* Clear background to gray */
172 glClearColor(0.5, 0.5, 0.5, 1.0);
173 glClear(GL_COLOR_BUFFER_BIT);
175 draw_pixmap(rgb_pixmap, rgb_x, rgb_y, draw_w, draw_h);
176 draw_pixmap(rgba_pixmap, rgba_x, rgba_y, draw_w, draw_h);
178 pass &= check_results(GL_FALSE, rgb_x, rgb_y, draw_w, draw_h);
179 pass &= check_results(GL_TRUE, rgba_x, rgba_y, draw_w, draw_h);
181 glXSwapBuffers(dpy, win);
183 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
186 static void
187 set_pixel(Display *dpy, Picture picture, int x, int y, GLfloat *color)
189 XRectangle rect = {x, y, 1, 1};
190 XRenderColor render_color;
192 render_color.red = 0xffff * color[0];
193 render_color.green = 0xffff * color[1];
194 render_color.blue = 0xffff * color[2];
195 render_color.alpha = 0xffff * color[3];
197 XRenderFillRectangles(dpy, PictOpSrc, picture, &render_color, &rect, 1);
201 * Creates a Pixmap and GLXPixmap with tex_data as the contents.
203 static GLXPixmap
204 create_pixmap(GLenum format)
206 static const int rgb_fb_config_attribs[] = {
207 GLX_RENDER_TYPE, GLX_RGBA_BIT,
208 GLX_RED_SIZE, 8,
209 GLX_GREEN_SIZE, 8,
210 GLX_BLUE_SIZE, 8,
211 GLX_ALPHA_SIZE, 0,
212 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
213 GLX_BIND_TO_TEXTURE_RGB_EXT, 1,
214 None
216 static const int rgba_fb_config_attribs[] = {
217 GLX_RENDER_TYPE, GLX_RGBA_BIT,
218 GLX_RED_SIZE, 8,
219 GLX_GREEN_SIZE, 8,
220 GLX_BLUE_SIZE, 8,
221 GLX_ALPHA_SIZE, 8,
222 GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
223 GLX_BIND_TO_TEXTURE_RGBA_EXT, 1,
224 None
226 static const int rgb_pixmap_attribs[] = {
227 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
228 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT,
229 None
231 static const int rgba_pixmap_attribs[] = {
232 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
233 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
234 None
236 static const int *fb_config_attribs, *pixmap_attribs;
237 GLXFBConfig *fb_configs;
238 GLXFBConfig fb_config;
239 int n_fb_configs;
240 Pixmap pixmap;
241 GLXPixmap glx_pixmap;
242 XVisualInfo *vis;
243 XRenderPictFormat *render_format;
244 Picture picture;
246 if (format == GL_RGBA) {
247 fb_config_attribs = rgba_fb_config_attribs;
248 pixmap_attribs = rgba_pixmap_attribs;
249 render_format = XRenderFindStandardFormat(dpy,
250 PictStandardARGB32);
251 } else {
252 fb_config_attribs = rgb_fb_config_attribs;
253 pixmap_attribs = rgb_pixmap_attribs;
254 render_format = XRenderFindStandardFormat(dpy,
255 PictStandardRGB24);
258 fb_configs = glXChooseFBConfig(dpy, DefaultScreen(dpy),
259 fb_config_attribs,
260 &n_fb_configs);
263 if (fb_configs == NULL || n_fb_configs < 1) {
264 fprintf(stderr, "No %s TFP FB config found\n",
265 format == GL_RGBA ? "RGBA" : "RGB");
266 return None;
268 fb_config = fb_configs[n_fb_configs - 1];
270 pixmap = XCreatePixmap(dpy, RootWindow(dpy, DefaultScreen(dpy)),
271 2, 2, render_format->depth);
272 picture = XRenderCreatePicture(dpy, pixmap, render_format, 0, NULL);
274 glx_pixmap = glXCreatePixmap(dpy, fb_config, pixmap, pixmap_attribs);
276 vis = glXGetVisualFromFBConfig(dpy, fb_config);
278 set_pixel(dpy, picture, 0, 0, tex_data[0]);
279 set_pixel(dpy, picture, 1, 0, tex_data[1]);
280 set_pixel(dpy, picture, 0, 1, tex_data[2]);
281 set_pixel(dpy, picture, 1, 1, tex_data[3]);
283 XFree(fb_configs);
284 XFree(vis);
286 return glx_pixmap;
289 static void init(void)
291 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
293 rgb_pixmap = create_pixmap(GL_RGB);
294 rgba_pixmap = create_pixmap(GL_RGBA);
297 int main(int argc, char**argv)
299 XVisualInfo *visinfo;
300 GLXContext ctx;
301 int i;
303 for(i = 1; i < argc; ++i) {
304 if (!strcmp(argv[i], "-auto"))
305 piglit_automatic = 1;
306 else
307 fprintf(stderr, "Unknown option: %s\n", argv[i]);
310 dpy = XOpenDisplay(NULL);
311 if (dpy == NULL) {
312 fprintf(stderr, "couldn't open display\n");
313 piglit_report_result(PIGLIT_FAIL);
316 visinfo = piglit_get_glx_visual(dpy);
317 ctx = piglit_get_glx_context(dpy, visinfo);
318 win = piglit_get_glx_window(dpy, visinfo);
319 XFree(visinfo);
321 glXMakeCurrent(dpy, win, ctx);
323 piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
325 if (piglit_automatic)
326 piglit_glx_set_no_input();
328 piglit_require_glx_extension(dpy, "GLX_EXT_texture_from_pixmap");
329 if (!piglit_is_extension_supported("GL_ARB_texture_env_combine")) {
330 fprintf(stderr, "Test requires GL_ARB_texture_env_combine\n");
331 piglit_report_result(PIGLIT_SKIP);
334 pglXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)
335 glXGetProcAddress((GLubyte *)"glXBindTexImageEXT");
336 pglXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)
337 glXGetProcAddress((GLubyte *)"glXReleaseTexImageEXT");
338 if (pglXBindTexImageEXT == NULL || pglXReleaseTexImageEXT == NULL) {
339 fprintf(stderr, "Couldn't get TFP functions\n");
340 piglit_report_result(PIGLIT_FAIL);
341 exit(1);
344 init();
346 if (!piglit_automatic) {
347 printf("Left rectangle (RGB) should be green on the top and\n"
348 "red on the bottom. The right rectangle (RGBA) should\n"
349 "be the same, but darker on the right half.\n");
350 printf("Press Escape to quit\n");
353 piglit_glx_event_loop(dpy, draw);
355 return 0;