Home | History | Annotate | Download | only in protected_memory
      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 content copy image tests
     23  *//*--------------------------------------------------------------------*/
     24 
     25 #include "vktProtectedMemCopyImageTests.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 class CopyImageTestInstance : public ProtectedTestInstance
     56 {
     57 public:
     58 									CopyImageTestInstance	(Context&						ctx,
     59 															 const vk::VkClearColorValue&	clearColorValue,
     60 															 const ValidationData&			refData,
     61 															 const ImageValidator&			validator,
     62 															 const CmdBufferType			cmdBufferType);
     63 virtual tcu::TestStatus				iterate					 (void);
     64 
     65 private:
     66 	const vk::VkFormat				m_imageFormat;
     67 	const vk::VkClearColorValue&	m_clearColorValue;
     68 	const ValidationData&			m_refData;
     69 	const ImageValidator&			m_validator;
     70 	const CmdBufferType				m_cmdBufferType;
     71 };
     72 
     73 class CopyImageTestCase : public TestCase
     74 {
     75 public:
     76 								CopyImageTestCase		(tcu::TestContext&			testCtx,
     77 														 const std::string&			name,
     78 														 vk::VkClearColorValue		clearColorValue,
     79 														 ValidationData				data,
     80 														 CmdBufferType				cmdBufferType)
     81 									: TestCase			(testCtx, name, "Clear and copy image.")
     82 									, m_clearColorValue	(clearColorValue)
     83 									, m_refData			(data)
     84 									, m_cmdBufferType	(cmdBufferType)
     85 								{
     86 								}
     87 
     88 	virtual						~CopyImageTestCase		(void) {}
     89 	virtual TestInstance*		createInstance			(Context& ctx) const
     90 								{
     91 									return new CopyImageTestInstance(ctx, m_clearColorValue, m_refData, m_validator, m_cmdBufferType);
     92 								}
     93 	virtual void				initPrograms			(vk::SourceCollections& programCollection) const
     94 								{
     95 									m_validator.initPrograms(programCollection);
     96 								}
     97 private:
     98 	vk::VkClearColorValue		m_clearColorValue;
     99 	ValidationData				m_refData;
    100 	ImageValidator				m_validator;
    101 	CmdBufferType				m_cmdBufferType;
    102 };
    103 
    104 CopyImageTestInstance::CopyImageTestInstance	(Context&						ctx,
    105 												 const vk::VkClearColorValue&	clearColorValue,
    106 												 const ValidationData&			refData,
    107 												 const ImageValidator&			validator,
    108 												 const CmdBufferType			cmdBufferType)
    109 	: ProtectedTestInstance		(ctx)
    110 	, m_imageFormat				(vk::VK_FORMAT_R8G8B8A8_UNORM)
    111 	, m_clearColorValue			(clearColorValue)
    112 	, m_refData					(refData)
    113 	, m_validator				(validator)
    114 	, m_cmdBufferType			(cmdBufferType)
    115 {
    116 }
    117 
    118 tcu::TestStatus CopyImageTestInstance::iterate()
    119 {
    120 	ProtectedContext&					ctx					(m_protectedContext);
    121 	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
    122 	const vk::VkDevice					device				= ctx.getDevice();
    123 	const vk::VkQueue					queue				= ctx.getQueue();
    124 	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();
    125 
    126 	// Create images
    127 	de::MovePtr<vk::ImageWithMemory>	colorImage			= createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
    128 																			RENDER_WIDTH, RENDER_HEIGHT,
    129 																			m_imageFormat,
    130 																			vk::VK_IMAGE_USAGE_SAMPLED_BIT
    131 																			| vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT);
    132 	de::MovePtr<vk::ImageWithMemory>	colorImageSrc		= createImage2D(ctx, PROTECTION_ENABLED, queueFamilyIndex,
    133 																			RENDER_WIDTH, RENDER_HEIGHT,
    134 																			m_imageFormat,
    135 																			vk::VK_IMAGE_USAGE_SAMPLED_BIT
    136 																			| vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT
    137 																			| vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT);
    138 
    139 	vk::Unique<vk::VkPipelineLayout>	pipelineLayout		(createPipelineLayout(ctx, 0u, DE_NULL));
    140 
    141 	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
    142 	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
    143 	vk::Unique<vk::VkCommandBuffer>		secondaryCmdBuffer	(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
    144 	vk::VkCommandBuffer					targetCmdBuffer		= (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
    145 
    146 	// Begin cmd buffer
    147 	beginCommandBuffer(vk, *cmdBuffer);
    148 
    149 	if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
    150 	{
    151 		// Begin secondary command buffer
    152 		const vk::VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
    153 		{
    154 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
    155 			DE_NULL,
    156 			(vk::VkRenderPass)0u,										// renderPass
    157 			0u,															// subpass
    158 			(vk::VkFramebuffer)0u,										// framebuffer
    159 			VK_FALSE,													// occlusionQueryEnable
    160 			(vk::VkQueryControlFlags)0u,								// queryFlags
    161 			(vk::VkQueryPipelineStatisticFlags)0u,						// pipelineStatistics
    162 		};
    163 		beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, secCmdBufInheritInfo);
    164 	}
    165 
    166 	// Start image barrier for source image.
    167 	{
    168 		const vk::VkImageMemoryBarrier	startImgBarrier		=
    169 		{
    170 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
    171 			DE_NULL,											// pNext
    172 			0,													// srcAccessMask
    173 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,					// dstAccessMask
    174 			vk::VK_IMAGE_LAYOUT_UNDEFINED,						// oldLayout
    175 			vk::VK_IMAGE_LAYOUT_GENERAL,						// newLayout
    176 			queueFamilyIndex,									// srcQueueFamilyIndex
    177 			queueFamilyIndex,									// dstQueueFamilyIndex
    178 			**colorImageSrc,									// image
    179 			{
    180 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
    181 				0u,												// baseMipLevel
    182 				1u,												// mipLevels
    183 				0u,												// baseArraySlice
    184 				1u,												// subresourceRange
    185 			}
    186 		};
    187 
    188 		vk.cmdPipelineBarrier(targetCmdBuffer,								// commandBuffer
    189 							  vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,		// srcStageMask
    190 							  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,		    // dstStageMask
    191 							  (vk::VkDependencyFlags)0,						// dependencyFlags
    192 							  0, (const vk::VkMemoryBarrier*)DE_NULL,		// memoryBarrierCount, pMemoryBarriers
    193 							  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,	// bufferMemoryBarrierCount, pBufferMemoryBarriers
    194 							  1, &startImgBarrier);							// imageMemoryBarrierCount, pImageMemoryBarriers
    195 	}
    196 
    197 	// Image clear
    198 	const vk::VkImageSubresourceRange subresourceRange =
    199 	{
    200 		vk::VK_IMAGE_ASPECT_COLOR_BIT,	// VkImageAspectFlags	aspectMask
    201 		0u,								// uint32_t				baseMipLevel
    202 		1u,								// uint32_t				levelCount
    203 		0u,								// uint32_t				baseArrayLayer
    204 		1u,								// uint32_t				layerCount
    205 	};
    206 	vk.cmdClearColorImage(targetCmdBuffer, **colorImageSrc, vk::VK_IMAGE_LAYOUT_GENERAL, &m_clearColorValue, 1, &subresourceRange);
    207 
    208 	// Image barrier to change accessMask to transfer read bit for source image.
    209 	{
    210 		const vk::VkImageMemoryBarrier initializeBarrier =
    211 		{
    212 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
    213 			DE_NULL,											// pNext
    214 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,					// srcAccessMask
    215 			vk::VK_ACCESS_TRANSFER_READ_BIT,					// dstAccessMask
    216 			vk::VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
    217 			vk::VK_IMAGE_LAYOUT_GENERAL,						// newLayout
    218 			queueFamilyIndex,									// srcQueueFamilyIndex
    219 			queueFamilyIndex,									// dstQueueFamilyIndex
    220 			**colorImageSrc,									// image
    221 			{
    222 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
    223 				0u,												// baseMipLevel
    224 				1u,												// mipLevels
    225 				0u,												// baseArraySlice
    226 				1u,												// subresourceRange
    227 			}
    228 		};
    229 
    230 		vk.cmdPipelineBarrier(targetCmdBuffer,
    231 							  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,	// srcStageMask
    232 							  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,	// dstStageMask
    233 							  (vk::VkDependencyFlags)0,
    234 							  0, (const vk::VkMemoryBarrier*)DE_NULL,
    235 							  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
    236 							  1, &initializeBarrier);
    237 	}
    238 
    239 	// Image barrier for destination image.
    240 	{
    241 		const vk::VkImageMemoryBarrier	initializeBarrier	=
    242 		{
    243 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
    244 			DE_NULL,											// pNext
    245 			0,													// srcAccessMask
    246 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,					// dstAccessMask
    247 			vk::VK_IMAGE_LAYOUT_UNDEFINED,						// oldLayout
    248 			vk::VK_IMAGE_LAYOUT_GENERAL,						// newLayout
    249 			queueFamilyIndex,									// srcQueueFamilyIndex
    250 			queueFamilyIndex,									// dstQueueFamilyIndex
    251 			**colorImage,										// image
    252 			{
    253 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
    254 				0u,												// baseMipLevel
    255 				1u,												// mipLevels
    256 				0u,												// baseArraySlice
    257 				1u,												// subresourceRange
    258 			}
    259 		};
    260 
    261 		vk.cmdPipelineBarrier(targetCmdBuffer,
    262 							  vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,	// srcStageMask
    263 							  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,		// dstStageMask
    264 							  (vk::VkDependencyFlags)0,
    265 							  0, (const vk::VkMemoryBarrier*)DE_NULL,
    266 							  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
    267 							  1, &initializeBarrier);
    268 	}
    269 
    270 	// Copy image
    271 	const vk::VkImageSubresourceLayers imgSubResCopy =
    272 	{
    273 		vk::VK_IMAGE_ASPECT_COLOR_BIT,			// VkImageAspectFlags		aspectMask;
    274 		0u,										// deUint32					mipLevel;
    275 		0u,										// deUint32					baseArrayLayer;
    276 		1u,										// deUint32					layerCount;
    277 	};
    278 	const vk::VkOffset3D	nullOffset		= {0u, 0u, 0u};
    279 	const vk::VkExtent3D	imageExtent		= {(deUint32)RENDER_WIDTH, (deUint32)RENDER_HEIGHT, 1u};
    280 	const vk::VkImageCopy	copyImageRegion	=
    281 	{
    282 		imgSubResCopy,							// VkImageSubresourceCopy	srcSubresource;
    283 		nullOffset,								// VkOffset3D				srcOffset;
    284 		imgSubResCopy,							// VkImageSubresourceCopy	destSubresource;
    285 		nullOffset,								// VkOffset3D				destOffset;
    286 		imageExtent,							// VkExtent3D				extent;
    287 
    288 	};
    289 	vk.cmdCopyImage(targetCmdBuffer,
    290 					**colorImageSrc, vk::VK_IMAGE_LAYOUT_GENERAL,	// srcImageLayout
    291 					**colorImage, vk::VK_IMAGE_LAYOUT_GENERAL,		// dstImageLayout
    292 					1u, &copyImageRegion);
    293 
    294 	// Image barrier to change accessMask for destination image.
    295 	{
    296 		const vk::VkImageMemoryBarrier	endImgBarrier	=
    297 		{
    298 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
    299 			DE_NULL,											// pNext
    300 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,					// srcAccessMask
    301 			vk::VK_ACCESS_SHADER_READ_BIT,						// dstAccessMask
    302 			vk::VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
    303 			vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// newLayout
    304 			queueFamilyIndex,									// srcQueueFamilyIndex
    305 			queueFamilyIndex,									// dstQueueFamilyIndex
    306 			**colorImage,										// image
    307 			{
    308 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
    309 				0u,												// baseMipLevel
    310 				1u,												// mipLevels
    311 				0u,												// baseArraySlice
    312 				1u,												// subresourceRange
    313 			}
    314 		};
    315 		vk.cmdPipelineBarrier(targetCmdBuffer,
    316 							  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,		// srcStageMask
    317 							  vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,	// dstStageMask
    318 							  (vk::VkDependencyFlags)0,
    319 							  0, (const vk::VkMemoryBarrier*)DE_NULL,
    320 							  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
    321 							  1, &endImgBarrier);
    322 	}
    323 
    324 	if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
    325 	{
    326 		endCommandBuffer(vk, *secondaryCmdBuffer);
    327 		vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
    328 	}
    329 
    330 	endCommandBuffer(vk, *cmdBuffer);
    331 
    332 	// Submit command buffer
    333 	const vk::Unique<vk::VkFence>	fence		(vk::createFence(vk, device));
    334 	VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
    335 
    336 	// Log out test data
    337 	ctx.getTestContext().getLog()
    338 			<< tcu::TestLog::Message << "Color clear value: " << tcu::Vec4(m_clearColorValue.float32) << tcu::TestLog::EndMessage;
    339 
    340 	// Validate resulting image
    341 	if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
    342 		return tcu::TestStatus::pass("Everything went OK");
    343 	else
    344 		return tcu::TestStatus::fail("Something went really wrong");
    345 }
    346 
    347 tcu::TestCaseGroup*	createCopyImageTests (tcu::TestContext& testCtx, CmdBufferType cmdBufferType)
    348 {
    349 	struct {
    350 		const vk::VkClearColorValue		clearColorValue;
    351 		const ValidationData			data;
    352 	} testData[] = {
    353 		{	{ { 1.0f, 0.0f, 0.0f, 1.0f } },
    354 			{
    355 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
    356 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
    357 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
    358 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
    359 			}
    360 		},
    361 		{	{ { 0.0f, 1.0f, 0.0f, 1.0f } },
    362 			{
    363 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
    364 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
    365 				{ tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
    366 				  tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), }
    367 			}
    368 		},
    369 		{	{ { 0.0f, 0.0f, 1.0f, 1.0f } },
    370 			{
    371 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
    372 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
    373 				{ tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
    374 				  tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), }
    375 			}
    376 		},
    377 		{	{ { 0.0f, 0.0f, 0.0f, 1.0f } },
    378 			{
    379 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
    380 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
    381 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
    382 				  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), }
    383 			}
    384 		},
    385 		{	{ { 1.0f, 0.0f, 0.0f, 1.0f } },
    386 			{
    387 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
    388 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
    389 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
    390 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
    391 			}
    392 		},
    393 		{	{ { 1.0f, 0.0f, 0.0f, 0.0f } },
    394 			{
    395 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
    396 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
    397 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
    398 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), }
    399 			}
    400 		},
    401 		{	{ { 0.1f, 0.2f, 0.3f, 0.0f } },
    402 			{
    403 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
    404 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
    405 				{ tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
    406 				  tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), }
    407 			}
    408 		},
    409 	};
    410 
    411 	de::MovePtr<tcu::TestCaseGroup> copyStaticTests	(new tcu::TestCaseGroup(testCtx, "static", "Copy Image Tests with static input"));
    412 
    413 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
    414 	{
    415 		const std::string name = "copy_" + de::toString(ndx + 1);
    416 		copyStaticTests->addChild(new CopyImageTestCase(testCtx, name.c_str(), testData[ndx].clearColorValue, testData[ndx].data, cmdBufferType));
    417 	}
    418 
    419 	/* Add a few randomized tests */
    420 	de::MovePtr<tcu::TestCaseGroup>	copyRandomTests		(new tcu::TestCaseGroup(testCtx, "random", "Copy Image Tests with random input"));
    421 	const int						testCount			= 10;
    422 	de::Random						rnd					(testCtx.getCommandLine().getBaseSeed());
    423 	for (int ndx = 0; ndx < testCount; ++ndx)
    424 	{
    425 		const std::string	name		= "copy_" + de::toString(ndx + 1);
    426 		vk::VkClearValue	clearValue	= vk::makeClearValueColorF32(
    427 											rnd.getFloat(0.0, 1.0f),
    428 											rnd.getFloat(0.0, 1.0f),
    429 											rnd.getFloat(0.0, 1.0f),
    430 											rnd.getFloat(0.0, 1.0f));
    431 
    432 		tcu::Vec4			refValue	(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]);
    433 		ValidationData		data		=
    434 		{
    435 			{ 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)),
    436 			  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)),
    437 			  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)),
    438 			  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)) },
    439 			{ refValue, refValue, refValue, refValue }
    440 		};
    441 		copyRandomTests->addChild(new CopyImageTestCase(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
    442 	}
    443 
    444 	std::string groupName = getCmdBufferTypeStr(cmdBufferType);
    445 	std::string groupDesc = "Copy Image Tests with " + groupName + " command buffer";
    446 	de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
    447 	copyTests->addChild(copyStaticTests.release());
    448 	copyTests->addChild(copyRandomTests.release());
    449 	return copyTests.release();
    450 }
    451 
    452 } // anonymous
    453 
    454 tcu::TestCaseGroup*	createCopyImageTests (tcu::TestContext& testCtx)
    455 {
    456 	de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, "copy", "Copy Image Tests"));
    457 
    458 	copyTests->addChild(createCopyImageTests(testCtx, CMD_BUFFER_PRIMARY));
    459 	copyTests->addChild(createCopyImageTests(testCtx, CMD_BUFFER_SECONDARY));
    460 
    461 	return copyTests.release();
    462 }
    463 
    464 } // ProtectedMem
    465 } // vkt
    466