glx-multithread-buffer: Add a new test reproducing a radeonsi bug

Submitted by Marek Olšák on May 13, 2019, 11:21 p.m.

Details

Message ID 20190513232138.25561-1-maraeo@gmail.com
State New
Headers show
Series "glx-multithread-buffer: Add a new test reproducing a radeonsi bug" ( rev: 1 ) in Piglit

Not browsing as part of any series.

Commit Message

Marek Olšák May 13, 2019, 11:21 p.m.
From: Marek Olšák <marek.olsak@amd.com>

---
 tests/glx/CMakeLists.gl.txt        |   1 +
 tests/glx/glx-multithread-buffer.c | 199 +++++++++++++++++++++++++++++
 tests/opengl.py                    |   1 +
 3 files changed, 201 insertions(+)
 create mode 100644 tests/glx/glx-multithread-buffer.c

Patch hide | download patch | download mbox

diff --git a/tests/glx/CMakeLists.gl.txt b/tests/glx/CMakeLists.gl.txt
index bd3780b8d..cc35f0289 100644
--- a/tests/glx/CMakeLists.gl.txt
+++ b/tests/glx/CMakeLists.gl.txt
@@ -31,20 +31,21 @@  IF(PIGLIT_BUILD_GLX_TESTS)
 	piglit_add_executable (glx-destroycontext-2 glx-destroycontext-2.c)
 	piglit_add_executable (glx-dont-care-mask glx-dont-care-mask.c)
 	piglit_add_executable (glx-multi-context-front glx-multi-context-front.c)
 	piglit_add_executable (glx-multi-context-ib-1 glx-multi-context-ib-1.c)
 	piglit_add_executable (glx-multi-context-single-window glx-multi-context-single-window.c)
 	piglit_add_executable (glx-multi-window-single-context glx-multi-window-single-context.c)
 	piglit_add_executable (glx-multithread glx-multithread.c)
 	target_link_libraries(glx-multithread pthread)
 	piglit_add_executable (glx-context-flush-control glx-context-flush-control.c)
 	target_link_libraries (glx-context-flush-control pthread)
+	piglit_add_executable (glx-multithread-buffer glx-multithread-buffer.c)
 	piglit_add_executable (glx-multithread-clearbuffer glx-multithread-clearbuffer.c)
 	target_link_libraries(glx-multithread-clearbuffer pthread)
 	piglit_add_executable (glx-multithread-texture glx-multithread-texture.c)
 	target_link_libraries(glx-multithread-texture pthread)
 	piglit_add_executable (glx-multithread-makecurrent-1 glx-multithread-makecurrent-1.c)
 	target_link_libraries(glx-multithread-makecurrent-1 pthread)
 	piglit_add_executable (glx-multithread-makecurrent-2 glx-multithread-makecurrent-2.c)
 	target_link_libraries(glx-multithread-makecurrent-2 pthread)
 	piglit_add_executable (glx-multithread-makecurrent-3 glx-multithread-makecurrent-3.c)
 	target_link_libraries(glx-multithread-makecurrent-3 pthread)
