Add yflip versions of tessellation winding order tests
authorJason Ekstrand <jason.ekstrand@intel.com>
Thu, 26 Jan 2017 22:27:48 +0000 (14:27 -0800)
committerPyry Haulos <phaulos@google.com>
Thu, 9 Mar 2017 22:57:01 +0000 (14:57 -0800)
Changed: dEQP-VK.tessellation.winding.triangles_*

Components: Vulkan

Change-Id: I3e0abc8d25132e129cb2979b1fce985ca4a60dc4

android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/tessellation/vktTessellationUtil.cpp
external/vulkancts/modules/vulkan/tessellation/vktTessellationWindingTests.cpp
external/vulkancts/mustpass/1.0.3/vk-default.txt

index dd782d4..1288c58 100644 (file)
@@ -170430,9 +170430,13 @@ dEQP-VK.tessellation.tesscoord.isolines_equal_spacing
 dEQP-VK.tessellation.tesscoord.isolines_fractional_odd_spacing
 dEQP-VK.tessellation.tesscoord.isolines_fractional_even_spacing
 dEQP-VK.tessellation.winding.triangles_ccw
+dEQP-VK.tessellation.winding.triangles_ccw_yflip
 dEQP-VK.tessellation.winding.triangles_cw
+dEQP-VK.tessellation.winding.triangles_cw_yflip
 dEQP-VK.tessellation.winding.quads_ccw
+dEQP-VK.tessellation.winding.quads_ccw_yflip
 dEQP-VK.tessellation.winding.quads_cw
+dEQP-VK.tessellation.winding.quads_cw_yflip
 dEQP-VK.tessellation.shader_input_output.patch_vertices_5_in_10_out
 dEQP-VK.tessellation.shader_input_output.patch_vertices_10_in_5_out
 dEQP-VK.tessellation.shader_input_output.primitive_id_tcs
index 687795f..57f423e 100644 (file)
@@ -609,15 +609,17 @@ Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&   vk,
                makeExtent2D(m_renderSize.x(), m_renderSize.y()),
        };
 
+       const bool haveRenderSize = m_renderSize.x() > 0 && m_renderSize.y() > 0;
+
        const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
        {
                VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,  // VkStructureType                             sType;
                DE_NULL,                                                                                                // const void*                                 pNext;
                (VkPipelineViewportStateCreateFlags)0,                                  // VkPipelineViewportStateCreateFlags          flags;
                1u,                                                                                                             // uint32_t                                    viewportCount;
-               &viewport,                                                                                              // const VkViewport*                           pViewports;
+               haveRenderSize ? &viewport : DE_NULL,                                   // const VkViewport*                           pViewports;
                1u,                                                                                                             // uint32_t                                    scissorCount;
-               &scissor,                                                                                               // const VkRect2D*                             pScissors;
+               haveRenderSize ? &scissor : DE_NULL,                                    // const VkRect2D*                             pScissors;
        };
 
        const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
@@ -701,6 +703,22 @@ Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&    vk,
                { 0.0f, 0.0f, 0.0f, 0.0f },                                                                     // float                                                                                blendConstants[4];
        };
 
