Test winding order of primitive topologies
authorPiotr Byszewski <piotr.byszewski@mobica.com>
Wed, 15 Jan 2020 16:14:24 +0000 (17:14 +0100)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Thu, 19 Mar 2020 08:44:50 +0000 (04:44 -0400)
Components: Vulkan

VK-GL-CTS issue: 1713

Affects:
dEQP-VK.transform_feedback.simple.winding_*

Change-Id: Ia5878614dd3e380e6b220d2be777670de2898e58

android/cts/master/vk-master-2020-03-01.txt
android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/transform_feedback/vktTransformFeedbackSimpleTests.cpp
external/vulkancts/mustpass/master/vk-default-no-waivers.txt
external/vulkancts/mustpass/master/vk-default.txt

index ce10fe4..45c58ff 100644 (file)
@@ -183496,18 +183496,46 @@ dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_beginqueryindexed_streamid_0_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8_131072
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_12
+dEQP-VK.transform_feedback.simple.winding_line_list_6
+dEQP-VK.transform_feedback.simple.winding_line_list_8
+dEQP-VK.transform_feedback.simple.winding_line_list_10
+dEQP-VK.transform_feedback.simple.winding_line_list_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_6
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_8
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_10
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_12
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_patch_list_6
+dEQP-VK.transform_feedback.simple.winding_patch_list_8
+dEQP-VK.transform_feedback.simple.winding_patch_list_10
+dEQP-VK.transform_feedback.simple.winding_patch_list_12
 dEQP-VK.transform_feedback.simple.draw_indirect_16
 dEQP-VK.transform_feedback.simple.draw_indirect_beginqueryindexed_streamid_0_16
 dEQP-VK.transform_feedback.simple.draw_indirect_endqueryindexed_streamid_0_16
index 2d58d0a..631f174 100644 (file)
@@ -579910,18 +579910,46 @@ dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_beginqueryindexed_streamid_0_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8_131072
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_12
+dEQP-VK.transform_feedback.simple.winding_line_list_6
+dEQP-VK.transform_feedback.simple.winding_line_list_8
+dEQP-VK.transform_feedback.simple.winding_line_list_10
+dEQP-VK.transform_feedback.simple.winding_line_list_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_6
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_8
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_10
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_12
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_patch_list_6
+dEQP-VK.transform_feedback.simple.winding_patch_list_8
+dEQP-VK.transform_feedback.simple.winding_patch_list_10
+dEQP-VK.transform_feedback.simple.winding_patch_list_12
 dEQP-VK.transform_feedback.simple.draw_indirect_16
 dEQP-VK.transform_feedback.simple.draw_indirect_beginqueryindexed_streamid_0_16
 dEQP-VK.transform_feedback.simple.draw_indirect_endqueryindexed_streamid_0_16
index 2aff013..14505d4 100644 (file)
@@ -42,6 +42,8 @@
 #include "tcuRGBA.hpp"
 
 #include <iostream>
+#include <functional>
+#include <set>
 
 namespace vkt
 {
@@ -66,7 +68,16 @@ enum TestType
        TEST_TYPE_XFB_CLIPDISTANCE,
        TEST_TYPE_XFB_CULLDISTANCE,
        TEST_TYPE_XFB_CLIP_AND_CULL,
+       TEST_TYPE_LINE_LIST,
+       TEST_TYPE_LINE_STRIP,
+       TEST_TYPE_TRIANGLE_LIST,
+       TEST_TYPE_TRIANGLE_STRIP,
+       TEST_TYPE_TRIANGLE_FAN,
+       TEST_TYPE_LINE_LIST_ADJACENCY,
+       TEST_TYPE_LINE_STRIP_ADJACENCY,
        TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+       TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+       TEST_TYPE_PATCH_LIST,
        TEST_TYPE_STREAMS_POINTSIZE,
        TEST_TYPE_STREAMS_CLIPDISTANCE,
        TEST_TYPE_STREAMS_CULLDISTANCE,
@@ -134,6 +145,8 @@ Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&               vk,
                                                                           const VkPipelineLayout               pipelineLayout,
                                                                           const VkRenderPass                   renderPass,
                                                                           const VkShaderModule                 vertexModule,
+                                                                          const VkShaderModule                 tessellationControlModule,
+                                                                          const VkShaderModule                 tessellationEvalModule,
                                                                           const VkShaderModule                 geometryModule,
                                                                           const VkShaderModule                 fragmendModule,
                                                                           const VkExtent2D                             renderSize,
@@ -182,22 +195,22 @@ Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&             vk,
        };
        const VkPipelineRasterizationStateCreateInfo*                   rasterizationStateCreateInfoPtr         = (rasterizationStreamPtr == DE_NULL) ? DE_NULL : &rasterizationStateCreateInfo;
 
