ext_gpu_shader4: add compiler tests for everything
[piglit.git] / tests / spec / gl-1.5 / normal3b3s-invariance.c
blobd80ba97a6da641c041cba7df95a54305e81e6ced
1 /*
2 * Copyright (C) 2014 VMware, Inc.
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 * Test GLbyte[3] and GLshort[3] normal vectors and OpenGL invariance.
27 * We draw a lit, curved surface in two passes. The first pass draws the
28 * surface with a blue material and GLfloat[3] normal vectors. The second
29 * pass draws the surface with a green material and GLbyte[3] (or GLshort[3])
30 * normal vectors. The second pass uses glDepthFunc(GL_EQUAL) and additive
31 * blending. So the result should be a cyan surface (blue + green).
33 * If OpenGL uses different vertex transformation paths for the GLfloat[3]
34 * vs. GLbyte[3] vs. GLshort[3] normal vectors we may get different vertex
35 * positions, and different fragment Z values, and an unexpected surface color.
37 * Note: we use vertex buffers/arrays and not glNormal3b/3s since the later
38 * might convert its parameters to floats.
40 * This test hits a VMware svga3d driver issue.
42 * Brian Paul
43 * 11 April 2014
46 #include "piglit-util-gl.h"
49 PIGLIT_GL_TEST_CONFIG_BEGIN
50 config.supports_gl_compat_version = 15;
51 config.window_visual = PIGLIT_GL_VISUAL_DOUBLE | PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DEPTH;
52 config.khr_no_error_support = PIGLIT_NO_ERRORS;
53 PIGLIT_GL_TEST_CONFIG_END
56 struct vertex {
57 GLfloat pos[3]; /* position */
58 GLfloat nf[3]; /* float normal */
59 GLshort ns[3]; /* short normal */
60 GLbyte nb[3]; /* byte normal */
64 static GLuint NumSections = 60;
66 static GLenum NormalType = GL_BYTE;
68 static const float blue[4] = { 0, 0, 1, 0 };
69 static const float green[4] = { 0, 1, 0, 0 };
70 static const float black[4] = { 0, 0, 0, 0 };
73 static GLbyte
74 float_to_byte(float v)
76 return (GLbyte) (v * 127.0);
80 static GLshort
81 float_to_short(float v)
83 return (GLshort) (v * 32767.0);
87 /**
88 * Setup a VBO for a curved surface with vertex positions, float normals
89 * and byte normals.
91 static void
92 setup_vbo(void)
94 const float radius = 20.0;
95 int i, j;
96 GLuint vbo;
97 struct vertex *vbo_data;
98 const unsigned num_verts = (NumSections + 1) * 2;
99 const unsigned vbo_size = sizeof(struct vertex) * num_verts;
101 glGenBuffers(1, &vbo);
102 glBindBuffer(GL_ARRAY_BUFFER, vbo);
103 glBufferData(GL_ARRAY_BUFFER, vbo_size, NULL, GL_STATIC_DRAW);
104 vbo_data = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
106 for (i = j = 0; i <= NumSections; i++) {
107 float a = (float) i / (NumSections) * M_PI * 2.0;
108 float x = cos(a);
109 float z = sin(a);
111 vbo_data[j].pos[0] = radius * x;
112 vbo_data[j].pos[1] = -10.0;
113 vbo_data[j].pos[2] = radius * z;
114 vbo_data[j].nf[0] = x;
115 vbo_data[j].nf[1] = 0;
116 vbo_data[j].nf[2] = z;
117 vbo_data[j].nb[0] = float_to_byte(x);
118 vbo_data[j].nb[1] = 0;
119 vbo_data[j].nb[2] = float_to_byte(z);
120 vbo_data[j].ns[0] = float_to_short(x);
121 vbo_data[j].ns[1] = 0;
122 vbo_data[j].ns[2] = float_to_short(z);
123 j++;
125 vbo_data[j].pos[0] = radius * x;
126 vbo_data[j].pos[1] = 10.0;
127 vbo_data[j].pos[2] = radius * z;
128 vbo_data[j].nf[0] = x;
129 vbo_data[j].nf[1] = 0;
130 vbo_data[j].nf[2] = z;
131 vbo_data[j].nb[0] = float_to_byte(x);
132 vbo_data[j].nb[1] = 0;
133 vbo_data[j].nb[2] = float_to_byte(z);
134 vbo_data[j].ns[0] = float_to_short(x);
135 vbo_data[j].ns[1] = 0;
136 vbo_data[j].ns[2] = float_to_short(z);
137 j++;
140 glUnmapBuffer(GL_ARRAY_BUFFER);
144 static void
145 draw_vbo(GLenum normal_type)
147 const unsigned num_verts = (NumSections + 1) * 2;
149 glVertexPointer(3, GL_FLOAT, sizeof(struct vertex),
150 (void *) offsetof(struct vertex, pos));
152 if (normal_type == GL_BYTE) {
153 glNormalPointer(GL_BYTE, sizeof(struct vertex),
154 (void *) offsetof(struct vertex, nb));
156 else if (normal_type == GL_SHORT) {
157 glNormalPointer(GL_SHORT, sizeof(struct vertex),
158 (void *) offsetof(struct vertex, ns));
160 else {
161 assert(normal_type == GL_FLOAT);
162 glNormalPointer(GL_FLOAT, sizeof(struct vertex),
163 (void *) offsetof(struct vertex, nf));
166 glEnable(GL_VERTEX_ARRAY);
167 glEnable(GL_NORMAL_ARRAY);
168 glDrawArrays(GL_TRIANGLE_STRIP, 0, num_verts);
172 static bool
173 draw(void)
175 GLfloat pix[3];
176 bool pass;
178 glViewport(0, 0, piglit_width, piglit_height);
179 glMatrixMode(GL_PROJECTION);
180 glLoadIdentity();
181 glFrustum(-1, 1, -1, 1, 2, 200);
183 glMatrixMode(GL_MODELVIEW);
184 glLoadIdentity();
185 glTranslatef(0, -5, -80);
187 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
189 glEnable(GL_BLEND);
191 glPushMatrix();
192 glRotatef(-25, 1, 0, 0);
194 /* Draw blue base color with glDepthFunc(<=) */
195 glMaterialfv(GL_FRONT, GL_DIFFUSE, blue);
196 glDepthFunc(GL_LEQUAL);
197 draw_vbo(GL_FLOAT);
199 /* Draw green highlight color with glDepthFunc(==).
200 * We should generate fragments with the same Z value as the
201 * first pass.
203 glMaterialfv(GL_FRONT, GL_DIFFUSE, green);
204 glDepthFunc(GL_EQUAL);
205 draw_vbo(NormalType);
207 glPopMatrix();
209 /* Probe: the center pixel should cyan (blue + green) */
210 glReadPixels(piglit_width / 2, piglit_height / 2, 1, 1,
211 GL_RGB, GL_FLOAT, pix);
212 pass = (pix[0] == 0.0 &&
213 pix[1] >= 0.75 &&
214 pix[2] >= 0.75);
215 if (!pass) {
216 printf("Expected (r=0, g>=0.75, b>=0.75), found (%g, %g, %g)\n",
217 pix[0], pix[1], pix[2]);
220 piglit_present_results();
222 return pass;
226 enum piglit_result
227 piglit_display(void)
229 bool pass = draw();
230 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
234 void
235 piglit_init(int argc, char **argv)
237 if (argc > 1) {
238 if (strcmp(argv[1], "GL_BYTE") == 0) {
239 NormalType = GL_BYTE;
241 else if (strcmp(argv[1], "GL_SHORT") == 0) {
242 NormalType = GL_SHORT;
244 else {
245 printf("Expected argument GL_BYTE or GL_SHORT\n");
246 piglit_report_result(PIGLIT_SKIP);
251 glMaterialfv(GL_FRONT, GL_EMISSION, black);
252 glMaterialfv(GL_FRONT, GL_DIFFUSE, black);
253 glMaterialfv(GL_FRONT, GL_SPECULAR, black);
254 glMaterialf(GL_FRONT, GL_SHININESS, 5);
255 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black);
257 glEnable(GL_LIGHTING);
258 glEnable(GL_LIGHT0);
260 glEnable(GL_DEPTH_TEST);
262 glEnable(GL_CULL_FACE);
264 glBlendFunc(GL_ONE, GL_ONE);
266 setup_vbo();