+       std::vector<VkDynamicState> dynamicStates;
+       if (!haveRenderSize)
+       {
+               dynamicStates.push_back(VK_DYNAMIC_STATE_VIEWPORT);
+               dynamicStates.push_back(VK_DYNAMIC_STATE_SCISSOR);
+       }
+
+       const VkPipelineDynamicStateCreateInfo pipelineDynamicStateInfo =
+       {
+               VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,   // VkStructureType                                              sType;
+               DE_NULL,                                                                                                // const void*                                                  pNext;
+               0,                                                                                                              // VkPipelineDynamicStateCreateFlags    flags;
+               static_cast<deUint32>(dynamicStates.size()),                    // uint32_t                                                             dynamicStateCount;
+               (dynamicStates.empty() ? DE_NULL : &dynamicStates[0]),  // const VkDynamicState*                                pDynamicStates;
+       };
+
        const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
        {
                VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,                                                // VkStructureType                                                                      sType;
@@ -716,7 +734,7 @@ Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface&     vk,
                (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo),    // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
                (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo),   // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
                (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo),             // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
-               DE_NULL,                                                                                                                                // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
+               &pipelineDynamicStateInfo,                                                                                              // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
                pipelineLayout,                                                                                                                 // VkPipelineLayout                                                                     layout;
                renderPass,                                                                                                                             // VkRenderPass                                                                         renderPass;
                0u,                                                                                                                                             // deUint32                                                                                     subpass;
index ddf56c9..1109223 100644 (file)
@@ -48,10 +48,12 @@ using namespace vk;
 namespace
 {
 
-std::string getCaseName (const TessPrimitiveType primitiveType, const Winding winding)
+std::string getCaseName (const TessPrimitiveType primitiveType, const Winding winding, bool yFlip)
 {
        std::ostringstream str;
        str << getTessPrimitiveTypeShaderName(primitiveType) << "_" << getWindingShaderName(winding);
+       if (yFlip)
+               str << "_yflip";
        return str.str();
 }
 
@@ -72,6 +74,7 @@ bool verifyResultImage (tcu::TestLog&                                         log,
                                                const tcu::ConstPixelBufferAccess       image,
                                                const TessPrimitiveType                         primitiveType,
                                                const Winding                                           winding,
+                                               bool                                                            yFlip,
                                                const Winding                                           frontFaceWinding)
 {
        const int totalNumPixels        = image.getWidth()*image.getHeight();
@@ -102,7 +105,7 @@ bool verifyResultImage (tcu::TestLog&                                               log,
                return false;
        }
 
-       if (frontFaceWinding == winding)
+       if ((frontFaceWinding == winding) != yFlip)
        {
                if (primitiveType == TESSPRIMITIVETYPE_TRIANGLES)
                {
@@ -111,6 +114,41 @@ bool verifyResultImage (tcu::TestLog&                                              log,
                                log << tcu::TestLog::Message << "Failure: wrong number of white pixels; expected approximately " << totalNumPixels/2 << tcu::TestLog::EndMessage;
                                return false;
                        }
+
+                       // Check number of filled pixels (from left) in top and bottom rows to
+                       // determine if triangle is in right orientation.
+                       {
+                               const tcu::IVec2        expectedStart   (0, 1);
+                               const tcu::IVec2        expectedEnd             (image.getWidth()-1, image.getWidth());
+                               const tcu::IVec2        expectedTop             = yFlip ? expectedStart : expectedEnd;
+                               const tcu::IVec2        expectedBottom  = yFlip ? expectedEnd : expectedStart;
+                               int                                     numTopFilled    = 0;
+                               int                                     numBottomFilled = 0;
+
+                               for (int x = 0; x < image.getWidth(); ++x)
+                               {
+                                       if (image.getPixel(x, 0) == white)
+                                               numTopFilled += 1;
+                                       else
+                                               break;
+                               }
+
+                               for (int x = 0; x < image.getWidth(); ++x)
+                               {
+                                       if (image.getPixel(x, image.getHeight()-1) == white)
+                                               numBottomFilled += 1;
+                                       else
+                                               break;
+                               }
+
+                               if (!de::inBounds(numTopFilled, expectedTop[0], expectedTop[1]) ||
+                                       !de::inBounds(numBottomFilled, expectedBottom[0], expectedBottom[1]))
+                               {
+                                       log << tcu::TestLog::Message << "Failure: triangle orientation is incorrect" << tcu::TestLog::EndMessage;
+                                       return false;
+                               }
+                       }
+
                }
                else if (primitiveType == TESSPRIMITIVETYPE_QUADS)
                {
@@ -140,7 +178,8 @@ class WindingTest : public TestCase
 public:
                                                                WindingTest             (tcu::TestContext&                      testCtx,
                                                                                                 const TessPrimitiveType        primitiveType,
-                                                                                                const Winding                          winding);
+                                                                                                const Winding                          winding,
+                                                                                                bool                                           yFlip);
 
        void                                            initPrograms    (SourceCollections&                     programCollection) const;
        TestInstance*                           createInstance  (Context&                                       context) const;
@@ -148,14 +187,17 @@ public:
 private:
        const TessPrimitiveType         m_primitiveType;
        const Winding                           m_winding;
+       const bool                                      m_yFlip;
 };
 
 WindingTest::WindingTest (tcu::TestContext&                    testCtx,
                                                  const TessPrimitiveType       primitiveType,
-                                                 const Winding                         winding)
-       : TestCase                      (testCtx, getCaseName(primitiveType, winding), "")
+                                                 const Winding                         winding,
+                                                 bool                                          yFlip)
+       : TestCase                      (testCtx, getCaseName(primitiveType, winding, yFlip), "")
        , m_primitiveType       (primitiveType)
        , m_winding                     (winding)
+       , m_yFlip                       (yFlip)
 {
 }
 
@@ -233,26 +275,33 @@ class WindingTestInstance : public TestInstance
 public:
                                                                WindingTestInstance (Context&                                   context,
                                                                                                         const TessPrimitiveType        primitiveType,
-                                                                                                        const Winding                          winding);
+                                                                                                        const Winding                          winding,
+                                                                                                        bool                                           yFlip);
 
        tcu::TestStatus                         iterate                         (void);
 
 private:
        const TessPrimitiveType         m_primitiveType;
        const Winding                           m_winding;
+       const bool                                      m_yFlip;
 };
 
 WindingTestInstance::WindingTestInstance (Context&                                     context,
                                                                                  const TessPrimitiveType       primitiveType,
-                                                                                 const Winding                         winding)
+                                                                                 const Winding                         winding,
+                                                                                 bool                                          yFlip)
        : TestInstance          (context)
        , m_primitiveType       (primitiveType)
        , m_winding                     (winding)
