1 /*
2  * Copyright © 2015 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 /**
25  * \file generatetexturemipmaps.c
26  * Verify the side-effect-free operation of glGenerateTextureMipmap
27  *
28  * After calling glGenerateTextureMipmap, there are 3 things that need to be
29  * verified:
30  *
31  * 1. The texture bindings have not been modified.
32  *
33  * 2. Textures not passed to glGenerateTextureMipmap have not had their data
34  *    modified.
35  *
36  * 3. The texture that was passed to glGenerateTextureMipmap has the correct
37  *    data in its mipmaps.
38  */
39 
40 #include "piglit-util-gl.h"
41 
42 PIGLIT_GL_TEST_CONFIG_BEGIN
43 
44 	config.supports_gl_core_version = 31;
45 	config.supports_gl_compat_version = 20;
46 
47 	config.window_visual = PIGLIT_GL_VISUAL_RGBA |
48 		PIGLIT_GL_VISUAL_DOUBLE;
49 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
50 
51 PIGLIT_GL_TEST_CONFIG_END
52 
53 /* 2x2 block of red pixels. */
54 static const float red[2 * 2 * 4] = {
55 	1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0,
56 	1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0
57 };
58 
59 /* 4x4 block of green pixels. */
60 static const float green[4 * 4 * 4] = {
61 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
62 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
63 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
64 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
65 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
66 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
67 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0,
68 	0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0
69 };
70 
71 /* 4x4 block of blue pixels. */
72 static const float blue[4 * 4 * 4] = {
73 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
74 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
75 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
76 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
77 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
78 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
79 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0,
80 	0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0
81 };
82 
83 void
piglit_init(int argc,char ** argv)84 piglit_init(int argc, char **argv)
85 {
86 	GLuint tex[2];
87 	GLuint bound;
88 	bool pass = true;
89 	unsigned i;
90 
91 	piglit_require_extension("GL_ARB_direct_state_access");
92 
93 	/* Create two textures.  Populate both with full mipmap stacks.
94 	 * Ensure that the data for levels > 0 is not the data that would be
95 	 * generated by glGenerateMipmap or glGenerateTextureMipmap.
96 	 */
97 	glGenTextures(2, tex);
98 
99 	for (i = 0; i <= 1; i++) {
100 		const float *const base_color = (i == 0) ? blue : green;
101 
102 		glActiveTexture(GL_TEXTURE0 + i);
103 		glBindTexture(GL_TEXTURE_2D, tex[i]);
104 		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 4, 4, 0, GL_RGBA,
105 			     GL_FLOAT, base_color);
106 		glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 2, 2, 0, GL_RGBA,
107 			     GL_FLOAT, red);
108 		glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 1, 1, 0, GL_RGBA,
109 			     GL_FLOAT, red);
110 		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
111 	}
112 
113 	/* Generate the mipmap stack for the texture that is not currently
114 	 * bound to unit 0 while unit 0 is the active unit.
115 	 */
116 	glActiveTexture(GL_TEXTURE0);
117 	glGenerateTextureMipmap(tex[1]);
118 	pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
119 
120 	/* Verify that the correct textures are still bound to the correct
121 	 * texture units.
122 	 */
123 	for (i = 0; i <= 1; i++) {
124 		glActiveTexture(GL_TEXTURE0 + i);
125 		glGetIntegerv(GL_TEXTURE_BINDING_2D, (GLint *) &bound);
126 		pass = piglit_check_gl_error(GL_NO_ERROR) && pass;
127 
128 		if (bound != tex[i]) {
129 			fprintf(stderr,
130 				"Wrong texture bound to unit %u.  Got %d, "
131 				"but expected %d (other texture is %d).\n",
132 				i, bound, tex[i], tex[1 - i]);
133 			pass = false;
134 		}
135 	}
136 
137 	/* Verify that each texture has the correct data in levels > 0.
138 	 *
139 	 * For the texture bound to unit 0 (which was not passed to
140 	 * glGenerateTextureMipmap), this should be the original red color.
141 	 *
142 	 * For the texture bound to unit 1 (which was passed to
143 	 * glGenerateTextureMipmap), this should be green generated from the
144 	 * base level.
145 	 */
146 	for (i = 0; i <= 1; i++) {
147 		const float *const level_color = (i == 0) ? red : green;
148 
149 		glActiveTexture(GL_TEXTURE0 + i);
150 		printf("Check level 1 of texture %u...\n", i);
151 		pass = piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 1,
152 						    0, 0, 2, 2,
153 						    level_color) && pass;
154 		printf("Check level 2 of texture %u...\n", i);
155 		pass = piglit_probe_texel_rect_rgba(GL_TEXTURE_2D, 2,
156 						    0, 0, 1, 1,
157 						    level_color) && pass;
158 	}
159 
160 	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
161 }
162 
163 enum piglit_result
piglit_display(void)164 piglit_display(void)
165 {
166 	return PIGLIT_FAIL;
167 }
168 
169