cl: Correct CL_DEVICE_DOUBLE_FP_CONFIG check for OpenCL > 1.2
[piglit.git] / tests / fast_color_clear / read-after-clear.c
blobc23d43a6177e3b81cec86d79fb86297b49a7d494
1 /*
2 * Copyright © 2013 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
21 * DEALINGS IN THE SOFTWARE.
24 /**
25 * \file read-after-clear.c
27 * Test that fast color clears of an off-screen buffer work properly
28 * when they are followed by various ways of reading from the buffer.
30 * There are four sub-tests (selectable by a command line parameter)
31 * for each of the following ways of reading from the texture buffer:
33 * - sample: read by sampling via a GLSL shader.
34 * - read_pixels: read using the glReadPixels() function.
35 * - blit: read by blitting from the texture to the windowsystem framebuffer.
36 * - copy: read by copying to a second texture using glCopyTexImage2D.
38 * In addition, each test can be qualified with "rb" or "tex" to
39 * choose whether the off-screen buffer is a texture or a
40 * renderbuffer. Note that the "rb" option is not allowed for the
41 * "sample" sub-test.
43 * The test operates by creating an off-screen buffer, painting it red
44 * using a non-fast-clear technique (rendering a quad using a shader),
45 * and then clearing it to green using a fast clear. Then it reads
46 * from the buffer using the technique specified on the command line,
47 * to verify that the fast clear data got successfully written to the
48 * buffer.
51 #include "piglit-util-gl.h"
53 #define TEX_WIDTH 512
54 #define TEX_HEIGHT 512
56 PIGLIT_GL_TEST_CONFIG_BEGIN
57 config.supports_gl_compat_version = 11;
58 config.window_width = TEX_WIDTH;
59 config.window_height = TEX_HEIGHT;
60 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA;
61 config.khr_no_error_support = PIGLIT_NO_ERRORS;
62 PIGLIT_GL_TEST_CONFIG_END
65 static enum subtest_enum {
66 SUBTEST_SAMPLE,
67 SUBTEST_READ_PIXELS,
68 SUBTEST_BLIT,
69 SUBTEST_COPY,
70 } subtest;
72 static bool use_texture;
75 static const char *vs_text =
76 "void main()\n"
77 "{\n"
78 " gl_Position = gl_Vertex;\n"
79 " gl_TexCoord[0] = gl_MultiTexCoord0;\n"
80 "}\n";
82 static const char *fs_text_paint_red =
83 "void main()\n"
84 "{\n"
85 " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
86 "}\n";
88 static const char *fs_text_sample =
89 "uniform sampler2D samp;\n"
90 "void main()\n"
91 "{\n"
92 " gl_FragColor = texture2D(samp, gl_TexCoord[0].xy);\n"
93 "}\n";
95 static GLuint prog_paint_red, prog_sample, tex1, tex2, fb;
98 static void
99 print_usage_and_exit(const char *prog_name)
101 printf("Usage: %s <subtest> <buffer_type>\n"
102 " where <subtest> is one of the following:\n"
103 " sample: read by sampling from the cleared buffer\n"
104 " read_pixels: read using glReadPixels()\n"
105 " blit: read by blitting from the cleared buffer\n"
106 " copy: read using glCopyTexImage2D()\n"
107 " and <buffer_type> is one of the following:\n"
108 " rb: off-screen buffer is a renderbuffer\n"
109 " tex: off-screen buffer is a texture\n", prog_name);
110 piglit_report_result(PIGLIT_FAIL);
114 static GLuint allocate_texture()
116 GLuint tex;
117 glGenTextures(1, &tex);
118 glBindTexture(GL_TEXTURE_2D, tex);
119 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
120 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
121 glTexImage2D(GL_TEXTURE_2D,
122 0 /* level */,
123 GL_RGBA /* internal format */,
124 TEX_WIDTH, TEX_HEIGHT,
125 0 /* border */,
126 GL_RGBA /* format */,
127 GL_BYTE /* type */,
128 NULL /* data */);
129 return tex;
133 void
134 piglit_init(int argc, char **argv)
136 GLuint vs, fs_paint_red, fs_sample;
137 GLenum fb_status;
139 /* Parse params */
140 if (argc != 3)
141 print_usage_and_exit(argv[0]);
142 if (strcmp(argv[1], "sample") == 0)
143 subtest = SUBTEST_SAMPLE;
144 else if (strcmp(argv[1], "read_pixels") == 0)
145 subtest = SUBTEST_READ_PIXELS;
146 else if (strcmp(argv[1], "blit") == 0)
147 subtest = SUBTEST_BLIT;
148 else if (strcmp(argv[1], "copy") == 0)
149 subtest = SUBTEST_COPY;
150 else
151 print_usage_and_exit(argv[0]);
152 if (strcmp(argv[2], "rb") == 0)
153 use_texture = false;
154 else if (strcmp(argv[2], "tex") == 0)
155 use_texture = true;
156 else
157 print_usage_and_exit(argv[0]);
159 /* Detect parameter conflicts */
160 if (subtest == SUBTEST_SAMPLE && !use_texture) {
161 printf("Subtest 'sample' requires buffer_type 'tex'.\n");
162 piglit_report_result(PIGLIT_FAIL);
165 /* Requirements */
166 piglit_require_vertex_shader();
167 piglit_require_fragment_shader();
168 piglit_require_extension("GL_ARB_framebuffer_object");
170 /* Compile shaders */
171 vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
172 fs_paint_red = piglit_compile_shader_text(GL_FRAGMENT_SHADER,
173 fs_text_paint_red);
174 prog_paint_red = piglit_link_simple_program(vs, fs_paint_red);
175 if (!prog_paint_red)
176 piglit_report_result(PIGLIT_FAIL);
177 fs_sample = piglit_compile_shader_text(GL_FRAGMENT_SHADER,
178 fs_text_sample);
179 prog_sample = piglit_link_simple_program(vs, fs_sample);
180 if (!prog_sample)
181 piglit_report_result(PIGLIT_FAIL);
182 if (!piglit_check_gl_error(GL_NO_ERROR))
183 piglit_report_result(PIGLIT_FAIL);
185 /* Set up framebuffer */
186 glGenFramebuffers(1, &fb);
187 glBindFramebuffer(GL_FRAMEBUFFER, fb);
188 if (use_texture) {
189 tex1 = allocate_texture();
190 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
191 GL_TEXTURE_2D, tex1, 0 /* level */);
192 } else {
193 GLuint rb;
194 glGenRenderbuffers(1, &rb);
195 glBindRenderbuffer(GL_RENDERBUFFER, rb);
196 glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA,
197 TEX_WIDTH, TEX_HEIGHT);
198 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
199 GL_RENDERBUFFER, rb);
201 if (!piglit_check_gl_error(GL_NO_ERROR))
202 piglit_report_result(PIGLIT_FAIL);
203 fb_status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
204 if (fb_status != GL_FRAMEBUFFER_COMPLETE) {
205 printf("Framebuffer status: %s\n",
206 piglit_get_gl_enum_name(fb_status));
207 piglit_report_result(PIGLIT_FAIL);
210 /* Set up second texture (used by "copy" test only) */
211 if (subtest == SUBTEST_COPY)
212 tex2 = allocate_texture();
213 if (!piglit_check_gl_error(GL_NO_ERROR))
214 piglit_report_result(PIGLIT_FAIL);
218 enum piglit_result
219 piglit_display(void)
221 bool pass = true;
222 static const GLfloat green[] = { 0.0, 1.0, 0.0, 1.0 };
224 /* Paint the texture red using a shader (not a fast clear). */
225 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fb);
226 glUseProgram(prog_paint_red);
227 glViewport(0, 0, TEX_WIDTH, TEX_HEIGHT);
228 piglit_draw_rect(-1, -1, 2, 2);
230 /* Clear the texture to green; this will be optimized using
231 * a fast color clear if the hardware is capable of it.
233 glClearColor(0, 1, 0, 1);
234 glClear(GL_COLOR_BUFFER_BIT);
236 switch (subtest) {
237 case SUBTEST_SAMPLE:
238 /* Sample from the texture and draw to the window
239 * system framebuffer.
241 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
242 glViewport(0, 0, piglit_width, piglit_height);
243 glUseProgram(prog_sample);
244 glUniform1i(glGetUniformLocation(prog_sample, "samp"), 0);
245 glActiveTexture(GL_TEXTURE0);
246 glBindTexture(GL_TEXTURE_2D, tex1);
247 piglit_draw_rect_tex(-1, -1, 2, 2, 0, 0, 1, 1);
248 glBindFramebuffer(GL_READ_FRAMEBUFFER, piglit_winsys_fbo);
249 pass = piglit_probe_rect_rgba(0, 0, piglit_width,
250 piglit_height, green) && pass;
251 break;
252 case SUBTEST_READ_PIXELS:
253 /* Read directly from the texture using
254 * glReadPixels().
256 glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
257 pass = piglit_probe_rect_rgba(0, 0, TEX_WIDTH, TEX_HEIGHT,
258 green) && pass;
259 /* And then clear the window system framebuffer to
260 * black since there is nothing to display in this
261 * subtest.
263 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
264 glClearColor(0, 0, 0, 1);
265 glClear(GL_COLOR_BUFFER_BIT);
266 break;
267 case SUBTEST_BLIT:
268 /* Blit from the texture to the window system
269 * fraembuffer.
271 glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
272 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
273 glBlitFramebuffer(0, 0, TEX_WIDTH, TEX_HEIGHT,
274 0, 0, piglit_width, piglit_height,
275 GL_COLOR_BUFFER_BIT, GL_NEAREST);
276 glBindFramebuffer(GL_READ_FRAMEBUFFER, piglit_winsys_fbo);
277 pass = piglit_probe_rect_rgba(0, 0, piglit_width,
278 piglit_height, green) && pass;
279 break;
280 case SUBTEST_COPY:
281 /* Copy to a second texture using glCopyTexImage2D(). */
282 glBindFramebuffer(GL_READ_FRAMEBUFFER, fb);
283 glBindTexture(GL_TEXTURE_2D, tex2);
284 glCopyTexImage2D(GL_TEXTURE_2D,
285 0 /* level */,
286 GL_RGBA,
287 0, 0, TEX_WIDTH, TEX_HEIGHT,
288 0 /* border */);
289 /* Sample from the second texture and draw to the
290 * window system framebuffer.
292 glBindFramebuffer(GL_DRAW_FRAMEBUFFER, piglit_winsys_fbo);
293 glViewport(0, 0, piglit_width, piglit_height);
294 glUseProgram(prog_sample);
295 glUniform1i(glGetUniformLocation(prog_sample, "samp"), 0);
296 glActiveTexture(GL_TEXTURE0);
297 glBindTexture(GL_TEXTURE_2D, tex2);
298 piglit_draw_rect_tex(-1, -1, 2, 2, 0, 0, 1, 1);
299 glBindFramebuffer(GL_READ_FRAMEBUFFER, piglit_winsys_fbo);
300 pass = piglit_probe_rect_rgba(0, 0, piglit_width,
301 piglit_height, green) && pass;
302 break;
305 if (!piglit_check_gl_error(GL_NO_ERROR))
306 pass = false;
308 piglit_present_results();
309 return pass ? PIGLIT_PASS : PIGLIT_FAIL;