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