From: Maciej Jesionowski Date: Fri, 18 Mar 2016 15:15:47 +0000 (+0100) Subject: Add tessellation shader tests (ported from ES 3.1) X-Git-Tag: upstream/0.1.0~840^2~17^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=abbf1c4efd3388dcfe59d125e5f33140c444a53a;p=platform%2Fupstream%2FVK-GL-CTS.git Add tessellation shader tests (ported from ES 3.1) Changes with respect to original tests: - Transform Feedback replaced with SSBO usage (impacted some failure conditions) - Geometry shader had to be used in some situations - GL queries replaced with Vulkan limits checks - Negative tests not ported due to ShaderLibrary limitation (shaders that fail compilation aren't supported) Mustpass exclusions: - Tests in `user_defined_io` group --- diff --git a/external/fetch_sources.py b/external/fetch_sources.py index 67024d5..1b814db 100644 --- a/external/fetch_sources.py +++ b/external/fetch_sources.py @@ -174,7 +174,7 @@ PACKAGES = [ "spirv-tools"), GitRepo( "https://github.com/KhronosGroup/glslang.git", - "5639f3aca5b75cbe5419a623eecf5e3794fab917", + "3357d870e455005a3781743e77403572eefb60d7", "glslang"), ] diff --git a/external/glslang/CMakeLists.txt b/external/glslang/CMakeLists.txt index 7c040e3..9ad2973 100644 --- a/external/glslang/CMakeLists.txt +++ b/external/glslang/CMakeLists.txt @@ -29,6 +29,7 @@ if (EXISTS ${GLSLANG_ABS_PATH}/glslang/GenericCodeGen/CodeGen.cpp) ${GLSLANG_ABS_PATH}/glslang/MachineIndependent ${GLSLANG_ABS_PATH}/glslang/GenericCodeGen ${GLSLANG_ABS_PATH}/glslang/OSDependent + ${GLSLANG_ABS_PATH}/hlsl ${GLSLANG_ABS_PATH}/OGLCompilersDLL ${GLSLANG_ABS_PATH}/SPIRV ) @@ -51,6 +52,7 @@ if (EXISTS ${GLSLANG_ABS_PATH}/glslang/GenericCodeGen/CodeGen.cpp) ${GLSLANG_ABS_PATH}/glslang/MachineIndependent/limits.cpp ${GLSLANG_ABS_PATH}/glslang/MachineIndependent/linkValidate.cpp ${GLSLANG_ABS_PATH}/glslang/MachineIndependent/parseConst.cpp + ${GLSLANG_ABS_PATH}/glslang/MachineIndependent/propagateNoContraction.cpp ${GLSLANG_ABS_PATH}/glslang/MachineIndependent/reflection.cpp ${GLSLANG_ABS_PATH}/glslang/MachineIndependent/preprocessor/Pp.cpp ${GLSLANG_ABS_PATH}/glslang/MachineIndependent/preprocessor/PpAtom.cpp @@ -63,10 +65,17 @@ if (EXISTS ${GLSLANG_ABS_PATH}/glslang/GenericCodeGen/CodeGen.cpp) ${GLSLANG_ABS_PATH}/glslang/GenericCodeGen/Link.cpp ${GLSLANG_ABS_PATH}/OGLCompilersDLL/InitializeDll.cpp + ${GLSLANG_ABS_PATH}/hlsl/hlslGrammar.cpp + ${GLSLANG_ABS_PATH}/hlsl/hlslOpMap.cpp + ${GLSLANG_ABS_PATH}/hlsl/hlslParseHelper.cpp + ${GLSLANG_ABS_PATH}/hlsl/hlslScanContext.cpp + ${GLSLANG_ABS_PATH}/hlsl/hlslTokenStream.cpp + ${GLSLANG_ABS_PATH}/SPIRV/GlslangToSpv.cpp ${GLSLANG_ABS_PATH}/SPIRV/InReadableOrder.cpp ${GLSLANG_ABS_PATH}/SPIRV/SpvBuilder.cpp ${GLSLANG_ABS_PATH}/SPIRV/SPVRemapper.cpp + ${GLSLANG_ABS_PATH}/SPIRV/Logger.cpp ${GLSLANG_ABS_PATH}/SPIRV/doc.cpp ${GLSLANG_ABS_PATH}/SPIRV/disassemble.cpp diff --git a/external/vulkancts/data/vulkan/data/tessellation/barrier_ref.png b/external/vulkancts/data/vulkan/data/tessellation/barrier_ref.png new file mode 100644 index 0000000..1f68aae Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/barrier_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_0.png new file mode 100644 index 0000000..8340b25 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_1.png new file mode 100644 index 0000000..af13309 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_2.png new file mode 100644 index 0000000..edcb04f Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_equal_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_0.png new file mode 100644 index 0000000..e7752a4 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_1.png new file mode 100644 index 0000000..bfc84fb Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_2.png new file mode 100644 index 0000000..b205d3d Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_even_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_0.png new file mode 100644 index 0000000..8340b25 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_1.png new file mode 100644 index 0000000..8a2f165 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_2.png new file mode 100644 index 0000000..f3faa84 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_quads_fractional_odd_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_0.png new file mode 100644 index 0000000..d6b5428 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_1.png new file mode 100644 index 0000000..1832754 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_2.png new file mode 100644 index 0000000..d1c1c99 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_equal_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_0.png new file mode 100644 index 0000000..9308abf Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_1.png new file mode 100644 index 0000000..2fdc5df Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_2.png new file mode 100644 index 0000000..29a85e0 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_even_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_0.png new file mode 100644 index 0000000..d6b5428 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_1.png new file mode 100644 index 0000000..853a31c Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_2.png new file mode 100644 index 0000000..58f3352 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_cover_triangles_fractional_odd_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_0.png new file mode 100644 index 0000000..d240932 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_1.png new file mode 100644 index 0000000..87d5764 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_2.png new file mode 100644 index 0000000..61c801d Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_equal_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_0.png new file mode 100644 index 0000000..a9065f6 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_1.png new file mode 100644 index 0000000..2b1f010 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_2.png new file mode 100644 index 0000000..7f37cd1 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_even_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_0.png new file mode 100644 index 0000000..d240932 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_1.png new file mode 100644 index 0000000..f8ed000 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_2.png new file mode 100644 index 0000000..e218794 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_quads_fractional_odd_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_0.png new file mode 100644 index 0000000..89c3533 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_1.png new file mode 100644 index 0000000..fd94847 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_2.png new file mode 100644 index 0000000..a2e7044 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_equal_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_0.png new file mode 100644 index 0000000..9336230 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_1.png new file mode 100644 index 0000000..6a58a2a Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_2.png new file mode 100644 index 0000000..342e109 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_even_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_0.png new file mode 100644 index 0000000..89c3533 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_1.png new file mode 100644 index 0000000..56d0fce Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_2.png new file mode 100644 index 0000000..a2e7044 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/fill_overlap_triangles_fractional_odd_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/gl_position_ref.png b/external/vulkancts/data/vulkan/data/tessellation/gl_position_ref.png new file mode 100644 index 0000000..e9a9c57 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/gl_position_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_0.png new file mode 100644 index 0000000..c7b6e82 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_1.png new file mode 100644 index 0000000..110b3cc Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_2.png new file mode 100644 index 0000000..9744722 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_equal_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_0.png new file mode 100644 index 0000000..70cb8ea Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_1.png new file mode 100644 index 0000000..1659c51 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_2.png new file mode 100644 index 0000000..9106ff5 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_even_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_0.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_0.png new file mode 100644 index 0000000..c7b6e82 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_0.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_1.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_1.png new file mode 100644 index 0000000..a90a547 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_1.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_2.png b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_2.png new file mode 100644 index 0000000..62e87e3 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/isolines_fractional_odd_spacing_ref_2.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/patch_vertices_10_in_5_out_ref.png b/external/vulkancts/data/vulkan/data/tessellation/patch_vertices_10_in_5_out_ref.png new file mode 100644 index 0000000..adf9cf7 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/patch_vertices_10_in_5_out_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/patch_vertices_5_in_10_out_ref.png b/external/vulkancts/data/vulkan/data/tessellation/patch_vertices_5_in_10_out_ref.png new file mode 100644 index 0000000..5f296ee Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/patch_vertices_5_in_10_out_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/primitive_id_tcs_ref.png b/external/vulkancts/data/vulkan/data/tessellation/primitive_id_tcs_ref.png new file mode 100644 index 0000000..011fc6c Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/primitive_id_tcs_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/primitive_id_tes_ref.png b/external/vulkancts/data/vulkan/data/tessellation/primitive_id_tes_ref.png new file mode 100644 index 0000000..011fc6c Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/primitive_id_tes_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_isolines_ref.png b/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_isolines_ref.png new file mode 100644 index 0000000..310c9d8 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_isolines_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_quads_ref.png b/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_quads_ref.png new file mode 100644 index 0000000..02bf1d5 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_quads_ref.png differ diff --git a/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_triangles_ref.png b/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_triangles_ref.png new file mode 100644 index 0000000..ce98970 Binary files /dev/null and b/external/vulkancts/data/vulkan/data/tessellation/user_defined_io_triangles_ref.png differ diff --git a/external/vulkancts/modules/vulkan/CMakeLists.txt b/external/vulkancts/modules/vulkan/CMakeLists.txt index 6ecf784..4a5b5db 100644 --- a/external/vulkancts/modules/vulkan/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(compute) add_subdirectory(image) add_subdirectory(wsi) add_subdirectory(sparse_resources) +add_subdirectory(tessellation) include_directories( api @@ -34,6 +35,7 @@ include_directories( image wsi sparse_resources + tessellation ) set(DEQP_VK_COMMON_SRCS @@ -75,6 +77,7 @@ set(DEQP_VK_COMMON_LIBS deqp-vk-image deqp-vk-wsi deqp-vk-sparse-resources + deqp-vk-tessellation ) add_library(deqp-vk-common STATIC ${DEQP_VK_COMMON_SRCS}) diff --git a/external/vulkancts/modules/vulkan/tessellation/CMakeLists.txt b/external/vulkancts/modules/vulkan/tessellation/CMakeLists.txt new file mode 100644 index 0000000..78b7f0e --- /dev/null +++ b/external/vulkancts/modules/vulkan/tessellation/CMakeLists.txt @@ -0,0 +1,37 @@ +include_directories(..) + +set(DEQP_VK_TESSELLATION_SRCS + vktTessellationTests.cpp + vktTessellationTests.hpp + vktTessellationUtil.cpp + vktTessellationUtil.hpp + vktTessellationLimitsTests.hpp + vktTessellationLimitsTests.cpp + vktTessellationCoordinatesTests.hpp + vktTessellationCoordinatesTests.cpp + vktTessellationWindingTests.hpp + vktTessellationWindingTests.cpp + vktTessellationShaderInputOutputTests.hpp + vktTessellationShaderInputOutputTests.cpp + vktTessellationMiscDrawTests.hpp + vktTessellationMiscDrawTests.cpp + vktTessellationCommonEdgeTests.hpp + vktTessellationCommonEdgeTests.cpp + vktTessellationFractionalSpacingTests.hpp + vktTessellationFractionalSpacingTests.cpp + vktTessellationPrimitiveDiscardTests.hpp + vktTessellationPrimitiveDiscardTests.cpp + vktTessellationInvarianceTests.hpp + vktTessellationInvarianceTests.cpp + vktTessellationUserDefinedIO.hpp + vktTessellationUserDefinedIO.cpp + ) + +set(DEQP_VK_TESSELLATION_LIBS + deqp-vk-common + tcutil + vkutil + ) + +add_library(deqp-vk-tessellation STATIC ${DEQP_VK_TESSELLATION_SRCS}) +target_link_libraries(deqp-vk-tessellation ${DEQP_VK_TESSELLATION_LIBS}) diff --git a/external/vulkancts/modules/vulkan/tessellation/vktTessellationCommonEdgeTests.cpp b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCommonEdgeTests.cpp new file mode 100644 index 0000000..db0b2d4 --- /dev/null +++ b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCommonEdgeTests.cpp @@ -0,0 +1,515 @@ +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Tessellation Common Edge Tests + *//*--------------------------------------------------------------------*/ + +#include "vktTessellationCommonEdgeTests.hpp" +#include "vktTestCaseUtil.hpp" +#include "vktTessellationUtil.hpp" + +#include "tcuTestLog.hpp" +#include "tcuTexture.hpp" + +#include "vkDefs.hpp" +#include "vkQueryUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkImageUtil.hpp" +#include "vkTypeUtil.hpp" +#include "vkStrUtil.hpp" + +#include "deUniquePtr.hpp" +#include "deStringUtil.hpp" + +#include +#include + +namespace vkt +{ +namespace tessellation +{ + +using namespace vk; + +namespace +{ + +enum CaseType +{ + CASETYPE_BASIC = 0, //!< Order patch vertices such that when two patches share a vertex, it's at the same index for both. + CASETYPE_PRECISE, //!< Vertex indices don't match like for CASETYPE_BASIC, but other measures are taken, using the 'precise' qualifier. + + CASETYPE_LAST +}; + +struct CaseDefinition +{ + TessPrimitiveType primitiveType; + SpacingMode spacingMode; + CaseType caseType; +}; + +//! Check that a certain rectangle in the image contains no black pixels. +//! Returns true if an image successfully passess the verification. +bool verifyResult (tcu::TestLog& log, const tcu::ConstPixelBufferAccess image) +{ + const int startX = static_cast(0.15f * image.getWidth()); + const int endX = static_cast(0.85f * image.getWidth()); + const int startY = static_cast(0.15f * image.getHeight()); + const int endY = static_cast(0.85f * image.getHeight()); + + for (int y = startY; y < endY; ++y) + for (int x = startX; x < endX; ++x) + { + const tcu::Vec4 pixel = image.getPixel(x, y); + + if (pixel.x() == 0 && pixel.y() == 0 && pixel.z() == 0) + { + log << tcu::TestLog::Message << "Failure: there seem to be cracks in the rendered result" << tcu::TestLog::EndMessage + << tcu::TestLog::Message << "Note: pixel with zero r, g and b channels found at " << tcu::IVec2(x, y) << tcu::TestLog::EndMessage; + + return false; + } + } + + log << tcu::TestLog::Message << "Success: there seem to be no cracks in the rendered result" << tcu::TestLog::EndMessage; + + return true; +} + +void initPrograms (vk::SourceCollections& programCollection, const CaseDefinition caseDef) +{ + DE_ASSERT(caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES || caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS); + + // Vertex shader + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "\n" + << "layout(location = 0) in highp vec2 in_v_position;\n" + << "layout(location = 1) in highp float in_v_tessParam;\n" + << "\n" + << "layout(location = 0) out highp vec2 in_tc_position;\n" + << "layout(location = 1) out highp float in_tc_tessParam;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " in_tc_position = in_v_position;\n" + << " in_tc_tessParam = in_v_tessParam;\n" + << "}\n"; + + programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); + } + + // Tessellation control shader + { + const int numVertices = (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 4); + + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "#extension GL_EXT_tessellation_shader : require\n" + << (caseDef.caseType == CASETYPE_PRECISE ? "#extension GL_EXT_gpu_shader5 : require\n" : "") + << "\n" + << "layout(vertices = " << numVertices << ") out;\n" + << "\n" + << "layout(location = 0) in highp vec2 in_tc_position[];\n" + << "layout(location = 1) in highp float in_tc_tessParam[];\n" + << "\n" + << "layout(location = 0) out highp vec2 in_te_position[];\n" + << "\n" + << (caseDef.caseType == CASETYPE_PRECISE ? "precise gl_TessLevelOuter;\n\n" : "") + << "void main (void)\n" + << "{\n" + << " in_te_position[gl_InvocationID] = in_tc_position[gl_InvocationID];\n" + << "\n" + << " gl_TessLevelInner[0] = 5.0;\n" + << " gl_TessLevelInner[1] = 5.0;\n" + << "\n" + << (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? + " gl_TessLevelOuter[0] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[1] + in_tc_tessParam[2]);\n" + " gl_TessLevelOuter[1] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[2] + in_tc_tessParam[0]);\n" + " gl_TessLevelOuter[2] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[0] + in_tc_tessParam[1]);\n" + : caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS ? + " gl_TessLevelOuter[0] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[0] + in_tc_tessParam[2]);\n" + " gl_TessLevelOuter[1] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[1] + in_tc_tessParam[0]);\n" + " gl_TessLevelOuter[2] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[3] + in_tc_tessParam[1]);\n" + " gl_TessLevelOuter[3] = 1.0 + 59.0 * 0.5 * (in_tc_tessParam[2] + in_tc_tessParam[3]);\n" + : "") + << "}\n"; + + programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()); + } + + // Tessellation evaluation shader + { + std::ostringstream primitiveSpecificCode; + if (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) + primitiveSpecificCode + << " highp vec2 pos = gl_TessCoord.x*in_te_position[0] + gl_TessCoord.y*in_te_position[1] + gl_TessCoord.z*in_te_position[2];\n" + << "\n" + << " highp float f = sqrt(3.0 * min(gl_TessCoord.x, min(gl_TessCoord.y, gl_TessCoord.z))) * 0.5 + 0.5;\n" + << " in_f_color = vec4(gl_TessCoord*f, 1.0);\n"; + else if (caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS) + primitiveSpecificCode + << (caseDef.caseType == CASETYPE_BASIC ? + " highp vec2 pos = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[0]\n" + " + ( gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[1]\n" + " + (1.0-gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[2]\n" + " + ( gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[3];\n" + : caseDef.caseType == CASETYPE_PRECISE ? + " highp vec2 a = (1.0-gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[0];\n" + " highp vec2 b = ( gl_TessCoord.x)*(1.0-gl_TessCoord.y)*in_te_position[1];\n" + " highp vec2 c = (1.0-gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[2];\n" + " highp vec2 d = ( gl_TessCoord.x)*( gl_TessCoord.y)*in_te_position[3];\n" + " highp vec2 pos = a+b+c+d;\n" + : "") + << "\n" + << " highp float f = sqrt(1.0 - 2.0 * max(abs(gl_TessCoord.x - 0.5), abs(gl_TessCoord.y - 0.5)))*0.5 + 0.5;\n" + << " in_f_color = vec4(0.1, gl_TessCoord.xy*f, 1.0);\n"; + + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "#extension GL_EXT_tessellation_shader : require\n" + << (caseDef.caseType == CASETYPE_PRECISE ? "#extension GL_EXT_gpu_shader5 : require\n" : "") + << "\n" + << "layout(" << getTessPrimitiveTypeShaderName(caseDef.primitiveType) << ", " + << getSpacingModeShaderName(caseDef.spacingMode) << ") in;\n" + << "\n" + << "layout(location = 0) in highp vec2 in_te_position[];\n" + << "\n" + << "layout(location = 0) out mediump vec4 in_f_color;\n" + << "\n" + << (caseDef.caseType == CASETYPE_PRECISE ? "precise gl_Position;\n\n" : "") + << "void main (void)\n" + << "{\n" + << primitiveSpecificCode.str() + << "\n" + << " // Offset the position slightly, based on the parity of the bits in the float representation.\n" + << " // This is done to detect possible small differences in edge vertex positions between patches.\n" + << " uvec2 bits = floatBitsToUint(pos);\n" + << " uint numBits = 0u;\n" + << " for (uint i = 0u; i < 32u; i++)\n" + << " numBits += ((bits[0] >> i) & 1u) + ((bits[1] >> i) & 1u);\n" + << " pos += float(numBits&1u)*0.04;\n" + << "\n" + << " gl_Position = vec4(pos, 0.0, 1.0);\n" + << "}\n"; + + programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()); + } + + // Fragment shader + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "\n" + << "layout(location = 0) in mediump vec4 in_f_color;\n" + << "\n" + << "layout(location = 0) out mediump vec4 o_color;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " o_color = in_f_color;\n" + << "}\n"; + + programCollection.glslSources.add("frag") << glu::FragmentSource(src.str()); + } +} + +//! Generic test code used by all test cases. +tcu::TestStatus test (Context& context, const CaseDefinition caseDef) +{ + DE_ASSERT(caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES || caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS); + DE_ASSERT(caseDef.caseType == CASETYPE_BASIC || caseDef.caseType == CASETYPE_PRECISE); + + requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER); + + const DeviceInterface& vk = context.getDeviceInterface(); + const VkDevice device = context.getDevice(); + const VkQueue queue = context.getUniversalQueue(); + const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); + Allocator& allocator = context.getDefaultAllocator(); + + // Prepare test data + + std::vector gridPosComps; + std::vector gridTessParams; + std::vector gridIndices; + + { + const int gridWidth = 4; + const int gridHeight = 4; + const int numVertices = (gridWidth+1)*(gridHeight+1); + const int numIndices = gridWidth*gridHeight * (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3*2 : 4); + const int numPosCompsPerVertex = 2; + const int totalNumPosComps = numPosCompsPerVertex*numVertices; + + gridPosComps.reserve(totalNumPosComps); + gridTessParams.reserve(numVertices); + gridIndices.reserve(numIndices); + + { + for (int i = 0; i < gridHeight+1; ++i) + for (int j = 0; j < gridWidth+1; ++j) + { + gridPosComps.push_back(-1.0f + 2.0f * ((float)j + 0.5f) / (float)(gridWidth+1)); + gridPosComps.push_back(-1.0f + 2.0f * ((float)i + 0.5f) / (float)(gridHeight+1)); + gridTessParams.push_back((float)(i*(gridWidth+1) + j) / (float)(numVertices-1)); + } + } + + // Generate patch vertex indices. + // \note If CASETYPE_BASIC, the vertices are ordered such that when multiple + // triangles/quads share a vertex, it's at the same index for everyone. + + if (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES) + { + for (int i = 0; i < gridHeight; i++) + for (int j = 0; j < gridWidth; j++) + { + const deUint16 corners[4] = + { + (deUint16)((i+0)*(gridWidth+1) + j+0), + (deUint16)((i+0)*(gridWidth+1) + j+1), + (deUint16)((i+1)*(gridWidth+1) + j+0), + (deUint16)((i+1)*(gridWidth+1) + j+1) + }; + + const int secondTriangleVertexIndexOffset = caseDef.caseType == CASETYPE_BASIC ? 0 : 1; + + for (int k = 0; k < 3; k++) + gridIndices.push_back(corners[(k+0 + i + (2-j%3)) % 3]); + for (int k = 0; k < 3; k++) + gridIndices.push_back(corners[(k+2 + i + (2-j%3) + secondTriangleVertexIndexOffset) % 3 + 1]); + } + } + else if (caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS) + { + for (int i = 0; i < gridHeight; ++i) + for (int j = 0; j < gridWidth; ++j) + { + for (int m = 0; m < 2; m++) + for (int n = 0; n < 2; n++) + gridIndices.push_back((deUint16)((i+(i+m)%2)*(gridWidth+1) + j+(j+n)%2)); + + if (caseDef.caseType == CASETYPE_PRECISE && (i+j) % 2 == 0) + std::reverse(gridIndices.begin() + (gridIndices.size() - 4), + gridIndices.begin() + gridIndices.size()); + } + } + else + DE_ASSERT(false); + + DE_ASSERT(static_cast(gridPosComps.size()) == totalNumPosComps); + DE_ASSERT(static_cast(gridTessParams.size()) == numVertices); + DE_ASSERT(static_cast(gridIndices.size()) == numIndices); + } + + // Vertex input buffer: we put both attributes and indices in here. + + const VkDeviceSize vertexDataSizeBytes = sizeInBytes(gridPosComps) + sizeInBytes(gridTessParams) + sizeInBytes(gridIndices); + const std::size_t vertexPositionsOffset = 0; + const std::size_t vertexTessParamsOffset = sizeInBytes(gridPosComps); + const std::size_t vertexIndicesOffset = vertexTessParamsOffset + sizeInBytes(gridTessParams); + + const Buffer vertexBuffer(vk, device, allocator, + makeBufferCreateInfo(vertexDataSizeBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_INDEX_BUFFER_BIT), MemoryRequirement::HostVisible); + + { + const Allocation& alloc = vertexBuffer.getAllocation(); + deUint8* const pData = static_cast(alloc.getHostPtr()); + + deMemcpy(pData + vertexPositionsOffset, &gridPosComps[0], static_cast(sizeInBytes(gridPosComps))); + deMemcpy(pData + vertexTessParamsOffset, &gridTessParams[0], static_cast(sizeInBytes(gridTessParams))); + deMemcpy(pData + vertexIndicesOffset, &gridIndices[0], static_cast(sizeInBytes(gridIndices))); + + flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), vertexDataSizeBytes); + // No barrier needed, flushed memory is automatically visible + } + + // Color attachment + + const tcu::IVec2 renderSize = tcu::IVec2(256, 256); + const VkFormat colorFormat = VK_FORMAT_R8G8B8A8_UNORM; + const VkImageSubresourceRange colorImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); + const Image colorAttachmentImage (vk, device, allocator, + makeImageCreateInfo(renderSize, colorFormat, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, 1u), + MemoryRequirement::Any); + + // Color output buffer: image will be copied here for verification + + const VkDeviceSize colorBufferSizeBytes = renderSize.x()*renderSize.y() * tcu::getPixelSize(mapVkFormat(colorFormat)); + const Buffer colorBuffer (vk, device, allocator, makeBufferCreateInfo(colorBufferSizeBytes, VK_BUFFER_USAGE_TRANSFER_DST_BIT), MemoryRequirement::HostVisible); + + // Pipeline + + const Unique colorAttachmentView (makeImageView (vk, device, *colorAttachmentImage, VK_IMAGE_VIEW_TYPE_2D, colorFormat, colorImageSubresourceRange)); + const Unique renderPass (makeRenderPass (vk, device, colorFormat)); + const Unique framebuffer (makeFramebuffer (vk, device, *renderPass, *colorAttachmentView, renderSize.x(), renderSize.y(), 1u)); + const Unique cmdPool (makeCommandPool (vk, device, queueFamilyIndex)); + const Unique cmdBuffer (makeCommandBuffer (vk, device, *cmdPool)); + const Unique pipelineLayout (makePipelineLayoutWithoutDescriptors(vk, device)); + + const int inPatchSize = (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? 3 : 4); + const Unique pipeline(GraphicsPipelineBuilder() + .setRenderSize (renderSize) + .setPatchControlPoints(inPatchSize) + .addVertexBinding (makeVertexInputBindingDescription(0u, sizeof(tcu::Vec2), VK_VERTEX_INPUT_RATE_VERTEX)) + .addVertexBinding (makeVertexInputBindingDescription(1u, sizeof(float), VK_VERTEX_INPUT_RATE_VERTEX)) + .addVertexAttribute (makeVertexInputAttributeDescription(0u, 0u, VK_FORMAT_R32G32_SFLOAT, 0u)) + .addVertexAttribute (makeVertexInputAttributeDescription(1u, 1u, VK_FORMAT_R32_SFLOAT, 0u)) + .setShader (vk, device, VK_SHADER_STAGE_VERTEX_BIT, context.getBinaryCollection().get("vert"), DE_NULL) + .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, context.getBinaryCollection().get("tesc"), DE_NULL) + .setShader (vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, context.getBinaryCollection().get("tese"), DE_NULL) + .setShader (vk, device, VK_SHADER_STAGE_FRAGMENT_BIT, context.getBinaryCollection().get("frag"), DE_NULL) + .build (vk, device, *pipelineLayout, *renderPass)); + + // Draw commands + + beginCommandBuffer(vk, *cmdBuffer); + + // Change color attachment image layout + { + const VkImageMemoryBarrier colorAttachmentLayoutBarrier = makeImageMemoryBarrier( + (VkAccessFlags)0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + *colorAttachmentImage, colorImageSubresourceRange); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, + 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentLayoutBarrier); + } + + // Begin render pass + { + const VkRect2D renderArea = { + makeOffset2D(0, 0), + makeExtent2D(renderSize.x(), renderSize.y()), + }; + const tcu::Vec4 clearColor(0.0f, 0.0f, 0.0f, 1.0f); + + beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor); + } + + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + { + const VkBuffer buffers[] = { *vertexBuffer, *vertexBuffer }; + const VkDeviceSize offsets[] = { vertexPositionsOffset, vertexTessParamsOffset, }; + vk.cmdBindVertexBuffers(*cmdBuffer, 0u, DE_LENGTH_OF_ARRAY(buffers), buffers, offsets); + + vk.cmdBindIndexBuffer(*cmdBuffer, *vertexBuffer, vertexIndicesOffset, VK_INDEX_TYPE_UINT16); + } + + vk.cmdDrawIndexed(*cmdBuffer, static_cast(gridIndices.size()), 1u, 0u, 0, 0u); + endRenderPass(vk, *cmdBuffer); + + // Copy render result to a host-visible buffer + { + const VkImageMemoryBarrier colorAttachmentPreCopyBarrier = makeImageMemoryBarrier( + VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT, + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + *colorAttachmentImage, colorImageSubresourceRange); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, + 0u, DE_NULL, 0u, DE_NULL, 1u, &colorAttachmentPreCopyBarrier); + } + { + const VkBufferImageCopy copyRegion = makeBufferImageCopy(makeExtent3D(renderSize.x(), renderSize.y(), 0), makeImageSubresourceLayers(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u)); + vk.cmdCopyImageToBuffer(*cmdBuffer, *colorAttachmentImage, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *colorBuffer, 1u, ©Region); + } + { + const VkBufferMemoryBarrier postCopyBarrier = makeBufferMemoryBarrier( + VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *colorBuffer, 0ull, colorBufferSizeBytes); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, + 0u, DE_NULL, 1u, &postCopyBarrier, 0u, DE_NULL); + } + + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + { + // Log the result image. + + const Allocation& colorBufferAlloc = colorBuffer.getAllocation(); + invalidateMappedMemoryRange(vk, device, colorBufferAlloc.getMemory(), colorBufferAlloc.getOffset(), colorBufferSizeBytes); + const tcu::ConstPixelBufferAccess imagePixelAccess(mapVkFormat(colorFormat), renderSize.x(), renderSize.y(), 1, colorBufferAlloc.getHostPtr()); + + tcu::TestLog& log = context.getTestContext().getLog(); + log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess) + << tcu::TestLog::Message + << "Note: coloring is done to clarify the positioning and orientation of the " + << (caseDef.primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? "triangles" : + caseDef.primitiveType == TESSPRIMITIVETYPE_QUADS ? "quads" : "") + << "; the color of a vertex corresponds to the index of that vertex in the patch" + << tcu::TestLog::EndMessage; + + if (caseDef.caseType == CASETYPE_BASIC) + log << tcu::TestLog::Message << "Note: each shared vertex has the same index among the primitives it belongs to" << tcu::TestLog::EndMessage; + else if (caseDef.caseType == CASETYPE_PRECISE) + log << tcu::TestLog::Message << "Note: the 'precise' qualifier is used to avoid cracks between primitives" << tcu::TestLog::EndMessage; + else + DE_ASSERT(false); + + // Verify the result. + + const bool ok = verifyResult(log, imagePixelAccess); + return (ok ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Failure")); + } +} + +std::string getCaseName (const TessPrimitiveType primitiveType, const SpacingMode spacingMode, const CaseType caseType) +{ + std::ostringstream str; + str << getTessPrimitiveTypeShaderName(primitiveType) << "_" << getSpacingModeShaderName(spacingMode) + << (caseType == CASETYPE_PRECISE ? "_precise" : ""); + return str.str(); +} + +} // anonymous + +//! These tests correspond to dEQP-GLES31.functional.tessellation.common_edge.* +tcu::TestCaseGroup* createCommonEdgeTests (tcu::TestContext& testCtx) +{ + de::MovePtr group (new tcu::TestCaseGroup(testCtx, "common_edge", "Draw multiple adjacent shapes and check that no cracks appear between them")); + + static const TessPrimitiveType primitiveTypes[] = + { + TESSPRIMITIVETYPE_TRIANGLES, + TESSPRIMITIVETYPE_QUADS, + }; + + for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitiveTypes); ++primitiveTypeNdx) + for (int caseTypeNdx = 0; caseTypeNdx < CASETYPE_LAST; ++caseTypeNdx) + for (int spacingModeNdx = 0; spacingModeNdx < SPACINGMODE_LAST; ++spacingModeNdx) + { + const TessPrimitiveType primitiveType = primitiveTypes[primitiveTypeNdx]; + const CaseType caseType = static_cast(caseTypeNdx); + const SpacingMode spacingMode = static_cast(spacingModeNdx); + const CaseDefinition caseDef = { primitiveType, spacingMode, caseType }; + + addFunctionCaseWithPrograms(group.get(), getCaseName(primitiveType, spacingMode, caseType), "", initPrograms, test, caseDef); + } + + return group.release(); +} + +} // tessellation +} // vkt diff --git a/external/vulkancts/modules/vulkan/tessellation/vktTessellationCommonEdgeTests.hpp b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCommonEdgeTests.hpp new file mode 100644 index 0000000..35e9921 --- /dev/null +++ b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCommonEdgeTests.hpp @@ -0,0 +1,40 @@ +#ifndef _VKTTESSELLATIONCOMMONEDGETESTS_HPP +#define _VKTTESSELLATIONCOMMONEDGETESTS_HPP +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Tessellation Common Edge Tests + *//*--------------------------------------------------------------------*/ + +#include "tcuDefs.hpp" +#include "tcuTestCase.hpp" + +namespace vkt +{ +namespace tessellation +{ + +tcu::TestCaseGroup* createCommonEdgeTests (tcu::TestContext& testCtx); + +} // tessellation +} // vkt + +#endif // _VKTTESSELLATIONCOMMONEDGETESTS_HPP diff --git a/external/vulkancts/modules/vulkan/tessellation/vktTessellationCoordinatesTests.cpp b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCoordinatesTests.cpp new file mode 100644 index 0000000..67ce58e --- /dev/null +++ b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCoordinatesTests.cpp @@ -0,0 +1,650 @@ +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Tessellation Coordinates Tests + *//*--------------------------------------------------------------------*/ + +#include "vktTessellationCoordinatesTests.hpp" +#include "vktTestCaseUtil.hpp" +#include "vktTessellationUtil.hpp" + +#include "tcuTestLog.hpp" +#include "tcuRGBA.hpp" +#include "tcuSurface.hpp" +#include "tcuTextureUtil.hpp" +#include "tcuVectorUtil.hpp" + +#include "vkDefs.hpp" +#include "vkQueryUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkTypeUtil.hpp" + +#include "deUniquePtr.hpp" + +#include +#include + +namespace vkt +{ +namespace tessellation +{ + +using namespace vk; + +namespace +{ + +template +class SizeLessThan +{ +public: + bool operator() (const T& a, const T& b) const { return a.size() < b.size(); } +}; + +std::string getCaseName (const TessPrimitiveType primitiveType, const SpacingMode spacingMode) +{ + std::ostringstream str; + str << getTessPrimitiveTypeShaderName(primitiveType) << "_" << getSpacingModeShaderName(spacingMode); + return str.str(); +} + +std::vector genTessLevelCases (const TessPrimitiveType primitiveType, + const SpacingMode spacingMode) +{ + static const TessLevels rawTessLevelCases[] = + { + { { 1.0f, 1.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, + { { 63.0f, 24.0f }, { 15.0f, 42.0f, 10.0f, 12.0f } }, + { { 3.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, + { { 4.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, + { { 2.0f, 2.0f }, { 6.0f, 8.0f, 7.0f, 9.0f } }, + { { 5.0f, 6.0f }, { 1.0f, 1.0f, 1.0f, 1.0f } }, + { { 1.0f, 6.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, + { { 5.0f, 1.0f }, { 2.0f, 3.0f, 1.0f, 4.0f } }, + { { 5.2f, 1.6f }, { 2.9f, 3.4f, 1.5f, 4.1f } } + }; + + if (spacingMode == SPACINGMODE_EQUAL) + return std::vector(DE_ARRAY_BEGIN(rawTessLevelCases), DE_ARRAY_END(rawTessLevelCases)); + else + { + std::vector result; + result.reserve(DE_LENGTH_OF_ARRAY(rawTessLevelCases)); + + for (int tessLevelCaseNdx = 0; tessLevelCaseNdx < DE_LENGTH_OF_ARRAY(rawTessLevelCases); ++tessLevelCaseNdx) + { + TessLevels curTessLevelCase = rawTessLevelCases[tessLevelCaseNdx]; + + float* const inner = &curTessLevelCase.inner[0]; + float* const outer = &curTessLevelCase.outer[0]; + + for (int j = 0; j < 2; ++j) inner[j] = static_cast(getClampedRoundedTessLevel(spacingMode, inner[j])); + for (int j = 0; j < 4; ++j) outer[j] = static_cast(getClampedRoundedTessLevel(spacingMode, outer[j])); + + if (primitiveType == TESSPRIMITIVETYPE_TRIANGLES) + { + if (outer[0] > 1.0f || outer[1] > 1.0f || outer[2] > 1.0f) + { + if (inner[0] == 1.0f) + inner[0] = static_cast(getClampedRoundedTessLevel(spacingMode, inner[0] + 0.1f)); + } + } + else if (primitiveType == TESSPRIMITIVETYPE_QUADS) + { + if (outer[0] > 1.0f || outer[1] > 1.0f || outer[2] > 1.0f || outer[3] > 1.0f) + { + if (inner[0] == 1.0f) inner[0] = static_cast(getClampedRoundedTessLevel(spacingMode, inner[0] + 0.1f)); + if (inner[1] == 1.0f) inner[1] = static_cast(getClampedRoundedTessLevel(spacingMode, inner[1] + 0.1f)); + } + } + + result.push_back(curTessLevelCase); + } + + DE_ASSERT(static_cast(result.size()) == DE_LENGTH_OF_ARRAY(rawTessLevelCases)); + return result; + } +} + +std::vector generateReferenceTessCoords (const TessPrimitiveType primitiveType, + const SpacingMode spacingMode, + const float* innerLevels, + const float* outerLevels) +{ + if (isPatchDiscarded(primitiveType, outerLevels)) + return std::vector(); + + switch (primitiveType) + { + case TESSPRIMITIVETYPE_TRIANGLES: + { + int inner; + int outer[3]; + getClampedRoundedTriangleTessLevels(spacingMode, innerLevels, outerLevels, &inner, &outer[0]); + + if (spacingMode != SPACINGMODE_EQUAL) + { + // \note For fractional spacing modes, exact results are implementation-defined except in special cases. + DE_ASSERT(de::abs(innerLevels[0] - static_cast(inner)) < 0.001f); + for (int i = 0; i < 3; ++i) + DE_ASSERT(de::abs(outerLevels[i] - static_cast(outer[i])) < 0.001f); + DE_ASSERT(inner > 1 || (outer[0] == 1 && outer[1] == 1 && outer[2] == 1)); + } + + return generateReferenceTriangleTessCoords(spacingMode, inner, outer[0], outer[1], outer[2]); + } + + case TESSPRIMITIVETYPE_QUADS: + { + int inner[2]; + int outer[4]; + getClampedRoundedQuadTessLevels(spacingMode, innerLevels, outerLevels, &inner[0], &outer[0]); + + if (spacingMode != SPACINGMODE_EQUAL) + { + // \note For fractional spacing modes, exact results are implementation-defined except in special cases. + for (int i = 0; i < 2; ++i) + DE_ASSERT(de::abs(innerLevels[i] - static_cast(inner[i])) < 0.001f); + for (int i = 0; i < 4; ++i) + DE_ASSERT(de::abs(outerLevels[i] - static_cast(outer[i])) < 0.001f); + + DE_ASSERT((inner[0] > 1 && inner[1] > 1) || (inner[0] == 1 && inner[1] == 1 && outer[0] == 1 && outer[1] == 1 && outer[2] == 1 && outer[3] == 1)); + } + + return generateReferenceQuadTessCoords(spacingMode, inner[0], inner[1], outer[0], outer[1], outer[2], outer[3]); + } + + case TESSPRIMITIVETYPE_ISOLINES: + { + int outer[2]; + getClampedRoundedIsolineTessLevels(spacingMode, &outerLevels[0], &outer[0]); + + if (spacingMode != SPACINGMODE_EQUAL) + { + // \note For fractional spacing modes, exact results are implementation-defined except in special cases. + DE_ASSERT(de::abs(outerLevels[1] - static_cast(outer[1])) < 0.001f); + } + + return generateReferenceIsolineTessCoords(outer[0], outer[1]); + } + + default: + DE_ASSERT(false); + return std::vector(); + } +} + +void drawPoint (tcu::Surface& dst, const int centerX, const int centerY, const tcu::RGBA& color, const int size) +{ + const int width = dst.getWidth(); + const int height = dst.getHeight(); + DE_ASSERT(de::inBounds(centerX, 0, width) && de::inBounds(centerY, 0, height)); + DE_ASSERT(size > 0); + + for (int yOff = -((size-1)/2); yOff <= size/2; ++yOff) + for (int xOff = -((size-1)/2); xOff <= size/2; ++xOff) + { + const int pixX = centerX + xOff; + const int pixY = centerY + yOff; + if (de::inBounds(pixX, 0, width) && de::inBounds(pixY, 0, height)) + dst.setPixel(pixX, pixY, color); + } +} + +void drawTessCoordPoint (tcu::Surface& dst, const TessPrimitiveType primitiveType, const tcu::Vec3& pt, const tcu::RGBA& color, const int size) +{ + // \note These coordinates should match the description in the log message in TessCoordTestInstance::iterate. + + static const tcu::Vec2 triangleCorners[3] = + { + tcu::Vec2(0.95f, 0.95f), + tcu::Vec2(0.5f, 0.95f - 0.9f*deFloatSqrt(3.0f/4.0f)), + tcu::Vec2(0.05f, 0.95f) + }; + + static const float quadIsolineLDRU[4] = + { + 0.1f, 0.9f, 0.9f, 0.1f + }; + + const tcu::Vec2 dstPos = primitiveType == TESSPRIMITIVETYPE_TRIANGLES ? pt.x()*triangleCorners[0] + + pt.y()*triangleCorners[1] + + pt.z()*triangleCorners[2] + + : primitiveType == TESSPRIMITIVETYPE_QUADS || + primitiveType == TESSPRIMITIVETYPE_ISOLINES ? tcu::Vec2((1.0f - pt.x())*quadIsolineLDRU[0] + pt.x()*quadIsolineLDRU[2], + (1.0f - pt.y())*quadIsolineLDRU[1] + pt.y()*quadIsolineLDRU[3]) + + : tcu::Vec2(-1.0f); + + drawPoint(dst, static_cast(dstPos.x() * dst.getWidth()), static_cast(dstPos.y() * dst.getHeight()), color, size); +} + +void drawTessCoordVisualization (tcu::Surface& dst, const TessPrimitiveType primitiveType, const std::vector& coords) +{ + const int imageWidth = 256; + const int imageHeight = 256; + dst.setSize(imageWidth, imageHeight); + + tcu::clear(dst.getAccess(), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + for (int i = 0; i < static_cast(coords.size()); ++i) + drawTessCoordPoint(dst, primitiveType, coords[i], tcu::RGBA::white(), 2); +} + +inline bool vec3XLessThan (const tcu::Vec3& a, const tcu::Vec3& b) +{ + return a.x() < b.x(); +} + +int binarySearchFirstVec3WithXAtLeast (const std::vector& sorted, float x) +{ + const tcu::Vec3 ref(x, 0.0f, 0.0f); + const std::vector::const_iterator first = std::lower_bound(sorted.begin(), sorted.end(), ref, vec3XLessThan); + if (first == sorted.end()) + return -1; + return static_cast(std::distance(sorted.begin(), first)); +} + +// Check that all points in subset are (approximately) present also in superset. +bool oneWayComparePointSets (tcu::TestLog& log, + tcu::Surface& errorDst, + const TessPrimitiveType primitiveType, + const std::vector& subset, + const std::vector& superset, + const char* subsetName, + const char* supersetName, + const tcu::RGBA& errorColor) +{ + const std::vector supersetSorted = sorted(superset, vec3XLessThan); + const float epsilon = 0.01f; + const int maxNumFailurePrints = 5; + int numFailuresDetected = 0; + + for (int subNdx = 0; subNdx < static_cast(subset.size()); ++subNdx) + { + const tcu::Vec3& subPt = subset[subNdx]; + + bool matchFound = false; + + { + // Binary search the index of the first point in supersetSorted with x in the [subPt.x() - epsilon, subPt.x() + epsilon] range. + const tcu::Vec3 matchMin = subPt - epsilon; + const tcu::Vec3 matchMax = subPt + epsilon; + const int firstCandidateNdx = binarySearchFirstVec3WithXAtLeast(supersetSorted, matchMin.x()); + + if (firstCandidateNdx >= 0) + { + // Compare subPt to all points in supersetSorted with x in the [subPt.x() - epsilon, subPt.x() + epsilon] range. + for (int superNdx = firstCandidateNdx; superNdx < static_cast(supersetSorted.size()) && supersetSorted[superNdx].x() <= matchMax.x(); ++superNdx) + { + const tcu::Vec3& superPt = supersetSorted[superNdx]; + + if (tcu::boolAll(tcu::greaterThanEqual (superPt, matchMin)) && + tcu::boolAll(tcu::lessThanEqual (superPt, matchMax))) + { + matchFound = true; + break; + } + } + } + } + + if (!matchFound) + { + ++numFailuresDetected; + if (numFailuresDetected < maxNumFailurePrints) + log << tcu::TestLog::Message << "Failure: no matching " << supersetName << " point found for " << subsetName << " point " << subPt << tcu::TestLog::EndMessage; + else if (numFailuresDetected == maxNumFailurePrints) + log << tcu::TestLog::Message << "Note: More errors follow" << tcu::TestLog::EndMessage; + + drawTessCoordPoint(errorDst, primitiveType, subPt, errorColor, 4); + } + } + + return numFailuresDetected == 0; +} + +//! Returns true on matching coordinate sets. +bool compareTessCoords (tcu::TestLog& log, + TessPrimitiveType primitiveType, + const std::vector& refCoords, + const std::vector& resCoords) +{ + tcu::Surface refVisual; + tcu::Surface resVisual; + bool success = true; + + drawTessCoordVisualization(refVisual, primitiveType, refCoords); + drawTessCoordVisualization(resVisual, primitiveType, resCoords); + + // Check that all points in reference also exist in result. + success = oneWayComparePointSets(log, refVisual, primitiveType, refCoords, resCoords, "reference", "result", tcu::RGBA::blue()) && success; + // Check that all points in result also exist in reference. + success = oneWayComparePointSets(log, resVisual, primitiveType, resCoords, refCoords, "result", "reference", tcu::RGBA::red()) && success; + + if (!success) + { + log << tcu::TestLog::Message << "Note: in the following reference visualization, points that are missing in result point set are blue (if any)" << tcu::TestLog::EndMessage + << tcu::TestLog::Image("RefTessCoordVisualization", "Reference tessCoord visualization", refVisual) + << tcu::TestLog::Message << "Note: in the following result visualization, points that are missing in reference point set are red (if any)" << tcu::TestLog::EndMessage; + } + + log << tcu::TestLog::Image("ResTessCoordVisualization", "Result tessCoord visualization", resVisual); + + return success; +} + +class TessCoordTest : public TestCase +{ +public: + TessCoordTest (tcu::TestContext& testCtx, + const TessPrimitiveType primitiveType, + const SpacingMode spacingMode); + + void initPrograms (SourceCollections& programCollection) const; + TestInstance* createInstance (Context& context) const; + +private: + const TessPrimitiveType m_primitiveType; + const SpacingMode m_spacingMode; +}; + +TessCoordTest::TessCoordTest (tcu::TestContext& testCtx, + const TessPrimitiveType primitiveType, + const SpacingMode spacingMode) + : TestCase (testCtx, getCaseName(primitiveType, spacingMode), "") + , m_primitiveType (primitiveType) + , m_spacingMode (spacingMode) +{ +} + +void TessCoordTest::initPrograms (SourceCollections& programCollection) const +{ + // Vertex shader - no inputs + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "\n" + << "void main (void)\n" + << "{\n" + << "}\n"; + + programCollection.glslSources.add("vert") << glu::VertexSource(src.str()); + } + + // Tessellation control shader + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "#extension GL_EXT_tessellation_shader : require\n" + << "\n" + << "layout(vertices = 1) out;\n" + << "\n" + << "layout(set = 0, binding = 0, std430) readonly restrict buffer TessLevels {\n" + << " float inner0;\n" + << " float inner1;\n" + << " float outer0;\n" + << " float outer1;\n" + << " float outer2;\n" + << " float outer3;\n" + << "} sb_levels;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " gl_TessLevelInner[0] = sb_levels.inner0;\n" + << " gl_TessLevelInner[1] = sb_levels.inner1;\n" + << "\n" + << " gl_TessLevelOuter[0] = sb_levels.outer0;\n" + << " gl_TessLevelOuter[1] = sb_levels.outer1;\n" + << " gl_TessLevelOuter[2] = sb_levels.outer2;\n" + << " gl_TessLevelOuter[3] = sb_levels.outer3;\n" + << "}\n"; + + programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str()); + } + + // Tessellation evaluation shader + { + std::ostringstream src; + src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_310_ES) << "\n" + << "#extension GL_EXT_tessellation_shader : require\n" + << "\n" + << "layout(" << getTessPrimitiveTypeShaderName(m_primitiveType) << ", " + << getSpacingModeShaderName(m_spacingMode) << ", point_mode) in;\n" + << "\n" + << "layout(set = 0, binding = 1, std430) coherent restrict buffer Output {\n" + << " int numInvocations;\n" + << " vec3 tessCoord[];\n" // alignment is 16 bytes, same as vec4 + << "} sb_out;\n" + << "\n" + << "void main (void)\n" + << "{\n" + << " int index = atomicAdd(sb_out.numInvocations, 1);\n" + << " sb_out.tessCoord[index] = gl_TessCoord;\n" + << "}\n"; + + programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str()); + } +} + +class TessCoordTestInstance : public TestInstance +{ +public: + TessCoordTestInstance (Context& context, + const TessPrimitiveType primitiveType, + const SpacingMode spacingMode); + + tcu::TestStatus iterate (void); + +private: + const TessPrimitiveType m_primitiveType; + const SpacingMode m_spacingMode; +}; + +TessCoordTestInstance::TessCoordTestInstance (Context& context, + const TessPrimitiveType primitiveType, + const SpacingMode spacingMode) + : TestInstance (context) + , m_primitiveType (primitiveType) + , m_spacingMode (spacingMode) +{ +} + +tcu::TestStatus TessCoordTestInstance::iterate (void) +{ + const DeviceInterface& vk = m_context.getDeviceInterface(); + const VkDevice device = m_context.getDevice(); + const VkQueue queue = m_context.getUniversalQueue(); + const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); + Allocator& allocator = m_context.getDefaultAllocator(); + + // Test data + + const std::vector tessLevelCases = genTessLevelCases(m_primitiveType, m_spacingMode); + std::vector > allReferenceTessCoords (tessLevelCases.size()); + + for (deUint32 i = 0; i < tessLevelCases.size(); ++i) + allReferenceTessCoords[i] = generateReferenceTessCoords(m_primitiveType, m_spacingMode, &tessLevelCases[i].inner[0], &tessLevelCases[i].outer[0]); + + const int maxNumVertices = static_cast(std::max_element(allReferenceTessCoords.begin(), allReferenceTessCoords.end(), SizeLessThan >())->size()); + + // Input buffer: tessellation levels. Data is filled in later. + + const Buffer tessLevelsBuffer(vk, device, allocator, + makeBufferCreateInfo(sizeof(TessLevels), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); + + // Output buffer: number of invocations + padding + tessellation coordinates. Initialized later. + + const int resultBufferTessCoordsOffset = 4 * sizeof(deInt32); + const int extraneousVertices = 16; // allow some room for extraneous vertices from duplicate shader invocations (number is arbitrary) + const VkDeviceSize resultBufferSizeBytes = resultBufferTessCoordsOffset + (maxNumVertices + extraneousVertices)*sizeof(tcu::Vec4); + const Buffer resultBuffer (vk, device, allocator, makeBufferCreateInfo(resultBufferSizeBytes, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT), MemoryRequirement::HostVisible); + + // Descriptors + + const Unique descriptorSetLayout(DescriptorSetLayoutBuilder() + .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) + .addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) + .build(vk, device)); + + const Unique descriptorPool(DescriptorPoolBuilder() + .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER) + .build(vk, device, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u)); + + const Unique descriptorSet(makeDescriptorSet(vk, device, *descriptorPool, *descriptorSetLayout)); + + const VkDescriptorBufferInfo tessLevelsBufferInfo = makeDescriptorBufferInfo(tessLevelsBuffer.get(), 0ull, sizeof(TessLevels)); + const VkDescriptorBufferInfo resultBufferInfo = makeDescriptorBufferInfo(resultBuffer.get(), 0ull, resultBufferSizeBytes); + + DescriptorSetUpdateBuilder() + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &tessLevelsBufferInfo) + .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(1u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultBufferInfo) + .update(vk, device); + + // Pipeline: set up vertex processing without rasterization + + const Unique renderPass (makeRenderPassWithoutAttachments (vk, device)); + const Unique framebuffer (makeFramebufferWithoutAttachments(vk, device, *renderPass)); + const Unique pipelineLayout(makePipelineLayout (vk, device, *descriptorSetLayout)); + const Unique cmdPool (makeCommandPool (vk, device, queueFamilyIndex)); + const Unique cmdBuffer (makeCommandBuffer (vk, device, *cmdPool)); + + const Unique pipeline(GraphicsPipelineBuilder() + .setShader(vk, device, VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vert"), DE_NULL) + .setShader(vk, device, VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_context.getBinaryCollection().get("tesc"), DE_NULL) + .setShader(vk, device, VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_context.getBinaryCollection().get("tese"), DE_NULL) + .build (vk, device, *pipelineLayout, *renderPass)); + + deUint32 numPassedCases = 0; + + // Repeat the test for all tessellation coords cases + for (deUint32 tessLevelCaseNdx = 0; tessLevelCaseNdx < tessLevelCases.size(); ++tessLevelCaseNdx) + { + m_context.getTestContext().getLog() + << tcu::TestLog::Message + << "Tessellation levels: " << getTessellationLevelsString(tessLevelCases[tessLevelCaseNdx], m_primitiveType) + << tcu::TestLog::EndMessage; + + // Upload tessellation levels data to the input buffer + { + const Allocation& alloc = tessLevelsBuffer.getAllocation(); + TessLevels* const bufferTessLevels = static_cast(alloc.getHostPtr()); + *bufferTessLevels = tessLevelCases[tessLevelCaseNdx]; + flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), sizeof(TessLevels)); + } + + // Clear the results buffer + { + const Allocation& alloc = resultBuffer.getAllocation(); + deMemset(alloc.getHostPtr(), 0, static_cast(resultBufferSizeBytes)); + flushMappedMemoryRange(vk, device, alloc.getMemory(), alloc.getOffset(), resultBufferSizeBytes); + } + + // Reset the command buffer and begin recording. + beginCommandBuffer(vk, *cmdBuffer); + beginRenderPassWithRasterizationDisabled(vk, *cmdBuffer, *renderPass, *framebuffer); + + vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline); + vk.cmdBindDescriptorSets(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet.get(), 0u, DE_NULL); + + // Process a single abstract vertex. + vk.cmdDraw(*cmdBuffer, 1u, 1u, 0u, 0u); + endRenderPass(vk, *cmdBuffer); + + { + const VkBufferMemoryBarrier shaderWriteBarrier = makeBufferMemoryBarrier( + VK_ACCESS_SHADER_WRITE_BIT, VK_ACCESS_HOST_READ_BIT, *resultBuffer, 0ull, resultBufferSizeBytes); + + vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, + 0u, DE_NULL, 1u, &shaderWriteBarrier, 0u, DE_NULL); + } + + endCommandBuffer(vk, *cmdBuffer); + submitCommandsAndWait(vk, device, queue, *cmdBuffer); + + // Verify results + { + const Allocation& resultAlloc = resultBuffer.getAllocation(); + invalidateMappedMemoryRange(vk, device, resultAlloc.getMemory(), resultAlloc.getOffset(), resultBufferSizeBytes); + + const deInt32 numResults = *static_cast(resultAlloc.getHostPtr()); + const std::vector resultTessCoords = readInterleavedData(numResults, resultAlloc.getHostPtr(), resultBufferTessCoordsOffset, sizeof(tcu::Vec4)); + const std::vector& referenceTessCoords = allReferenceTessCoords[tessLevelCaseNdx]; + const int numExpectedResults = static_cast(referenceTessCoords.size()); + tcu::TestLog& log = m_context.getTestContext().getLog(); + + if (numResults < numExpectedResults) + { + log << tcu::TestLog::Message + << "Failure: generated " << numResults << " coordinates, but the expected reference value is " << numExpectedResults + << tcu::TestLog::EndMessage; + } + else if (numResults == numExpectedResults) + log << tcu::TestLog::Message << "Note: generated " << numResults << " tessellation coordinates" << tcu::TestLog::EndMessage; + else + { + log << tcu::TestLog::Message + << "Note: generated " << numResults << " coordinates (out of which " << numExpectedResults << " must be unique)" + << tcu::TestLog::EndMessage; + } + + if (m_primitiveType == TESSPRIMITIVETYPE_TRIANGLES) + log << tcu::TestLog::Message << "Note: in the following visualization(s), the u=1, v=1, w=1 corners are at the right, top, and left corners, respectively" << tcu::TestLog::EndMessage; + else if (m_primitiveType == TESSPRIMITIVETYPE_QUADS || m_primitiveType == TESSPRIMITIVETYPE_ISOLINES) + log << tcu::TestLog::Message << "Note: in the following visualization(s), u and v coordinate go left-to-right and bottom-to-top, respectively" << tcu::TestLog::EndMessage; + else + DE_ASSERT(false); + + if (compareTessCoords(log, m_primitiveType, referenceTessCoords, resultTessCoords) && (numResults >= numExpectedResults)) + ++numPassedCases; + } + } // for tessLevelCaseNdx + + return (numPassedCases == tessLevelCases.size() ? tcu::TestStatus::pass("OK") : tcu::TestStatus::fail("Some cases have failed")); +} + +TestInstance* TessCoordTest::createInstance (Context& context) const +{ + requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER | FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS); + + return new TessCoordTestInstance(context, m_primitiveType, m_spacingMode); +} + +} // anonymous + +//! Based on dEQP-GLES31.functional.tessellation.tesscoord.* +//! \note Transform feedback is replaced with SSBO. Because of that, this version allows duplicate coordinates from shader invocations. +//! The test still fails if not enough coordinates are generated, or if coordinates don't match the reference data. +tcu::TestCaseGroup* createCoordinatesTests (tcu::TestContext& testCtx) +{ + de::MovePtr group (new tcu::TestCaseGroup(testCtx, "tesscoord", "Tessellation coordinates tests")); + + for (int primitiveTypeNdx = 0; primitiveTypeNdx < TESSPRIMITIVETYPE_LAST; ++primitiveTypeNdx) + for (int spacingModeNdx = 0; spacingModeNdx < SPACINGMODE_LAST; ++spacingModeNdx) + group->addChild(new TessCoordTest(testCtx, (TessPrimitiveType)primitiveTypeNdx, (SpacingMode)spacingModeNdx)); + + return group.release(); +} + +} // tessellation +} // vkt diff --git a/external/vulkancts/modules/vulkan/tessellation/vktTessellationCoordinatesTests.hpp b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCoordinatesTests.hpp new file mode 100644 index 0000000..3dc7feb --- /dev/null +++ b/external/vulkancts/modules/vulkan/tessellation/vktTessellationCoordinatesTests.hpp @@ -0,0 +1,40 @@ +#ifndef _VKTTESSELLATIONCOORDINATESTESTS_HPP +#define _VKTTESSELLATIONCOORDINATESTESTS_HPP +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Tessellation Coordinates Tests + *//*--------------------------------------------------------------------*/ + +#include "tcuDefs.hpp" +#include "tcuTestCase.hpp" + +namespace vkt +{ +namespace tessellation +{ + +tcu::TestCaseGroup* createCoordinatesTests (tcu::TestContext& testCtx); + +} // tessellation +} // vkt + +#endif // _VKTTESSELLATIONCOORDINATESTESTS_HPP diff --git a/external/vulkancts/modules/vulkan/tessellation/vktTessellationFractionalSpacingTests.cpp b/external/vulkancts/modules/vulkan/tessellation/vktTessellationFractionalSpacingTests.cpp new file mode 100644 index 0000000..b3f9392 --- /dev/null +++ b/external/vulkancts/modules/vulkan/tessellation/vktTessellationFractionalSpacingTests.cpp @@ -0,0 +1,582 @@ +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2014 The Android Open Source Project + * Copyright (c) 2016 The Khronos Group Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *//*! + * \file + * \brief Tessellation Fractional Spacing Tests + *//*--------------------------------------------------------------------*/ + +#include "vktTessellationFractionalSpacingTests.hpp" +#include "vktTestCaseUtil.hpp" +#include "vktTessellationUtil.hpp" + +#include "tcuTestLog.hpp" + +#include "vkDefs.hpp" +#include "vkQueryUtil.hpp" +#include "vkBuilderUtil.hpp" +#include "vkTypeUtil.hpp" + +#include "deUniquePtr.hpp" +#include "deStringUtil.hpp" + +#include +#include + +namespace vkt +{ +namespace tessellation +{ + +using namespace vk; + +namespace +{ + +template +std::vector members (const std::vector& objs, MembT T::* membP) +{ + std::vector result(objs.size()); + for (int i = 0; i < static_cast(objs.size()); ++i) + result[i] = objs[i].*membP; + return result; +} + +//! Predicate functor for comparing structs by their members. +template +class MemberPred +{ +public: + MemberPred (MembT T::* membP) : m_membP(membP), m_pred(Pred()) {} + bool operator() (const T& a, const T& b) const { return m_pred(a.*m_membP, b.*m_membP); } + +private: + MembT T::* m_membP; + Pred m_pred; +}; + +//! Convenience wrapper for MemberPred, because class template arguments aren't deduced based on constructor arguments. +template