diff --git a/tests/glx/glx-multithread-buffer.c b/tests/glx/glx-multithread-buffer.c
new file mode 100644
index 000000000..1047165e8
--- /dev/null
+++ b/tests/glx/glx-multithread-buffer.c
@@ -0,0 +1,199 @@ 
+/*
+ * Copyright (c) 2019 Baldur Karlsson <baldurk@baldurk.org>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/** @file glx-multithread-buffer.c
+ *
+ * Create a buffer shared between two contexts, invalidate it on one while it is
+ * bound on another to exhibit broken descriptor handling.
+ */
+
+#include <unistd.h>
+
+#include "piglit-util-gl.h"
+#include "piglit-glx-util.h"
+
+int piglit_width = 50, piglit_height = 50;
+
+static Display *dpy;
+static Window draw_win;
+static GLXPixmap load_win;
+static XVisualInfo *visinfo;
+
+static const char *vs_text =
+  "#version 140\n"
+  "in vec4 vertex;\n"
+  "void main() {\n"
+  "const vec2 verts[4] = vec2[4](vec2(-0.7, -0.7), vec2( 0.7, -0.7),\n"
+  "                              vec2(-0.7,  0.7), vec2( 0.7,  0.7));"
+  "gl_Position = vec4(verts[gl_VertexID].xy, 0.0, 1.0);}\n"
+  ;
+
+static const char *fs_text =
+  "#version 140\n"
+  "out vec4 v;\n"
+  "uniform buffoo0 { vec4 a; };\n"
+  "void main() {\n"
+  "    v = vec4(1.0, 0.0, 0.0, 1.0)+a;\n"
+  "}\n"
+  ;
+
+static const float green[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
+
+enum piglit_result
+draw(Display *dpy)
+{
+  int ret, i;
+  GLuint prog, vs, fs, buf;
+  GLXContext ctx1, ctx2;
+  void *ptr;
+  unsigned char pixel[4];
+
+  ctx1 = piglit_get_glx_context_share(dpy, visinfo, NULL);
+  ctx2 = piglit_get_glx_context_share(dpy, visinfo, ctx1);
+
+  ret = glXMakeCurrent(dpy, draw_win, ctx1);
+  assert(ret);
+
+  piglit_dispatch_default_init(PIGLIT_DISPATCH_GL);
+
+  glGenBuffers(1, &buf);
+  glBindBuffer(GL_UNIFORM_BUFFER, buf);
+  glBufferData(GL_UNIFORM_BUFFER, 2048, NULL, GL_DYNAMIC_DRAW);
+
+  prog = glCreateProgram();
+  vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);
+  fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);
+  if (!piglit_check_gl_error(GL_NO_ERROR))
+    piglit_report_result(PIGLIT_FAIL);
+
+  glAttachShader(prog, vs);
+  glAttachShader(prog, fs);
+  glLinkProgram(prog);
+  if (!piglit_check_gl_error(GL_NO_ERROR))
+    piglit_report_result(PIGLIT_FAIL);
+
+  if (!piglit_link_check_status(prog)) {
+    piglit_report_result(PIGLIT_FAIL);
+  }
+
+  glClearColor(0, 0, 1, 1);
+  glUseProgram(prog);
+  glBindBufferBase(GL_UNIFORM_BUFFER, 0, buf);
+  
+  ret = glXMakeCurrent(dpy, draw_win, ctx2);
+  assert(ret);
+  glClearColor(0, 0, 1, 1);
+  glUseProgram(prog);
+  glBindBufferBase(GL_UNIFORM_BUFFER, 0, buf);
+
+  for (i = 0; i < 10; ++i) {
+    ret = glXMakeCurrent(dpy, draw_win, ctx1);
+    assert(ret);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    glUseProgram(prog);
+
+    ptr = glMapBufferRange(GL_UNIFORM_BUFFER, 0, 128,
+                           GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+    memset(ptr, 0, 128);
+    memcpy(ptr, green, sizeof(green));
+    glUnmapBuffer(GL_UNIFORM_BUFFER);
+
+    piglit_draw_rect(0, 0, 1, 1);
+
+    memset(pixel, 0, sizeof(pixel));
+    glReadPixels(piglit_width/2, piglit_height/2, 1, 1,
+                 GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+    if (pixel[0] != 255 || pixel[1] != 255 || pixel[2] != 0) {
+      printf("Incorrect pixel at iteration %d: %u,%u,%u\n",
+             i, pixel[0], pixel[1], pixel[2]);
+      piglit_report_result(PIGLIT_FAIL);
+    }
+
+    glXSwapBuffers(dpy, draw_win);
+
+    ret = glXMakeCurrent(dpy, draw_win, ctx2);
+    assert(ret);
+
+    glClear(GL_COLOR_BUFFER_BIT);
+
+    ptr = glMapBufferRange(GL_UNIFORM_BUFFER, 0, 128,
+                           GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT);
+    memset(ptr, 0, 128);
+    memcpy(ptr, green, sizeof(green));
+    glUnmapBuffer(GL_UNIFORM_BUFFER);
+
+    piglit_draw_rect(0, 0, 1, 1);
+
+    memset(pixel, 0, sizeof(pixel));
+    glReadPixels(piglit_width/2, piglit_height/2, 1, 1,
+                 GL_RGBA, GL_UNSIGNED_BYTE, pixel);
+    if (pixel[0] != 255 || pixel[1] != 255 || pixel[2] != 0) {
+      printf("Incorrect pixel at iteration %d: %u,%u,%u\n",
+             i, pixel[0], pixel[1], pixel[2]);
+      piglit_report_result(PIGLIT_FAIL);
+    }
+
+    glXSwapBuffers(dpy, draw_win);
+  }
+  
+  glDeleteBuffers(1, &buf);
+
+  glXDestroyContext(dpy, ctx1);
+  glXDestroyContext(dpy, ctx2);
+
+  return PIGLIT_PASS;
+}
+
+int
+main(int argc, char **argv)
+{
+  int i;
+  Pixmap pixmap;
+
+  for(i = 1; i < argc; ++i) {
+    if (!strcmp(argv[i], "-auto"))
+      piglit_automatic = 1;
+    else
+      fprintf(stderr, "Unknown option: %s\n", argv[i]);
+  }
+
+  XInitThreads();
+  dpy = XOpenDisplay(NULL);
+  if (dpy == NULL) {
+    fprintf(stderr, "couldn't open display\n");
+    piglit_report_result(PIGLIT_FAIL);
+  }
+  visinfo = piglit_get_glx_visual(dpy);
+  draw_win = piglit_get_glx_window(dpy, visinfo);
+  pixmap = XCreatePixmap(dpy, DefaultRootWindow(dpy),
+    piglit_width, piglit_height, visinfo->depth);
+  load_win = glXCreateGLXPixmap(dpy, visinfo, pixmap);
+
+  XMapWindow(dpy, draw_win);
+
+  piglit_glx_event_loop(dpy, draw);
+
+  return 0;
+}
diff --git a/tests/opengl.py b/tests/opengl.py
index 339686e13..29d7110b3 100644
--- a/tests/opengl.py
+++ b/tests/opengl.py
@@ -377,20 +377,21 @@  with profile.test_list.group_manager(
     g(['glx-close-display'], run_concurrent=False)
     g(['glx-fbconfig-sanity'], run_concurrent=False)
     g(['glx-fbconfig-compliance'], run_concurrent=False)
     g(['glx-fbconfig-bad'], run_concurrent=False)
     g(['glx-fbo-binding'], run_concurrent=False)
     g(['glx-multi-context-front'], run_concurrent=False)
     g(['glx-multi-context-ib-1'], run_concurrent=False)
     g(['glx-multi-context-single-window'], run_concurrent=False)
     g(['glx-multi-window-single-context'], run_concurrent=False)
     g(['glx-multithread'], run_concurrent=False)
+    g(['glx-multithread-buffer'], run_concurrent=False)
     g(['glx-multithread-clearbuffer'], run_concurrent=False)
     g(['glx-multithread-texture'], run_concurrent=False)
     g(['glx-multithread-makecurrent-1'], run_concurrent=False)
     g(['glx-multithread-makecurrent-2'], run_concurrent=False)
     g(['glx-multithread-makecurrent-3'], run_concurrent=False)
     g(['glx-multithread-makecurrent-4'], run_concurrent=False)
     g(['glx-multithread-shader-compile'], run_concurrent=False)
     g(['glx-shader-sharing'], run_concurrent=False)
     g(['glx-swap-exchange'], run_concurrent=False)
     g(['glx-swap-event', '--event'], 'glx-swap-event_event',