ovr_multiview: add some basic glsl tests
[piglit.git] / tests / spec / arb_vertex_program / matrix-property-bindings.c
blobc47a4647965f3cf4dd1b0d6b12733285f8e7c915
1 /*
2 * Copyright © 2017 Fabian Bieler
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 matrix-property-bindings.c:
26 * Access GL transformation state in ARB_vertex_program.
28 * Set matrix property bindings with the OpenGL glLoadMatrix API and access it
29 * in ARB vertex programs.
32 #include "piglit-util-gl.h"
33 #include "piglit-matrix.h"
35 PIGLIT_GL_TEST_CONFIG_BEGIN
37 config.supports_gl_compat_version = 13;
38 config.window_visual = PIGLIT_GL_VISUAL_RGB;
39 config.khr_no_error_support = PIGLIT_NO_ERRORS;
41 PIGLIT_GL_TEST_CONFIG_END
43 #ifdef _WIN32
44 #define SRAND(x) srand(x)
45 #define DRAND() ((float)rand() / RAND_MAX)
46 #else
47 #define SRAND(x) srand48(x)
48 #define DRAND() drand48()
49 #endif
52 * This vertex program compares test_param[i] against expectedi using epsilon
53 * as tolerance for all i from 0 to 3 inclusive.
54 * On match result.color is set to green, red otherwise.
56 static const char *vp_template =
57 "!!ARBvp1.0\n"
58 "PARAM epsilon = 0.00390625;\n"
59 "PARAM expected0 = {%f, %f, %f, %f};\n"
60 "PARAM expected1 = {%f, %f, %f, %f};\n"
61 "PARAM expected2 = {%f, %f, %f, %f};\n"
62 "PARAM expected3 = {%f, %f, %f, %f};\n"
63 "PARAM test_param[4] = { %s };\n"
64 "TEMP tmp1;\n"
65 "TEMP tmp2;\n"
67 "SUB tmp1, expected0, test_param[0];\n"
68 "ABS tmp1, tmp1;\n"
69 "SLT tmp1, tmp1, epsilon;\n"
70 "DP4 tmp2.x, tmp1, tmp1;\n" /* tmp2.x = 4 */
72 "SUB tmp1, expected1, test_param[1];\n"
73 "ABS tmp1, tmp1;\n"
74 "SLT tmp1, tmp1, epsilon;\n"
75 "DP4 tmp2.y, tmp1, tmp1;\n" /* tmp2.y = 4 */
77 "SUB tmp1, expected2, test_param[2];\n"
78 "ABS tmp1, tmp1;\n"
79 "SLT tmp1, tmp1, epsilon;\n"
80 "DP4 tmp2.z, tmp1, tmp1;\n" /* tmp2.z = 4 */
82 "SUB tmp1, expected3, test_param[3];\n"
83 "ABS tmp1, tmp1;\n"
84 "SLT tmp1, tmp1, epsilon;\n"
85 "DP4 tmp2.w, tmp1, tmp1;\n" /* tmp2.w = 4 */
87 "DP4 tmp2.x, tmp2, tmp2;\n" /* tmp2.x = 64 */
89 "SLT tmp1.x, tmp2.x, 64;\n" /* tmp1.x = 0 */
90 "SGE tmp1.y, tmp2.x, 64;\n" /* tmp1.y = 1 */
91 "SWZ result.color, tmp1, x, y, 0, 1;\n"
93 "MOV result.position, vertex.position;\n"
94 "END";
96 /**
97 * Check that the constant parameter \name is equal to \m.
99 * Since we also test for derived state involving floating point computation
100 * don't test for strict equality but rather only check if the parameter's
101 * components are within and epsilon of their expected values.
103 static bool
104 check_prg_param_(const float *m, const char *name)
106 char *vp_text;
107 const float green[3] = {0.0, 1.0, 0.0};
109 asprintf(&vp_text, vp_template, m[0], m[4], m[8], m[12], m[1], m[5],
110 m[9], m[13], m[2], m[6], m[10], m[14], m[3], m[7], m[11],
111 m[15], name);
112 GLuint prog = piglit_compile_program(GL_VERTEX_PROGRAM_ARB, vp_text);
113 free(vp_text);
114 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prog);
116 glClear(GL_COLOR_BUFFER_BIT);
117 piglit_draw_rect(-1, -1, 2, 2);
119 glDeleteProgramsARB(1, &prog);
121 if (piglit_probe_pixel_rgb_silent(piglit_width / 2, piglit_height / 2,
122 green, NULL))
123 return true;
124 printf("Failed parameter: '%s'.\n", name);
125 return false;
129 * printf-like version of function above.
131 static bool
132 check_prg_param(const float *m, const char *format, ...) PRINTFLIKE(2, 3);
133 static bool
134 check_prg_param(const float *m, const char *format, ...)
136 char *name;
137 va_list ap;
139 va_start(ap, format);
140 vasprintf(&name, format, ap);
141 va_end(ap);
143 const bool r = check_prg_param_(m, name);
144 free(name);
145 return r;
149 * Load random 16 floats between 0 and 1 into matrix \pname
150 * and return them in \m.
152 static void
153 load_matrix(float m[16], const GLenum pname)
155 glMatrixMode(pname);
156 for (int i = 0; i < 16; ++i)
157 m[i] = DRAND();
158 glLoadMatrixf(m);
162 * Check that matrix \pname contains the values \m.
163 * if \idx is positive add it as and index to the matrix array.
164 * if \idx is zero check both indexed and non-indexed variants.
165 * if \idx is negative check non-indexed matrix.
166 * Also check the matrix' transpose, inverse and transpose inverse.
168 static bool
169 check_matrix_variants(const char *prefix, const float m[16], const int idx)
171 bool pass = true;
172 float m_T[16], m_inv[16], m_inv_T[16];
174 piglit_matrix_transpose(m_T, m);
175 piglit_matrix_inverse(m_inv, m);
176 piglit_matrix_transpose(m_inv_T, m_inv);
178 if (idx >= 0) {
179 pass = check_prg_param(m, "state.matrix.%s[%d]", prefix,
180 idx) && pass;
181 pass = check_prg_param(m_T, "state.matrix.%s[%d].transpose",
182 prefix, idx) && pass;
183 pass = check_prg_param(m_inv, "state.matrix.%s[%d].inverse",
184 prefix, idx) && pass;
185 pass = check_prg_param(m_inv_T,
186 "state.matrix.%s[%d].invtrans", prefix,
187 idx) && pass;
189 if (idx <= 0) {
190 pass = check_prg_param(m, "state.matrix.%s", prefix) && pass;
191 pass = check_prg_param(m_T, "state.matrix.%s.transpose",
192 prefix) && pass;
193 pass = check_prg_param(m_inv, "state.matrix.%s.inverse",
194 prefix) && pass;
195 pass = check_prg_param(m_inv_T, "state.matrix.%s.invtrans",
196 prefix) && pass;
199 return pass;
203 * Load random data in matrix \pname and check it by it's shader name \name
204 * with (optional) index \idx.
206 static bool
207 load_and_test_matrix(const char *name, const GLenum pname, const int idx)
209 float mat[16];
211 load_matrix(mat, pname);
212 return check_matrix_variants(name, mat, idx);
215 enum piglit_result
216 piglit_display(void)
218 bool pass = true;
220 /* Test modelview and projection matrices. */
221 pass = load_and_test_matrix("modelview", GL_MODELVIEW, -1) && pass;
223 pass = load_and_test_matrix("projection", GL_PROJECTION, -1) && pass;
225 /* Test modelview-projection matrix. */
226 float mvp[16], proj[16], mview[16];
227 load_matrix(mview, GL_MODELVIEW);
228 load_matrix(proj, GL_PROJECTION);
229 piglit_matrix_mul_matrix(mvp, proj, mview);
230 pass = check_matrix_variants("mvp", mvp, -1) && pass;
232 /* Test texture matrices. */
233 int max_texture_coords;
234 glGetIntegerv(GL_MAX_TEXTURE_COORDS, &max_texture_coords);
235 for (int t = 0; t < max_texture_coords; ++t) {
236 glActiveTexture(GL_TEXTURE0 + t);
237 pass = load_and_test_matrix("texture", GL_TEXTURE, t) && pass;
240 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
243 void
244 piglit_init(int argc, char **argv)
246 piglit_require_extension("GL_ARB_vertex_program");
248 glEnable(GL_VERTEX_PROGRAM_ARB);
250 SRAND(17);