+       , m_yFlip                       (yFlip)
 {
 }
 
 tcu::TestStatus WindingTestInstance::iterate (void)
 {
+       if (m_yFlip && !de::contains(m_context.getDeviceExtensions().begin(), m_context.getDeviceExtensions().end(), "VK_KHR_maintenance1"))
+               TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance1 not supported");
+
        const DeviceInterface&  vk                                      = m_context.getDeviceInterface();
        const VkDevice                  device                          = m_context.getDevice();
        const VkQueue                   queue                           = m_context.getUniversalQueue();
@@ -285,7 +334,6 @@ tcu::TestStatus WindingTestInstance::iterate (void)
        // Front face is static state, so we have to create two pipelines.
 
        const Unique<VkPipeline> pipelineCounterClockwise(GraphicsPipelineBuilder()
-               .setRenderSize   (renderSize)
                .setCullModeFlags(cullMode)
                .setFrontFace    (VK_FRONT_FACE_COUNTER_CLOCKWISE)
                .setShader               (vk, device, VK_SHADER_STAGE_VERTEX_BIT,                                  m_context.getBinaryCollection().get("vert"), DE_NULL)
@@ -295,7 +343,6 @@ tcu::TestStatus WindingTestInstance::iterate (void)
                .build                   (vk, device, *pipelineLayout, *renderPass));
 
        const Unique<VkPipeline> pipelineClockwise(GraphicsPipelineBuilder()
-               .setRenderSize   (renderSize)
                .setCullModeFlags(cullMode)
                .setFrontFace    (VK_FRONT_FACE_CLOCKWISE)
                .setShader               (vk, device, VK_SHADER_STAGE_VERTEX_BIT,                                  m_context.getBinaryCollection().get("vert"), DE_NULL)
@@ -359,6 +406,24 @@ tcu::TestStatus WindingTestInstance::iterate (void)
                        beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, renderArea, clearColor);
                }
 
