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