fbo-alphatest-formats.c 10.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
/*
 * Copyright © 2010 Intel Corporation
 * Copyright © 2010 Marek Olšák <maraeo@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 *
 * Authors:
 *    Eric Anholt <eric@anholt.net>
 *    Marek Olšák <maraeo@gmail.com>
 *
 */

30
#include "piglit-util-gl.h"
31 32
#include "fbo-formats.h"

33 34
PIGLIT_GL_TEST_CONFIG_BEGIN

35 36
	config.supports_gl_compat_version = 10;

37 38 39 40 41 42
	/* Drivers that do not support GL_ARB_texture_non_power_of_two require
	 * window dimensions that are powers of two for this test.
	 */
	config.window_width = next_power_of_two(config.window_width);
	config.window_height = next_power_of_two(config.window_height);

43
	config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
44
	config.khr_no_error_support = PIGLIT_NO_ERRORS;
45 46

PIGLIT_GL_TEST_CONFIG_END
47

48 49 50 51 52 53 54
/**
 * Draw a quad with alpha testing
 * \param rect  the coords of the rectangle to draw
 * \param alpha  the alpha value to use when drawing the rect (color is white)
 * \param func  the glAlphaFunc mode to test
 * \param ref  the glAlphaFunc reference value
 */
55 56 57 58 59 60 61 62 63 64
static void alphatest(const float *rect, float alpha, GLenum func, float ref)
{
	glColor4f(1, 1, 1, alpha);
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(func, ref);
	piglit_draw_rect(rect[0], rect[1], rect[2], rect[3]);
	glDisable(GL_ALPHA_TEST);
	glColor4f(1, 1, 1, 1);
}

65
static enum piglit_result test_format(const struct format_desc *format)
66 67 68 69 70
{
	GLboolean pass = GL_TRUE;
	GLuint tex, fb;
	GLenum status;
	int r, g, b, l, a, i;
71
	const char *name = get_format_name(format->internalformat);
72 73 74 75 76 77 78 79 80 81 82 83 84

	float cpass[] = {1, 1, 1, 1};
	float cfail[] = {0, 0, 0, 0};

	float pos0[] = {-1.0,  -1.0, 0.25, 2.0};
	float pos1[] = {-0.75, -1.0, 0.25, 2.0};
	float pos2[] = {-0.5,  -1.0, 0.25, 2.0};
	float pos3[] = {-0.25, -1.0, 0.25, 2.0};
	float pos4[] = { 0.0,  -1.0, 0.25, 2.0};
	float pos5[] = { 0.25, -1.0, 0.25, 2.0};
	float pos6[] = { 0.5,  -1.0, 0.25, 2.0};
	float pos7[] = { 0.75, -1.0, 0.25, 2.0};

85
        if (format->base_internal_format == GL_DEPTH_COMPONENT ||
86
            format->base_internal_format == GL_DEPTH_STENCIL ||
87
            format->base_internal_format == GL_STENCIL_INDEX ||
88
	    format->base_internal_format == GL_ALPHA)
89 90
		return PIGLIT_SKIP;

91 92 93 94
	/*
	 * Check alpha test using an FBO that contains/wraps a texture.
	 */

95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
	glGenFramebuffersEXT(1, &fb);
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
	glViewport(0, 0, piglit_width, piglit_height);

	glGenTextures(1, &tex);
	glBindTexture(GL_TEXTURE_2D, tex);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	glTexImage2D(GL_TEXTURE_2D, 0, format->internalformat,
		     piglit_width, piglit_height, 0,
		     GL_RGBA, GL_FLOAT, NULL);

	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
				 GL_TEXTURE_LUMINANCE_SIZE, &l);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
				 GL_TEXTURE_ALPHA_SIZE, &a);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
				 GL_TEXTURE_INTENSITY_SIZE, &i);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
				 GL_TEXTURE_RED_SIZE, &r);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
				 GL_TEXTURE_GREEN_SIZE, &g);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
				 GL_TEXTURE_BLUE_SIZE, &b);

