diff options
author | Topi Pohjolainen <topi.pohjolainen@intel.com> | 2017-11-30 15:31:26 +0200 |
---|---|---|
committer | Topi Pohjolainen <topi.pohjolainen@intel.com> | 2017-12-22 12:21:59 +0200 |
commit | ee62463de3d8d94c1c697980bf55df8f272f0e5c (patch) | |
tree | e877ad53c157b382f48c63e9b554a7f5468cc802 | |
parent | 7f28bb5bbf335927ee9239d595169770860ef2c0 (diff) |
ext_memory_object: Test render with vulkan and sample with glexternal_objects
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,
v2:
- pipeline setup moved into common code
- check for vkGetImageMemoryRequirements2KHR() (Fredrik)
- check that image type is supported by the device (Fredrik)
v3:
- pass usage, handle type and the expected feature as args to
is_layout_supported() (Fredrik)
- whitespace fix (Andres)
Reviewed-by: Andres Rodriguez <andresx7@gmail.com> (v2)
Signed-off-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
-rw-r--r-- | tests/spec/ext_memory_object/CMakeLists.gl.txt | 18 | ||||
-rw-r--r-- | tests/spec/ext_memory_object/vk_export_image_as_tex.c | 224 | ||||
-rw-r--r-- | tests/spec/ext_memory_object/vk_fragcoord.fs | 7 | ||||
-rw-r--r-- | tests/spec/ext_memory_object/vk_fragcoord.vs | 8 |
4 files changed, 257 insertions, 0 deletions
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..74f7bbffa --- /dev/null +++ b/tests/spec/ext_memory_object/vk_export_image_as_tex.c @@ -0,0 +1,224 @@ +/* + * 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 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"; + +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.layout.num_samples == 1); + + prog = piglit_build_simple_program(gl_vs_src, gl_fs_src); + glUseProgram(prog); +} + +static bool +render_and_wait(struct vk_core *core, struct vk_simple_pipeline *pipeline, + VkFramebuffer fb, unsigned w, unsigned h) +{ + 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(core->dev); + bool status = false; + + if (fence == VK_NULL_HANDLE) + goto cleanup; + + vk_setup_vertex_buffer(core, vertices, sizeof(vertices), &vb); + if (vb.buf == VK_NULL_HANDLE) + goto cleanup; + + vk_begin_render_pass(core->cmd_buf, pipeline->render_pass, fb, w, h); + + if (!vk_draw(core, pipeline->pipeline, vb.buf, fence)) + goto cleanup; + + status = vkWaitForFences(core->dev, 1, &fence, true, timeout) == + VK_SUCCESS; + +cleanup: + if (vb.buf != VK_NULL_HANDLE) { + vkFreeMemory(core->dev, vb.mem, NULL); + vkDestroyBuffer(core->dev, vb.buf, NULL); + } + + if (fence != VK_NULL_HANDLE) + vkDestroyFence(core->dev, fence, NULL); + + return status; +} + +enum piglit_result +piglit_display(void) +{ + const VkImageUsageFlagBits usage = VK_IMAGE_USAGE_SAMPLED_BIT | + VK_IMAGE_USAGE_TRANSFER_SRC_BIT; + const float green[] = { 0.0, 1.0, 0.0, 1.0 }; + const unsigned offset = 0; + GLuint tex, mem_obj; + bool result = false; + struct vk_core vk_core; + struct vk_simple_pipeline vk_pipeline; + struct vk_fb vk_fb; + + vk_core_init(&vk_core); + + if (!is_layout_supported( + &vk_core, &test_tex_layout.layout, usage, + VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR, + VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT_KHR)) + piglit_report_result(PIGLIT_SKIP); + + /* Make sure Vulkan can export memory. */ + if (vk_get_proc_addr_for_mem_fd(vk_core.dev) == NULL || + vk_get_proc_addr_for_image_mem_req(vk_core.dev) == NULL) { + vk_core_cleanup(&vk_core); + piglit_report_result(PIGLIT_SKIP); + } + + vk_create_simple_pipeline( + &vk_core, &test_tex_layout.layout, + vk_fragcoord_vs_spir_v_src, + sizeof(vk_fragcoord_vs_spir_v_src), + vk_fragcoord_fs_spir_v_src, + sizeof(vk_fragcoord_fs_spir_v_src), + &vk_pipeline); + if (vk_pipeline.pipeline == VK_NULL_HANDLE) + goto cleanup; + + vk_setup_fb(&vk_core, + test_tex_layout.layout.w, test_tex_layout.layout.h, + test_tex_layout.layout.num_samples, + test_tex_layout.layout.src_format, + test_tex_layout.layout.src_tiling, + VK_FORMAT_UNDEFINED, VK_IMAGE_TILING_LINEAR, + test_tex_layout.layout.num_layers, &vk_fb); + if (vk_fb.fb == VK_NULL_HANDLE) + goto cleanup; + + if (!render_and_wait( + &vk_core, &vk_pipeline, vk_fb.fb, + test_tex_layout.layout.w, test_tex_layout.layout.h)) + goto cleanup; + + if (!create_mem_obj_for_vk_dev_mem( + vk_core.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.layout.w / piglit_width, + 2.0 * test_tex_layout.layout.h / piglit_height, + 0, 0, 1, 1); + + result = piglit_probe_rect_rgba( + 0, 0, test_tex_layout.layout.w, test_tex_layout.layout.h, + green); + +cleanup: + vk_destroy_simple_pipeline(vk_core.dev, &vk_pipeline); + vk_fb_destroy(vk_core.dev, &vk_fb); + vk_core_cleanup(&vk_core); + + 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; +} |