1 /*
2  * Copyright 2015 Ilia Mirkin
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 DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 /** @file texview.c
25  *
26  * A test to make sure that ARB_copy_image respects texture views on
27  * both the source and destination ends.
28  */
29 #include "piglit-util-gl.h"
30 
31 PIGLIT_GL_TEST_CONFIG_BEGIN
32         config.supports_gl_compat_version = 13;
33         config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
34 	config.khr_no_error_support = PIGLIT_NO_ERRORS;
35 PIGLIT_GL_TEST_CONFIG_END
36 
37 static const float green[4] = {0.0, 1.0, 0.0, 1.0};
38 static const float red[4] = {1.0, 0.0, 0.0, 1.0};
39 
40 static bool
test_2d(void)41 test_2d(void)
42 {
43 	bool pass = true;
44 	GLuint src, dst;
45 	float red4[16];
46 	float green4[16];
47 	int i, j;
48 
49 	memcpy(&red4[0], red, sizeof(red));
50 	memcpy(&red4[4], red, sizeof(red));
51 	memcpy(&red4[8], red, sizeof(red));
52 	memcpy(&red4[12], red, sizeof(red));
53 
54 	memcpy(&green4[0], green, sizeof(green));
55 	memcpy(&green4[4], green, sizeof(green));
56 	memcpy(&green4[8], green, sizeof(green));
57 	memcpy(&green4[12], green, sizeof(green));
58 
59 	glGenTextures(1, &src);
60 	glGenTextures(1, &dst);
61 
62 	glBindTexture(GL_TEXTURE_2D, dst);
63 	glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2);
64 
65 	glBindTexture(GL_TEXTURE_2D, src);
66 	glTexStorage2D(GL_TEXTURE_2D, 2, GL_RGBA8, 2, 2);
67 
68 	for (i = 0; i < 2; i++) {
69 		for (j = 0; j < 2; j++) {
70 			GLuint views[2];
71 			float pixels[16];
72 
73 
74 			/* reset src to red, but make one pixel green */
75 			glBindTexture(GL_TEXTURE_2D, src);
76 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2,
77 					GL_RGBA, GL_FLOAT, red4);
78 			glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1,
79 					GL_RGBA, GL_FLOAT, red);
80 			glTexSubImage2D(GL_TEXTURE_2D, i, 0, 0, 1, 1,
81 					GL_RGBA, GL_FLOAT, green);
82 
83 			glBindTexture(GL_TEXTURE_2D, dst);
84 			glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 2, 2,
85 					GL_RGBA, GL_FLOAT, red4);
86 			glTexSubImage2D(GL_TEXTURE_2D, 1, 0, 0, 1, 1,
87 					GL_RGBA, GL_FLOAT, red);
88 
89 			/* create views of the source/dest levels */
90 			glGenTextures(2, views);
91 			glTextureView(views[0], GL_TEXTURE_2D, src,
92 				      GL_RGBA8, i, 1, 0, 1);
93 			glTextureView(views[1], GL_TEXTURE_2D, dst,
94 				      GL_RGBA8, j, 1, 0, 1);
95 
96 			/* copy one pixel of src to destination */
97 			glCopyImageSubData(views[0], GL_TEXTURE_2D, 0, 0, 0, 0,
98 					   views[1], GL_TEXTURE_2D, 0, 0, 0, 0,
99 					   1, 1, 1);
100 
101 			glGetTexImage(GL_TEXTURE_2D, j, GL_RGBA, GL_FLOAT, pixels);
102 			if (memcmp(pixels, green, sizeof(green))) {
103 				pass = false;
104 				printf("failed copying from level %d to level %d\n", i, j);
105 			}
106 			glDeleteTextures(2, views);
107 		}
108 	}
109 
110 	glDeleteTextures(1, &src);
111 	glDeleteTextures(1, &dst);
112 	return pass;
113 }
114 
115 static bool
test_2d_array(void)116 test_2d_array(void)
117 {
118 	bool pass = true;
119 	GLuint src, dst;
120 	float red2[8];
121 	float green2[8];
122 	int i, j;
123 
124 	memcpy(&red2[0], red, sizeof(red));
125 	memcpy(&red2[4], red, sizeof(red));
126 
127 	memcpy(&green2[0], green, sizeof(green));
128 	memcpy(&green2[4], green, sizeof(green));
129 
130 	glGenTextures(1, &src);
131 	glGenTextures(1, &dst);
132 
133 	glBindTexture(GL_TEXTURE_2D_ARRAY, src);
134 	glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 1, 1, 2);
135 
136 	glBindTexture(GL_TEXTURE_2D_ARRAY, dst);
137 	glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, 1, 1, 2);
138 
139 	for (i = 0; i < 2; i++) {
140 		for (j = 0; j < 2; j++) {
141 			GLuint views[2];
142 			float pixels[8];
143 
144 			/* reset src to red, but make one pixel green */
145 			glBindTexture(GL_TEXTURE_2D_ARRAY, src);
146 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0,
147 					1, 1, 2,
148 					GL_RGBA, GL_FLOAT, red2);
149 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i,
150 					1, 1, 1,
151 					GL_RGBA, GL_FLOAT, green);
152 
153 			glBindTexture(GL_TEXTURE_2D_ARRAY, dst);
154 			glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0,
155 					1, 1, 2,
156 					GL_RGBA, GL_FLOAT, red2);
157 
158 			/* create views of the source/dest levels */
159 			glGenTextures(2, views);
160 			glTextureView(views[0], GL_TEXTURE_2D_ARRAY, src,
161 				      GL_RGBA8, 0, 1, i, 1);
162 			glTextureView(views[1], GL_TEXTURE_2D_ARRAY, dst,
163 				      GL_RGBA8, 0, 1, j, 1);
164 
165 			/* copy one pixel of src to destination */
166 			glCopyImageSubData(views[0], GL_TEXTURE_2D_ARRAY,
167 					   0, 0, 0, 0,
168 					   views[1], GL_TEXTURE_2D_ARRAY,
169 					   0, 0, 0, 0,
170 					   1, 1, 1);
171 
172 			glGetTexImage(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, GL_FLOAT, pixels);
173 			if (memcmp(&pixels[j*4], green, sizeof(green))) {
174 				pass = false;
175 				printf("failed copying from layer %d to layer %d\n", i, j);
176 			}
177 			glDeleteTextures(2, views);
178 		}
179 	}
180 
181 	glDeleteTextures(1, &src);
182 	glDeleteTextures(1, &dst);
183 	return pass;
184 }
185 
186 void
piglit_init(int argc,char ** argv)187 piglit_init(int argc, char **argv)
188 {
189 	bool pass = true;
190 	piglit_require_extension("GL_ARB_copy_image");
191 	piglit_require_extension("GL_ARB_texture_view");
192 	piglit_require_extension("GL_ARB_texture_storage");
193 
194 	pass &= test_2d();
195 	if (piglit_is_extension_supported("GL_EXT_texture_array"))
196 		pass &= test_2d_array();
197 
198 	piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);
199 }
200 
201 enum piglit_result
piglit_display(void)202 piglit_display(void)
203 {
204 	return PIGLIT_FAIL;
205 }
206