1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2018 The Khronos Group Inc. 6 * Copyright (c) 2018 Danylo Piliaiev <danylo.piliaiev (at) gmail.com> 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief Test for conditional rendering of vkCmdClearAttachments 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktConditionalClearAttachmentTests.hpp" 26 #include "vktConditionalRenderingTestUtil.hpp" 27 28 #include "vktTestCaseUtil.hpp" 29 #include "vktDrawTestCaseUtil.hpp" 30 31 #include "vktDrawBaseClass.hpp" 32 33 #include "tcuTestLog.hpp" 34 #include "tcuResource.hpp" 35 #include "tcuImageCompare.hpp" 36 #include "tcuTextureUtil.hpp" 37 #include "tcuRGBA.hpp" 38 39 #include "vkDefs.hpp" 40 #include "vkCmdUtil.hpp" 41 #include "vkTypeUtil.hpp" 42 43 namespace vkt 44 { 45 namespace conditional 46 { 47 namespace 48 { 49 50 struct ConditionalTestSpec : public Draw::TestSpecBase 51 { 52 ConditionalData conditionalData; 53 }; 54 55 class ConditionalClearAttachmentTest : public Draw::DrawTestsBaseClass 56 { 57 public: 58 typedef ConditionalTestSpec TestSpec; 59 60 ConditionalClearAttachmentTest (Context &context, ConditionalTestSpec testSpec); 61 62 virtual tcu::TestStatus iterate (void); 63 protected: 64 const ConditionalData m_conditionalData; 65 de::SharedPtr<Draw::Buffer> m_conditionalBuffer; 66 67 vk::Move<vk::VkCommandBuffer> m_secondaryCmdBuffer; 68 }; 69 70 ConditionalClearAttachmentTest::ConditionalClearAttachmentTest (Context &context, ConditionalTestSpec testSpec) 71 : Draw::DrawTestsBaseClass(context, testSpec.shaders[glu::SHADERTYPE_VERTEX], testSpec.shaders[glu::SHADERTYPE_FRAGMENT], vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) 72 , m_conditionalData(testSpec.conditionalData) 73 { 74 checkConditionalRenderingCapabilities(context, m_conditionalData); 75 76 m_data.push_back(Draw::VertexElementData(tcu::Vec4(0.0f), tcu::Vec4(0.0f), 0)); 77 78 initialize(); 79 80 m_secondaryCmdBuffer = vk::allocateCommandBuffer(m_vk, m_context.getDevice(), *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY); 81 }; 82 83 tcu::TestStatus ConditionalClearAttachmentTest::iterate (void) 84 { 85 tcu::TestLog& log = m_context.getTestContext().getLog(); 86 const vk::VkQueue queue = m_context.getUniversalQueue(); 87 const vk::VkDevice device = m_context.getDevice(); 88 89 const tcu::Vec4 clearColor = tcu::RGBA::black().toVec(); 90 const tcu::Vec4 drawColor = tcu::RGBA::blue().toVec(); 91 92 beginRenderPass(m_conditionalData.useSecondaryBuffer ? vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS : vk::VK_SUBPASS_CONTENTS_INLINE); 93 94 vk::VkCommandBuffer targetCmdBuffer = *m_cmdBuffer; 95 96 if (m_conditionalData.useSecondaryBuffer) 97 { 98 const vk::VkCommandBufferInheritanceConditionalRenderingInfoEXT conditionalRenderingInheritanceInfo = 99 { 100 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT, 101 DE_NULL, 102 VK_TRUE // conditionalRenderingEnable 103 }; 104 105 const vk::VkCommandBufferInheritanceInfo inheritanceInfo = 106 { 107 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, 108 &conditionalRenderingInheritanceInfo, 109 *m_renderPass, // renderPass 110 0u, // subpass 111 *m_framebuffer, // framebuffer 112 VK_FALSE, // occlusionQueryEnable 113 (vk::VkQueryControlFlags)0u, // queryFlags 114 (vk::VkQueryPipelineStatisticFlags)0u, // pipelineStatistics 115 }; 116 117 const vk::VkCommandBufferBeginInfo commandBufferBeginInfo = 118 { 119 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 120 DE_NULL, 121 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, 122 &inheritanceInfo 123 }; 124 125 m_vk.beginCommandBuffer(*m_secondaryCmdBuffer, &commandBufferBeginInfo); 126 127 targetCmdBuffer = *m_secondaryCmdBuffer; 128 } 129 130 m_vk.cmdBindPipeline(targetCmdBuffer, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline); 131 132 const vk::VkClearAttachment clearAttachment = 133 { 134 vk::VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 135 0u, // deUint32 colorAttachment; 136 vk::makeClearValueColor(drawColor) // VkClearValue clearValue; 137 }; 138 139 const vk::VkClearRect rect = 140 { 141 vk::makeRect2D(WIDTH, HEIGHT), // VkRect2D rect; 142 0u, // uint32_t baseArrayLayer; 143 1u, // uint32_t layerCount; 144 }; 145 146 if (m_conditionalData.useSecondaryBuffer) 147 { 148 m_vk.cmdClearAttachments(*m_secondaryCmdBuffer, 1, &clearAttachment, 1, &rect); 149 } 150 151 if (m_conditionalData.conditionEnabled) 152 { 153 m_conditionalBuffer = createConditionalRenderingBuffer(m_context, m_conditionalData); 154 beginConditionalRendering(m_vk, *m_cmdBuffer, *m_conditionalBuffer, m_conditionalData); 155 } 156 157 if (!m_conditionalData.useSecondaryBuffer) 158 { 159 m_vk.cmdClearAttachments(*m_cmdBuffer, 1, &clearAttachment, 1, &rect); 160 } 161 162 if (m_conditionalData.useSecondaryBuffer) 163 { 164 m_vk.endCommandBuffer(*m_secondaryCmdBuffer); 165 166 m_vk.cmdExecuteCommands(*m_cmdBuffer, 1, &m_secondaryCmdBuffer.get()); 167 } 168 169 if (m_conditionalData.conditionEnabled) 170 { 171 m_vk.cmdEndConditionalRenderingEXT(*m_cmdBuffer); 172 } 173 174 endRenderPass(m_vk, *m_cmdBuffer); 175 endCommandBuffer(m_vk, *m_cmdBuffer); 176 177 submitCommandsAndWait(m_vk, device, queue, m_cmdBuffer.get()); 178 179 // Validation 180 tcu::Texture2D referenceFrame(vk::mapVkFormat(m_colorAttachmentFormat), (int)(0.5 + WIDTH), (int)(0.5 + HEIGHT)); 181 referenceFrame.allocLevel(0); 182 183 const deInt32 frameWidth = referenceFrame.getWidth(); 184 const deInt32 frameHeight = referenceFrame.getHeight(); 185 186 tcu::clear(referenceFrame.getLevel(0), clearColor); 187 188 const tcu::Vec4 referenceColor = m_conditionalData.expectCommandExecution ? 189 drawColor : clearColor; 190 191 for (int y = 0; y < frameHeight; y++) 192 { 193 for (int x = 0; x < frameWidth; x++) 194 { 195 referenceFrame.getLevel(0).setPixel(referenceColor, x, y); 196 } 197 } 198 199 const vk::VkOffset3D zeroOffset = { 0, 0, 0 }; 200 const tcu::ConstPixelBufferAccess renderedFrame = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), 201 vk::VK_IMAGE_LAYOUT_GENERAL, zeroOffset, WIDTH, HEIGHT, vk::VK_IMAGE_ASPECT_COLOR_BIT); 202 203 qpTestResult res = QP_TEST_RESULT_PASS; 204 205 if (!tcu::fuzzyCompare(log, "Result", "Image comparison result", 206 referenceFrame.getLevel(0), renderedFrame, 0.05f, 207 tcu::COMPARE_LOG_RESULT)) 208 { 209 res = QP_TEST_RESULT_FAIL; 210 } 211 212 return tcu::TestStatus(res, qpGetTestResultName(res)); 213 }; 214 215 } // anonymous 216 217 ConditionalClearAttachmentTests::ConditionalClearAttachmentTests (tcu::TestContext &testCtx) 218 : TestCaseGroup (testCtx, "clear_attachments", "vkCmdClearAttachments with conditional rendering") 219 { 220 /* Left blank on purpose */ 221 } 222 223 ConditionalClearAttachmentTests::~ConditionalClearAttachmentTests (void) {} 224 225 void ConditionalClearAttachmentTests::init (void) 226 { 227 for (int conditionNdx = 0; conditionNdx < DE_LENGTH_OF_ARRAY(conditional::s_testsData); conditionNdx++) 228 { 229 const ConditionalData& conditionData = conditional::s_testsData[conditionNdx]; 230 231 tcu::TestCaseGroup* conditionalDrawRootGroup = new tcu::TestCaseGroup(m_testCtx, de::toString(conditionData).c_str(), ""); 232 233 ConditionalTestSpec testSpec; 234 testSpec.conditionalData = conditionData; 235 testSpec.shaders[glu::SHADERTYPE_VERTEX] = "vulkan/dynamic_state/VertexFetch.vert"; 236 testSpec.shaders[glu::SHADERTYPE_FRAGMENT] = "vulkan/dynamic_state/VertexFetch.frag"; 237 238 conditionalDrawRootGroup->addChild(new Draw::InstanceFactory<ConditionalClearAttachmentTest>(m_testCtx, "clear_attachments", "", testSpec)); 239 240 addChild(conditionalDrawRootGroup); 241 } 242 } 243 244 } // conditional 245 } // vkt 246