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 blit image tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemBlitImageTests.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 BlitImageTestInstance : public ProtectedTestInstance
56 {
57 public:
58 									BlitImageTestInstance	(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 BlitImageTestCase : public TestCase
74 {
75 public:
BlitImageTestCase(tcu::TestContext & testCtx,const std::string & name,vk::VkClearColorValue clearColorValue,ValidationData data,CmdBufferType cmdBufferType)76 								BlitImageTestCase			(tcu::TestContext&			testCtx,
77 															 const std::string&			name,
78 															 vk::VkClearColorValue		clearColorValue,
79 															 ValidationData				data,
80 															 CmdBufferType				cmdBufferType)
81 									: TestCase				(testCtx, name, "Clear and blit image.")
82 									, m_clearColorValue		(clearColorValue)
83 									, m_refData				(data)
84 									, m_cmdBufferType		(cmdBufferType)
85 								{
86 								}
87 
~BlitImageTestCase(void)88 	virtual						~BlitImageTestCase			(void) {}
createInstance(Context & ctx) const89 	virtual TestInstance*		createInstance				(Context& ctx) const
90 								{
91 									return new BlitImageTestInstance(ctx, m_clearColorValue, m_refData, m_validator, m_cmdBufferType);
92 								}
initPrograms(vk::SourceCollections & programCollection) const93 	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 
BlitImageTestInstance(Context & ctx,const vk::VkClearColorValue & clearColorValue,const ValidationData & refData,const ImageValidator & validator,const CmdBufferType cmdBufferType)104 BlitImageTestInstance::BlitImageTestInstance	(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 
iterate()118 tcu::TestStatus BlitImageTestInstance::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 	// Blit 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::VkOffset3D				imageOffset		=	{RENDER_WIDTH, RENDER_HEIGHT, 1};
280 	const vk::VkImageBlit				imageBlit		=
281 	 {
282 		imgSubResCopy,											// VkImageSubresourceLayers		srcSubresource;
283 		{
284 			nullOffset,
285 			imageOffset,
286 		},														// VkOffset3D					srcOffsets[2];
287 		imgSubResCopy,											// VkImageSubresourceLayers		dstSubresource;
288 		{
289 			nullOffset,
290 			imageOffset,
291 		},														// VkOffset3D					dstOffsets[2];
292 	 };
293 	vk.cmdBlitImage(targetCmdBuffer, **colorImageSrc, vk::VK_IMAGE_LAYOUT_GENERAL,
294 					**colorImage, vk::VK_IMAGE_LAYOUT_GENERAL, 1u, &imageBlit, vk::VK_FILTER_NEAREST);
295 
296 	// Image barrier to change accessMask to shader read bit for destination image.
297 	{
298 		const vk::VkImageMemoryBarrier	endImgBarrier	=
299 		{
300 			vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,			// sType
301 			DE_NULL,											// pNext
302 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,					// srcAccessMask
303 			vk::VK_ACCESS_SHADER_READ_BIT,						// dstAccessMask
304 			vk::VK_IMAGE_LAYOUT_GENERAL,						// oldLayout
305 			vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,		// newLayout
306 			queueFamilyIndex,									// srcQueueFamilyIndex
307 			queueFamilyIndex,									// dstQueueFamilyIndex
308 			**colorImage,										// image
309 			{
310 				vk::VK_IMAGE_ASPECT_COLOR_BIT,					// aspectMask
311 				0u,												// baseMipLevel
312 				1u,												// mipLevels
313 				0u,												// baseArraySlice
314 				1u,												// subresourceRange
315 			}
316 		};
317 		vk.cmdPipelineBarrier(targetCmdBuffer,
318 							  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,		// srcStageMask
319 							  vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,	// dstStageMask
320 							  (vk::VkDependencyFlags)0,
321 							  0, (const vk::VkMemoryBarrier*)DE_NULL,
322 							  0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
323 							  1, &endImgBarrier);
324 	}
325 
326 	if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
327 	{
328 		endCommandBuffer(vk, *secondaryCmdBuffer);
329 		vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
330 	}
331 
332 	endCommandBuffer(vk, *cmdBuffer);
333 
334 	// Submit command buffer
335 	const vk::Unique<vk::VkFence>	fence		(vk::createFence(vk, device));
336 	VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
337 
338 	// Log out test data
339 	ctx.getTestContext().getLog()
340 		<< tcu::TestLog::Message << "Color clear value: " << tcu::Vec4(m_clearColorValue.float32) << tcu::TestLog::EndMessage;
341 
342 	// Validate resulting image
343 	if (m_validator.validateImage(ctx, m_refData, **colorImage, m_imageFormat, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL))
344 		return tcu::TestStatus::pass("Everything went OK");
345 	else
346 		return tcu::TestStatus::fail("Something went really wrong");
347 }
348 
createBlitImageTests(tcu::TestContext & testCtx,CmdBufferType cmdBufferType)349 tcu::TestCaseGroup*	createBlitImageTests (tcu::TestContext& testCtx, CmdBufferType cmdBufferType)
350 {
351 	struct {
352 		const vk::VkClearColorValue		clearColorValue;
353 		const ValidationData			data;
354 	} testData[] = {
355 		{	{ { 1.0f, 0.0f, 0.0f, 1.0f } },
356 			{
357 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
358 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
359 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
360 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
361 			}
362 		},
363 		{	{ { 0.0f, 1.0f, 0.0f, 1.0f } },
364 			{
365 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
366 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
367 				{ tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
368 				  tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), }
369 			}
370 		},
371 		{	{ { 0.0f, 0.0f, 1.0f, 1.0f } },
372 			{
373 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
374 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
375 				{ tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f),
376 				  tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), }
377 			}
378 		},
379 		{	{ { 0.0f, 0.0f, 0.0f, 1.0f } },
380 			{
381 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
382 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
383 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f),
384 				  tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f), }
385 			}
386 		},
387 		{	{ { 1.0f, 0.0f, 0.0f, 1.0f } },
388 			{
389 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
390 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
391 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f),
392 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), }
393 			}
394 		},
395 		{	{ { 1.0f, 0.0f, 0.0f, 0.0f } },
396 			{
397 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
398 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
399 				{ tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f),
400 				  tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 0.0f, 0.0f, 0.0f), }
401 			}
402 		},
403 		{	{ { 0.1f, 0.2f, 0.3f, 0.0f } },
404 			{
405 				{ tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f), tcu::Vec4(1.0f, 1.0f, 0.0f, 0.0f),
406 				  tcu::Vec4(0.1f, 0.1f, 0.0f, 0.0f), tcu::Vec4(0.5f, 0.5f, 0.0f, 0.0f), },
407 				{ tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f),
408 				  tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), tcu::Vec4(0.1f, 0.2f, 0.3f, 0.0f), }
409 			}
410 		},
411 	};
412 
413 	de::MovePtr<tcu::TestCaseGroup> blitStaticTests (new tcu::TestCaseGroup(testCtx, "static", "Blit Image Tests with static input"));
414 
415 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
416 	{
417 		const std::string name = "blit_" + de::toString(ndx + 1);
418 		blitStaticTests->addChild(new BlitImageTestCase(testCtx, name.c_str(), testData[ndx].clearColorValue, testData[ndx].data, cmdBufferType));
419 	}
420 
421 	/* Add a few randomized tests */
422 	de::MovePtr<tcu::TestCaseGroup>	blitRandomTests	(new tcu::TestCaseGroup(testCtx, "random", "Blit Image Tests with random input"));
423 	const int						testCount			= 10;
424 	de::Random						rnd					(testCtx.getCommandLine().getBaseSeed());
425 	for (int ndx = 0; ndx < testCount; ++ndx)
426 	{
427 		const std::string	name		= "blit_" + de::toString(ndx + 1);
428 		vk::VkClearValue	clearValue	= vk::makeClearValueColorF32(
429 											rnd.getFloat(0.0, 1.0f),
430 											rnd.getFloat(0.0, 1.0f),
431 											rnd.getFloat(0.0, 1.0f),
432 											rnd.getFloat(0.0, 1.0f));
433 
434 		tcu::Vec4			refValue	(clearValue.color.float32[0], clearValue.color.float32[1], clearValue.color.float32[2], clearValue.color.float32[3]);
435 		ValidationData		data		=
436 		{
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 			  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)),
440 			  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)) },
441 			{ refValue, refValue, refValue, refValue }
442 		};
443 		blitRandomTests->addChild(new BlitImageTestCase(testCtx, name.c_str(), clearValue.color, data, cmdBufferType));
444 	}
445 
446 	std::string groupName = getCmdBufferTypeStr(cmdBufferType);
447 	std::string groupDesc = "Blit Image Tests with " + groupName + " command buffer";
448 	de::MovePtr<tcu::TestCaseGroup> blitTests (new tcu::TestCaseGroup(testCtx, groupName.c_str(), groupDesc.c_str()));
449 	blitTests->addChild(blitStaticTests.release());
450 	blitTests->addChild(blitRandomTests.release());
451 	return blitTests.release();
452 }
453 
454 } // anonymous
455 
createBlitImageTests(tcu::TestContext & testCtx)456 tcu::TestCaseGroup*	createBlitImageTests (tcu::TestContext& testCtx)
457 {
458 	de::MovePtr<tcu::TestCaseGroup> blitTests (new tcu::TestCaseGroup(testCtx, "blit", "Blit Image Tests"));
459 
460 	blitTests->addChild(createBlitImageTests(testCtx, CMD_BUFFER_PRIMARY));
461 	blitTests->addChild(createBlitImageTests(testCtx, CMD_BUFFER_SECONDARY));
462 
463 	return blitTests.release();
464 }
465 
466 } // ProtectedMem
467 } // vkt
468