From 27b51a3b3543f943c2350b8925aba677b3f654bf Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Thu, 26 Jan 2017 14:27:48 -0800 Subject: [PATCH] Add yflip versions of tessellation winding order tests Changed: dEQP-VK.tessellation.winding.triangles_* Components: Vulkan Change-Id: I3e0abc8d25132e129cb2979b1fce985ca4a60dc4 (cherry picked from commit a9c1d0abb740baa5f368758f17142336baeb17f9) --- android/cts/master/vk-master.txt | 4 + .../vulkan/tessellation/vktTessellationUtil.cpp | 24 +++++- .../tessellation/vktTessellationWindingTests.cpp | 92 +++++++++++++++++++--- external/vulkancts/mustpass/1.0.2/vk-default.txt | 4 + 4 files changed, 109 insertions(+), 15 deletions(-) diff --git a/android/cts/master/vk-master.txt b/android/cts/master/vk-master.txt index 642ae3d..6d7cca3 100644 --- a/android/cts/master/vk-master.txt +++ b/android/cts/master/vk-master.txt @@ -196916,9 +196916,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 diff --git a/external/vulkancts/modules/vulkan/tessellation/vktTessellationUtil.cpp b/external/vulkancts/modules/vulkan/tessellation/vktTessellationUtil.cpp index 4178a7a..84ebb4b 100644 --- a/external/vulkancts/modules/vulkan/tessellation/vktTessellationUtil.cpp +++ b/external/vulkancts/modules/vulkan/tessellation/vktTessellationUtil.cpp @@ -609,15 +609,17 @@ Move 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 GraphicsPipelineBuilder::build (const DeviceInterface& vk, { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; }; + std::vector 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(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 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; diff --git a/external/vulkancts/modules/vulkan/tessellation/vktTessellationWindingTests.cpp b/external/vulkancts/modules/vulkan/tessellation/vktTessellationWindingTests.cpp index 10a2448..8d0f730 100644 --- a/external/vulkancts/modules/vulkan/tessellation/vktTessellationWindingTests.cpp +++ b/external/vulkancts/modules/vulkan/tessellation/vktTessellationWindingTests.cpp @@ -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 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 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(renderSize.y()) : 0.0f, // float y; + static_cast(renderSize.x()), // float width; + static_cast(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(); } diff --git a/external/vulkancts/mustpass/1.0.2/vk-default.txt b/external/vulkancts/mustpass/1.0.2/vk-default.txt index 5f82b7d..90ef627 100644 --- a/external/vulkancts/mustpass/1.0.2/vk-default.txt +++ b/external/vulkancts/mustpass/1.0.2/vk-default.txt @@ -197194,9 +197194,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 -- 2.7.4