aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/spec/ext_external_objects/CMakeLists.gl.txt2
-rw-r--r--tests/spec/ext_external_objects/vk_semaphores.c370
2 files changed, 372 insertions, 0 deletions
diff --git a/tests/spec/ext_external_objects/CMakeLists.gl.txt b/tests/spec/ext_external_objects/CMakeLists.gl.txt
index 93bce72af..f944af88f 100644
--- a/tests/spec/ext_external_objects/CMakeLists.gl.txt
+++ b/tests/spec/ext_external_objects/CMakeLists.gl.txt
@@ -148,6 +148,8 @@ IF(LIBVULKAN_FOUND)
vk.c interop.c helpers.c vk_vert_buf_reuse.c ${VK_BLUE_VERT_PATH} ${VK_BLUE_FRAG_PATH})
piglit_add_executable (ext_external_objects-vk-depth-display
vk.c interop.c helpers.c vk_depth_display.c ${VK_ZQUAD_VERT_PATH} ${VK_ZQUAD_FRAG_PATH})
+ piglit_add_executable (ext_external_objects-vk-semaphores
+ vk.c interop.c helpers.c vk_semaphores.c ${VK_BANDS_VERT_PATH} ${VK_BANDS_FRAG_PATH})
ENDIF()
# vim: ft=cmake:
diff --git a/tests/spec/ext_external_objects/vk_semaphores.c b/tests/spec/ext_external_objects/vk_semaphores.c
new file mode 100644
index 000000000..d449e718e
--- /dev/null
+++ b/tests/spec/ext_external_objects/vk_semaphores.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright © 2021 Igalia S.L.
+ *
+ * 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.
+ *
+ * Author:
+ * Eleni Maria Stea <estea@igalia.com>
+ */
+
+#include <piglit-util-gl.h>
+#include "interop.h"
+#include "params.h"
+#include "helpers.h"
+PIGLIT_GL_TEST_CONFIG_BEGIN
+
+config.supports_gl_compat_version = 30;
+config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE;
+config.khr_no_error_support = PIGLIT_HAS_ERRORS;
+
+PIGLIT_GL_TEST_CONFIG_END
+
+static const char vs[] =
+ "#version 130\n"
+ "in vec4 piglit_vertex;\n"
+ "in vec2 piglit_texcoord;\n"
+ "out vec2 tex_coords;\n"
+ "void main()\n"
+ "{\n"
+ " gl_Position = piglit_vertex;\n"
+ " tex_coords = piglit_texcoord;\n"
+ "}\n";
+
+static const char fs[] =
+ "#version 130\n"
+ "in vec2 tex_coords;\n"
+ "uniform sampler2D tex; \n"
+ "out vec4 color;\n"
+ "void main() \n"
+ "{\n"
+ " color = texture(tex, tex_coords);\n"
+ "}\n";
+
+static bool
+vk_init(uint32_t w,
+ uint32_t h,
+ uint32_t d,
+ uint32_t num_samples,
+ uint32_t num_levels,
+ uint32_t num_layers,
+ VkFormat color_format,
+ VkFormat depth_format,
+ VkImageTiling color_tiling,
+ VkImageTiling depth_tiling,
+ VkImageLayout color_in_layout,
+ VkImageLayout depth_in_layout,
+ VkImageLayout color_end_layout,
+ VkImageLayout depth_end_layout);
+
+static void
+cleanup(void);
+
+static void
+vk_cleanup(void);
+
+static bool
+gl_init();
+
+static void
+gl_cleanup(void);
+
+static struct vk_ctx vk_core;
+static struct vk_image_att vk_color_att;
+static struct vk_image_att vk_depth_att;
+static struct vk_renderer vk_rnd;
+
+static GLenum gl_target = GL_TEXTURE_2D;
+static GLenum gl_tex_storage_format = GL_RGBA32F;
+static GLuint gl_tex;
+static GLint gl_prog;
+static GLuint gl_mem_obj;
+
+static struct gl_ext_semaphores gl_sem;
+static struct vk_semaphores vk_sem;
+static bool vk_sem_has_wait = true;
+static bool vk_sem_has_signal = true;
+
+static float vk_fb_color[4] = { 1.0, 0.0, 0.0, 1.0 };
+
+void piglit_init(int argc, char **argv)
+{
+ piglit_require_extension("GL_ARB_texture_storage");
+ piglit_require_extension("GL_EXT_memory_object");
+ piglit_require_extension("GL_EXT_memory_object_fd");
+ piglit_require_extension("GL_EXT_semaphore");
+ piglit_require_extension("GL_EXT_semaphore_fd");
+
+ atexit(cleanup);
+
+ w = piglit_width;
+ h = piglit_height;
+
+ if (!vk_init(w, h, d, num_samples, num_levels, num_layers,
+ color_format, depth_format,
+ color_tiling, depth_tiling,
+ color_in_layout, depth_in_layout,
+ color_end_layout, depth_end_layout)) {
+ fprintf(stderr, "Failed to initialize Vulkan, skipping the test.\n");
+ piglit_report_result(PIGLIT_SKIP);
+ }
+ /* create memory object and gl texture */
+ if (!gl_create_mem_obj_from_vk_mem(&vk_core, &vk_color_att.obj.mobj,
+ &gl_mem_obj)) {
+ fprintf(stderr, "Failed to create GL memory object from Vulkan memory.\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ if (!gl_gen_tex_from_mem_obj(&vk_color_att.props,
+ gl_tex_storage_format,
+ gl_mem_obj, 0, &gl_tex)) {
+ fprintf(stderr, "Failed to create texture from GL memory object.\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ if (!gl_create_semaphores_from_vk(&vk_core, &vk_sem, &gl_sem)) {
+ fprintf(stderr, "Failed to import semaphores from Vulkan.\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ if (!gl_init()) {
+ fprintf(stderr, "Failed to initialize structs for GL rendering.\n");
+ piglit_report_result(PIGLIT_FAIL);
+ }
+
+ /* one initial vk rendering to fill the texture */
+ GLuint layout = gl_get_layout_from_vk(color_in_layout);
+ if (vk_sem_has_wait) {
+ glSignalSemaphoreEXT(gl_sem.gl_frame_ready, 0, 0, 1,
+ &gl_tex, &layout);
+ glFlush();
+ }
+
+ struct vk_image_att images[] = { vk_color_att, vk_depth_att };
+ vk_draw(&vk_core, 0, &vk_rnd, vk_fb_color, 4, &vk_sem,
+ vk_sem_has_wait, vk_sem_has_signal, images, ARRAY_SIZE(images), 0, 0, w, h);
+
+ layout = gl_get_layout_from_vk(color_end_layout);
+ if (vk_sem_has_signal) {
+ glWaitSemaphoreEXT(gl_sem.vk_frame_done, 0, 0, 1,
+ &gl_tex, &layout);
+ glFlush();
+ }
+
+ /* no gl rendering before display */
+}
+
+enum piglit_result
+piglit_display(void)
+{
+ enum piglit_result res = PIGLIT_PASS;
+ int i;
+ float colors[6][4] = {
+ {1.0, 0.0, 0.0, 1.0},
+ {0.0, 1.0, 0.0, 1.0},
+ {0.0, 0.0, 1.0, 1.0},
+ {1.0, 1.0, 0.0, 1.0},
+ {1.0, 0.0, 1.0, 1.0},
+ {0.0, 1.0, 1.0, 1.0}
+ };
+ GLuint layout = gl_get_layout_from_vk(color_in_layout);
+
+ if (vk_sem_has_wait) {
+ glSignalSemaphoreEXT(gl_sem.gl_frame_ready, 0, 0, 1,
+ &gl_tex, &layout);
+ glFlush();
+ }
+
+ struct vk_image_att images[] = { vk_color_att, vk_depth_att };
+ vk_clear_color(&vk_core, 0, &vk_rnd, vk_fb_color, 4, &vk_sem,
+ vk_sem_has_wait, vk_sem_has_signal, images,
+ ARRAY_SIZE(images), 0, 0, w, h);
+ layout = gl_get_layout_from_vk(color_end_layout);
+ if (vk_sem_has_signal) {
+ glWaitSemaphoreEXT(gl_sem.vk_frame_done, 0, 0, 1,
+ &gl_tex, &layout);
+ glFlush();
+ }
+
+ /* OpenGL rendering */
+ glBindTexture(gl_target, gl_tex);
+ piglit_draw_rect_tex(-1, -1,
+ 2,
+ 2,
+ 0, 0, 1, 1);
+
+ for (i = 0; i < 6; i++) {
+ float x = i * (float)piglit_width / 6.0 + (float)piglit_width / 12.0;
+ float y = (float)piglit_height / 2.0;
+
+ if (!piglit_probe_pixel_rgba(x, y, colors[0]))
+ res = PIGLIT_FAIL;
+ }
+
+ piglit_present_results();
+ return res;
+}
+
+static bool
+vk_init(uint32_t w,
+ uint32_t h,
+ uint32_t d,
+ uint32_t num_samples,
+ uint32_t num_levels,
+ uint32_t num_layers,
+ VkFormat color_format,
+ VkFormat depth_format,
+ VkImageTiling color_tiling,
+ VkImageTiling depth_tiling,
+ VkImageLayout color_in_layout,
+ VkImageLayout depth_in_layout,
+ VkImageLayout color_end_layout,
+ VkImageLayout depth_end_layout)
+{
+ char *vs_src = 0;
+ char *fs_src = 0;
+ unsigned int vs_sz;
+ unsigned int fs_sz;
+
+ if (!vk_init_ctx_for_rendering(&vk_core)) {
+ fprintf(stderr, "Failed to create Vulkan context.\n");
+ return false;
+ }
+
+ if (!vk_check_gl_compatibility(&vk_core)) {
+ fprintf(stderr, "Mismatch in driver/device UUID\n");
+ return false;
+ }
+
+ /* creating external images */
+ /* color image */
+ if (!vk_fill_ext_image_props(&vk_core,
+ w, h, d,
+ num_samples,
+ num_levels,
+ num_layers,
+ color_format,
+ color_tiling,
+ color_in_layout,
+ color_end_layout,
+ true,
+ &vk_color_att.props)) {
+ fprintf(stderr, "Unsupported color image properties.\n");
+ return false;
+ }
+ if (!vk_create_ext_image(&vk_core, &vk_color_att.props, &vk_color_att.obj)) {
+ fprintf(stderr, "Failed to create color image.\n");
+ return false;
+ }
+
+ /* depth image */
+ if (!vk_fill_ext_image_props(&vk_core,
+ w, h, d,
+ num_samples,
+ num_levels,
+ num_layers,
+ depth_format,
+ depth_tiling,
+ depth_in_layout,
+ depth_end_layout,
+ false,
+ &vk_depth_att.props)) {
+ fprintf(stderr, "Unsupported depth image properties.\n");
+ return false;
+ }
+
+ if (!vk_create_ext_image(&vk_core, &vk_depth_att.props, &vk_depth_att.obj)) {
+ fprintf(stderr, "Failed to create depth image.\n");
+ goto fail;
+ }
+
+ /* load shaders */
+ if (!(vs_src = load_shader(VK_BANDS_VERT, &vs_sz)))
+ goto fail;
+
+ if (!(fs_src = load_shader(VK_BANDS_FRAG, &fs_sz)))
+ goto fail;
+
+ /* create Vulkan renderer */
+ if (!vk_create_renderer(&vk_core, vs_src, vs_sz, fs_src, fs_sz,
+ false, false,
+ &vk_color_att, &vk_depth_att, 0, &vk_rnd)) {
+ fprintf(stderr, "Failed to create Vulkan renderer.\n");
+ goto fail;
+ }
+
+ if (!vk_create_semaphores(&vk_core, &vk_sem)) {
+ fprintf(stderr, "Failed to create semaphores.\n");
+ goto fail;
+ }
+
+ free(vs_src);
+ free(fs_src);
+
+ return true;
+
+fail:
+ free(vs_src);
+ free(fs_src);
+
+ return false;
+}
+
+static void
+vk_cleanup(void)
+{
+ vk_destroy_ext_image(&vk_core, &vk_color_att.obj);
+ vk_destroy_ext_image(&vk_core, &vk_depth_att.obj);
+
+ vk_destroy_renderer(&vk_core, &vk_rnd);
+ vk_destroy_semaphores(&vk_core, &vk_sem);
+
+ vk_cleanup_ctx(&vk_core);
+}
+
+static void
+cleanup(void)
+{
+ gl_cleanup();
+ vk_cleanup();
+}
+
+static bool
+gl_init()
+{
+ gl_prog = piglit_build_simple_program(vs, fs);
+ glUseProgram(gl_prog);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ return glGetError() == GL_NO_ERROR;
+}
+
+static void
+gl_cleanup(void)
+{
+ glBindTexture(gl_target, 0);
+
+ glDeleteTextures(1, &gl_tex);
+ glDeleteProgram(gl_prog);
+
+ glDeleteSemaphoresEXT(1, &gl_sem.gl_frame_ready);
+ glDeleteSemaphoresEXT(1, &gl_sem.vk_frame_done);
+
+ glDeleteMemoryObjectsEXT(1, &gl_mem_obj);
+}