2 * Copyright (c) 2012 Mathias Fröhlich
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
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
25 * @file glx-multithread-shader-compile.c
26 * @author Mathias Fröhlich
28 * Create two GLX contexts and concurrently compile shaders.
29 * Exercises a race condition with the r600 llvm compiler.
32 #include "piglit-util-gl.h"
33 #include "piglit-glx-util.h"
36 static const char *vert_shader_text
=
39 " gl_Position = ftransform(); \n"
40 " gl_FrontColor = gl_Color; \n"
43 static const char *frag_shader_text
=
46 " gl_FragColor = vec4(1.0) - gl_Color; \n"
49 static pthread_mutex_t mutex
;
52 thread_func(void *arg
)
59 dpy
= piglit_get_glx_display();
60 visinfo
= piglit_get_glx_visual(dpy
);
61 win
= piglit_get_glx_window(dpy
, visinfo
);
63 for (i
= 0; i
< 100; ++i
) {
65 GLuint vert_shader
, frag_shader
;
68 ctx
= piglit_get_glx_context(dpy
, visinfo
);
69 glXMakeCurrent(dpy
, win
, ctx
);
71 /* Ok, not nice but should be safe due to all threads working
72 * on the same type of context.
74 pthread_mutex_lock(&mutex
);
75 piglit_dispatch_default_init(PIGLIT_DISPATCH_GL
);
76 pthread_mutex_unlock(&mutex
);
78 vert_shader
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vert_shader_text
);
79 piglit_check_gl_error(GL_NO_ERROR
);
81 frag_shader
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, frag_shader_text
);
82 piglit_check_gl_error(GL_NO_ERROR
);
84 program
= piglit_link_simple_program(vert_shader
, frag_shader
);
85 piglit_check_gl_error(GL_NO_ERROR
);
87 glUseProgram(program
);
88 piglit_check_gl_error(GL_NO_ERROR
);
90 glXDestroyContext(dpy
, ctx
);
97 main(int argc
, char **argv
)
100 pthread_t thread1
, thread2
;
102 for (int i
= 1; i
< argc
; i
++) {
103 if (!strcmp(argv
[i
], "-auto"))
104 piglit_automatic
= 1;
106 fprintf(stderr
, "Unknown option: %s\n", argv
[i
]);
111 pthread_mutex_init(&mutex
, NULL
);
113 /* Now, spawn some threads that compile simple shaders.
115 pthread_create(&thread1
, NULL
, thread_func
, NULL
);
116 pthread_create(&thread2
, NULL
, thread_func
, NULL
);
118 ret
= pthread_join(thread1
, NULL
);
120 ret
= pthread_join(thread2
, NULL
);
123 pthread_mutex_destroy(&mutex
);
125 piglit_report_result(PIGLIT_PASS
);