sotest.c revision 32001f49
1/* 2 * GL_ARB_shader_objects & GL_ARB_vertex_shader interface test application. 3 * Neither compiler nor executor is being tested here, although some simple shader 4 * compilation tests are performed. 5 * 6 * Perfectly valid behaviour produces output that does not have a line 7 * beginning with three stars (***). 8 * 9 * Author: Michal Krol 10 */ 11 12#include "framework.h" 13 14enum TEST_TYPE 15{ 16 TT_GETERROR_NOERROR, 17 TT_GETERROR_INVALIDVALUE, 18 TT_GETERROR_INVALIDOPERATION, 19 TT_PARAM1_ZERO, 20 TT_PARAM1_NONZERO 21}; 22 23static enum TEST_TYPE current_test; 24 25static void begintest (enum TEST_TYPE type, const char *name) 26{ 27 current_test = type; 28 printf ("\n BEGIN TEST: %s\n", name); 29 while (glGetError () != GL_NO_ERROR) 30 ; 31} 32 33static void endtest1 (GLuint param1) 34{ 35 const char *msg = NULL; 36 37 switch (current_test) 38 { 39 case TT_GETERROR_NOERROR: 40 if (glGetError () != GL_NO_ERROR) 41 msg = "glGetError () does not return GL_NO_ERROR"; 42 break; 43 case TT_GETERROR_INVALIDVALUE: 44 if (glGetError () != GL_INVALID_VALUE) 45 msg = "glGetError () does not return GL_INVALID_VALUE"; 46 break; 47 case TT_GETERROR_INVALIDOPERATION: 48 if (glGetError () != GL_INVALID_OPERATION) 49 msg = "glGetError () does not return GL_INVALID_OPERATION"; 50 break; 51 case TT_PARAM1_ZERO: 52 if (param1) 53 msg = "The parameter is not zero"; 54 break; 55 case TT_PARAM1_NONZERO: 56 if (!param1) 57 msg = "The parameter is not non-zero"; 58 break; 59 default: 60 assert (0); 61 } 62 63 if (msg == NULL) 64 printf (" OK\n"); 65 else 66 printf ("*** %s\n", msg); 67 68 while (glGetError () != GL_NO_ERROR) 69 ; 70} 71 72static void endtest (void) 73{ 74 endtest1 (0); 75} 76 77static GLhandleARB vert = 0; 78static GLhandleARB frag = 0; 79static GLhandleARB prog = 0; 80 81static GLhandleARB find_invalid_handle (void) 82{ 83 GLhandleARB handle; 84 85 for (handle = 1; handle < 16; handle++) 86 if (handle != vert && handle != frag && handle != prog) 87 return handle; 88 assert (0); 89 return 0; 90} 91 92static const char *invsynvertsrc = 93 "void main () {\n" 94 " gl_Position = gl_ModelViewMatrix ! gl_Vertex;\n" /* unexpected token */ 95 "}\n" 96; 97 98static const char *invsemvertsrc = 99 "void main () {\n" 100 " gl_Position = gl_ModelviewMatrix * gl_Vertex;\n" /* undeclared identifier */ 101 "}\n" 102; 103 104static const char *uniforms = 105 "uniform vec4 CommonUniform;\n" 106; 107 108static const char *validvertsrc = 109 "uniform vec4 VertexUniform;\n" 110 "attribute vec4 FirstAttrib;\n" 111 "attribute vec4 SecondAttrib;\n" 112 "void main () {\n" 113 " gl_Position = gl_ModelViewMatrix * gl_Vertex + CommonUniform + VertexUniform\n" 114 " + FirstAttrib + SecondAttrib;\n" 115 "}\n" 116; 117 118static const char *invsynfragsrc = 119 "void main () {\n" 120 " gl_FragColor = gl_Color\n" /* missing ; */ 121 "}\n" 122; 123 124static const char *invsemfragsrc = 125 "void main () {\n" 126 " gl_FragColor = gl_FrontColor;\n" /* gl_FrontColor only in vertex shader */ 127 "}\n" 128; 129 130static const char *validfragsrc = 131 "uniform vec4 FragmentUniform;\n" 132 "void main () {\n" 133 " gl_FragColor = gl_Color + CommonUniform + FragmentUniform;\n" 134 "}\n" 135; 136 137void InitScene (void) 138{ 139 GLint params[1]; 140 const char *tab[2]; 141 142 /* 143 * GL should silently ignore calls that delete object 0. 144 */ 145 begintest (TT_GETERROR_NOERROR, "glDeleteObject(0)"); 146 glDeleteObjectARB (0); 147 endtest (); 148 149 /* 150 * GL generates an error on invalid object handle. 151 */ 152 begintest (TT_GETERROR_INVALIDVALUE, "Pass invalid non-zero object handle"); 153 glDeleteObjectARB (find_invalid_handle ()); 154 endtest (); 155 glUseProgramObjectARB (find_invalid_handle ()); 156 endtest (); 157 158 /* 159 * Create object. GL should return unique non-zero values. 160 */ 161 begintest (TT_PARAM1_NONZERO, "Create object"); 162 vert = glCreateShaderObjectARB (GL_VERTEX_SHADER_ARB); 163 endtest1 (vert); 164 frag = glCreateShaderObjectARB (GL_FRAGMENT_SHADER_ARB); 165 endtest1 (frag); 166 prog = glCreateProgramObjectARB (); 167 endtest1 (prog); 168 endtest1 (vert != frag && frag != prog && prog != vert); 169 170 /* 171 * Link empty program. 172 */ 173 begintest (TT_PARAM1_NONZERO, "Link empty program"); 174 glLinkProgramARB (prog); 175 endtest1 (CheckObjectStatus (prog)); 176 177 /* 178 * Use empty program object. Empty program objects are valid. 179 */ 180 begintest (TT_GETERROR_NOERROR, "Use empty program object"); 181 glUseProgramObjectARB (prog); 182 endtest (); 183 184 /* 185 * Attach invalid object handles. Program object 0 should not be accepted. 186 */ 187 begintest (TT_GETERROR_INVALIDVALUE, "Attach invalid object handle"); 188 glAttachObjectARB (0, find_invalid_handle ()); 189 endtest (); 190 glAttachObjectARB (0, frag); 191 endtest (); 192 glAttachObjectARB (find_invalid_handle (), find_invalid_handle ()); 193 endtest (); 194 glAttachObjectARB (find_invalid_handle (), frag); 195 endtest (); 196 glAttachObjectARB (prog, find_invalid_handle ()); 197 endtest (); 198 199 /* 200 * Attach valid object handles with wrong semantics. 201 */ 202 begintest (TT_GETERROR_INVALIDOPERATION, "Attach object badly"); 203 glAttachObjectARB (vert, frag); 204 endtest (); 205 glAttachObjectARB (vert, prog); 206 endtest (); 207 glAttachObjectARB (prog, prog); 208 endtest (); 209 210 /* 211 * Detach non-attached object. 212 */ 213 begintest (TT_GETERROR_INVALIDOPERATION, "Detach non-attached object"); 214 glDetachObjectARB (prog, vert); 215 endtest (); 216 glDetachObjectARB (prog, frag); 217 endtest (); 218 219 /* 220 * Attach shader. 221 */ 222 begintest (TT_GETERROR_NOERROR, "Attach shader to program object"); 223 glAttachObjectARB (prog, vert); 224 endtest (); 225 glAttachObjectARB (prog, frag); 226 endtest (); 227 228 /* 229 * Attach object twice. 230 */ 231 begintest (TT_GETERROR_INVALIDOPERATION, "Attach object twice"); 232 glAttachObjectARB (prog, vert); 233 endtest (); 234 glAttachObjectARB (prog, frag); 235 endtest (); 236 237 /* 238 * Detach attached object. 239 */ 240 begintest (TT_GETERROR_NOERROR, "Detach attached object"); 241 glDetachObjectARB (prog, vert); 242 endtest (); 243 glDetachObjectARB (prog, frag); 244 endtest (); 245 246 /* 247 * Attach shader again. 248 */ 249 begintest (TT_GETERROR_NOERROR, "Attach shader again"); 250 glAttachObjectARB (prog, vert); 251 endtest (); 252 glAttachObjectARB (prog, frag); 253 endtest (); 254 255 /* 256 * Delete attached object. 257 */ 258 begintest (TT_GETERROR_NOERROR, "Delete attached object"); 259 glDeleteObjectARB (vert); 260 endtest (); 261 glDeleteObjectARB (frag); 262 endtest (); 263 264 /* 265 * Query delete status. It should return TRUE. Object handles are still valid 266 * as they are referenced by program object container. 267 */ 268 begintest (TT_PARAM1_NONZERO, "Query delete status"); 269 glGetObjectParameterivARB (vert, GL_OBJECT_DELETE_STATUS_ARB, params); 270 endtest1 (params[0]); 271 glGetObjectParameterivARB (frag, GL_OBJECT_DELETE_STATUS_ARB, params); 272 endtest1 (params[0]); 273 274 /* 275 * Delete already deleted attached object. The behaviour is undefined, but we 276 * check for no errors. The object still exists, so the handle value is okay. 277 * In other words, these calls should be silently ignored by GL. 278 */ 279 begintest (TT_GETERROR_NOERROR, "Delete already deleted attached object"); 280 glDeleteObjectARB (vert); 281 endtest (); 282 glDeleteObjectARB (frag); 283 endtest (); 284 285 /* 286 * Compile shader source with syntax error. 287 */ 288 begintest (TT_PARAM1_ZERO, "Compile shader source with syntax error"); 289 glShaderSourceARB (vert, 1, &invsynvertsrc, NULL); 290 glCompileShaderARB (vert); 291 endtest1 (CheckObjectStatus (vert)); 292 glShaderSourceARB (frag, 1, &invsynfragsrc, NULL); 293 glCompileShaderARB (frag); 294 endtest1 (CheckObjectStatus (frag)); 295 296 /* 297 * Compile shader source with semantic error. 298 */ 299 begintest (TT_PARAM1_ZERO, "Compile shader source with semantic error"); 300 glShaderSourceARB (vert, 1, &invsemvertsrc, NULL); 301 glCompileShaderARB (vert); 302 endtest1 (CheckObjectStatus (vert)); 303 glShaderSourceARB (frag, 1, &invsemfragsrc, NULL); 304 glCompileShaderARB (frag); 305 endtest1 (CheckObjectStatus (frag)); 306 307 /* 308 * Link ill-formed vertex-fragment program. 309 */ 310 begintest (TT_PARAM1_ZERO, "Link ill-formed vertex-fragment program"); 311 glLinkProgramARB (prog); 312 endtest1 (CheckObjectStatus (prog)); 313 314 /* 315 * Use badly linked program object. 316 */ 317 begintest (TT_GETERROR_INVALIDOPERATION, "Use badly linked program object"); 318 glUseProgramObjectARB (prog); 319 endtest (); 320 321 /* 322 * Compile well-formed shader source. Check if multi-string sources can be handled. 323 */ 324 begintest (TT_PARAM1_NONZERO, "Compile well-formed shader source"); 325 tab[0] = uniforms; 326 tab[1] = validvertsrc; 327 glShaderSourceARB (vert, 2, tab, NULL); 328 glCompileShaderARB (vert); 329 endtest1 (CheckObjectStatus (vert)); 330 tab[0] = uniforms; 331 tab[1] = validfragsrc; 332 glShaderSourceARB (frag, 2, tab, NULL); 333 glCompileShaderARB (frag); 334 endtest1 (CheckObjectStatus (frag)); 335 336 /* 337 * Link vertex-fragment program. 338 */ 339 begintest (TT_PARAM1_NONZERO, "Link vertex-fragment program"); 340 glLinkProgramARB (prog); 341 endtest1 (CheckObjectStatus (prog)); 342 343 /* 344 * Use valid linked program object. 345 */ 346 begintest (TT_GETERROR_NOERROR, "Use linked program object"); 347 glUseProgramObjectARB (prog); 348 endtest (); 349 350 /* 351 * Get current program. 352 */ 353 begintest (TT_PARAM1_NONZERO, "Get current program"); 354 endtest1 (glGetHandleARB (GL_PROGRAM_OBJECT_ARB) == prog); 355 356 /* 357 * Use 0 program object. 358 */ 359 begintest (TT_GETERROR_NOERROR, "Use 0 program object"); 360 glUseProgramObjectARB (0); 361 endtest (); 362 363 /* 364 * Query uniform location. Uniforms with gl_ prefix cannot be queried. 365 */ 366 begintest (TT_PARAM1_NONZERO, "Query uniform location"); 367 endtest1 (glGetUniformLocationARB (prog, "gl_ModelViewMatrix") == -1); 368 endtest1 (glGetUniformLocationARB (prog, "UniformThatDoesNotExist") == -1); 369 endtest1 (glGetUniformLocationARB (prog, "") == -1); 370 endtest1 (glGetUniformLocationARB (prog, "CommonUniform") != -1); 371 endtest1 (glGetUniformLocationARB (prog, "VertexUniform") != -1); 372 endtest1 (glGetUniformLocationARB (prog, "FragmentUniform") != -1); 373 374 /* 375 * Query attrib location. Attribs with gl_ prefix cannot be queried. 376 * When gl_Vertex is used, none of the generic attribs can have index 0. 377 */ 378 begintest (TT_PARAM1_NONZERO, "Query attrib location"); 379 endtest1 (glGetAttribLocationARB (prog, "gl_Vertex") == -1); 380 endtest1 (glGetAttribLocationARB (prog, "AttribThatDoesNotExist") == -1); 381 endtest1 (glGetAttribLocationARB (prog, "") == -1); 382 endtest1 (glGetAttribLocationARB (prog, "FirstAttrib") > 0); 383 endtest1 (glGetAttribLocationARB (prog, "SecondAttrib") > 0); 384 385 /* 386 * Bind attrib locations, link and check if locations are correct. 387 */ 388 begintest (TT_PARAM1_NONZERO, "Bind attrib location #1"); 389 glBindAttribLocationARB (prog, 1, "FirstAttrib"); 390 glBindAttribLocationARB (prog, 2, "SecondAttrib"); 391 glLinkProgramARB (prog); 392 endtest1 (CheckObjectStatus (prog)); 393 endtest1 (glGetAttribLocationARB (prog, "FirstAttrib") == 1); 394 endtest1 (glGetAttribLocationARB (prog, "SecondAttrib") == 2); 395 396 /* 397 * Bind attrib locations in different order. Link and check if locations are correct. 398 */ 399 begintest (TT_PARAM1_NONZERO, "Bind attrib location #2"); 400 glBindAttribLocationARB (prog, 1, "SecondAttrib"); 401 glBindAttribLocationARB (prog, 2, "FirstAttrib"); 402 glLinkProgramARB (prog); 403 endtest1 (CheckObjectStatus (prog)); 404 endtest1 (glGetAttribLocationARB (prog, "SecondAttrib") == 1); 405 endtest1 (glGetAttribLocationARB (prog, "FirstAttrib") == 2); 406 407 /* 408 * Detach deleted object. 409 */ 410 begintest (TT_GETERROR_NOERROR, "Detach deleted object"); 411 glDetachObjectARB (prog, vert); 412 endtest (); 413 glDetachObjectARB (prog, frag); 414 endtest (); 415 416 /* 417 * Delete deleted detached object. 418 */ 419 begintest (TT_GETERROR_INVALIDVALUE, "Delete deleted detached object"); 420 glDeleteObjectARB (vert); 421 endtest (); 422 glDeleteObjectARB (frag); 423 endtest (); 424 425 exit (0); 426} 427 428void RenderScene (void) 429{ 430 /* never reached */ 431 assert (0); 432} 433 434int main (int argc, char *argv[]) 435{ 436 InitFramework (&argc, argv); 437 return 0; 438} 439 440