From 2c9a280e3ad6491ebc2ee9878a37bdf4fb3bfb89 Mon Sep 17 00:00:00 2001 From: Piotr Byszewski Date: Thu, 21 Jan 2021 16:53:23 +0100 Subject: [PATCH] Add decoration mismatch tests Components: Vulkan VK-GL-CTS issue: 2554 New tests: dEQP-VK.pipeline.interface_matching.decoration_mismatch.* Change-Id: I4f98d36b0568234d303e3234d78c2023f866b775 (cherry picked from commit 42fab9c7a4ff23fc086d4e5b6a8f4a009c36762c) --- AndroidGen.mk | 1 + .../cts/master/vk-master-2021-03-01/pipeline.txt | 54 ++ android/cts/master/vk-master/pipeline.txt | 54 ++ .../modules/vulkan/pipeline/CMakeLists.txt | 2 + .../pipeline/vktPipelineInterfaceMatchingTests.cpp | 962 +++++++++++++++++++++ .../pipeline/vktPipelineInterfaceMatchingTests.hpp | 38 + .../modules/vulkan/pipeline/vktPipelineTests.cpp | 2 + .../mustpass/master/vk-default/pipeline.txt | 54 ++ 8 files changed, 1167 insertions(+) create mode 100644 external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.cpp create mode 100644 external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.hpp diff --git a/AndroidGen.mk b/AndroidGen.mk index 70a073a..85c8c04 100644 --- a/AndroidGen.mk +++ b/AndroidGen.mk @@ -236,6 +236,7 @@ LOCAL_SRC_FILES := \ external/vulkancts/modules/vulkan/pipeline/vktPipelineImageUtil.cpp \ external/vulkancts/modules/vulkan/pipeline/vktPipelineImageViewTests.cpp \ external/vulkancts/modules/vulkan/pipeline/vktPipelineInputAssemblyTests.cpp \ + external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.cpp \ external/vulkancts/modules/vulkan/pipeline/vktPipelineLogicOpTests.cpp \ external/vulkancts/modules/vulkan/pipeline/vktPipelineMakeUtil.cpp \ external/vulkancts/modules/vulkan/pipeline/vktPipelineMatchedAttachmentsTests.cpp \ diff --git a/android/cts/master/vk-master-2021-03-01/pipeline.txt b/android/cts/master/vk-master-2021-03-01/pipeline.txt index c8f1add..dfdc194 100644 --- a/android/cts/master/vk-master-2021-03-01/pipeline.txt +++ b/android/cts/master/vk-master-2021-03-01/pipeline.txt @@ -19360,6 +19360,60 @@ dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.line_list_wit dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.triangle_list dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.triangle_list_with_adjacency dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.patch_list +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_geom_out_frag_in dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_in_render_pass_with_availability_bit dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_out_of_render_pass_with_availability_bit dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_out_of_render_pass_host_query_reset_with_availability_bit diff --git a/android/cts/master/vk-master/pipeline.txt b/android/cts/master/vk-master/pipeline.txt index a466ecf..595a70c 100644 --- a/android/cts/master/vk-master/pipeline.txt +++ b/android/cts/master/vk-master/pipeline.txt @@ -149667,6 +149667,60 @@ dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.line_list_wit dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.triangle_list dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.triangle_list_with_adjacency dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.patch_list +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_geom_out_frag_in dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_in_render_pass dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_out_of_render_pass dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_out_of_render_pass_host_query_reset diff --git a/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt b/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt index d23e7bf..96d2802 100644 --- a/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt +++ b/external/vulkancts/modules/vulkan/pipeline/CMakeLists.txt @@ -63,6 +63,8 @@ set(DEQP_VK_PIPELINE_SRCS vktPipelineMultisampleShaderFragmentMaskTests.hpp vktPipelineInputAssemblyTests.cpp vktPipelineInputAssemblyTests.hpp + vktPipelineInterfaceMatchingTests.cpp + vktPipelineInterfaceMatchingTests.hpp vktPipelineReferenceRenderer.cpp vktPipelineReferenceRenderer.hpp vktPipelineRenderToImageTests.cpp diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.cpp new file mode 100644 index 0000000..bd66419 --- /dev/null +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.cpp @@ -0,0 +1,962 @@ +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2021 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 vktPipelineInterfaceMatchingTests.cpp + * \brief Tests for decorations matching + *//*--------------------------------------------------------------------*/ + +#include "vktPipelineInterfaceMatchingTests.hpp" +#include "vktPipelineImageUtil.hpp" + +#include "vkBuilderUtil.hpp" +#include "vkBarrierUtil.hpp" +#include "vkImageUtil.hpp" +#include "vkMemUtil.hpp" +#include "vkQueryUtil.hpp" +#include "vkTypeUtil.hpp" +#include "vkCmdUtil.hpp" +#include "vkObjUtil.hpp" + +#include "tcuTestLog.hpp" +#include "tcuTestCase.hpp" +#include "tcuStringTemplate.hpp" + +#include + +namespace vkt +{ +namespace pipeline +{ + +using namespace vk; +using namespace de; +using namespace tcu; + +namespace +{ + +enum class TestType +{ + DECORATION_MISMATCH = 0, +}; + +enum class VecType +{ + VEC2 = 0, + VEC3, + VEC4, + IVEC2, + IVEC3, + IVEC4, + UVEC2, + UVEC3, + UVEC4, +}; + +enum class DecorationType +{ + NONE = 0, + FLAT, + NO_PERSPECTIVE, + COMPONENT0 +}; + +enum class PipelineType +{ + // all combinations with vert and frag + VERT_OUT_FRAG_IN = 0, + + // all combinations with vert, tesc, tese and frag + VERT_OUT_TESC_IN_TESE_FRAG, + VERT_TESC_TESE_OUT_FRAG_IN, + VERT_TESC_OUT_TESE_IN_FRAG, + + // all combinations with vert, geom and frag + VERT_OUT_GEOM_IN_FRAG, + VERT_GEOM_OUT_FRAG_IN, + + // all combinations with vert, tesc, tese, geom and frag + VERT_OUT_TESC_IN_TESE_GEOM_FRAG, // this won't add coverage as it is similar to VERT_OUT_TESC_IN_TESE_FRAG + //VERT_TESC_OUT_TESE_IN_GEOM_FRAG, // this won't add coverage as it is similar to VERT_TESC_OUT_TESE_IN_FRAG + VERT_TESC_TESE_OUT_GEOM_IN_FRAG, + VERT_TESC_TESE_GEOM_OUT_FRAG_IN, +}; + +enum class DefinitionType +{ + LOOSE_VARIABLE = 0, +}; + +struct TestParams +{ + TestType testType; + + VecType outVecType; + VecType inVecType; + + DecorationType outDeclDecoration; + DecorationType inDeclDecoration; + + PipelineType pipelineType; + DefinitionType definitionType; +}; + +typedef de::SharedPtr TestParamsSp; + +// helper function that check if specified pipeline is in set of pipelines +bool isPipelineOneOf(PipelineType pipelineType, std::set pipelines) +{ + return !!pipelines.count(pipelineType); +} + +class InterfaceMatchingTestInstance : public vkt::TestInstance +{ +public: + InterfaceMatchingTestInstance (Context& context, + const TestParamsSp params); + virtual ~InterfaceMatchingTestInstance (void) = default; + + tcu::TestStatus iterate(void) override; + +private: + TestParamsSp m_params; + SimpleAllocator m_alloc; + + Move m_vertexBuffer; + de::MovePtr m_vertexBufferAlloc; + Move m_resultBuffer; + de::MovePtr m_resultBufferAlloc; + + Move m_colorImage; + de::MovePtr m_colorImageAlloc; + Move m_colorAttachmentView; + Move m_renderPass; + Move m_framebuffer; + + Move m_vertShaderModule; + Move m_tescShaderModule; + Move m_teseShaderModule; + Move m_geomShaderModule; + Move m_fragShaderModule; + + Move m_pipelineLayout; + Move m_graphicsPipeline; + + Move m_cmdPool; + Move m_cmdBuffer; +}; + +InterfaceMatchingTestInstance::InterfaceMatchingTestInstance(Context& context, const TestParamsSp params) + : vkt::TestInstance(context) + , m_params(params) + , m_alloc(context.getDeviceInterface(), context.getDevice(), + getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())) +{ +} + +tcu::TestStatus InterfaceMatchingTestInstance::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(); + const VkComponentMapping componentMappingRGBA = makeComponentMappingRGBA(); + VkImageSubresourceRange subresourceRange { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }; + const VkFormat colorFormat (VK_FORMAT_R8G8B8A8_UNORM); + const tcu::UVec2 renderSize (16, 16); + const tcu::TextureFormat textureFormat = mapVkFormat(colorFormat); + const VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * textureFormat.getPixelSize(); + const VkDeviceSize vertexBufferOffset = 0; + + // create color image that is used as a color attachment + { + const VkImageCreateInfo colorImageParams + { + VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkImageCreateFlags flags; + VK_IMAGE_TYPE_2D, // VkImageType imageType; + colorFormat, // VkFormat format; + { renderSize.x(), renderSize.y(), 1u }, // VkExtent3D extent; + 1u, // deUint32 mipLevels; + 1u, // deUint32 arrayLayers; + VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; + VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; + VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage; + VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; + 1u, // deUint32 queueFamilyIndexCount; + &queueFamilyIndex, // const deUint32* pQueueFamilyIndices; + VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; + }; + + m_colorImage = createImage(vk, device, &colorImageParams); + + // allocate and bind color image memory + m_colorImageAlloc = m_alloc.allocate(getImageMemoryRequirements(vk, device, *m_colorImage), MemoryRequirement::Any); + VK_CHECK(vk.bindImageMemory(device, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset())); + } + + // create color attachment view + { + const VkImageViewCreateInfo colorAttachmentViewParams + { + VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkImageViewCreateFlags flags; + *m_colorImage, // VkImage image; + VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; + colorFormat, // VkFormat format; + componentMappingRGBA, // VkComponentMapping components; + subresourceRange // VkImageSubresourceRange subresourceRange; + }; + + m_colorAttachmentView = createImageView(vk, device, &colorAttachmentViewParams); + } + + // create render pass + m_renderPass = makeRenderPass(vk, device, colorFormat); + + // create framebuffer + { + const VkFramebufferCreateInfo framebufferParams + { + VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkFramebufferCreateFlags flags; + *m_renderPass, // VkRenderPass renderPass; + 1u, // deUint32 attachmentCount; + &m_colorAttachmentView.get(), // const VkImageView* pAttachments; + (deUint32)renderSize.x(), // deUint32 width; + (deUint32)renderSize.y(), // deUint32 height; + 1u // deUint32 layers; + }; + + m_framebuffer = createFramebuffer(vk, device, &framebufferParams); + } + + // create pipeline layout + { + const VkPipelineLayoutCreateInfo pipelineLayoutParams + { + VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; + DE_NULL, // const void* pNext; + 0u, // VkPipelineLayoutCreateFlags flags; + 0u, // deUint32 setLayoutCount; + DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; + 0u, // deUint32 pushConstantRangeCount; + DE_NULL // const VkPushConstantRange* pPushConstantRanges; + }; + + m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutParams); + } + + // create pipeline + bool useTess = isPipelineOneOf(m_params->pipelineType, { + PipelineType::VERT_OUT_TESC_IN_TESE_FRAG, + PipelineType::VERT_TESC_TESE_OUT_FRAG_IN, + PipelineType::VERT_TESC_OUT_TESE_IN_FRAG, + PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG, + PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG, + PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN }); + + m_vertShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0); + m_fragShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("frag"), 0); + if (useTess) + { + m_tescShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tesc"), 0); + m_teseShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tese"), 0); + } + + if (isPipelineOneOf(m_params->pipelineType, { + PipelineType::VERT_OUT_GEOM_IN_FRAG, + PipelineType::VERT_GEOM_OUT_FRAG_IN, + PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG, + PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG, + PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN })) + { + m_geomShaderModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("geom"), 0); + } + m_graphicsPipeline = makeGraphicsPipeline( + vk, // DeviceInterface& vk + device, // VkDevice device + *m_pipelineLayout, // VkPipelineLayout pipelineLayout + *m_vertShaderModule, // VkShaderModule vertexShaderModule + *m_tescShaderModule, // VkShaderModule tessellationControlModule + *m_teseShaderModule, // VkShaderModule tessellationEvalModule + *m_geomShaderModule, // VkShaderModule geometryShaderModule + *m_fragShaderModule, // VkShaderModule fragmentShaderModule + *m_renderPass, // VkRenderPass renderPass + { makeViewport(renderSize) }, // std::vector& viewports + { makeRect2D(renderSize) }, // std::vector& scissors + useTess ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, // VkPrimitiveTopology topology + 0u, // const deUint32 subpass + useTess ? 1u : 0u); // const deUint32 patchControlPoints + + // create vertex buffer + { + std::vector vertices + { + 1.0f, -1.0f, 0.0f, 1.0f, + -1.0f, 1.0f, 0.0f, 1.0f, + -1.0f, -1.0f, 0.0f, 1.0f, + }; + const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(vertices.size() * sizeof(float), VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); + + m_vertexBuffer = createBuffer(vk, device, &bufferCreateInfo); + m_vertexBufferAlloc = m_alloc.allocate(getBufferMemoryRequirements(vk, device, *m_vertexBuffer), MemoryRequirement::HostVisible); + VK_CHECK(vk.bindBufferMemory(device, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset())); + + deMemcpy(m_vertexBufferAlloc->getHostPtr(), vertices.data(), vertices.size() * sizeof(float)); + flushAlloc(vk, device, *m_vertexBufferAlloc); + } + + // create buffer to which we will grab rendered result + { + const VkBufferCreateInfo bufferCreateInfo = makeBufferCreateInfo(pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT); + + m_resultBuffer = createBuffer(vk, device, &bufferCreateInfo); + m_resultBufferAlloc = m_alloc.allocate(getBufferMemoryRequirements(vk, device, *m_resultBuffer), MemoryRequirement::HostVisible); + VK_CHECK(vk.bindBufferMemory(device, *m_resultBuffer, m_resultBufferAlloc->getMemory(), m_resultBufferAlloc->getOffset())); + } + + // create command pool and command buffer + m_cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); + m_cmdBuffer = allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); + + // record command buffer + beginCommandBuffer(vk, *m_cmdBuffer, 0u); + + // change image layout so we can use it as color attachment + const VkImageMemoryBarrier attachmentLayoutBarrier = makeImageMemoryBarrier( + VK_ACCESS_NONE_KHR, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + *m_colorImage, subresourceRange); + vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, + 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &attachmentLayoutBarrier); + + // render single triangle + beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(renderSize), Vec4(0.0f, 0.0f, 0.0f, 1.0f)); + + vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline); + vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &*m_vertexBuffer, &vertexBufferOffset); + vk.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0); + + endRenderPass(vk, *m_cmdBuffer); + + copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, *m_resultBuffer, tcu::IVec2(renderSize.x(), renderSize.y())); + + endCommandBuffer(vk, *m_cmdBuffer); + + // submit commands + submitCommandsAndWait(vk, device, queue, *m_cmdBuffer); + + // read buffer data + invalidateAlloc(vk, device, *m_resultBufferAlloc); + + // validate result - verification is done in glsl, just checking + // two texels, if test passed then r channel should be set to 255 + const unsigned char* bufferPtr = static_cast(m_resultBufferAlloc->getHostPtr()); + if ((bufferPtr[0] > 254) && (bufferPtr[renderSize.x()*4+8] > 254)) + return TestStatus::pass("Pass"); + + const tcu::ConstPixelBufferAccess resultAccess(textureFormat, tcu::IVec3((int)renderSize.x(), (int)renderSize.y(), 1u), bufferPtr); + TestLog& log = m_context.getTestContext().getLog(); + log << tcu::TestLog::ImageSet("Result of rendering", "") + << TestLog::Image("Result", "", resultAccess) + << tcu::TestLog::EndImageSet; + + return TestStatus::fail("Fail"); +} + +class InterfaceMatchingTestCase : public vkt::TestCase +{ +public: + InterfaceMatchingTestCase (tcu::TestContext& testContext, + TestParamsSp params); + virtual ~InterfaceMatchingTestCase (void) = default; + + void initPrograms (SourceCollections& sourceCollections) const override; + void checkSupport (Context& context) const override; + TestInstance* createInstance (Context& context) const override; + +protected: + + enum class ComponentType + { + FLOAT = 0, + INT, + UINT + }; + + struct VecData + { + std::string glslType; + ComponentType componentType; + deUint32 componentsCount; + std::string components[4]; + }; + + struct DecorationData + { + std::string namePart; + std::string glslDecoration; + std::string glslComponent; + }; + + // helper structure used during construction of in/out declaration + struct PipelineData + { + bool outDeclArray; + bool inFlatDecoration; // needed for frag in + bool inDeclArray; + }; + + typedef std::map SpecializationMap; + + std::string genOutAssignment (const std::string& variableName, const VecData& outVecData) const; + std::string genInVerification (const std::string& variableName, const VecData& outVecData, const VecData& inVecData) const; + + const VecData& getVecData (VecType vecType) const; + const DecorationData& getDecorationData (DecorationType decorationType) const; + const PipelineData& getPipelineData (PipelineType pipelineType) const; + std::string generateName (const TestParams& testParams) const; + +private: + + const TestParamsSp m_params; +}; + +InterfaceMatchingTestCase::InterfaceMatchingTestCase(tcu::TestContext& testContext, + TestParamsSp params) + : vkt::TestCase (testContext, generateName(*params), "") + , m_params (params) +{ +} + +void InterfaceMatchingTestCase::initPrograms(SourceCollections& sourceCollections) const +{ + GlslSourceCollection& glslSources = sourceCollections.glslSources; + const VecData& outVecData = getVecData(m_params->outVecType); + const VecData& inVecData = getVecData(m_params->inVecType); + const DecorationData& outDecorationData = getDecorationData(m_params->outDeclDecoration); + const DecorationData& inDecorationData = getDecorationData(m_params->inDeclDecoration); + const PipelineData& pipelineData = getPipelineData(m_params->pipelineType); + + // deterimine if decoration or array is needed for in/out declarations + const std::string outDeclArray = pipelineData.outDeclArray ? "[]" : ""; + const std::string inDeclArray = pipelineData.inDeclArray ? "[]" : ""; + const std::string variableToAssignArray = pipelineData.outDeclArray ? "[gl_InvocationID]" : ""; + const std::string variableToVerifyArray = pipelineData.inDeclArray ? "[0]" : ""; + + std::string outDecoration = ""; + std::string inDecoration = pipelineData.inFlatDecoration ? "flat " : ""; + std::string outComponent = outDecorationData.glslComponent; + std::string inComponent = inDecorationData.glslComponent; + if (m_params->testType == TestType::DECORATION_MISMATCH) + { + outDecoration = outDecorationData.glslDecoration; + inDecoration = inDecorationData.glslDecoration; + } + + std::string outDeclaration; + std::string inDeclaration; + std::string variableToAssignName; + std::string variableToVerifyName; + + // generate in/out declarations + switch (m_params->definitionType) + { + case DefinitionType::LOOSE_VARIABLE: + outDeclaration = "layout(location = 0" + outDecorationData.glslComponent + ") out " + outDecoration + outVecData.glslType + " looseVariable" + outDeclArray + ";\n"; + inDeclaration = "layout(location = 0" + inDecorationData.glslComponent + ") in " + inDecoration + inVecData.glslType + " looseVariable" + inDeclArray + ";\n"; + variableToAssignName = "looseVariable" + variableToAssignArray; + variableToVerifyName = "looseVariable" + variableToVerifyArray; + break; + + default: + DE_ASSERT(DE_FALSE); + } + + std::string outValueAssignment = genOutAssignment (variableToAssignName, outVecData); + std::string inValueVerification = genInVerification(variableToVerifyName, outVecData, inVecData); + + // create specialization map and grab references to both + // values so we dont have to index into it in every case + SpecializationMap specializationMap + { + { "DECLARATIONS", "" }, + { "OPERATIONS", "" }, + }; + std::string& declarations = specializationMap["DECLARATIONS"]; + std::string& operations = specializationMap["OPERATIONS"]; + + // define vertex shader source + if (isPipelineOneOf(m_params->pipelineType, { + PipelineType::VERT_OUT_FRAG_IN, + PipelineType::VERT_OUT_TESC_IN_TESE_FRAG, + PipelineType::VERT_OUT_GEOM_IN_FRAG, + PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG })) + { + declarations = outDeclaration; + operations = outValueAssignment; + } + // else passthrough source + + tcu::StringTemplate vertTemplate( + "#version 450\n" + "layout(location = 0) in vec4 inPosition;\n" + "${DECLARATIONS}" + "void main(void)\n" + "{\n" + " gl_Position = inPosition;\n" + "${OPERATIONS}" + "}\n"); + glslSources.add("vert") << glu::VertexSource(vertTemplate.specialize(specializationMap)); + + // define tesselation control shader source + bool tescNeeded = DE_FALSE; + switch (m_params->pipelineType) + { + case PipelineType::VERT_TESC_OUT_TESE_IN_FRAG: + declarations = outDeclaration; + operations = outValueAssignment; + tescNeeded = DE_TRUE; + break; + + case PipelineType::VERT_OUT_TESC_IN_TESE_FRAG: + case PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG: + declarations = inDeclaration + + "layout(location = 0) out float outResult[];\n"; + operations = " float result;\n" + + inValueVerification + + " outResult[gl_InvocationID] = result;\n"; + tescNeeded = DE_TRUE; + break; + + case PipelineType::VERT_TESC_TESE_OUT_FRAG_IN: + case PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG: + case PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN: + // passthrough sources + tescNeeded = DE_TRUE; + break; + + default: + break; + } + + std::string tescSource = tescNeeded ? + StringTemplate( + "#version 450\n" + "#extension GL_EXT_tessellation_shader : require\n\n" + "layout(vertices = 1) out;\n\n" + "${DECLARATIONS}" + "void main(void)\n" + "{\n" + " gl_TessLevelInner[0] = 1.0;\n" + " gl_TessLevelOuter[0] = 1.0;\n" + " gl_TessLevelOuter[1] = 1.0;\n" + " gl_TessLevelOuter[2] = 1.0;\n" + "${OPERATIONS}" + "}\n").specialize(specializationMap) + : ""; + + // define tesselation evaluation shader source + bool teseNeeded = DE_FALSE; + switch (m_params->pipelineType) + { + case PipelineType::VERT_TESC_TESE_OUT_FRAG_IN: + case PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG: + declarations = outDeclaration; + operations = outValueAssignment; + teseNeeded = DE_TRUE; + break; + + case PipelineType::VERT_TESC_OUT_TESE_IN_FRAG: + declarations = inDeclaration + + "layout(location = 0) out float outResult;\n"; + operations = " float result;\n" + + inValueVerification + + " outResult = result;\n"; + teseNeeded = DE_TRUE; + break; + + case PipelineType::VERT_OUT_TESC_IN_TESE_FRAG: + case PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG: + declarations = "layout(location = 0) in float inResult[];\n" + "layout(location = 0) out float outResult;\n"; + operations = " outResult = inResult[0];\n"; + teseNeeded = DE_TRUE; + break; + + case PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN: + // passthrough sources + teseNeeded = DE_TRUE; + break; + + default: + break; + } + + std::string teseSource = teseNeeded ? + StringTemplate( + "#version 450\n" + "#extension GL_EXT_tessellation_shader : require\n\n" + "layout(triangles) in;\n" + "${DECLARATIONS}" + "void main(void)\n" + "{\n" + " gl_Position = vec4(gl_TessCoord.xy * 2.0 - 1.0, 0.0, 1.0);\n" + "${OPERATIONS}" + "}\n").specialize(specializationMap) + : ""; + + DE_ASSERT(tescSource.empty() == teseSource.empty()); + if (!tescSource.empty()) + { + glslSources.add("tesc") << glu::TessellationControlSource(tescSource); + glslSources.add("tese") << glu::TessellationEvaluationSource(teseSource); + } + + // define geometry shader source + bool geomNeeded = DE_FALSE; + switch (m_params->pipelineType) + { + case PipelineType::VERT_GEOM_OUT_FRAG_IN: + case PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN: + declarations = outDeclaration; + operations = outValueAssignment; + geomNeeded = DE_TRUE; + break; + + case PipelineType::VERT_OUT_GEOM_IN_FRAG: + case PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG: + declarations = inDeclaration + + "layout(location = 0) out float result;\n"; + operations = inValueVerification; + geomNeeded = DE_TRUE; + break; + + case PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG: + declarations = "layout(location = 0) in float inResult[];\n" + "layout(location = 0) out float outResult;\n"; + operations = " outResult = inResult[0];\n"; + geomNeeded = DE_TRUE; + break; + + default: + break; + } + + if (geomNeeded) + { + tcu::StringTemplate geomTemplate( + "#version 450\n" + "#extension GL_EXT_geometry_shader : require\n" + "layout(triangles) in;\n" + "layout(triangle_strip, max_vertices=3) out;\n" + "${DECLARATIONS}" + "void main(void)\n" + "{\n" + "${OPERATIONS}" + " gl_Position = vec4( 1.0, -1.0, 0.0, 1.0);\n" + " EmitVertex();\n" + "${OPERATIONS}" + " gl_Position = vec4(-1.0, 1.0, 0.0, 1.0);\n" + " EmitVertex();\n" + "${OPERATIONS}" + " gl_Position = vec4(-1.0, -1.0, 0.0, 1.0);\n" + " EmitVertex();\n" + " EndPrimitive();\n" + "}\n"); + glslSources.add("geom") << glu::GeometrySource(geomTemplate.specialize(specializationMap)); + } + + // define fragment shader source + if (isPipelineOneOf(m_params->pipelineType, { + PipelineType::VERT_OUT_FRAG_IN, + PipelineType::VERT_TESC_TESE_OUT_FRAG_IN, + PipelineType::VERT_GEOM_OUT_FRAG_IN, + PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN })) + { + declarations = inDeclaration; + operations = " float result = 0.0;\n" + + inValueVerification; + } + else // passthrough source + { + declarations = "layout(location = 0) in flat float result;\n"; + operations = ""; + } + + tcu::StringTemplate fragTemplate( + "#version 450\n" + "layout(location = 0) out vec4 fragColor;\n" + "${DECLARATIONS}" + "void main(void)\n" + "{\n" + "${OPERATIONS}" + " fragColor = vec4(result);\n" + "}\n"); + glslSources.add("frag") << glu::FragmentSource(fragTemplate.specialize(specializationMap)); +} + +std::string InterfaceMatchingTestCase::genOutAssignment(const std::string& variableName, const VecData& outVecData) const +{ + // generate value assignment to out variable; + // for vec2/looseVariable this will generate: + // "looseVariable = vec2(-2.0, 3.0);" + + // define separators to avoid if statements in loop + std::string outSeparator(", "); + std::string endSeparator(""); + std::vector outSeparators(4, &outSeparator); + outSeparators[outVecData.componentsCount - 1] = &endSeparator; + + // generate value assignment + std::string outValueAssignment = std::string(" ") + variableName + " = " + outVecData.glslType + "("; + for (deUint32 i = 0; i < outVecData.componentsCount; ++i) + outValueAssignment += outVecData.components[i] + *outSeparators[i]; + + return outValueAssignment + ");\n"; +} + +std::string InterfaceMatchingTestCase::genInVerification(const std::string& variableName, const VecData& outVecData, const VecData& inVecData) const +{ + // generate value verification; + // note that input has same or less components then output; + // for vec2/looseVariable this will generate: + // "result = float(abs(looseVariable.x - -2.0) < eps) *" + // "float(abs(looseVariable.y - 3.0) < eps);\n" + + static const std::string componentNames[] = { "x", "y", "z", "w" }; + + // define separators to avoid if statements in loop + std::string inSeparator (" *\n\t\t "); + std::string endSeparator (""); + std::string* inSeparators[] { &inSeparator, &inSeparator, &inSeparator, &endSeparator }; + + inSeparators[inVecData.componentsCount - 1] = &endSeparator; + + std::string inValueVerification(" result = "); + tcu::StringTemplate verificationTemplate( + inVecData.componentType == ComponentType::FLOAT ? + "float(abs(" + variableName + ".${COMPONENT} - ${VALUE}) < 0.001)" : + "float(" + variableName + ".${COMPONENT} == ${VALUE})"); + + // verify each component using formula for float or int + for (deUint32 i = 0; i < inVecData.componentsCount; ++i) + { + inValueVerification += verificationTemplate.specialize({ + { "COMPONENT", componentNames[i] }, + { "VALUE", outVecData.components[i] } + }); + inValueVerification += *inSeparators[i]; + } + + return inValueVerification + ";\n"; +} + +void InterfaceMatchingTestCase::checkSupport(Context& context) const +{ + const InstanceInterface& vki = context.getInstanceInterface(); + const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); + const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physicalDevice); + + if (isPipelineOneOf(m_params->pipelineType, { + PipelineType::VERT_OUT_TESC_IN_TESE_FRAG, + PipelineType::VERT_TESC_TESE_OUT_FRAG_IN, + PipelineType::VERT_TESC_OUT_TESE_IN_FRAG, + PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG, + PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG, + PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN })) + if (!features.tessellationShader) + TCU_THROW(NotSupportedError, "Tessellation shader not supported"); + + if (isPipelineOneOf(m_params->pipelineType, { + PipelineType::VERT_OUT_GEOM_IN_FRAG, + PipelineType::VERT_GEOM_OUT_FRAG_IN, + PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG, + PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG, + PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN })) + if (!features.geometryShader) + TCU_THROW(NotSupportedError, "Geometry shader not supported"); +} + +TestInstance* InterfaceMatchingTestCase::createInstance(Context& context) const +{ + return new InterfaceMatchingTestInstance(context, m_params); +} + +const InterfaceMatchingTestCase::VecData& InterfaceMatchingTestCase::getVecData(VecType vecType) const +{ + static const std::map vecDataMap + { + { VecType::VEC2, { "vec2", ComponentType::FLOAT, 2, { "-2.0", "3.0", "", "" } } }, + { VecType::VEC3, { "vec3", ComponentType::FLOAT, 3, { "-3.0", "2.0", "5.0", "" } } }, + { VecType::VEC4, { "vec4", ComponentType::FLOAT, 4, { "-4.0", "-9.0", "3.0", "7.0" } } }, + { VecType::IVEC2, { "ivec2", ComponentType::INT, 2, { "-4", "8", "", "" } } }, + { VecType::IVEC3, { "ivec3", ComponentType::INT, 3, { "-5", "10", "15", "" } } }, + { VecType::IVEC4, { "ivec4", ComponentType::INT, 4, { "-16", "12", "20", "80" } } }, + { VecType::UVEC2, { "uvec2", ComponentType::UINT, 2, { "2", "8", "", "" } } }, + { VecType::UVEC3, { "uvec3", ComponentType::UINT, 3, { "3", "9", "27", "" } } }, + { VecType::UVEC4, { "uvec4", ComponentType::UINT, 4, { "4", "16", "64", "256" } } }, + }; + + DE_ASSERT(vecDataMap.find(vecType) != vecDataMap.end()); + return vecDataMap.at(vecType); +} + +const InterfaceMatchingTestCase::DecorationData& InterfaceMatchingTestCase::getDecorationData(DecorationType decorationType) const +{ + static const std::map decorationDataMap + { + { DecorationType::NONE, { "none", "", "" } }, + { DecorationType::FLAT, { "flat", "flat ", "" } }, + { DecorationType::NO_PERSPECTIVE, { "noperspective", "noperspective ", "" } }, + { DecorationType::COMPONENT0, { "component0", "", ", component = 0 " } }, + }; + + DE_ASSERT(decorationDataMap.find(decorationType) != decorationDataMap.end()); + return decorationDataMap.at(decorationType); +} + +const InterfaceMatchingTestCase::PipelineData& InterfaceMatchingTestCase::getPipelineData(PipelineType pipelineType) const +{ + // pipelineDataMap is used to simplify generation of declarations in glsl + // it represent fallowing rules: + // * for case where tesc outputs variable it must be declarred as an array + // * when frag input variable is verified we need to use flat interpolation + // * all stages except for frag need input to be array (note: we do not use input in vert) + + static const std::map pipelineDataMap + { + // outArr inFlat inArr + { PipelineType::VERT_OUT_FRAG_IN, { 0, 1, 0 } }, + { PipelineType::VERT_OUT_TESC_IN_TESE_FRAG, { 0, 0, 1 } }, + { PipelineType::VERT_TESC_TESE_OUT_FRAG_IN, { 0, 1, 0 } }, + { PipelineType::VERT_TESC_OUT_TESE_IN_FRAG, { 1, 0, 1 } }, + { PipelineType::VERT_OUT_GEOM_IN_FRAG, { 0, 0, 1 } }, + { PipelineType::VERT_GEOM_OUT_FRAG_IN, { 0, 1, 0 } }, + { PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG, { 0, 0, 1 } }, + { PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG, { 0, 0, 1 } }, + { PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN, { 0, 1, 0 } }, + }; + + DE_ASSERT(pipelineDataMap.find(pipelineType) != pipelineDataMap.end()); + return pipelineDataMap.at(pipelineType); +} + +std::string InterfaceMatchingTestCase::generateName(const TestParams& testParams) const +{ + static const std::map pipelineTypeMap + { + { PipelineType::VERT_OUT_FRAG_IN, "vert_out_frag_in" }, + { PipelineType::VERT_OUT_TESC_IN_TESE_FRAG, "vert_out_tesc_in_tese_frag" }, + { PipelineType::VERT_TESC_TESE_OUT_FRAG_IN, "vert_tesc_tese_out_frag_in" }, + { PipelineType::VERT_TESC_OUT_TESE_IN_FRAG, "vert_tesc_out_tese_in_frag" }, + { PipelineType::VERT_OUT_GEOM_IN_FRAG, "vert_out_geom_in_frag" }, + { PipelineType::VERT_GEOM_OUT_FRAG_IN, "vert_geom_out_frag_in" }, + { PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG, "vert_out_tesc_in_tese_geom_frag" }, + { PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG, "vert_tesc_tese_out_geom_in_frag" }, + { PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN, "vert_tesc_tese_geom_out_frag_in" }, + }; + + static const std::map definitionTypeMap + { + { DefinitionType::LOOSE_VARIABLE, "loose_variable" }, + }; + + DE_ASSERT(pipelineTypeMap.find(testParams.pipelineType) != pipelineTypeMap.end()); + DE_ASSERT(definitionTypeMap.find(testParams.definitionType) != definitionTypeMap.end()); + + std::string caseName; + caseName = "out_" + getDecorationData(testParams.outDeclDecoration).namePart + + "_in_" + getDecorationData(testParams.inDeclDecoration).namePart; + + return caseName + "_" + + definitionTypeMap.at(testParams.definitionType) + "_" + + pipelineTypeMap.at(testParams.pipelineType); +}; + +} // anonymous + +tcu::TestCaseGroup* createInterfaceMatchingTests(tcu::TestContext& testCtx) +{ + PipelineType pipelineTypeList[] + { + PipelineType::VERT_OUT_FRAG_IN, + PipelineType::VERT_OUT_TESC_IN_TESE_FRAG, + PipelineType::VERT_TESC_TESE_OUT_FRAG_IN, + PipelineType::VERT_TESC_OUT_TESE_IN_FRAG, + PipelineType::VERT_OUT_GEOM_IN_FRAG, + PipelineType::VERT_GEOM_OUT_FRAG_IN, + PipelineType::VERT_OUT_TESC_IN_TESE_GEOM_FRAG, + PipelineType::VERT_TESC_TESE_OUT_GEOM_IN_FRAG, + PipelineType::VERT_TESC_TESE_GEOM_OUT_FRAG_IN, + }; + + DefinitionType definitionsTypeList[] + { + DefinitionType::LOOSE_VARIABLE, + }; + + de::MovePtr testGroup(new tcu::TestCaseGroup(testCtx, "interface_matching", "")); + + std::vector > decorationPairs + { + { DecorationType::NONE, DecorationType::NO_PERSPECTIVE }, + { DecorationType::NONE, DecorationType::FLAT }, + { DecorationType::FLAT, DecorationType::NO_PERSPECTIVE }, + { DecorationType::FLAT, DecorationType::NONE }, + { DecorationType::NO_PERSPECTIVE, DecorationType::FLAT }, + { DecorationType::NO_PERSPECTIVE, DecorationType::NONE }, + { DecorationType::COMPONENT0, DecorationType::NONE }, + { DecorationType::NONE, DecorationType::COMPONENT0 }, + }; + + de::MovePtr decorationMismatching(new tcu::TestCaseGroup(testCtx, "decoration_mismatch", "Decoration mismatch tests")); + for (PipelineType stageType : pipelineTypeList) + for (DefinitionType defType : definitionsTypeList) + for (const auto& decoration : decorationPairs) + { + // tests component = 0 only for loose variables or member of block + if (((decoration.first == DecorationType::COMPONENT0) || + (decoration.second == DecorationType::COMPONENT0)) && + (defType == DefinitionType::LOOSE_VARIABLE)) + continue; + + auto testParams = new TestParams + { + TestType::DECORATION_MISMATCH, + VecType::VEC4, + VecType::VEC4, + decoration.first, + decoration.second, + stageType, + defType + }; + decorationMismatching->addChild(new InterfaceMatchingTestCase(testCtx, TestParamsSp(testParams))); + } + + testGroup->addChild(decorationMismatching.release()); + return testGroup.release(); +} + +} // pipeline +} // vkt diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.hpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.hpp new file mode 100644 index 0000000..0282763 --- /dev/null +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineInterfaceMatchingTests.hpp @@ -0,0 +1,38 @@ +#ifndef _VKTPIPELINEINTERFACEMATCHINGTESTS_HPP +#define _VKTPIPELINEINTERFACEMATCHINGTESTS_HPP +/*------------------------------------------------------------------------ + * Vulkan Conformance Tests + * ------------------------ + * + * Copyright (c) 2021 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 vktPipelineInterfaceMatchingTests.hpp + * \brief Tests for decorations matching + *//*--------------------------------------------------------------------*/ + +#include "vktTestCase.hpp" + +namespace vkt +{ +namespace pipeline +{ + +tcu::TestCaseGroup* createInterfaceMatchingTests (tcu::TestContext& testCtx); + +} // pipeline +} // vkt + +#endif // _VKTPIPELINEINTERFACEMATCHINGTESTS_HPP diff --git a/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp b/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp index 7197c79..5f97cd2 100644 --- a/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp +++ b/external/vulkancts/modules/vulkan/pipeline/vktPipelineTests.cpp @@ -31,6 +31,7 @@ #include "vktPipelineLogicOpTests.hpp" #include "vktPipelineImageTests.hpp" #include "vktPipelineInputAssemblyTests.hpp" +#include "vktPipelineInterfaceMatchingTests.hpp" #include "vktPipelineSamplerTests.hpp" #include "vktPipelineImageViewTests.hpp" #include "vktPipelinePushConstantTests.hpp" @@ -91,6 +92,7 @@ void createChildren (tcu::TestCaseGroup* pipelineTests) pipelineTests->addChild(createMultisampleShaderBuiltInTests (testCtx)); pipelineTests->addChild(createTestGroup (testCtx, "vertex_input", "", createVertexInputTests)); pipelineTests->addChild(createInputAssemblyTests (testCtx)); + pipelineTests->addChild(createInterfaceMatchingTests (testCtx)); pipelineTests->addChild(createTimestampTests (testCtx)); pipelineTests->addChild(createCacheTests (testCtx)); pipelineTests->addChild(createRenderToImageTests (testCtx)); diff --git a/external/vulkancts/mustpass/master/vk-default/pipeline.txt b/external/vulkancts/mustpass/master/vk-default/pipeline.txt index ca2f7c6..10c3456 100644 --- a/external/vulkancts/mustpass/master/vk-default/pipeline.txt +++ b/external/vulkancts/mustpass/master/vk-default/pipeline.txt @@ -149678,6 +149678,60 @@ dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.line_list_wit dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.triangle_list dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.triangle_list_with_adjacency dEQP-VK.pipeline.input_assembly.primitive_restart.index_type_uint8.patch_list +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_tesc_in_tese_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_out_tese_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_out_tesc_in_tese_geom_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_out_geom_in_frag +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_noperspective_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_none_in_flat_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_noperspective_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_flat_in_none_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_flat_loose_variable_vert_tesc_tese_geom_out_frag_in +dEQP-VK.pipeline.interface_matching.decoration_mismatch.out_noperspective_in_none_loose_variable_vert_tesc_tese_geom_out_frag_in dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_in_render_pass dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_out_of_render_pass dEQP-VK.pipeline.timestamp.basic_graphics_tests.vertex_input_stage_out_of_render_pass_host_query_reset -- 2.7.4