-       return makeGraphicsPipeline(vk,                                                                 // const DeviceInterface&                                                       vk
-                                                               device,                                                         // const VkDevice                                                                       device
-                                                               pipelineLayout,                                         // const VkPipelineLayout                                                       pipelineLayout
-                                                               vertexModule,                                           // const VkShaderModule                                                         vertexShaderModule
-                                                               DE_NULL,                                                        // const VkShaderModule                                                         tessellationControlModule
-                                                               DE_NULL,                                                        // const VkShaderModule                                                         tessellationEvalModule
-                                                               geometryModule,                                         // const VkShaderModule                                                         geometryShaderModule
-                                                               fragmendModule,                                         // const VkShaderModule                                                         fragmentShaderModule
-                                                               renderPass,                                                     // const VkRenderPass                                                           renderPass
-                                                               viewports,                                                      // const std::vector<VkViewport>&                                       viewports
-                                                               scissors,                                                       // const std::vector<VkRect2D>&                                         scissors
-                                                               topology,                                                       // const VkPrimitiveTopology                                            topology
-                                                               subpass,                                                        // const deUint32                                                                       subpass
-                                                               0u,                                                                     // const deUint32                                                                       patchControlPoints
-                                                               vertexInputStateCreateInfoPtr,          // const VkPipelineVertexInputStateCreateInfo*          vertexInputStateCreateInfo
-                                                               rasterizationStateCreateInfoPtr);       // const VkPipelineRasterizationStateCreateInfo*        rasterizationStateCreateInfo
+       return makeGraphicsPipeline(vk,                                                                                 // const DeviceInterface&                                                       vk
+                                                               device,                                                                         // const VkDevice                                                                       device
+                                                               pipelineLayout,                                                         // const VkPipelineLayout                                                       pipelineLayout
+                                                               vertexModule,                                                           // const VkShaderModule                                                         vertexShaderModule
+                                                               tessellationControlModule,                                      // const VkShaderModule                                                         tessellationControlModule
+                                                               tessellationEvalModule,                                         // const VkShaderModule                                                         tessellationEvalModule
+                                                               geometryModule,                                                         // const VkShaderModule                                                         geometryShaderModule
+                                                               fragmendModule,                                                         // const VkShaderModule                                                         fragmentShaderModule
+                                                               renderPass,                                                                     // const VkRenderPass                                                           renderPass
+                                                               viewports,                                                                      // const std::vector<VkViewport>&                                       viewports
+                                                               scissors,                                                                       // const std::vector<VkRect2D>&                                         scissors
+                                                               topology,                                                                       // const VkPrimitiveTopology                                            topology
+                                                               subpass,                                                                        // const deUint32                                                                       subpass
+                                                               (tessellationEvalModule != DE_NULL) * 3u,       // const deUint32                                                                       patchControlPoints
+                                                               vertexInputStateCreateInfoPtr,                          // const VkPipelineVertexInputStateCreateInfo*          vertexInputStateCreateInfo
+                                                               rasterizationStateCreateInfoPtr);                       // const VkPipelineRasterizationStateCreateInfo*        rasterizationStateCreateInfo
 }
 
 VkImageCreateInfo makeImageCreateInfo (const VkImageCreateFlags flags, const VkImageType type, const VkFormat format, const VkExtent2D size, const deUint32 numLayers, const VkImageUsageFlags usage)
@@ -374,7 +387,8 @@ protected:
        deUint32                                                                                getNextChunkSize                                (const deUint32 usedBytes, const deUint32 bufBytes);
        std::vector<VkDeviceSize>                                               generateSizesList                               (const size_t bufBytes, const size_t chunkCount);
        std::vector<VkDeviceSize>                                               generateOffsetsList                             (const std::vector<VkDeviceSize>& sizesList);
-       void                                                                                    verifyTransformFeedbackBuffer   (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes);
+       void                                                                                    verifyTransformFeedbackBuffer   (const MovePtr<Allocation>& bufAlloc,
+                                                                                                                                                                        const deUint32 bufBytes);
 
        const bool                                                                              m_extensions;
        const VkExtent2D                                                                m_imageExtent2D;
@@ -495,12 +509,13 @@ std::vector<VkDeviceSize> TransformFeedbackTestInstance::generateOffsetsList (co
        return result;
 }
 
-void TransformFeedbackTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const deUint32 bufBytes)
+void TransformFeedbackTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc,
+                                                                                                                                  const deUint32 bufBytes)
 {
        const DeviceInterface&  vk                      = m_context.getDeviceInterface();
        const VkDevice                  device          = m_context.getDevice();
 
-       invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), bufBytes);
+       invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
 
        const deUint32                  numPoints       = static_cast<deUint32>(bufBytes / sizeof(deUint32));
        const deUint32*                 tfData          = (deUint32*)bufAlloc->getHostPtr();
@@ -536,7 +551,7 @@ tcu::TestStatus TransformFeedbackBasicTestInstance::iterate (void)
        const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
        const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
        const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
@@ -609,7 +624,7 @@ tcu::TestStatus TransformFeedbackResumeTestInstance::iterate (void)
        const Unique<VkRenderPass>                              renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
        const Unique<VkFramebuffer>                             framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>                  pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                                pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+       const Unique<VkPipeline>                                pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
 
        const Unique<VkCommandPool>                             cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>                   cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
@@ -675,50 +690,205 @@ tcu::TestStatus TransformFeedbackResumeTestInstance::iterate (void)
        return tcu::TestStatus::pass("Pass");
 }
 