120 121 122
	/* Set up expected colors for testing the pass and fail cases.
	 * We're using glReadPixels from the texture.
	 */
123
        if (i) {
124 125 126
		/* GL_INTENSITY texture:  result = (I,0,0,0) */
		cpass[3] = cpass[2] = cpass[1] = 0;
		cfail[3] = cfail[2] = cfail[1] = 0;
127
        } else if (l) {
128 129 130
		/* GL_LUMINANCE texture:  result = (L,0,0,A) */
		cpass[2] = cpass[1] = 0;
		cfail[2] = cfail[1] = 0;
131 132 133 134 135
		if (!a) {
			cpass[3] = 1;
			cfail[3] = 1;
		}
        } else {
136
		/* other format */
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
		if (!r) {
			cpass[0] = 0;
			cfail[0] = 0;
		}
		if (!g) {
			cpass[1] = 0;
			cfail[1] = 0;
		}
		if (!b) {
			cpass[2] = 0;
			cfail[2] = 0;
		}
		if (!a) {
			cpass[3] = 1;
			cfail[3] = 1;
		}
        }

	/* Clamp the bits for the framebuffer, except we aren't checking
	 * the actual framebuffer bits.
	 */
	if (l > 8)
		l = 8;
	if (i > 8)
		i = 8;
	if (r > 8)
		r = 8;
	if (g > 8)
		g = 8;
	if (b > 8)
		b = 8;
	if (a > 8)
		a = 8;

        if (i) {
		piglit_set_tolerance_for_bits(i, i, i, i);
        } else if (l) {
		piglit_set_tolerance_for_bits(l, l, l, a);
        } else {
		piglit_set_tolerance_for_bits(r, g, b, a);
        }

	glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
				  GL_COLOR_ATTACHMENT0_EXT,
				  GL_TEXTURE_2D,
				  tex,
				  0);
184 185
	if (!piglit_check_gl_error(GL_NO_ERROR))
		piglit_report_result(PIGLIT_FAIL);
186 187

	status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
188
	printf("Testing %s", name);
189
	if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
190 191
		printf("- fbo incomplete (status = %s)\n",
		       piglit_get_gl_enum_name(status));
192
		piglit_report_subtest_result(PIGLIT_SKIP, "%s", name);
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
		return PIGLIT_SKIP;
	}
        printf("\n");

	glClearColor(0.0, 0.0, 0.0, 0.0);
	glClear(GL_COLOR_BUFFER_BIT);

	alphatest(pos0, 0.2, GL_LESS, 0.25);
	alphatest(pos1, 0.96, GL_LEQUAL, 0.92);
	alphatest(pos2, 0.6, GL_GREATER, 0.55);
	alphatest(pos3, 0.9, GL_GREATER, 0.1);
	alphatest(pos4, 0.35, GL_GEQUAL, 0.4);
	alphatest(pos5, 0.4, GL_EQUAL, 0.4);
	alphatest(pos6, 0.8, GL_NOTEQUAL, 0.8);
	alphatest(pos7, 0.3, GL_NEVER, 3);

209 210
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 1 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing FBO result, 1: 0.2 < 0.25.\n");
211 212
		pass = GL_FALSE;
        }
213 214
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 3 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing FBO result, 2: 0.96 <= 0.92.\n");
215 216
		pass = GL_FALSE;
        }
217 218
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 5 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing FBO result, 3: 0.6 > 0.55.\n");
219 220
		pass = GL_FALSE;
        }
221 222
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 7 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing FBO result, 4: 0.9 > 0.1.\n");
223 224
		pass = GL_FALSE;
        }
225 226
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 9 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing FBO result, 5: 0.35 >= 0.4.\n");
227 228
		pass = GL_FALSE;
	}
