1 /*
2  * Copyright (c) The Piglit project 2007
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  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the 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 NON-INFRINGEMENT.  IN NO EVENT SHALL
18  * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 
24 #pragma once
25 #ifndef __PIGLIT_UTIL_GL_H__
26 #define __PIGLIT_UTIL_GL_H__
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #include <errno.h>
33 #include <limits.h>
34 
35 #include "piglit-util.h"
36 
37 #include <piglit/gl_wrap.h>
38 #include <piglit/glut_wrap.h>
39 
40 #define piglit_get_proc_address(x) piglit_dispatch_resolve_function(x)
41 
42 #include "piglit-framework-gl.h"
43 #include "piglit-shader.h"
44 
45 extern const uint8_t fdo_bitmap[];
46 extern const unsigned int fdo_bitmap_width;
47 extern const unsigned int fdo_bitmap_height;
48 
49 extern bool piglit_is_core_profile;
50 
51 /**
52  * Determine if the API is OpenGL ES.
53  */
54 bool piglit_is_gles(void);
55 
56 /**
57  * Determine if the API is OpenGL ES 3.x.
58  */
59 bool piglit_is_gles3(void);
60 
61 /**
62  * \brief Get version of OpenGL or OpenGL ES API.
63  *
64  * Returned version is multiplied by 10 to make it an integer.  So for
65  * example, if the GL version is 2.1, the return value is 21.
66  */
67 int piglit_get_gl_version(void);
68 
69 /**
70  * \precondition name is not null
71  */
72 bool piglit_is_extension_supported(const char *name);
73 
74 /**
75  * reinitialize the supported extension List.
76  */
77 void piglit_gl_invalidate_extensions();
78 
79 /**
80  * \brief Convert a GL error to a string.
81  *
82  * For example, given GL_INVALID_ENUM, return "GL_INVALID_ENUM".
83  *
84  * Return "(unrecognized error)" if the enum is not recognized.
85  */
86 const char* piglit_get_gl_error_name(GLenum error);
87 
88 /**
89  * \brief Convert a GL enum to a string.
90  *
91  * For example, given GL_INVALID_ENUM, return "GL_INVALID_ENUM".
92  *
93  * Return "(unrecognized enum)" if the enum is not recognized.
94  */
95 const char *piglit_get_gl_enum_name(GLenum param);
96 
97 /**
98  * \brief Convert a string to a GL enum.
99  *
100  * For example, given "GL_INVALID_ENUM", return GL_INVALID_ENUM.
101  *
102  * abort() if the string is not recognized.
103  */
104 GLenum piglit_get_gl_enum_from_name(const char *name);
105 
106 GLenum
107 piglit_get_gl_memory_barrier_enum_from_name(const char *name);
108 
109 /**
110  * \brief Convert a GL primitive type enum value to a string.
111  *
112  * For example, given GL_POLYGON, return "GL_POLYGON".
113  * We don't use piglit_get_gl_enum_name() for this because there are
114  * other enums which alias the prim type enums (ex: GL_POINTS = GL_NONE);
115  *
116  * Return "(unrecognized enum)" if the enum is not recognized.
117  */
118 const char *piglit_get_prim_name(GLenum prim);
119 
120 
121 /**
122  * \brief Check for unexpected GL errors.
123  *
124  * If glGetError() returns an error other than \c expected_error, then
125  * print a diagnostic and return GL_FALSE.  Otherwise return GL_TRUE.
126  */
127 GLboolean
128 piglit_check_gl_error_(GLenum expected_error, const char *file, unsigned line);
129 
130 #define piglit_check_gl_error(expected) \
131  piglit_check_gl_error_((expected), __FILE__, __LINE__)
132 
133 /**
134  * \brief Drain all GL errors.
135  *
136  * Repeatly call glGetError and discard errors until it returns GL_NO_ERROR.
137  */
138 void piglit_reset_gl_error(void);
139 
140 void piglit_require_gl_version(int required_version_times_10);
141 void piglit_require_extension(const char *name);
142 void piglit_require_not_extension(const char *name);
143 unsigned piglit_num_components(GLenum format);
144 bool piglit_get_luminance_intensity_bits(GLenum internalformat, int *bits);
145 int piglit_probe_pixel_rgb_silent(int x, int y, const float* expected, float *out_probe);
146 int piglit_probe_pixel_rgba_silent(int x, int y, const float* expected, float *out_probe);
147 int piglit_probe_pixel_rgb(int x, int y, const float* expected);
148 int piglit_probe_pixel_rgba(int x, int y, const float* expected);
149 int piglit_probe_rect_r_ubyte(int x, int y, int w, int h, GLubyte expected);
150 int piglit_probe_rect_rgb(int x, int y, int w, int h, const float* expected);
151 int piglit_probe_rect_rgb_silent(int x, int y, int w, int h, const float *expected);
152 int piglit_probe_rect_rgba(int x, int y, int w, int h, const float* expected);
153 int piglit_probe_rect_rgba_varying(int x, int y, int w, int h,
154 				   const float* expected, size_t stride);
155 int piglit_probe_rect_rgba_int(int x, int y, int w, int h, const int* expected);
156 int piglit_probe_rect_rgba_uint(int x, int y, int w, int h, const unsigned int* expected);
157 bool piglit_probe_rect_two_rgb(int x, int y, int w, int h,
158 			       const float *expected1,
159 			       const float *expected2);
160 void piglit_compute_probe_tolerance(GLenum format, float *tolerance);
161 
162 /**
163  * Compare two pixels.
164  * \param x the x coordinate of the pixel being probed
165  * \param y the y coordinate of the pixel being probed
166  */
167 int piglit_compare_pixels(int x, int y, const float *expected, const float *probe,
168 			 const float *tolerance, int num_components);
169 
170 /**
171  * Compare two adjacent in-memory floating-point images.
172  * Adjacent means: y1 == y2 && x1 == x2 - w;
173  *
174  * \param w the width of the rectangle containing both images
175  * \param h the height of the rectangle containing both images
176  * \param images : the start of the buffer containing the observed image on
177  *		the left and the expected image on the right
178  */
179 int piglit_compare_image_halves_color(int w, int h, int num_components,
180 			    const float *tolerance,
181 			    const float *expected_observed_image);
182 int piglit_compare_images_color(int x, int y, int w, int h, int num_components,
183 				const float *tolerance,
184 				const float *expected_image,
185 				const float *observed_image);
186 int piglit_probe_image_color(int x, int y, int w, int h, GLenum format, const float *image);
187 int piglit_probe_image_rgb(int x, int y, int w, int h, const float *image);
188 int piglit_probe_image_rgba(int x, int y, int w, int h, const float *image);
189 int piglit_compare_images_ubyte(int x, int y, int w, int h,
190 				const GLubyte *expected_image,
191 				const GLubyte *observed_image);
192 int piglit_equal_images_update_rgba8(const GLubyte *expected_original,
193 				     const GLubyte *expected_updated,
194 				     const GLubyte *observed,
195 				     unsigned w, unsigned h, unsigned d,
196 				     unsigned ux, unsigned uy, unsigned uz,
197 				     unsigned uw, unsigned uh, unsigned ud,
198 				     unsigned bits);
199 int piglit_probe_image_stencil(int x, int y, int w, int h, const GLubyte *image);
200 int piglit_probe_image_ubyte(int x, int y, int w, int h, GLenum format,
201 			     const GLubyte *image);
202 int piglit_probe_texel_rect_rgb(int target, int level, int x, int y,
203 				int w, int h, const float *expected);
204 int piglit_probe_texel_rgb(int target, int level, int x, int y,
205 			   const float* expected);
206 int piglit_probe_texel_rect_rgba(int target, int level, int x, int y,
207 				 int w, int h, const float *expected);
208 int piglit_probe_texel_rgba(int target, int level, int x, int y,
209 			    const float* expected);
210 int piglit_probe_texel_volume_rgba(int target, int level, int x, int y, int z,
211 				 int w, int h, int d, const float *expected);
212 int piglit_probe_pixel_depth(int x, int y, float expected);
213 int piglit_probe_rect_depth(int x, int y, int w, int h, float expected);
214 int piglit_probe_pixel_stencil(int x, int y, unsigned expected);
215 int piglit_probe_rect_stencil(int x, int y, int w, int h, unsigned expected);
216 int piglit_probe_rect_halves_equal_rgba(int x, int y, int w, int h);
217 
218 /**
219  * \brief Check if two rectangles are equivalent
220  *
221  * Given the coordinates of two rectangles, check that the two are equal.
222  * The first rectangle is what's observed, whereas the second rectangle is
223  * what's expected.
224  */
225 int piglit_probe_rects_equal(int x1, int y1, int x2, int y2,
226 			int w, int h, GLenum format);
227 
228 bool piglit_probe_buffer(GLuint buf, GLenum target, const char *label,
229 			 unsigned n, unsigned num_components,
230 			 const float *expected);
231 bool piglit_probe_buffer_doubles(GLuint buf, GLenum target, const char *label,
232 				 unsigned n, unsigned num_components,
233 				 const double *expected);
234 int piglit_use_fragment_program(void);
235 int piglit_use_vertex_program(void);
236 void piglit_require_fragment_program(void);
237 void piglit_require_vertex_program(void);
238 GLuint piglit_compile_program(GLenum target, const char* text);
239 GLvoid piglit_draw_triangle(float x1, float y1, float x2, float y2,
240 			    float x3, float y3);
241 GLvoid piglit_draw_triangle_z(float z, float x1, float y1, float x2, float y2,
242 			      float x3, float y3);
243 GLvoid piglit_draw_rect_custom(float x, float y, float w, float h,
244 			       bool use_patches, unsigned instance_count);
245 GLvoid piglit_draw_rect(float x, float y, float w, float h);
246 GLvoid piglit_draw_rect_z(float z, float x, float y, float w, float h);
247 GLvoid piglit_draw_rect_tex(float x, float y, float w, float h,
248                             float tx, float ty, float tw, float th);
249 GLvoid piglit_draw_rect_back(float x, float y, float w, float h);
250 void piglit_draw_rect_from_arrays(const void *verts, const void *tex,
251 				  bool use_patches, unsigned instance_count);
252 
253 unsigned short piglit_half_from_float(float val);
254 
255 /**
256  * Wrapper for piglit_half_from_float() which allows using an exact
257  * hex bit pattern to generate a half float value.
258  */
259 static inline unsigned short
strtohf_hex(const char * nptr,char ** endptr)260 strtohf_hex(const char *nptr, char **endptr)
261 {
262 	/* skip spaces and tabs */
263 	while (*nptr == ' ' || *nptr == '\t')
264 		nptr++;
265 
266 	if (strncmp(nptr, "0x", 2) == 0) {
267 		uint32_t u = strtoul(nptr, endptr, 16);
268 		if (u > USHRT_MAX) {
269 			errno = ERANGE;
270 			return USHRT_MAX;
271 		} else {
272 			return u;
273 		}
274 	} else {
275 		return piglit_half_from_float(strtod_inf(nptr, endptr));
276 	}
277 }
278 
279 void piglit_escape_exit_key(unsigned char key, int x, int y);
280 
281 void piglit_gen_ortho_projection(double left, double right, double bottom,
282 				 double top, double near_val, double far_val,
283 				 GLboolean push);
284 void piglit_ortho_projection(int w, int h, GLboolean push);
285 void piglit_frustum_projection(GLboolean push, double l, double r, double b,
286 			       double t, double n, double f);
287 void piglit_gen_ortho_uniform(GLint location, double left, double right,
288 			      double bottom, double top, double near_val,
289 			      double far_val);
290 void piglit_ortho_uniform(GLint location, int w, int h);
291 
292 GLuint
293 piglit_quads_texture(GLuint tex, unsigned level,
294 		     unsigned width, unsigned height,
295 		     unsigned horiz_square_size,
296 		     unsigned vert_square_size,
297 		     const float *bl, const float *br,
298 		     const float *tl, const float *tr);
299 GLuint piglit_checkerboard_texture(GLuint tex, unsigned level,
300     unsigned width, unsigned height,
301     unsigned horiz_square_size, unsigned vert_square_size,
302     const float *black, const float *white);
303 GLuint piglit_miptree_texture(void);
304 GLfloat *piglit_rgbw_image(GLenum internalFormat, int w, int h,
305                            GLboolean alpha, GLenum basetype);
306 GLubyte *piglit_rgbw_image_ubyte(int w, int h, GLboolean alpha);
307 GLuint piglit_rgbw_texture(GLenum internalFormat, int w, int h, GLboolean mip,
308 		    GLboolean alpha, GLenum basetype);
309 GLuint piglit_rgbw_texture_1d(void);
310 GLuint piglit_rgbw_texture_3d(void);
311 GLuint piglit_integer_texture(GLenum internalFormat, int w, int h, int b, int a);
312 GLuint piglit_depth_texture(GLenum target, GLenum format, int w, int h, int d, GLboolean mip);
313 GLuint piglit_array_texture(GLenum target, GLenum format, int w, int h, int d, GLboolean mip);
314 GLuint piglit_multisample_texture(GLenum target, GLuint tex,
315 				  GLenum internalFormat,
316 				  unsigned width, unsigned height,
317 				  unsigned depth, unsigned samples,
318 				  GLenum format, GLenum type, const void *data);
319 extern float piglit_tolerance[4];
320 void piglit_set_tolerance_for_bits(int rbits, int gbits, int bbits, int abits);
321 extern void piglit_require_transform_feedback(void);
322 
323 bool
324 piglit_get_compressed_block_size(GLenum format,
325 				 unsigned *bw, unsigned *bh, unsigned *bytes);
326 
327 unsigned
328 piglit_compressed_image_size(GLenum format, unsigned width, unsigned height);
329 
330 unsigned
331 piglit_compressed_pixel_offset(GLenum format, unsigned width,
332 			       unsigned x, unsigned y);
333 
334 void
335 piglit_visualize_image(float *img, GLenum base_internal_format,
336 		       int image_width, int image_height,
337 		       int image_count, bool rhs);
338 
339 float piglit_srgb_to_linear(float x);
340 float piglit_linear_to_srgb(float x);
341 
342 extern GLfloat cube_face_texcoords[6][4][3];
343 extern const char *cube_face_names[6];
344 extern const GLenum cube_face_targets[6];
345 
346 /**
347  * Common vertex program code to perform a model-view-project matrix transform
348  */
349 #define PIGLIT_VERTEX_PROGRAM_MVP_TRANSFORM		\
350 	"ATTRIB	iPos = vertex.position;\n"		\
351 	"OUTPUT	oPos = result.position;\n"		\
352 	"PARAM	mvp[4] = { state.matrix.mvp };\n"	\
353 	"DP4	oPos.x, mvp[0], iPos;\n"		\
354 	"DP4	oPos.y, mvp[1], iPos;\n"		\
355 	"DP4	oPos.z, mvp[2], iPos;\n"		\
356 	"DP4	oPos.w, mvp[3], iPos;\n"
357 
358 static const GLint PIGLIT_ATTRIB_POS = 0;
359 static const GLint PIGLIT_ATTRIB_TEX = 1;
360 
361 /**
362  * Given a GLSL version number, return the lowest-numbered GL version
363  * that is guaranteed to support it.
364  */
365 unsigned
366 required_gl_version_from_glsl_version(unsigned glsl_version);
367 
368 void
369 piglit_write_png(const char *filename, GLenum base_format,
370                  int width, int height, GLubyte *data, bool flip_y);
371 
372 #ifdef __cplusplus
373 } /* end extern "C" */
374 #endif
375 
376 #endif /* __PIGLIT_UTIL_GL_H__ */
377