-class TransformFeedbackTriangleStripWithAdjacencyTestInstance : public TransformFeedbackTestInstance
+class TransformFeedbackWindingOrderTestInstance : public TransformFeedbackTestInstance
 {
 public:
-                                               TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters);
+       TransformFeedbackWindingOrderTestInstance(Context& context, const TestParameters& parameters);
+
+protected:
+       struct TopologyParameters
+       {
+               VkPrimitiveTopology topology;
+
+               // number of vertex in primitive; 2 for line, 3 for triangle
+               deUint32 vertexPerPrimitive;
+
+               // pointer to function calculating number of points that
+               // will be generated for given part count
+               std::function<deUint32(deUint32)> getNumGeneratedPoints;
+
+               // pointer to function generating expected values; parameter is
+               // primitive index, result array with expected data for primitive vertex
+               std::function<std::vector<deUint32>(deUint32)> getExpectedValuesForPrimitive;
+       };
+       typedef const std::map<TestType, TopologyParameters> TopologyParametersMap;
 
 protected:
-       tcu::TestStatus         iterate                                                                                                 (void);
-       void                            verifyTransformFeedbackBuffer                                                   (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes);
+       const TopologyParametersMap&    getTopologyParametersMap                                        (void);
+       tcu::TestStatus                                 iterate                                                                         (void);
+       void                                                    verifyTransformFeedbackBuffer                           (const MovePtr<Allocation>& bufAlloc,
+                                                                                                                                                                const deUint32 bufBytes);
+
+private:
+       TopologyParameters                              m_tParameters;
+       const bool                                              m_requiresTesselationStage;
 };
 
-TransformFeedbackTriangleStripWithAdjacencyTestInstance::TransformFeedbackTriangleStripWithAdjacencyTestInstance (Context& context, const TestParameters& parameters)
+TransformFeedbackWindingOrderTestInstance::TransformFeedbackWindingOrderTestInstance(Context& context, const TestParameters& parameters)
        : TransformFeedbackTestInstance (context, parameters)
+       , m_requiresTesselationStage(parameters.testType == TEST_TYPE_PATCH_LIST)
 {
+       if (m_requiresTesselationStage && !context.getDeviceFeatures().tessellationShader)
+               throw tcu::NotSupportedError("Tessellation shader not supported");
+
+       TopologyParametersMap topologyParametersMap = getTopologyParametersMap();
+       DE_ASSERT(topologyParametersMap.find(parameters.testType) != topologyParametersMap.end());
+       m_tParameters = topologyParametersMap.at(parameters.testType);
 }
 
-tcu::TestStatus TransformFeedbackTriangleStripWithAdjacencyTestInstance::iterate (void)
+const TransformFeedbackWindingOrderTestInstance::TopologyParametersMap& TransformFeedbackWindingOrderTestInstance::getTopologyParametersMap(void)
 {
-       const DeviceInterface&                          vk                                              = m_context.getDeviceInterface();
-       const VkDevice                                          device                                  = m_context.getDevice();
-       const deUint32                                          queueFamilyIndex                = m_context.getUniversalQueueFamilyIndex();
-       const VkQueue                                           queue                                   = m_context.getUniversalQueue();
-       Allocator&                                                      allocator                               = m_context.getDefaultAllocator();
+       static const TopologyParametersMap topologyParametersMap =
+       {
+               {
+                       TEST_TYPE_LINE_LIST,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_LINE_LIST,
+                               2u,
+                               [](deUint32 partCount)  {       return partCount;       },
+                               [](deUint32 i)                  {       return std::vector<deUint32>{ 2 * i, 2 * i + 1u };      }
+                       }
+               },
+               {
+                       TEST_TYPE_LINE_STRIP,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_LINE_STRIP,
+                               2u,
+                               [](deUint32 partCount)  {       return 2u * (partCount - 1);    },
+                               [](deUint32 i)                  {       return std::vector<deUint32>{ i, i + 1u };      }
+                       }
+               },
+               {
+                       TEST_TYPE_TRIANGLE_LIST,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
+                               3u,
+                               [](deUint32 partCount)  {       return partCount;       },
+                               [](deUint32 i)                  {       return std::vector<deUint32>{ 3 * i, 3 * i + 1u, 3 * i + 2u };  }
+                       }
+               },
+               {
+                       TEST_TYPE_TRIANGLE_STRIP,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
+                               3u,
+                               [](deUint32 partCount)  {       return 3u * (partCount - 2);    },
+                               [](deUint32 i)
+                               {
+                                       const deUint32  iMod2 = i % 2;
+                                       return std::vector<deUint32>{ i, i + 1 + iMod2, i + 2 - iMod2 };
+                               }
+                       }
+               },
+               {
+                       TEST_TYPE_TRIANGLE_FAN,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN,
+                               3u,
+                               [](deUint32 partCount)  {       return partCount;       },
+                               [](deUint32 i)                  {       return std::vector<deUint32>{ i + 1, i + 2, 0 };        }
+                       }
+               },
+               {
+                       TEST_TYPE_LINE_LIST_ADJACENCY,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY,
+                               2u,
+                               [](deUint32 partCount)  {       return partCount / 4u;  },              // note: this cant be replaced with partCount / 2 as for partCount=6 we will get 3 instead of 2
+                               [](deUint32 i)                  {       return std::vector<deUint32>{ i + 1u, i + 2u }; }
+                       }
+               },
+               {
+                       TEST_TYPE_LINE_STRIP_ADJACENCY,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY,
+                               2u,
+                               [](deUint32 partCount)  {       return 2u * (partCount - 3u);   },
+                               [](deUint32 i)                  {       return std::vector<deUint32>{ i + 1u, i + 2u }; }
+                       }
+               },
+               {
+                       TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY,
+                               3u,
+                               [](deUint32 partCount)  {       return partCount / 2u;  },
+                               [](deUint32 i)                  {       return std::vector<deUint32>{ 6 * i, 6 * i + 2u, 6 * i + 4u     };      }
+                       }
+               },
+               {
+                       TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY,
+                               3u,
+                               [](deUint32 partCount)  {       return 3u * (partCount / 2u - 2u);      },
+                               [](deUint32 i)
+                               {
+                                       const bool even = (0 == i % 2);
+                                       if (even)
+                                               return std::vector<deUint32>{ 2 * i + 0, 2 * i + 2, 2 * i + 4 };
+                                       return std::vector<deUint32>{ 2 * i + 0, 2 * i + 4, 2 * i + 2 };
+                               }
+                       }
+               },
+               {
+                       TEST_TYPE_PATCH_LIST,
+                       {
+                               VK_PRIMITIVE_TOPOLOGY_PATCH_LIST,
+                               9u,
+                               [](deUint32 partCount)  {       return partCount * 3u;  },
+                               [](deUint32 i)
+                               {
+                                       // we cant generate vertex numbers in tesselation evaluation shader;
+                                       // check if patch index is correct for every 9 generated vertex
+                                       return std::vector<deUint32>(9, i);
+                               }
+                       }
+               }
+       };
 