229 230
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 11 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing FBO result, 6: 0.4 == 0.4.\n");
231 232
		pass = GL_FALSE;
	}
233 234
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 13 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing FBO result, 7: 0.8 != 0.8.\n");
235 236
		pass = GL_FALSE;
	}
237 238
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 15 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing FBO result, 8: FALSE.\n");
239 240 241
		pass = GL_FALSE;
	}

242 243 244 245

	/*
	 * Now check alpha test using the window buffer.
	 */
246
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, piglit_winsys_fbo);
247 248 249 250 251 252 253 254 255 256 257 258 259 260
	glViewport(0, 0, piglit_width, piglit_height);

	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,   GL_REPLACE);
	glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);

	glColor4f(1, 1, 1, 1);
	glEnable(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, tex);
	piglit_draw_rect_tex(-1, -1, 2, 2,
			     0, 0, 1, 1);

	glDisable(GL_TEXTURE_2D);
	glDeleteTextures(1, &tex);
261
	glBindFramebufferEXT(GL_FRAMEBUFFER, piglit_winsys_fbo);
262 263
	glDeleteFramebuffersEXT(1, &fb);

264
	if (!pass) {
265
		piglit_present_results();
266
		piglit_report_subtest_result(PIGLIT_FAIL, "%s", name);
267 268 269
		return PIGLIT_FAIL;
	}

270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
	/* Set up expected colors for testing the pass and fail cases.
	 * These are the colors we expect to see with glReadPixels from the window.
	 * The colors are different than above for the intensity/luminance cases
	 * because here we're actually sampling from the texture.
	 */
        if (i) {
		/* GL_INTENSITY texture: RGBA=(I,I,I,I) */
		cpass[3] = cpass[2] = cpass[1] = cpass[0];
		cfail[3] = cfail[2] = cfail[1] = cfail[0];
        } else if (l) {
		/* GL_LUMINANCE texture: RGBA=(L,L,L,A) */
		cpass[2] = cpass[1] = cpass[0];
		cfail[2] = cfail[1] = cfail[0];
		if (!a) {
			cpass[3] = 1;
			cfail[3] = 1;
		}
	}
	else {
		/* same R,G,B,A that we computed above */
	}

292 293
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 1 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing window result, 1: 0.2 < 0.25.\n");
294 295
		pass = GL_FALSE;
	}
296 297
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 3 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing window result, 2: 0.96 <= 0.92.\n");
298 299
		pass = GL_FALSE;
	}
300 301
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 5 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing window result, 3: 0.6 > 0.55.\n");
302 303
		pass = GL_FALSE;
	}
304 305
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 7 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing window result, 4: 0.9 > 0.1.\n");
306 307
		pass = GL_FALSE;
	}
308 309
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 9 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing window result, 5: 0.35 >= 0.4.\n");
310 311
		pass = GL_FALSE;
	}
312 313
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 11 / 16, 0, cpass, NULL)) {
		printf("  FAIL when testing window result, 6: 0.4 == 0.4.\n");
314 315
		pass = GL_FALSE;
	}
316 317
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 13 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing window result, 7: 0.8 != 0.8.\n");
318 319
		pass = GL_FALSE;
	}
320 321
	if (!piglit_probe_pixel_rgb_silent(piglit_width * 15 / 16, 0, cfail, NULL)) {
		printf("  FAIL when testing window result, 8: FALSE.\n");
322 323 324
		pass = GL_FALSE;
	}

325
	piglit_present_results();
326

327
	piglit_report_subtest_result(pass ? PIGLIT_PASS : PIGLIT_FAIL,
328
				     "%s", name);
329
	return pass ? PIGLIT_PASS : PIGLIT_FAIL;
330 331 332 333
}

enum piglit_result piglit_display(void)
{
334
	return fbo_formats_display(test_format);
335 336 337 338
}

void piglit_init(int argc, char **argv)
{
339
	fbo_formats_init(argc, argv, GL_TRUE);
340
}