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