+       return topologyParametersMap;
+}
+
+tcu::TestStatus TransformFeedbackWindingOrderTestInstance::iterate (void)
+{
        DE_ASSERT(m_parameters.partCount >= 6);
 
-       const VkPrimitiveTopology                       topology                                (VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP_WITH_ADJACENCY);
-       const Unique<VkShaderModule>            vertexModule                    (createShaderModule                                             (vk, device, m_context.getBinaryCollection().get("vert"), 0u));
-       const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
-       const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
-       const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u, DE_NULL, topology));
-       const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
-       const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+       const DeviceInterface&                  vk                                      = m_context.getDeviceInterface();
+       const VkDevice                                  device                          = m_context.getDevice();
+       const deUint32                                  queueFamilyIndex        = m_context.getUniversalQueueFamilyIndex();
+       const VkQueue                                   queue                           = m_context.getUniversalQueue();
+       Allocator&                                              allocator                       = m_context.getDefaultAllocator();
 
-       const deUint32                                          numPrimitives                   = m_parameters.partCount / 2u - 2u;
-       const deUint32                                          numPoints                               = 3u * numPrimitives;
-       const VkDeviceSize                                      bufferSize                              = numPoints * sizeof(deUint32);
-       const VkBufferCreateInfo                        tfBufCreateInfo                 = makeBufferCreateInfo(bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
-       const Move<VkBuffer>                            tfBuf                                   = createBuffer(vk, device, &tfBufCreateInfo);
-       const MovePtr<Allocation>                       tfBufAllocation                 = allocator.allocate(getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
-       const VkMemoryBarrier                           tfMemoryBarrier                 = makeMemoryBarrier(VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
-       const VkDeviceSize                                      tfBufBindingSize                = bufferSize;
-       const VkDeviceSize                                      tfBufBindingOffset              = 0u;
-       const deUint32                                          startValue                              = 0u;
+       const Move<VkShaderModule>              vertexModule(createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0u));
+       Move<VkShaderModule>                    tescModule;
+       Move<VkShaderModule>                    teseModule;
+       if (m_requiresTesselationStage)
+       {
+               tescModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tesc"), 0u);
+               teseModule = createShaderModule(vk, device, m_context.getBinaryCollection().get("tese"), 0u);
+       }
+
+       const Unique<VkRenderPass>              renderPass                      (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
+       const Unique<VkFramebuffer>             framebuffer                     (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
+       const Unique<VkPipelineLayout>  pipelineLayout          (TransformFeedback::makePipelineLayout  (vk, device));
+       const Unique<VkPipeline>                pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass,
+                                                                                                                                                                                                *vertexModule,
+                                                                                                                                                                                                m_requiresTesselationStage ? *tescModule : DE_NULL,
+                                                                                                                                                                                                m_requiresTesselationStage ? *teseModule : DE_NULL,
+                                                                                                                                                                                                DE_NULL,
+                                                                                                                                                                                                DE_NULL,
+                                                                                                                                                                                                m_imageExtent2D, 0u, DE_NULL, m_tParameters.topology));
+       const Unique<VkCommandPool>             cmdPool                         (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
+       const Unique<VkCommandBuffer>   cmdBuffer                       (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
+       const VkDeviceSize                              bufferSize                      = m_tParameters.getNumGeneratedPoints   (m_parameters.partCount) * sizeof(deUint32);
+       const VkBufferCreateInfo                tfBufCreateInfo         = makeBufferCreateInfo                                  (bufferSize, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT);
+       const Move<VkBuffer>                    tfBuf                           = createBuffer                                                  (vk, device, &tfBufCreateInfo);
+       const MovePtr<Allocation>               tfBufAllocation         = allocator.allocate                                    (getBufferMemoryRequirements(vk, device, *tfBuf), MemoryRequirement::HostVisible);
+       const VkMemoryBarrier                   tfMemoryBarrier         = makeMemoryBarrier                                             (VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT, VK_ACCESS_HOST_READ_BIT);
+       const VkDeviceSize                              tfBufBindingSize        = bufferSize;
+       const VkDeviceSize                              tfBufBindingOffset      = 0u;
+       const deUint32                                  startValue                      = 0u;
 
        VK_CHECK(vk.bindBufferMemory(device, *tfBuf, tfBufAllocation->getMemory(), tfBufAllocation->getOffset()));
 
@@ -745,51 +915,62 @@ tcu::TestStatus TransformFeedbackTriangleStripWithAdjacencyTestInstance::iterate
        endCommandBuffer(vk, *cmdBuffer);
        submitCommandsAndWait(vk, device, queue, *cmdBuffer);
 
-       verifyTransformFeedbackBuffer(tfBufAllocation, bufferSize);
+       verifyTransformFeedbackBuffer(tfBufAllocation, static_cast<deUint32>(bufferSize));
 
        return tcu::TestStatus::pass("Pass");
 }
 
-void TransformFeedbackTriangleStripWithAdjacencyTestInstance::verifyTransformFeedbackBuffer (const MovePtr<Allocation>& bufAlloc, const VkDeviceSize bufBytes)
+void TransformFeedbackWindingOrderTestInstance::verifyTransformFeedbackBuffer(const MovePtr<Allocation>& bufAlloc,
+                                                                                                                                                         const deUint32 bufBytes)
 {
-       const DeviceInterface&  vk                      = m_context.getDeviceInterface();
-       const VkDevice                  device          = m_context.getDevice();
+       const DeviceInterface&  vk              = m_context.getDeviceInterface();
+       const VkDevice                  device  = m_context.getDevice();
 
        invalidateMappedMemoryRange(vk, device, bufAlloc->getMemory(), bufAlloc->getOffset(), VK_WHOLE_SIZE);
 
-       const deUint32                  numPoints       = static_cast<deUint32>(bufBytes / sizeof(deUint32));
-       const deUint32*                 tfData          = (deUint32*)bufAlloc->getHostPtr();
+       const deUint32  numPoints                       = static_cast<deUint32>(bufBytes / sizeof(deUint32));
+       const deUint32  vertexPerPrimitive      = m_tParameters.vertexPerPrimitive;
+       const deUint32  numPrimitives           = numPoints / vertexPerPrimitive;
+       const deUint32* tfData                          = (deUint32*)bufAlloc->getHostPtr();
 
-       for (deUint32 dataNdx = 0; dataNdx + 2 < numPoints; dataNdx += 3)
+       for (deUint32 primitiveIndex = 0; primitiveIndex < numPrimitives; ++primitiveIndex)
        {
-               const deUint32  i                       = dataNdx / 3;
-               const bool              even            = (0 == i % 2);
-               deUint32                vertexNumbers[3];
-               bool                    correctWinding = false;
-
-               if (even)
-               {
-                       vertexNumbers[0] = 2 * i + 0;
-                       vertexNumbers[1] = 2 * i + 2;
-                       vertexNumbers[2] = 2 * i + 4;
-               }
-               else
+               const deUint32*                 tfDataForPrimitive                      = &tfData[primitiveIndex * vertexPerPrimitive];
+               std::vector<deUint32>   expectedDataForPrimitive        = m_tParameters.getExpectedValuesForPrimitive(primitiveIndex);
+
+               // For multi - vertex primitives, all values for a given vertex are written before writing values for any other vertex.
+               // Implementations may write out any vertex within the primitive first, but all subsequent vertices for that primitive
+               // must be written out in a consistent winding order
+               bool correctWinding = true;
+               for (deUint32 combinationIndex = 0; combinationIndex < vertexPerPrimitive; combinationIndex++)
                {
-                       vertexNumbers[0] = 2 * i + 0;
-                       vertexNumbers[1] = 2 * i + 4;
-                       vertexNumbers[2] = 2 * i + 2;
-               }
+                       correctWinding = true;
+                       for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
+                       {
+                               correctWinding &= (tfDataForPrimitive[vertexIndex] == expectedDataForPrimitive[(combinationIndex + vertexIndex) % vertexPerPrimitive]);
 
-               for (deUint32 j = 0; j < 3 && !correctWinding; j++)
-               {
-                       correctWinding = (tfData[dataNdx] == vertexNumbers[j] && tfData[dataNdx + 1] == vertexNumbers[(j+1) % 3] && tfData[dataNdx + 2] == vertexNumbers[(j+2) % 3]);
+                               // if data for this vertex is not correct then there
+                               // is no need to check other, go to next combination
+                               if (!correctWinding)
+                                       break;
+                       }
+
+                       // no need to check other combinations, we found correct one
+                       if (correctWinding)
+                               break;
                }
 
                if (!correctWinding)
                {
-                       TCU_FAIL(std::string("Failed at item ") + de::toString(dataNdx) +
-                                       " received: " + de::toString(tfData[dataNdx]) + "," + de::toString(tfData[dataNdx + 1]) + "," + de::toString(tfData[dataNdx + 2]) +
-                                       " expected: " + de::toString(vertexNumbers[0]) + "," + de::toString(vertexNumbers[1]) + "," + de::toString(vertexNumbers[2]) );
+                       std::stringstream message;
+                       message << "Failed at primitive " << primitiveIndex << " received: [";
+                       for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
+                               message << de::toString(tfDataForPrimitive[vertexIndex]) << " ";
+                       message << "] expected: [";
+                       for (deUint32 vertexIndex = 0; vertexIndex < vertexPerPrimitive; vertexIndex++)
+                               message << de::toString(expectedDataForPrimitive[vertexIndex]) << " ";
+                       message << "]";
+                       TCU_FAIL(message.str());
                }
        }
 }
@@ -856,7 +1037,7 @@ tcu::TestStatus TransformFeedbackBuiltinTestInstance::iterate (void)
        const Unique<VkRenderPass>                      renderPass                              (makeRenderPass                                                 (vk, device, VK_FORMAT_UNDEFINED));
        const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
        const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
@@ -998,7 +1179,7 @@ tcu::TestStatus TransformFeedbackMultistreamTestInstance::iterate (void)
 
        const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
+       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, *geomModule, DE_NULL, m_imageExtent2D, 0u));
        const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
@@ -1164,7 +1345,7 @@ tcu::TestStatus TransformFeedbackStreamsTestInstance::iterate (void)
 
        const Unique<VkFramebuffer>                     framebuffer                     (makeFramebuffer                                                (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>          pipelineLayout          (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, *fragModule, m_imageExtent2D, 0u, &m_parameters.streamId));
+       const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, *geomModule, *fragModule, m_imageExtent2D, 0u, &m_parameters.streamId));
        const Unique<VkCommandPool>                     cmdPool                         (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
@@ -1304,7 +1485,7 @@ tcu::TestStatus TransformFeedbackIndirectDrawTestInstance::iterate (void)
 
        const Unique<VkFramebuffer>                     framebuffer                     (makeFramebuffer                                                (vk, device, *renderPass, *colorAttachment, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>          pipelineLayout          (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, *fragModule, m_imageExtent2D, 0u, DE_NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true));
+       const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, DE_NULL, *fragModule, m_imageExtent2D, 0u, DE_NULL, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, true));
        const Unique<VkCommandPool>                     cmdPool                         (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
@@ -1386,7 +1567,7 @@ tcu::TestStatus TransformFeedbackBackwardDependencyTestInstance::iterate (void)
        const Unique<VkRenderPass>                      renderPass                      (TransformFeedback::makeRenderPass              (vk, device));
        const Unique<VkFramebuffer>                     framebuffer                     (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>          pipelineLayout          (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
+       const Unique<VkPipeline>                        pipeline                        (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertexModule, DE_NULL, DE_NULL, DE_NULL, DE_NULL, m_imageExtent2D, 0u));
        const Unique<VkCommandPool>                     cmdPool                         (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                       (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
@@ -1520,7 +1701,7 @@ tcu::TestStatus TransformFeedbackQueryTestInstance::iterate (void)
 
        const Unique<VkFramebuffer>                     framebuffer                             (makeFramebuffer                                                (vk, device, *renderPass, 0u, DE_NULL, m_imageExtent2D.width, m_imageExtent2D.height));
        const Unique<VkPipelineLayout>          pipelineLayout                  (TransformFeedback::makePipelineLayout  (vk, device));
-       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, *geomModule, DE_NULL, m_imageExtent2D, 0u));
+       const Unique<VkPipeline>                        pipeline                                (makeGraphicsPipeline                                   (vk, device, *pipelineLayout, *renderPass, *vertModule, DE_NULL, DE_NULL, *geomModule, DE_NULL, m_imageExtent2D, 0u));
        const Unique<VkCommandPool>                     cmdPool                                 (createCommandPool                                              (vk, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
        const Unique<VkCommandBuffer>           cmdBuffer                               (allocateCommandBuffer                                  (vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
 
@@ -1736,8 +1917,21 @@ vkt::TestInstance*       TransformFeedbackTestCase::createInstance (vkt::Context& cont
        if (m_parameters.testType == TEST_TYPE_XFB_CLIP_AND_CULL)
                return new TransformFeedbackBuiltinTestInstance(context, m_parameters);
 
-       if (m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY)
-               return new TransformFeedbackTriangleStripWithAdjacencyTestInstance(context, m_parameters);
+       static const std::set<TestType> windingTests =
+       {
+               TEST_TYPE_LINE_LIST,
+               TEST_TYPE_LINE_STRIP,
+               TEST_TYPE_TRIANGLE_LIST,
+               TEST_TYPE_TRIANGLE_STRIP,
+               TEST_TYPE_TRIANGLE_FAN,
+               TEST_TYPE_LINE_LIST_ADJACENCY,
+               TEST_TYPE_LINE_STRIP_ADJACENCY,
+               TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+               TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+               TEST_TYPE_PATCH_LIST
+       };
+       if (windingTests.count(m_parameters.testType))
+               return new TransformFeedbackWindingOrderTestInstance(context, m_parameters);
 
        if (m_parameters.testType == TEST_TYPE_STREAMS)
                return new TransformFeedbackStreamsTestInstance(context, m_parameters);
@@ -1773,11 +1967,20 @@ void TransformFeedbackTestCase::initPrograms (SourceCollections& programCollecti
        const bool vertexShaderOnly             =  m_parameters.testType == TEST_TYPE_BASIC
                                                                        || m_parameters.testType == TEST_TYPE_RESUME
                                                                        || m_parameters.testType == TEST_TYPE_BACKWARD_DEPENDENCY
-                                                                       || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY;
+                                                                       || m_parameters.testType == TEST_TYPE_LINE_LIST
+                                                                       || m_parameters.testType == TEST_TYPE_LINE_STRIP
+                                                                       || m_parameters.testType == TEST_TYPE_TRIANGLE_LIST
+                                                                       || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP
+                                                                       || m_parameters.testType == TEST_TYPE_TRIANGLE_FAN
+                                                                       || m_parameters.testType == TEST_TYPE_LINE_LIST_ADJACENCY
+                                                                       || m_parameters.testType == TEST_TYPE_LINE_STRIP_ADJACENCY
+                                                                       || m_parameters.testType == TEST_TYPE_TRIANGLE_STRIP_ADJACENCY
+                                                                       || m_parameters.testType == TEST_TYPE_TRIANGLE_LIST_ADJACENCY;
        const bool requiresFullPipeline =  m_parameters.testType == TEST_TYPE_STREAMS
                                                                        || m_parameters.testType == TEST_TYPE_STREAMS_POINTSIZE
                                                                        || m_parameters.testType == TEST_TYPE_STREAMS_CULLDISTANCE
-                                                                       || m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE;
+                                                                       || m_parameters.testType == TEST_TYPE_STREAMS_CLIPDISTANCE
+                                                                       || m_parameters.testType == TEST_TYPE_PATCH_LIST;
        const bool xfbBuiltinPipeline   =  m_parameters.testType == TEST_TYPE_XFB_POINTSIZE
                                                                        || m_parameters.testType == TEST_TYPE_XFB_CLIPDISTANCE
                                                                        || m_parameters.testType == TEST_TYPE_XFB_CULLDISTANCE
@@ -1808,6 +2011,55 @@ void TransformFeedbackTestCase::initPrograms (SourceCollections& programCollecti
                return;
        }
 
+       if (m_parameters.testType == TEST_TYPE_PATCH_LIST)
+       {
+               // Vertex shader
+               {
+                       std::ostringstream src;
+                       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "layout(push_constant) uniform pushConstants\n"
+                               << "{\n"
+                               << "    uint start;\n"
+                               << "} uInput;\n"
+                               << "void main(void)\n"
+                               << "{\n"
+                               << "    //idx_out = uInput.start + gl_VertexIndex;\n"                           // TODO
+                               << "}\n";
+                       programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
+               }
+
+               // Tesselation control shader
+               {
+                       std::ostringstream src;
+                       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "layout(vertices = 3) out;\n"
+                               << "void main (void)\n"
+                               << "{\n"
+                               << "    gl_TessLevelInner[0] = 2.0;\n" // generate three triangles out of each patch
+                               << "    gl_TessLevelOuter[0] = 1.0;\n"
+                               << "    gl_TessLevelOuter[1] = 1.0;\n"
+                               << "    gl_TessLevelOuter[2] = 1.0;\n"
+                               << "}\n";
+                       programCollection.glslSources.add("tesc") << glu::TessellationControlSource(src.str());
+               }
+
+               // Tessellation evaluation shader
+               {
+                       std::ostringstream src;
+                       src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
+                               << "layout(triangles, ccw) in;\n"
+                               << "layout(xfb_buffer = 0, xfb_offset = 0, xfb_stride = 4, location = 0) out uint idx_out;\n"
+                               << "\n"
+                               << "void main (void)\n"
+                               << "{\n"
+                               << "    idx_out = gl_PrimitiveID;\n" // all vertex generated from patch will have its id
+                               << "}\n";
+                       programCollection.glslSources.add("tese") << glu::TessellationEvaluationSource(src.str());
+               }
+
+               return;
+       }
+
        if (xfbBuiltinPipeline)
        {
                const std::string       outputBuiltIn           = (m_parameters.testType == TEST_TYPE_XFB_POINTSIZE)     ? "float gl_PointSize;\n"
@@ -2217,8 +2469,33 @@ void createTransformFeedbackSimpleTests (tcu::TestCaseGroup* group)
 
        {
                const deUint32          bufferCounts[]  = { 6, 8, 10, 12 };
-               const TestType          testTypes[]             = { TEST_TYPE_TRIANGLE_STRIP_ADJACENCY };
-               const std::string       testTypeNames[] = { "triangle_strip_with_adjacency"};
+               const TestType          testTypes[]             =
+               {
+                       // note: no need to test POINT_LIST as is tested in many tests
+                       TEST_TYPE_LINE_LIST,
+                       TEST_TYPE_LINE_STRIP,
+                       TEST_TYPE_TRIANGLE_LIST,
+                       TEST_TYPE_TRIANGLE_STRIP,
+                       TEST_TYPE_TRIANGLE_FAN,
+                       TEST_TYPE_LINE_LIST_ADJACENCY,
+                       TEST_TYPE_LINE_STRIP_ADJACENCY,
+                       TEST_TYPE_TRIANGLE_STRIP_ADJACENCY,
+                       TEST_TYPE_TRIANGLE_LIST_ADJACENCY,
+                       TEST_TYPE_PATCH_LIST
+               };
+               const std::string       testTypeNames[] =
+               {
+                       "winding_line_list",
+                       "winding_line_strip",
+                       "winding_triangle_list",
+                       "winding_triangle_strip",
+                       "winding_triangle_fan",
+                       "winding_line_list_with_adjacency",
+                       "winding_line_strip_with_adjacency",
+                       "winding_triangle_strip_with_adjacency",
+                       "winding_triangle_list_with_adjacency",
+                       "winding_patch_list"
+               };
 
                for (deUint32 testTypesNdx = 0; testTypesNdx < DE_LENGTH_OF_ARRAY(testTypes); ++testTypesNdx)
                {
@@ -2227,14 +2504,10 @@ void createTransformFeedbackSimpleTests (tcu::TestCaseGroup* group)
 
                        for (deUint32 bufferCountsNdx = 0; bufferCountsNdx < DE_LENGTH_OF_ARRAY(bufferCounts); ++bufferCountsNdx)
                        {
-                               const deUint32                  vertexCount     = bufferCounts[bufferCountsNdx];
+                               const deUint32  vertexCount     = bufferCounts[bufferCountsNdx];
                                TestParameters  parameters      = { testType, 0u, vertexCount, 0u, 0u, 0u, STREAM_ID_0_NORMAL, false };
 
-                               group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
-                               parameters.streamId0Mode = STREAM_ID_0_BEGIN_QUERY_INDEXED;
-                               group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_beginqueryindexed_streamid_0_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
-                               parameters.streamId0Mode = STREAM_ID_0_END_QUERY_INDEXED;
-                               group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_endqueryindexed_streamid_0_" + de::toString(vertexCount)).c_str(), "Triangle Strip With Adjacency Transform Feedback test", parameters));
+                               group->addChild(new TransformFeedbackTestCase(group->getTestContext(), (testName + "_" + de::toString(vertexCount)).c_str(), "Topology winding test", parameters));
                        }
                }
        }
index eb70325..a76cf5b 100644 (file)
@@ -582177,18 +582177,46 @@ dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_beginqueryindexed_streamid_0_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8_131072
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_12
+dEQP-VK.transform_feedback.simple.winding_line_list_6
+dEQP-VK.transform_feedback.simple.winding_line_list_8
+dEQP-VK.transform_feedback.simple.winding_line_list_10
+dEQP-VK.transform_feedback.simple.winding_line_list_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_6
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_8
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_10
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_12
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_patch_list_6
+dEQP-VK.transform_feedback.simple.winding_patch_list_8
+dEQP-VK.transform_feedback.simple.winding_patch_list_10
+dEQP-VK.transform_feedback.simple.winding_patch_list_12
 dEQP-VK.transform_feedback.simple.draw_indirect_16
 dEQP-VK.transform_feedback.simple.draw_indirect_beginqueryindexed_streamid_0_16
 dEQP-VK.transform_feedback.simple.draw_indirect_endqueryindexed_streamid_0_16
index e2c34cf..683e476 100644 (file)
@@ -582024,18 +582024,46 @@ dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_beginqueryindexed_streamid_0_8_131072
 dEQP-VK.transform_feedback.simple.xfb_clip_and_cull_endqueryindexed_streamid_0_8_131072
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_6
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_8
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_10
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_beginqueryindexed_streamid_0_12
-dEQP-VK.transform_feedback.simple.triangle_strip_with_adjacency_endqueryindexed_streamid_0_12
+dEQP-VK.transform_feedback.simple.winding_line_list_6
+dEQP-VK.transform_feedback.simple.winding_line_list_8
+dEQP-VK.transform_feedback.simple.winding_line_list_10
+dEQP-VK.transform_feedback.simple.winding_line_list_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_12
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_6
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_8
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_10
+dEQP-VK.transform_feedback.simple.winding_triangle_fan_12
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_line_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_strip_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_6
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_8
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_10
+dEQP-VK.transform_feedback.simple.winding_triangle_list_with_adjacency_12
+dEQP-VK.transform_feedback.simple.winding_patch_list_6
+dEQP-VK.transform_feedback.simple.winding_patch_list_8
+dEQP-VK.transform_feedback.simple.winding_patch_list_10
+dEQP-VK.transform_feedback.simple.winding_patch_list_12
 dEQP-VK.transform_feedback.simple.draw_indirect_16
 dEQP-VK.transform_feedback.simple.draw_indirect_beginqueryindexed_streamid_0_16
 dEQP-VK.transform_feedback.simple.draw_indirect_endqueryindexed_streamid_0_16