Example: ./bin/ext_memory_object-vk_export_image_as_tex 0 0 GL_TEXTURE_2D GL_RGBA 1 64 64 1 0 1 0 1 -auto -fbo
Usage in turn gives: Usage: ./bin/ext_memory_object-vk_export_image_as_tex <src_format> <src_tiling> <target> <format> <num_samples> <w> <h> <z> <first_level> <num_levels> <first_layer> <num_layers> TODO: First two arguments do not have parser support yet and are ignored. For now test uses hardcoded values of VK_FORMAT_R8G8B8A8_UNORM and VK_IMAGE_TILING_LINEAR respectively, Signed-off-by: Topi Pohjolainen <topi.pohjolai...@intel.com> --- tests/spec/ext_memory_object/CMakeLists.gl.txt | 18 ++ .../ext_memory_object/vk_export_image_as_tex.c | 262 +++++++++++++++++++++ tests/spec/ext_memory_object/vk_fragcoord.fs | 7 + tests/spec/ext_memory_object/vk_fragcoord.vs | 8 + 4 files changed, 295 insertions(+) create mode 100644 tests/spec/ext_memory_object/vk_export_image_as_tex.c create mode 100644 tests/spec/ext_memory_object/vk_fragcoord.fs create mode 100644 tests/spec/ext_memory_object/vk_fragcoord.vs diff --git a/tests/spec/ext_memory_object/CMakeLists.gl.txt b/tests/spec/ext_memory_object/CMakeLists.gl.txt index 3a714e6af..601618685 100644 --- a/tests/spec/ext_memory_object/CMakeLists.gl.txt +++ b/tests/spec/ext_memory_object/CMakeLists.gl.txt @@ -1,3 +1,16 @@ + +add_custom_command ( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord_vs.h + COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/compile_and_dump_glsl_as_spirv.py --with-glslc=${GLSLC} --stage=vertex ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord.vs > ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord_vs.h + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord.vs +) + +add_custom_command ( + OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord_fs.h + COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/compile_and_dump_glsl_as_spirv.py --with-glslc=${GLSLC} --stage=fragment ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord.fs > ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord_fs.h + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord.fs +) + include_directories( ${GLEXT_INCLUDE_DIR} ${OPENGL_INCLUDE_PATH} @@ -6,9 +19,14 @@ include_directories( link_libraries ( piglitutil_${piglit_target_api} ${OPENGL_gl_LIBRARY} + ${LIBVULKAN_LDFLAGS} ) piglit_add_executable (ext_memory_object-api-errors api-errors.c) +piglit_add_executable (ext_memory_object-vk_export_image_as_tex + vk_export_image_as_tex.c common.c vk_fb.c vk_common.c + ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord_fs.h + ${CMAKE_CURRENT_SOURCE_DIR}/vk_fragcoord_vs.h) # vim: ft=cmake: diff --git a/tests/spec/ext_memory_object/vk_export_image_as_tex.c b/tests/spec/ext_memory_object/vk_export_image_as_tex.c new file mode 100644 index 000000000..448fea890 --- /dev/null +++ b/tests/spec/ext_memory_object/vk_export_image_as_tex.c @@ -0,0 +1,262 @@ +/* + * Copyright 2017 Intel Corporation + * + * 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. + */ + +/** + * Test GL sampling memory exported from Vulkan. + * + * Test draws with Vulkan an image with gradient color where intensity of red + * increases horizontally and intensity of green increases vertically. This + * image is exported to GL which creates a texture against it and samples it + * with a custom fragment shader. The shader compares the sampled values + * against the expected gradient and writes green in case of match and + * otherwise red. Finally the test probes for the green. + */ + +#include "piglit-util-gl.h" +#include "vk_common.h" +#include "common.h" +#include "vk_fragcoord_vs.h" +#include "vk_fragcoord_fs.h" + +PIGLIT_GL_TEST_CONFIG_BEGIN + + config.supports_gl_compat_version = 20; + config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DOUBLE; + config.khr_no_error_support = PIGLIT_HAS_ERRORS; + +PIGLIT_GL_TEST_CONFIG_END + +struct tex_layout test_tex_layout; + +static VkDevice vk_dev = VK_NULL_HANDLE; +static VkRenderPass vk_render_pass = VK_NULL_HANDLE; +static VkPipeline vk_pipeline = VK_NULL_HANDLE; +static VkShaderModule vk_vs = VK_NULL_HANDLE; +static VkShaderModule vk_fs = VK_NULL_HANDLE; + +static struct vk_fb vk_fb = { + { { VK_NULL_HANDLE, VK_NULL_HANDLE }, VK_NULL_HANDLE }, + { { VK_NULL_HANDLE, VK_NULL_HANDLE }, VK_NULL_HANDLE }, + VK_NULL_HANDLE, + VK_NULL_HANDLE }; + +static const char gl_vs_src[] = + "#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 gl_fs_src[] = + "#version 130\n" + "in vec2 tex_coords;\n" + "out vec4 color;\n" + "uniform sampler2D tex; \n" + "void main() \n" + "{\n" + " vec4 expected;\n" + " expected.xy = tex_coords;\n" + " expected.zw = vec2(0.3, 1.0);\n" + " if (distance(texture2D(tex, tex_coords), expected) < (1.0/255))\n" + " color = vec4(0.0, 1.0, 0.0, 1.0);\n" + " else {\n" + " color = vec4(1.0, 0.0, 0.0, 1.0);\n" + " }\n" + "}\n"; + +static void +pipeline_cleanup(void) +{ + if (vk_pipeline != VK_NULL_HANDLE) + vkDestroyPipeline(vk_dev, vk_pipeline, NULL); + + if (vk_vs != VK_NULL_HANDLE) + vkDestroyShaderModule(vk_dev, vk_vs, NULL); + + if (vk_fs != VK_NULL_HANDLE) + vkDestroyShaderModule(vk_dev, vk_fs, NULL); + + if (vk_render_pass != VK_NULL_HANDLE) + vkDestroyRenderPass(vk_dev, vk_render_pass, NULL); + + vk_fb_destroy(vk_dev, &vk_fb); + + vk_cleanup(); +} + +void +piglit_init(int argc, char **argv) +{ + int prog; + + /* From the EXT_external_objects spec: + * + * "GL_EXT_memory_object requires ARB_texture_storage or a + * version of OpenGL or OpenGL ES that incorporates it." + */ + piglit_require_extension("GL_ARB_texture_storage"); + piglit_require_extension("GL_EXT_memory_object"); + piglit_require_extension("GL_EXT_memory_object_fd"); + + assert(argc > 0); + parse_tex_layout((const char **)argv + 1, argc - 1, + argv[0], &test_tex_layout); + + assert(test_tex_layout.num_samples == 1); + + prog = piglit_build_simple_program(gl_vs_src, gl_fs_src); + glUseProgram(prog); + + vk_dev = vk_init(); + + /* Make sure Vulkan can export memory. */ + if (vk_get_proc_addr_for_mem_fd(vk_dev) == NULL) { + vk_cleanup(); + piglit_report_result(PIGLIT_SKIP); + } + + vk_render_pass = vk_create_render_pass( + test_tex_layout.src_format, test_tex_layout.num_samples, + test_tex_layout.src_tiling == VK_IMAGE_TILING_OPTIMAL ? + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : + VK_IMAGE_LAYOUT_GENERAL, + test_tex_layout.src_tiling == VK_IMAGE_TILING_OPTIMAL ? + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : + VK_IMAGE_LAYOUT_GENERAL); + if (vk_render_pass == VK_NULL_HANDLE) + goto fail; + + vk_vs = vk_add_shader(vk_fragcoord_vs_spir_v_src, + sizeof(vk_fragcoord_vs_spir_v_src)); + if (vk_vs == VK_NULL_HANDLE) + goto fail; + + vk_fs = vk_add_shader(vk_fragcoord_fs_spir_v_src, + sizeof(vk_fragcoord_fs_spir_v_src)); + if (vk_fs == VK_NULL_HANDLE) + goto fail; + + vk_pipeline = vk_create_pipeline( + test_tex_layout.w, test_tex_layout.h, 1, + VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, + 8, VK_FORMAT_R32G32_SFLOAT, + vk_render_pass, vk_fs, vk_vs); + if (vk_pipeline == VK_NULL_HANDLE) + goto fail; + + vk_setup_fb(vk_dev, + test_tex_layout.w, test_tex_layout.h, + test_tex_layout.num_samples, + test_tex_layout.src_format, test_tex_layout.src_tiling, + VK_FORMAT_UNDEFINED, VK_IMAGE_TILING_LINEAR, + test_tex_layout.num_layers, &vk_fb); + if (vk_fb.fb != VK_NULL_HANDLE) + return; + +fail: + pipeline_cleanup(); + piglit_report_result(PIGLIT_FAIL); +} + +static bool +render_and_wait(void) +{ + const uint64_t timeout = UINT64_MAX; + const float vertices[] = { + 0.0, 1.0, + 1.0, 1.0, + 0.0, 0.0, + 1.0, 0.0 + }; + struct vk_vertex_buffer vb = { VK_NULL_HANDLE, VK_NULL_HANDLE }; + VkFence fence = vk_create_fence(vk_dev); + bool status = false; + + if (fence == VK_NULL_HANDLE) + goto cleanup; + + vk_setup_vertex_buffer(vertices, sizeof(vertices), &vb); + if (vb.buf == VK_NULL_HANDLE) + goto cleanup; + + vk_begin_render_pass(vk_render_pass, vk_fb.fb, + test_tex_layout.w, test_tex_layout.h); + + if (!vk_draw(vk_pipeline, vb.buf, fence)) + goto cleanup; + + status = vkWaitForFences(vk_dev, 1, &fence, true, timeout) == + VK_SUCCESS; + +cleanup: + if (vb.buf != VK_NULL_HANDLE) { + vkFreeMemory(vk_dev, vb.mem, NULL); + vkDestroyBuffer(vk_dev, vb.buf, NULL); + } + + if (fence != VK_NULL_HANDLE) + vkDestroyFence(vk_dev, fence, NULL); + + return status; +} + +enum piglit_result +piglit_display(void) +{ + const float green[] = { 0.0, 1.0, 0.0, 1.0 }; + const unsigned offset = 0; + GLuint tex, mem_obj; + bool result = false; + + if (!render_and_wait()) + goto cleanup; + + if (!create_mem_obj_for_vk_dev_mem( + vk_dev, vk_fb.color.image.mem, vk_fb.color.image.size, + &mem_obj)) + goto cleanup; + + create_tex_from_vk_dev_mem(&test_tex_layout, mem_obj, offset, &tex); + + /* Sample the memory imported from Vulkan comparing to expected + * values. In case of match, draw green, otherwise red. + */ + piglit_draw_rect_tex( + -1, -1, + 2.0 * test_tex_layout.w / piglit_width, + 2.0 * test_tex_layout.h / piglit_height, + 0, 0, 1, 1); + + result = piglit_probe_rect_rgba(0, 0, + test_tex_layout.w, test_tex_layout.h, + green); + +cleanup: + pipeline_cleanup(); + + return result ? PIGLIT_PASS : PIGLIT_FAIL; +} diff --git a/tests/spec/ext_memory_object/vk_fragcoord.fs b/tests/spec/ext_memory_object/vk_fragcoord.fs new file mode 100644 index 000000000..942329b53 --- /dev/null +++ b/tests/spec/ext_memory_object/vk_fragcoord.fs @@ -0,0 +1,7 @@ +layout(location = 0) in vec2 v_coords; +layout(location = 0) out vec4 f_color; +void main() +{ + f_color.xy = v_coords; + f_color.zw = vec2(0.3, 1.0); +} diff --git a/tests/spec/ext_memory_object/vk_fragcoord.vs b/tests/spec/ext_memory_object/vk_fragcoord.vs new file mode 100644 index 000000000..f39931340 --- /dev/null +++ b/tests/spec/ext_memory_object/vk_fragcoord.vs @@ -0,0 +1,8 @@ +layout(location = 0) in vec4 a_position; +layout(location = 0) out vec2 v_coords; +void main() +{ + gl_Position.xy = a_position.xy * 2 - vec2(1.0); + gl_Position.zw = vec2(0.0, 1.0); + v_coords = (gl_Position.xy + 1.0) / 2.0; +} -- 2.14.1 _______________________________________________ Piglit mailing list Piglit@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/piglit