2 * Copyright (c) 2019 Baldur Karlsson <baldurk@baldurk.org>
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
24 /** @file glx-multithread-buffer.c
26 * Create a buffer shared between two contexts, invalidate it on one while it is
27 * bound on another to exhibit broken descriptor handling.
32 #include "piglit-util-gl.h"
33 #include "piglit-glx-util.h"
35 int piglit_width
= 50, piglit_height
= 50;
38 static Window draw_win
;
39 static GLXPixmap load_win
;
40 static XVisualInfo
*visinfo
;
42 static const char *vs_text
=
46 "const vec2 verts[4] = vec2[4](vec2(-0.7, -0.7), vec2( 0.7, -0.7),\n"
47 " vec2(-0.7, 0.7), vec2( 0.7, 0.7));"
48 "gl_Position = vec4(verts[gl_VertexID].xy, 0.0, 1.0);}\n"
51 static const char *fs_text
=
54 "uniform buffoo0 { vec4 a; };\n"
56 " v = vec4(1.0, 0.0, 0.0, 1.0)+a;\n"
60 static const float green
[4] = { 0.0f
, 1.0f
, 0.0f
, 1.0f
};
66 GLuint prog
, vs
, fs
, buf
;
67 GLXContext ctx1
, ctx2
;
69 unsigned char pixel
[4];
71 ctx1
= piglit_get_glx_context_share(dpy
, visinfo
, NULL
);
72 ctx2
= piglit_get_glx_context_share(dpy
, visinfo
, ctx1
);
74 ret
= glXMakeCurrent(dpy
, draw_win
, ctx1
);
77 piglit_dispatch_default_init(PIGLIT_DISPATCH_GL
);
79 piglit_require_GLSL_version(140);
81 glGenBuffers(1, &buf
);
82 glBindBuffer(GL_UNIFORM_BUFFER
, buf
);
83 glBufferData(GL_UNIFORM_BUFFER
, 2048, NULL
, GL_DYNAMIC_DRAW
);
85 prog
= glCreateProgram();
86 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vs_text
);
87 fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, fs_text
);
88 if (!piglit_check_gl_error(GL_NO_ERROR
))
89 piglit_report_result(PIGLIT_FAIL
);
91 glAttachShader(prog
, vs
);
92 glAttachShader(prog
, fs
);
94 if (!piglit_check_gl_error(GL_NO_ERROR
))
95 piglit_report_result(PIGLIT_FAIL
);
97 if (!piglit_link_check_status(prog
)) {
98 piglit_report_result(PIGLIT_FAIL
);
101 glClearColor(0, 0, 1, 1);
103 glBindBufferBase(GL_UNIFORM_BUFFER
, 0, buf
);
105 ret
= glXMakeCurrent(dpy
, draw_win
, ctx2
);
107 glClearColor(0, 0, 1, 1);
109 glBindBufferBase(GL_UNIFORM_BUFFER
, 0, buf
);
111 for (i
= 0; i
< 10; ++i
) {
112 ret
= glXMakeCurrent(dpy
, draw_win
, ctx1
);
115 glClear(GL_COLOR_BUFFER_BIT
);
119 ptr
= glMapBufferRange(GL_UNIFORM_BUFFER
, 0, 128,
120 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_BUFFER_BIT
);
122 memcpy(ptr
, green
, sizeof(green
));
123 glUnmapBuffer(GL_UNIFORM_BUFFER
);
125 piglit_draw_rect(0, 0, 1, 1);
127 memset(pixel
, 0, sizeof(pixel
));
128 glReadPixels(piglit_width
/2, piglit_height
/2, 1, 1,
129 GL_RGBA
, GL_UNSIGNED_BYTE
, pixel
);
130 if (pixel
[0] != 255 || pixel
[1] != 255 || pixel
[2] != 0) {
131 printf("Incorrect pixel at iteration %d: %u,%u,%u\n",
132 i
, pixel
[0], pixel
[1], pixel
[2]);
133 piglit_report_result(PIGLIT_FAIL
);
136 glXSwapBuffers(dpy
, draw_win
);
138 ret
= glXMakeCurrent(dpy
, draw_win
, ctx2
);
141 glClear(GL_COLOR_BUFFER_BIT
);
143 ptr
= glMapBufferRange(GL_UNIFORM_BUFFER
, 0, 128,
144 GL_MAP_WRITE_BIT
| GL_MAP_INVALIDATE_BUFFER_BIT
);
146 memcpy(ptr
, green
, sizeof(green
));
147 glUnmapBuffer(GL_UNIFORM_BUFFER
);
149 piglit_draw_rect(0, 0, 1, 1);
151 memset(pixel
, 0, sizeof(pixel
));
152 glReadPixels(piglit_width
/2, piglit_height
/2, 1, 1,
153 GL_RGBA
, GL_UNSIGNED_BYTE
, pixel
);
154 if (pixel
[0] != 255 || pixel
[1] != 255 || pixel
[2] != 0) {
155 printf("Incorrect pixel at iteration %d: %u,%u,%u\n",
156 i
, pixel
[0], pixel
[1], pixel
[2]);
157 piglit_report_result(PIGLIT_FAIL
);
160 glXSwapBuffers(dpy
, draw_win
);
163 glDeleteBuffers(1, &buf
);
165 glXDestroyContext(dpy
, ctx1
);
166 glXDestroyContext(dpy
, ctx2
);
172 main(int argc
, char **argv
)
177 for(i
= 1; i
< argc
; ++i
) {
178 if (!strcmp(argv
[i
], "-auto"))
179 piglit_automatic
= 1;
181 fprintf(stderr
, "Unknown option: %s\n", argv
[i
]);
185 dpy
= XOpenDisplay(NULL
);
187 fprintf(stderr
, "couldn't open display\n");
188 piglit_report_result(PIGLIT_FAIL
);
190 visinfo
= piglit_get_glx_visual(dpy
);
191 draw_win
= piglit_get_glx_window(dpy
, visinfo
);
192 pixmap
= XCreatePixmap(dpy
, DefaultRootWindow(dpy
),
193 piglit_width
, piglit_height
, visinfo
->depth
);
194 load_win
= glXCreateGLXPixmap(dpy
, visinfo
, pixmap
);
196 piglit_glx_event_loop(dpy
, draw
);