glsl: test loop unroll with uint overflow
[piglit.git] / tests / spec / arb_clear_texture / common.c
blobe3ca0ef278254618b0ecd1dcd1598a0138007873
1 /*
2 * Copyright (c) 2014 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 #include "common.h"
26 #define TEX_WIDTH 64
27 #define TEX_HEIGHT 256
29 #define ZERO_CLEAR_X 10
30 #define ZERO_CLEAR_Y 15
31 #define ZERO_CLEAR_WIDTH 8
32 #define ZERO_CLEAR_HEIGHT 12
34 #define VALUE_CLEAR_X 30
35 #define VALUE_CLEAR_Y 50
36 #define VALUE_CLEAR_WIDTH 9
37 #define VALUE_CLEAR_HEIGHT 13
39 /* Arbitrary values that is big enough for four doubles */
40 static const GLubyte clearValue[] = {
41 0x1f, 0x1e, 0x1d, 0x1c,
42 0x1b, 0x1a, 0x19, 0x18,
43 0x17, 0x16, 0x15, 0x14,
44 0x13, 0x12, 0x11, 0x10,
45 0x0f, 0x0e, 0x0d, 0x0c,
46 0x0b, 0x0a, 0x09, 0x08,
47 0x07, 0x06, 0x05, 0x04,
48 0x03, 0x02, 0x01, 0x00,
51 static GLuint
52 create_texture(GLenum internalFormat,
53 GLenum format,
54 GLenum type,
55 GLsizei texelSize)
57 GLubyte *data, *p;
58 GLuint tex;
59 int i;
61 data = malloc(TEX_WIDTH * TEX_HEIGHT * texelSize);
62 p = data;
64 /* Fill the data with increasing bytes */
65 for (i = 0; i < TEX_WIDTH * TEX_HEIGHT * texelSize; i++)
66 *(p++) = i;
68 glGenTextures(1, &tex);
69 glBindTexture(GL_TEXTURE_2D, tex);
70 glTexImage2D(GL_TEXTURE_2D,
71 0, /* level */
72 internalFormat,
73 TEX_WIDTH, TEX_HEIGHT,
74 0, /* border */
75 format, type,
76 data);
78 free(data);
80 return tex;
83 static void
84 clear_sub_texture(GLuint tex, GLenum format, GLenum type, GLsizei texelSize)
86 /* Clear one region using a NULL (all zeroes) value */
87 glClearTexSubImage(tex,
88 0, /* level */
89 ZERO_CLEAR_X,
90 ZERO_CLEAR_Y,
91 0, /* z */
92 ZERO_CLEAR_WIDTH,
93 ZERO_CLEAR_HEIGHT,
94 1, /* depth */
95 format,
96 type,
97 NULL /* value */);
99 /* Clear another region to a known value */
100 glClearTexSubImage(tex,
101 0, /* level */
102 VALUE_CLEAR_X,
103 VALUE_CLEAR_Y,
104 0, /* z */
105 VALUE_CLEAR_WIDTH,
106 VALUE_CLEAR_HEIGHT,
107 1, /* depth */
108 format,
109 type,
110 clearValue);
113 static void
114 clear_whole_texture(GLuint tex, GLenum format, GLenum type, GLsizei texelSize)
116 /* Clear to a known value */
117 glClearTexImage(tex,
119 format,
120 type,
121 clearValue);
124 static bool
125 is_value_clear(const GLubyte *texel, GLsizei texelSize, bool is_float)
127 if (is_float) {
128 const float expected = ((float *) clearValue)[0];
129 const float actual = ((float *) texel)[0];
130 if (fabs((actual - expected) / expected) > 0.001)
131 return false;
132 } else {
133 for (int i = 0; i < texelSize; i++)
134 if (texel[i] != clearValue[i])
135 return false;
138 return true;
141 static bool
142 is_zero_clear(const GLubyte *texel, GLsizei texelSize)
144 int i;
146 for (i = 0; i < texelSize; i++)
147 if (texel[i] != 0)
148 return false;
150 return true;
153 static bool
154 is_initial_value(const GLubyte *texel, GLsizei texelSize,
155 GLuint offset, bool is_float)
157 if (is_float) {
158 const char x = offset & 0xff;
159 const char expected_bytes[4] = {x, x + 1, x + 2, x + 3};
160 const float expected = ((float *) expected_bytes)[0];
162 float actual = ((float *) texel)[0];
164 if (fabs((actual - expected) / expected) > 0.001)
165 return false;
166 } else {
167 for (int b = 0; b < texelSize; b++) {
168 if (texel[b] != ((offset + b) & 0xff))
169 return false;
173 return true;
176 static bool
177 check_texels_partial_clear(GLenum format, GLenum type, GLsizei texelSize)
179 const bool is_float = (format == GL_DEPTH_COMPONENT);
180 GLubyte *data, *p;
181 bool success = true;
182 int x, y;
184 data = malloc(TEX_WIDTH * TEX_HEIGHT * texelSize);
186 glPixelStorei(GL_PACK_ALIGNMENT, 1);
188 glGetTexImage(GL_TEXTURE_2D,
189 0, /* level */
190 format, type,
191 data);
193 p = data;
195 for (y = 0; y < TEX_HEIGHT; y++) {
196 for (x = 0; x < TEX_WIDTH; x++) {
197 if (x >= VALUE_CLEAR_X &&
198 x < VALUE_CLEAR_X + VALUE_CLEAR_WIDTH &&
199 y >= VALUE_CLEAR_Y &&
200 y < VALUE_CLEAR_Y + VALUE_CLEAR_HEIGHT) {
201 if (!is_value_clear(p, texelSize, is_float))
202 success = false;
203 } else if (x >= ZERO_CLEAR_X &&
204 x < ZERO_CLEAR_X + ZERO_CLEAR_WIDTH &&
205 y >= ZERO_CLEAR_Y &&
206 y < ZERO_CLEAR_Y + ZERO_CLEAR_HEIGHT) {
207 if (!is_zero_clear(p, texelSize))
208 success = false;
209 } else {
210 if (!is_initial_value(p, texelSize, p - data, is_float))
211 success = false;
214 p += texelSize;
218 free(data);
220 return success;
223 static bool
224 check_texels_full_clear(GLenum format, GLenum type, GLsizei texelSize)
226 const bool is_depth = format == GL_DEPTH_COMPONENT;
227 GLubyte *data, *p;
228 bool success = true;
230 data = malloc(TEX_WIDTH * TEX_HEIGHT * texelSize);
232 glPixelStorei(GL_PACK_ALIGNMENT, 1);
234 glGetTexImage(GL_TEXTURE_2D,
235 0, /* level */
236 format, type,
237 data);
239 p = data;
241 for (int y = 0; y < TEX_HEIGHT; y++) {
242 for (int x = 0; x < TEX_WIDTH; x++) {
243 if (!is_value_clear(p, texelSize, is_depth))
244 success = false;
246 p += texelSize;
250 free(data);
252 return success;
255 bool
256 test_format(GLenum internalFormat,
257 GLenum format,
258 GLenum type,
259 GLsizei texelSize)
261 GLuint tex;
262 bool pass;
264 /* glClearTexture is either in the GL_ARB_clear_texture
265 * extension or in core in GL 4.4
267 if (piglit_get_gl_version() < 44 &&
268 !piglit_is_extension_supported("GL_ARB_clear_texture")) {
269 printf("OpenGL 4.4 or GL_ARB_clear_texture is required.\n");
270 piglit_report_result(PIGLIT_SKIP);
273 tex = create_texture(internalFormat, format, type, texelSize);
275 if (!piglit_check_gl_error(GL_NO_ERROR))
276 return false;
278 clear_sub_texture(tex, format, type, texelSize);
280 if (!piglit_check_gl_error(GL_NO_ERROR))
281 return false;
283 glBindTexture(GL_TEXTURE_2D, tex);
285 pass = check_texels_partial_clear(format, type, texelSize);
287 clear_whole_texture(tex, format, type, texelSize);
289 if (!piglit_check_gl_error(GL_NO_ERROR))
290 return false;
292 pass = check_texels_full_clear(format, type, texelSize) && pass;
294 glBindTexture(GL_TEXTURE_2D, 0);
296 glDeleteTextures(1, &tex);
298 return pass;
301 bool
302 test_formats(const struct format *formats,
303 int n_formats)
305 bool overallResult = true;
306 bool pass;
307 int i;
309 for (i = 0; i < n_formats; i++) {
310 const struct format *format = formats + i;
312 pass = test_format(format->internalFormat,
313 format->format,
314 format->type,
315 format->texelSize);
317 printf("internalFormat = %s, format = %s, type = %s : %s\n",
318 piglit_get_gl_enum_name(format->internalFormat),
319 piglit_get_gl_enum_name(format->format),
320 piglit_get_gl_enum_name(format->type),
321 pass ? "pass" : "fail");
323 overallResult &= pass;
326 return overallResult;
329 bool
330 test_invalid_format(GLenum internalFormat,
331 GLenum texImageFormat,
332 GLenum texImageType,
333 GLenum clearValueFormat,
334 GLenum clearValueType)
336 static const GLubyte dummy_data[sizeof (float) * 4];
337 bool pass = true;
338 GLuint tex;
340 glGenTextures(1, &tex);
341 glBindTexture(GL_TEXTURE_2D, tex);
342 glTexImage2D(GL_TEXTURE_2D,
343 0, /* level */
344 internalFormat,
345 1, 1, /* width/height */
346 0, /* border */
347 texImageFormat,
348 texImageType,
349 dummy_data);
351 pass &= piglit_check_gl_error(GL_NO_ERROR);
353 glClearTexImage(tex, 0, clearValueFormat, clearValueType, dummy_data);
355 pass &= piglit_check_gl_error(GL_INVALID_OPERATION);
357 glBindTexture(GL_TEXTURE_2D, 0);
358 glDeleteTextures(1, &tex);
360 return pass;