1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2017 The Khronos Group Inc. 6 * Copyright (c) 2017 Samsung Electronics Co., Ltd. 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 Protected memory attachment render pass load tests 23 *//*--------------------------------------------------------------------*/ 24 25 #include "vktProtectedMemAttachmentLoadTests.hpp" 26 27 #include "deRandom.hpp" 28 #include "tcuTestLog.hpp" 29 #include "tcuVector.hpp" 30 31 #include "vkPrograms.hpp" 32 #include "vktTestCase.hpp" 33 #include "vktTestGroupUtil.hpp" 34 #include "vkTypeUtil.hpp" 35 #include "vkBuilderUtil.hpp" 36 #include "vkCmdUtil.hpp" 37 38 #include "vktProtectedMemContext.hpp" 39 #include "vktProtectedMemUtils.hpp" 40 #include "vktProtectedMemImageValidator.hpp" 41 42 namespace vkt 43 { 44 namespace ProtectedMem 45 { 46 47 namespace 48 { 49 50 enum { 51 RENDER_WIDTH = 128, 52 RENDER_HEIGHT = 128, 53 }; 54 55 56 class AttachmentLoadTestInstance : public ProtectedTestInstance 57 { 58 public: 59 AttachmentLoadTestInstance (Context& ctx, 60 const vk::VkClearValue& clearValue, 61 const ValidationData& refData, 62 const ImageValidator& validator); 63 virtual tcu::TestStatus iterate (void); 64 65 private: 66 const vk::VkFormat m_imageFormat; 67 const vk::VkClearValue& m_clearValue; 68 const ValidationData& m_refData; 69 const ImageValidator& m_validator; 70 }; 71 72 73 class AttachmentLoadTestCase : public TestCase 74 { 75 public: 76 AttachmentLoadTestCase (tcu::TestContext& testCtx, 77 const std::string& name, 78 vk::VkClearValue clearValue, 79 ValidationData data) 80 : TestCase (testCtx, name, "Clear on render pass initialization.") 81 , m_clearValue (clearValue) 82 , m_refData (data) 83 { 84 } 85 86 virtual ~AttachmentLoadTestCase (void) {} 87 virtual TestInstance* createInstance (Context& ctx) const 88 { 89 return new AttachmentLoadTestInstance(ctx, m_clearValue, m_refData, m_validator); 90 } 91 virtual void initPrograms (vk::SourceCollections& programCollection) const 92 { 93 m_validator.initPrograms(programCollection); 94 } 95 private: 96 vk::VkClearValue m_clearValue; 97 ValidationData m_refData; 98 ImageValidator m_validator; 99 }; 100 101 AttachmentLoadTestInstance::AttachmentLoadTestInstance (Context& ctx, 102 const vk::VkClearValue& clearValue, 103 const ValidationData& refData, 104 const ImageValidator& validator) 105 : ProtectedTestInstance (ctx) 106 , m_imageFormat (vk::VK_FORMAT_R8G8B8A8_UNORM) 107 , m_clearValue (clearValue) 108 , m_refData (refData) 109 , m_validator (validator) 110 { 111 } 112 113 tcu::TestStatus AttachmentLoadTestInstance::iterate() 114 { 115 ProtectedContext& ctx (m_protectedContext); 116 const vk::DeviceInterface& vk = ctx.getDeviceInterface(); 117 const vk::VkDevice device = ctx.getDevice(); 118 const vk::VkQueue queue = ctx.getQueue(); 119 const deUint32 queueFamilyIndex = ctx.getQueueFamilyIndex(); 120 121 // Create output image 122 de::MovePtr<vk::ImageWithMemory> colorImage (createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex, 123 RENDER_WIDTH, RENDER_HEIGHT, 124 m_imageFormat, 125 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|vk::VK_IMAGE_USAGE_SAMPLED_BIT)); 126 vk::Unique<vk::VkImageView> colorImageView (createImageView(ctx, **colorImage, m_imageFormat)); 127 128 vk::Unique<vk::VkRenderPass> renderPass (createRenderPass(ctx, m_imageFormat)); 129 vk::Unique<vk::VkFramebuffer> framebuffer (createFramebuffer(ctx, RENDER_WIDTH, RENDER_HEIGHT, *renderPass, *colorImageView)); 130 vk::Unique<vk::VkPipelineLayout> pipelineLayout (createPipelineLayout(ctx, 0u, DE_NULL)); 131 132 vk::Unique<vk::VkCommandPool> cmdPool (makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex)); 133 vk::Unique<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 134 135 // Begin cmd buffer 136 beginCommandBuffer(vk, *cmdBuffer); 137 138 // Start image barrier 139 { 140 const vk::VkImageMemoryBarrier startImgBarrier = 141 { 142 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 143 DE_NULL, // pNext 144 0, // srcAccessMask 145 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask 146 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout 147 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout 148 queueFamilyIndex, // srcQueueFamilyIndex 149 queueFamilyIndex, // dstQueueFamilyIndex 150 **colorImage, // image 151 { 152 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 153 0u, // baseMipLevel 154 1u, // mipLevels 155 0u, // baseArraySlice 156 1u, // subresourceRange 157 } 158 }; 159 160 vk.cmdPipelineBarrier(*cmdBuffer, 161 vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 162 vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 163 (vk::VkDependencyFlags)0, 164 0, (const vk::VkMemoryBarrier*)DE_NULL, 165 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 166 1, &startImgBarrier); 167 } 168 169 // Image clear 170 beginRenderPass(vk, *cmdBuffer, *renderPass, *framebuffer, vk::makeRect2D(0, 0, RENDER_WIDTH, RENDER_HEIGHT), m_clearValue); 171 endRenderPass(vk, *cmdBuffer); 172 173 { 174 // Image validator reads image in compute shader 175 const vk::VkImageMemoryBarrier endImgBarrier = 176 { 177 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // sType 178 DE_NULL, // pNext 179 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask 180 vk::VK_ACCESS_SHADER_READ_BIT, // dstAccessMask 181 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout 182 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout 183 queueFamilyIndex, // srcQueueFamilyIndex 184 queueFamilyIndex, // dstQueueFamilyIndex 185 **colorImage, // image 186 { 187 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask 188 0u, // baseMipLevel 189 1u, // mipLevels 190 0u, // baseArraySlice 191 1u, // subresourceRange 192 } 193 }; 194 vk.cmdPipelineBarrier(*cmdBuffer, 195 vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, 196 vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 197 (vk::VkDependencyFlags)0, 198 0, (const vk::VkMemoryBarrier*)DE_NULL, 199 0, (const vk::VkBufferMemoryBarrier*)DE_NULL, 200 1, &endImgBarrier); 201 } 202 203 endCommandBuffer(vk, *cmdBuffer); 204 205 // Submit command buffer 206 const vk::Unique<vk::VkFence> fence (vk::createFence(vk, device)); 207 VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull)); 208 209 // Log out test data 210 ctx.getTestContext().getLog() 211 << tcu::TestLog::Message << "Color clear value: " << tcu::Vec4(m_clearValue.color.float32) << tcu::TestLog::EndMessage 212 << tcu::TestLog::Message << "Depth clear value: " << m_clearValue.depthStencil.depth << tcu::TestLog::EndMessage 213 << tcu::TestLog::Message << "Stencil clear value: " << m_clearValue.depthStencil.stencil << tcu::TestLog::EndMessage; 214 215 // Validate resulting image 216 if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)) 217 return tcu::TestStatus::pass("Everything went OK"); 218 else 219 return tcu::TestStatus::fail("Something went really wrong"); 220 } 221 222 } // anonymous 223 224 tcu::TestCaseGroup* createAttachmentLoadTests (tcu::TestContext& testCtx) 225 { 226 struct { 227 const vk::VkClearValue clearValue; 228 const ValidationData data; 229 } testData[] = { 230 { vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f), 231 { 232 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), 233 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, 234 { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), 235 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), } 236 } 237 }, 238 { vk::makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f), 239 { 240 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), 241 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, 242 { tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), 243 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), } 244 } 245 }, 246 { vk::makeClearValueColorF32(0.0f, 0.0f, 1.0f, 1.0f), 247 { 248 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), 249 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, 250 { tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), 251 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), } 252 } 253 }, 254 { vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 1.0f), 255 { 256 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), 257 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, 258 { tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), 259 tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), } 260 } 261 }, 262 { vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 1.0f), 263 { 264 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), 265 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, 266 { tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), 267 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), } 268 } 269 }, 270 { vk::makeClearValueColorF32(1.0f, 0.0f, 0.0f, 0.0f), 271 { 272 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), 273 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, 274 { tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), 275 tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), } 276 } 277 }, 278 { vk::makeClearValueColorF32(0.1f, 0.2f, 0.3f, 0.0f), 279 { 280 { tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f), 281 tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), }, 282 { tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), 283 tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), } 284 } 285 }, 286 }; 287 288 de::MovePtr<tcu::TestCaseGroup> loadStaticTests (new tcu::TestCaseGroup(testCtx, "static", "Attachment Load Op Tests with static input")); 289 290 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx) 291 { 292 const std::string name = "clear_" + de::toString(ndx + 1); 293 loadStaticTests->addChild(new AttachmentLoadTestCase(testCtx, name.c_str(), testData[ndx].clearValue, testData[ndx].data)); 294 } 295 296 /* Add a few randomized tests */ 297 de::MovePtr<tcu::TestCaseGroup> loadRandomTests (new tcu::TestCaseGroup(testCtx, "random", "Attachment Load Op Tests with random input")); 298 const int testCount = 10; 299 de::Random rnd (testCtx.getCommandLine().getBaseSeed()); 300 for (int ndx = 0; ndx < testCount; ++ndx) 301 { 302 const std::string name = "clear_" + de::toString(ndx + 1); 303 vk::VkClearValue clearValue = vk::makeClearValueColorF32( 304 rnd.getFloat(0.0, 1.0f), 305 rnd.getFloat(0.0, 1.0f), 306 rnd.getFloat(0.0, 1.0f), 307 rnd.getFloat(0.0, 1.0f)); 308 309 tcu::Vec4 refValue (clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]); 310 ValidationData data = { 311 { tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)), 312 tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)), 313 tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)), 314 tcu::Vec4(rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f), rnd.getFloat(0.0f, 1.0f)) }, 315 { refValue, refValue, refValue, refValue } 316 }; 317 318 loadRandomTests->addChild(new AttachmentLoadTestCase(testCtx, name.c_str(), clearValue, data)); 319 } 320 321 de::MovePtr<tcu::TestCaseGroup> loadTests (new tcu::TestCaseGroup(testCtx, "load_op", "Attachment Load Op Tests")); 322 loadTests->addChild(loadStaticTests.release()); 323 loadTests->addChild(loadRandomTests.release()); 324 return loadTests.release(); 325 } 326 327 } // ProtectedMem 328 } // vkt 329