+               const VkViewport viewport =
+               {
+                       0.0f,                                                                                                                   // float        x;
+                       m_yFlip ? static_cast<float>(renderSize.y()) : 0.0f,                    // float        y;
+                       static_cast<float>(renderSize.x()),                                                             // float        width;
+                       static_cast<float>(m_yFlip ? -renderSize.y() : renderSize.y()), // float        height;
+                       0.0f,                                                                                                                   // float        minDepth;
+                       1.0f,                                                                                                                   // float        maxDepth;
+               };
+               vk.cmdSetViewport(*cmdBuffer, 0, 1, &viewport);
+
+               const VkRect2D scissor =
+               {
+                       makeOffset2D(0, 0),
+                       makeExtent2D(renderSize.x(), renderSize.y()),
+               };
+               vk.cmdSetScissor(*cmdBuffer, 0, 1, &scissor);
+
                vk.cmdBindPipeline(*cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, testCases[caseNdx].pipeline);
 
                // Process a single abstract vertex.
@@ -399,7 +464,7 @@ tcu::TestStatus WindingTestInstance::iterate (void)
                        log << tcu::TestLog::Image("color0", "Rendered image", imagePixelAccess);
 
                        // Verify case result
-                       success = success && verifyResultImage(log, imagePixelAccess, m_primitiveType, m_winding, frontFaceWinding);
+                       success = success && verifyResultImage(log, imagePixelAccess, m_primitiveType, m_winding, m_yFlip, frontFaceWinding);
                }
        }  // for windingNdx
 
@@ -410,7 +475,7 @@ TestInstance* WindingTest::createInstance (Context& context) const
 {
        requireFeatures(context.getInstanceInterface(), context.getPhysicalDevice(), FEATURE_TESSELLATION_SHADER);
 
-       return new WindingTestInstance(context, m_primitiveType, m_winding);
+       return new WindingTestInstance(context, m_primitiveType, m_winding, m_yFlip);
 }
 
 } // anonymous
@@ -428,7 +493,10 @@ tcu::TestCaseGroup* createWindingTests (tcu::TestContext& testCtx)
 
        for (int primitiveTypeNdx = 0; primitiveTypeNdx < DE_LENGTH_OF_ARRAY(primitivesNoIsolines); ++primitiveTypeNdx)
        for (int windingNdx = 0; windingNdx < WINDING_LAST; ++windingNdx)
-               group->addChild(new WindingTest(testCtx, primitivesNoIsolines[primitiveTypeNdx], (Winding)windingNdx));
+       {
+               group->addChild(new WindingTest(testCtx, primitivesNoIsolines[primitiveTypeNdx], (Winding)windingNdx, false));
+               group->addChild(new WindingTest(testCtx, primitivesNoIsolines[primitiveTypeNdx], (Winding)windingNdx, true));
+       }
 
        return group.release();
 }
index 0ec98e1..c514a8c 100644 (file)
@@ -192712,9 +192712,13 @@ dEQP-VK.tessellation.tesscoord.isolines_equal_spacing
 dEQP-VK.tessellation.tesscoord.isolines_fractional_odd_spacing
 dEQP-VK.tessellation.tesscoord.isolines_fractional_even_spacing
 dEQP-VK.tessellation.winding.triangles_ccw
+dEQP-VK.tessellation.winding.triangles_ccw_yflip
 dEQP-VK.tessellation.winding.triangles_cw
+dEQP-VK.tessellation.winding.triangles_cw_yflip
 dEQP-VK.tessellation.winding.quads_ccw
+dEQP-VK.tessellation.winding.quads_ccw_yflip
 dEQP-VK.tessellation.winding.quads_cw
+dEQP-VK.tessellation.winding.quads_cw_yflip
 dEQP-VK.tessellation.shader_input_output.patch_vertices_5_in_10_out
 dEQP-VK.tessellation.shader_input_output.patch_vertices_10_in_5_out
 dEQP-VK.tessellation.shader_input_output.primitive_id_tcs