ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / ext_render_snorm / render.c
blob1d4a69c2d0e171a26cd184d46374433d8a4633f6
1 /*
2 * Copyright © 2018 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 DEALINGS
21 * IN THE SOFTWARE.
24 /**
25 * @file
26 * Basic tests for formats added by GL_EXT_render_snorm extension
28 * https://www.khronos.org/registry/OpenGL/extensions/EXT/EXT_render_snorm.txt
30 * Test includes:
31 * - texture uploads
32 * - mipmap generation
33 * - framebuffer creation
34 * - rendering to
35 * - reading from
38 #include "piglit-util-gl.h"
40 PIGLIT_GL_TEST_CONFIG_BEGIN
41 config.supports_gl_es_version = 31;
42 config.window_visual = PIGLIT_GL_VISUAL_RGBA;
43 PIGLIT_GL_TEST_CONFIG_END
45 #define PIGLIT_RESULT(x) x ? PIGLIT_PASS : PIGLIT_FAIL
47 static const char vs_source[] =
48 "#version 310 es\n"
49 "layout(location = 0) in highp vec4 vertex;\n"
50 "layout(location = 1) in highp vec4 uv;\n"
51 "out highp vec2 tex_coord;\n"
52 "\n"
53 "void main()\n"
54 "{\n"
55 " gl_Position = vertex;\n"
56 " tex_coord = uv.st;\n"
57 "}\n";
59 static const char fs_source[] =
60 "#version 310 es\n"
61 "layout(location = 0) uniform sampler2D texture;\n"
62 "in highp vec2 tex_coord;\n"
63 "out highp vec4 color;\n"
64 "void main()\n"
65 "{\n"
66 " color = texture2D(texture, tex_coord);\n"
67 "}\n";
69 /* trianglestrip, interleaved vertices + texcoords */
70 static const GLfloat vertex_data[] = {
71 -1.0f, 1.0f,
72 0.0f, 1.0f,
73 1.0f, 1.0f,
74 1.0f, 1.0f,
75 -1.0f, -1.0f,
76 0.0f, 0.0f,
77 1.0f, -1.0f,
78 1.0f, 0.0f
81 static const struct fmt_test {
82 GLenum iformat;
83 GLenum base_format;
84 unsigned bpp;
85 } tests[] = {
86 { GL_R8_SNORM, GL_RED, 1, },
87 { GL_RG8_SNORM, GL_RG, 2, },
88 { GL_RGBA8_SNORM, GL_RGBA, 4, },
91 static GLuint prog;
93 static void
94 upload(const struct fmt_test *test, void *data)
96 glTexStorage2D(GL_TEXTURE_2D, 4, test->iformat, piglit_width,
97 piglit_height);
98 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, piglit_width,
99 piglit_height, test->base_format, GL_BYTE, data);
100 glGenerateMipmap(GL_TEXTURE_2D);
103 static void
104 value_for_format(const struct fmt_test *test, void *value)
106 unsigned short val = SCHAR_MAX;
108 char *v = value;
109 /* red */
110 v[0] = val;
111 /* green */
112 if (test->bpp > 1) {
113 v[0] = 0;
114 v[1] = val;
116 /* blue */
117 if (test->bpp > 2) {
118 v[0] = 0;
119 v[1] = 0;
120 v[2] = val;
121 v[3] = val;
125 static void
126 generate_data(const struct fmt_test *test)
128 unsigned pixels = piglit_width * piglit_height;
129 void *data = malloc(pixels * test->bpp);
131 char *p = data;
132 for (unsigned i = 0; i < pixels; i++, p += test->bpp)
133 value_for_format(test, p);
135 upload(test, data);
136 free(data);
139 static GLuint
140 create_and_bind_empty_texture()
142 GLuint tex;
143 glGenTextures(1, &tex);
144 glBindTexture(GL_TEXTURE_2D, tex);
146 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
147 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
148 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
149 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
151 return tex;
154 static GLuint
155 create_and_bind_texture(const struct fmt_test *test)
157 GLuint tex = create_and_bind_empty_texture();
158 generate_data(test);
159 return tex;
162 static GLuint
163 create_and_bind_rbo(const struct fmt_test *test)
165 GLuint rbo;
166 glGenRenderbuffers(1, &rbo);
167 glBindRenderbuffer(GL_RENDERBUFFER, rbo);
168 glRenderbufferStorage(GL_RENDERBUFFER, test->iformat, piglit_width,
169 piglit_height);
170 return rbo;
173 static GLuint
174 create_and_bind_fbo(const struct fmt_test *test, GLuint *tex)
176 GLuint fbo;
177 GLuint fbo_tex = create_and_bind_empty_texture(test);
178 upload(test, NULL);
180 *tex = fbo_tex;
182 glGenFramebuffers(1, &fbo);
183 glBindFramebuffer(GL_FRAMEBUFFER, fbo);
184 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
185 GL_TEXTURE_2D, fbo_tex, 0);
186 return fbo;
189 static void
190 render_texture(GLuint texture, GLenum target, GLuint fbo_target)
192 glBindTexture(target, texture);
193 glBindFramebuffer(GL_FRAMEBUFFER, fbo_target);
195 glViewport(0, 0, piglit_width, piglit_height);
197 glClear(GL_COLOR_BUFFER_BIT);
198 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
201 static bool
202 verify_contents(const struct fmt_test *test)
204 bool result = true;
205 unsigned amount = piglit_width * piglit_height;
206 void *pix = malloc(amount * 4);
207 glReadPixels(0, 0, piglit_width, piglit_height, GL_RGBA, GL_BYTE, pix);
209 char value[4] = { 0, 0, 0, SCHAR_MAX };
210 value_for_format(test, value);
212 char *p = pix;
213 for (unsigned i = 0; i < amount; i++, p += 4) {
214 if (memcmp(p, value, sizeof(value)) == 0)
215 continue;
217 fprintf(stderr, "value:\n%d % d %d %d\nexpect:\n%d %d %d %d",
218 p[0], p[1], p[2], p[3],
219 value[0], value[1], value[2], value[3]);
221 piglit_report_subtest_result(PIGLIT_FAIL,
222 "format 0x%x read fail",
223 test->iformat);
224 result = false;
225 break;
228 free(pix);
229 return result;
232 static bool
233 test_format(const struct fmt_test *test)
235 bool pass = true;
237 glUseProgram(prog);
238 glUniform1i(0 /* explicit loc */, 0);
240 /* Test glRenderbufferStorage. */
241 GLuint rbo = create_and_bind_rbo(test);
242 if (!rbo || !piglit_check_gl_error(GL_NO_ERROR)) {
243 piglit_report_subtest_result(PIGLIT_FAIL,
244 "format 0x%x RBO test",
245 test->iformat);
246 pass &= false;
247 } else {
248 piglit_report_subtest_result(PIGLIT_PASS,
249 "format 0x%x RBO test",
250 test->iformat);
252 glDeleteRenderbuffers(1, &rbo);
254 /* Create framebuffer object. */
255 GLuint fbo_tex;
256 const GLuint fbo = create_and_bind_fbo(test, &fbo_tex);
258 if (glCheckFramebufferStatus(GL_FRAMEBUFFER) !=
259 GL_FRAMEBUFFER_COMPLETE) {
260 piglit_report_subtest_result(PIGLIT_FAIL,
261 "format 0x%x fbo fail",
262 test->iformat);
263 pass &= false;
266 /* Create a texture, upload data */
267 const GLuint texture = create_and_bind_texture(test);
269 render_texture(texture, GL_TEXTURE_2D, fbo);
271 glDeleteTextures(1, &texture);
273 /* Test glCopyTexImage2D by copying current fbo content to
274 * a texture, rendering copy back to fbo and verifying fbo contents.
276 GLuint tmp_tex = create_and_bind_empty_texture();
277 glCopyTexImage2D(GL_TEXTURE_2D, 0, test->iformat, 0, 0, piglit_width,
278 piglit_height, 0);
280 render_texture(tmp_tex, GL_TEXTURE_2D, fbo);
282 glDeleteTextures(1, &tmp_tex);
284 /* Verify contents. */
285 pass &= verify_contents(test);
287 glDeleteFramebuffers(1, &fbo);
289 /* Render fbo contents to window. */
290 render_texture(fbo_tex, GL_TEXTURE_2D, 0);
292 piglit_present_results();
294 glDeleteTextures(1, &fbo_tex);
296 return pass;
299 enum piglit_result
300 piglit_display(void)
302 glEnableVertexAttribArray(0);
303 glEnableVertexAttribArray(1);
305 glActiveTexture(GL_TEXTURE0);
307 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
308 vertex_data);
309 glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
310 (void*) (vertex_data + (2 * sizeof(float))));
312 bool pass = true;
314 const struct fmt_test *test = tests;
316 /* Loop over each format. */
317 for (unsigned i = 0; i < ARRAY_SIZE(tests); i++, test++) {
318 bool fmt_pass = test_format(test);
319 piglit_report_subtest_result(PIGLIT_RESULT(fmt_pass),
320 "format 0x%x",
321 test->iformat);
322 pass &= fmt_pass;
325 if (!piglit_check_gl_error(GL_NO_ERROR))
326 piglit_report_result(PIGLIT_FAIL);
328 return PIGLIT_RESULT(pass);
331 void
332 piglit_init(int argc, char **argv)
334 piglit_require_extension("GL_EXT_render_snorm");
335 prog = piglit_build_simple_program(vs_source, fs_source);