• 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 memory fill/update/copy buffer tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemFillUpdateCopyBufferTests.hpp"
26 
27 #include <limits>
28 #include "deRandom.hpp"
29 #include "tcuTestLog.hpp"
30 #include "tcuVector.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 "vktProtectedMemBufferValidator.hpp"
42 
43 namespace vkt
44 {
45 namespace ProtectedMem
46 {
47 
48 namespace
49 {
50 
51 enum {
52 	BUFFER_SIZE		= 64,
53 	MAX_POSITION	= BUFFER_SIZE / 4,
54 };
55 
56 enum CmdType {
57 	FILL_BUFFER,
58 	UPDATE_BUFFER,
59 	COPY_BUFFER,
60 };
61 
getTestTypeName(CmdType cmdType)62 static const char* getTestTypeName(CmdType cmdType)
63 {
64 	switch (cmdType) {
65 		case FILL_BUFFER:		return "Fill buffer";
66 		case UPDATE_BUFFER:		return "Update buffer";
67 		case COPY_BUFFER:		return "Copy buffer";
68 		default:
69 			DE_ASSERT(false);
70 			return DE_NULL;
71 	}
72 }
73 
74 template<typename T>
75 class FillUpdateCopyBufferTestInstance : public ProtectedTestInstance
76 {
77 public:
78 								FillUpdateCopyBufferTestInstance	(Context&					ctx,
79 																	 const deUint32				fillValue,
80 																	 const BufferValidator<T>&	validator,
81 																	 CmdType					cmdType,
82 																	 const CmdBufferType		cmdBufferType);
83 	virtual tcu::TestStatus		iterate								(void);
84 
85 private:
86 	const deUint32				m_fillValue;
87 	const BufferValidator<T>&	m_validator;
88 	CmdType						m_cmdType;
89 	const CmdBufferType			m_cmdBufferType;
90 };
91 
92 
93 template<typename T>
94 class FillUpdateCopyBufferTestCase : public TestCase
95 {
96 public:
FillUpdateCopyBufferTestCase(tcu::TestContext & testCtx,const std::string & name,deUint32 fillValue,ValidationData<T> data,CmdType cmdType,CmdBufferType cmdBufferType)97 							FillUpdateCopyBufferTestCase	(tcu::TestContext&		testCtx,
98 															 const std::string&		name,
99 															 deUint32				fillValue,
100 															 ValidationData<T>		data,
101 															 CmdType				cmdType,
102 															 CmdBufferType			cmdBufferType)
103 								: TestCase			(testCtx, name, getTestTypeName(cmdType))
104 								, m_fillValue		(fillValue)
105 								, m_validator		(data)
106 								, m_cmdType			(cmdType)
107 								, m_cmdBufferType	(cmdBufferType)
108 							{
109 							}
110 
~FillUpdateCopyBufferTestCase(void)111 	virtual					~FillUpdateCopyBufferTestCase	(void) {}
createInstance(Context & ctx) const112 	virtual TestInstance*	createInstance					(Context& ctx) const
113 							{
114 								return new FillUpdateCopyBufferTestInstance<T>(ctx, m_fillValue, m_validator, m_cmdType, m_cmdBufferType);
115 							}
initPrograms(vk::SourceCollections & programCollection) const116 	virtual void			initPrograms					(vk::SourceCollections& programCollection) const
117 							{
118 								m_validator.initPrograms(programCollection);
119 							}
120 private:
121 	deUint32				m_fillValue;
122 	BufferValidator<T>		m_validator;
123 	CmdType					m_cmdType;
124 	CmdBufferType			m_cmdBufferType;
125 };
126 
127 template<typename T>
FillUpdateCopyBufferTestInstance(Context & ctx,const deUint32 fillValue,const BufferValidator<T> & validator,CmdType cmdType,const CmdBufferType cmdBufferType)128 FillUpdateCopyBufferTestInstance<T>::FillUpdateCopyBufferTestInstance	(Context&					ctx,
129 																		 const deUint32				fillValue,
130 																		 const BufferValidator<T>&	validator,
131 																		 CmdType					cmdType,
132 																		 const CmdBufferType		cmdBufferType)
133 	: ProtectedTestInstance	(ctx)
134 	, m_fillValue			(fillValue)
135 	, m_validator			(validator)
136 	, m_cmdType				(cmdType)
137 	, m_cmdBufferType		(cmdBufferType)
138 {
139 }
140 
141 template<typename T>
iterate()142 tcu::TestStatus FillUpdateCopyBufferTestInstance<T>::iterate()
143 {
144 	ProtectedContext&					ctx					(m_protectedContext);
145 	const vk::DeviceInterface&			vk					= ctx.getDeviceInterface();
146 	const vk::VkDevice					device				= ctx.getDevice();
147 	const vk::VkQueue					queue				= ctx.getQueue();
148 	const deUint32						queueFamilyIndex	= ctx.getQueueFamilyIndex();
149 	const deUint32						bufferSize			= (deUint32)(BUFFER_SIZE * sizeof(deUint32));
150 
151 	de::MovePtr<vk::BufferWithMemory>	dstBuffer			(makeBuffer(ctx,
152 																		PROTECTION_ENABLED,
153 																		queueFamilyIndex,
154 																		bufferSize,
155 																		vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
156 																			| vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
157 																		vk::MemoryRequirement::Protected));
158 
159 	de::MovePtr<vk::BufferWithMemory>	srcBuffer			(makeBuffer(ctx,
160 																		PROTECTION_ENABLED,
161 																		queueFamilyIndex,
162 																		bufferSize,
163 																		vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT
164 																			| vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT
165 																			| vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT,
166 																		vk::MemoryRequirement::Protected));
167 
168 	vk::Unique<vk::VkCommandPool>		cmdPool				(makeCommandPool(vk, device, PROTECTION_ENABLED, queueFamilyIndex));
169 	vk::Unique<vk::VkCommandBuffer>		cmdBuffer			(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
170 	vk::Unique<vk::VkCommandBuffer>		secondaryCmdBuffer	(vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY));
171 	vk::VkCommandBuffer					targetCmdBuffer		= (m_cmdBufferType == CMD_BUFFER_SECONDARY) ? *secondaryCmdBuffer : *cmdBuffer;
172 
173 	// Begin cmd buffer
174 	beginCommandBuffer(vk, *cmdBuffer);
175 
176 	if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
177 	{
178 		// Begin secondary command buffer
179 		const vk::VkCommandBufferInheritanceInfo	secCmdBufInheritInfo	=
180 		{
181 			vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
182 			DE_NULL,
183 			(vk::VkRenderPass)0u,										// renderPass
184 			0u,															// subpass
185 			(vk::VkFramebuffer)0u,										// framebuffer
186 			VK_FALSE,													// occlusionQueryEnable
187 			(vk::VkQueryControlFlags)0u,								// queryFlags
188 			(vk::VkQueryPipelineStatisticFlags)0u,						// pipelineStatistics
189 		};
190 		beginSecondaryCommandBuffer(vk, *secondaryCmdBuffer, secCmdBufInheritInfo);
191 	}
192 
193 	switch (m_cmdType) {
194 		case FILL_BUFFER:
195 			{
196 				// Fill buffer
197 				vk.cmdFillBuffer(targetCmdBuffer, **dstBuffer, 0u, VK_WHOLE_SIZE, m_fillValue);
198 				break;
199 			}
200 
201 		case UPDATE_BUFFER:
202 			{
203 				// Update buffer
204 				deUint32 data[BUFFER_SIZE];
205 				for (size_t ndx = 0; ndx < BUFFER_SIZE; ndx++)
206 					data[ndx] = m_fillValue;
207 				vk.cmdUpdateBuffer(targetCmdBuffer, **dstBuffer, 0u, bufferSize, (const deUint32 *) &data);
208 				break;
209 			}
210 
211 		case COPY_BUFFER:
212 			{
213 				vk.cmdFillBuffer(targetCmdBuffer, **srcBuffer, 0u, VK_WHOLE_SIZE, m_fillValue);
214 
215 				const vk::VkBufferMemoryBarrier copyBufferBarrier	=
216 				{
217 					vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType		sType
218 					DE_NULL,											// const void*			pNext
219 					vk::VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags		srcAccessMask
220 					vk::VK_ACCESS_TRANSFER_READ_BIT,					// VkAccessFlags		dstAccessMask
221 					queueFamilyIndex,									// uint32_t				srcQueueFamilyIndex
222 					queueFamilyIndex,									// uint32_t				dstQueueFamilyIndex
223 					**srcBuffer,										// VkBuffer				buffer
224 					0u,													// VkDeviceSize			offset
225 					VK_WHOLE_SIZE,										// VkDeviceSize			size
226 				};
227 
228 				vk.cmdPipelineBarrier(targetCmdBuffer,
229 									  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
230 									  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
231 									  (vk::VkDependencyFlags)0,
232 									  0, (const vk::VkMemoryBarrier*)DE_NULL,
233 									  1, &copyBufferBarrier,
234 									  0, (const vk::VkImageMemoryBarrier*)DE_NULL);
235 
236 				// Copy buffer
237 				const vk::VkBufferCopy				copyBufferRegion		=
238 				{
239 					0ull,								// VkDeviceSize		srcOffset;
240 					0ull,								// VkDeviceSize		dstOffset;
241 					bufferSize							// VkDeviceSize		size;
242 				};
243 				vk.cmdCopyBuffer(targetCmdBuffer, **srcBuffer, **dstBuffer, 1u, &copyBufferRegion);
244 				break;
245 			}
246 
247 		default:
248 			DE_ASSERT(false);
249 			break;
250 	}
251 
252 	{
253 		// Buffer validator reads buffer in compute shader
254 		const vk::VkBufferMemoryBarrier	endBufferBarrier		=
255 		{
256 			vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,		// VkStructureType		sType
257 			DE_NULL,											// const void*			pNext
258 			vk::VK_ACCESS_TRANSFER_WRITE_BIT,					// VkAccessFlags		srcAccessMask
259 			vk::VK_ACCESS_SHADER_READ_BIT,						// VkAccessFlags		dstAccessMask
260 			queueFamilyIndex,									// uint32_t				srcQueueFamilyIndex
261 			queueFamilyIndex,									// uint32_t				dstQueueFamilyIndex
262 			**dstBuffer,										// VkBuffer				buffer
263 			0u,													// VkDeviceSize			offset
264 			VK_WHOLE_SIZE,										// VkDeviceSize			size
265 		};
266 		vk.cmdPipelineBarrier(targetCmdBuffer,
267 							  vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
268 							  vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
269 							  (vk::VkDependencyFlags)0,
270 							  0, (const vk::VkMemoryBarrier*)DE_NULL,
271 							  1, &endBufferBarrier,
272 							  0, (const vk::VkImageMemoryBarrier*)DE_NULL);
273 	}
274 
275 	if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
276 	{
277 		endCommandBuffer(vk, *secondaryCmdBuffer);
278 		vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
279 	}
280 
281 	endCommandBuffer(vk, *cmdBuffer);
282 
283 	// Submit command buffer
284 	const vk::Unique<vk::VkFence>	fence		(vk::createFence(vk, device));
285 	VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
286 
287 	// Log out test data
288 	ctx.getTestContext().getLog()
289 		<< tcu::TestLog::Message << "Fill value: " << m_fillValue << tcu::TestLog::EndMessage;
290 
291 	// Validate resulting buffer
292 	if (m_validator.validateBuffer(ctx, **dstBuffer))
293 		return tcu::TestStatus::pass("Everything went OK");
294 	else
295 		return tcu::TestStatus::fail("Something went really wrong");
296 }
297 
createFillUpdateCopyBufferFloatTests(tcu::TestContext & testCtx,CmdType cmdType,CmdBufferType cmdBufferType)298 tcu::TestCaseGroup*	createFillUpdateCopyBufferFloatTests (tcu::TestContext& testCtx, CmdType cmdType, CmdBufferType cmdBufferType)
299 {
300 	struct {
301 		const union {
302 			float		flt;
303 			deUint32	uint;
304 		}							fillValue;
305 		const ValidationDataVec4	data;
306 	} testData[] = {
307 		{	{ 3.2f },
308 			{
309 				{ tcu::IVec4(1),			tcu::IVec4(2),			tcu::IVec4(3),			tcu::IVec4(4)			},
310 				{ tcu::Vec4(3.2f),			tcu::Vec4(3.2f),		tcu::Vec4(3.2f),		tcu::Vec4(3.2f)			}
311 			}
312 		},
313 		{	{ 18.8f },
314 			{
315 				{ tcu::IVec4(5),			tcu::IVec4(6),			tcu::IVec4(7),			tcu::IVec4(8)			},
316 				{ tcu::Vec4(18.8f),			tcu::Vec4(18.8f),		tcu::Vec4(18.8f),		tcu::Vec4(18.8f)		}
317 			}
318 		},
319 		{	{ 669154.6f },
320 			{
321 				{ tcu::IVec4(9),			tcu::IVec4(10),			tcu::IVec4(11),			tcu::IVec4(12)			},
322 				{ tcu::Vec4(669154.6f),		tcu::Vec4(669154.6f),	tcu::Vec4(669154.6f),	tcu::Vec4(669154.6f)	}
323 			}
324 		},
325 		{	{ -40.0f },
326 			{
327 				{ tcu::IVec4(13),			tcu::IVec4(14),			tcu::IVec4(15),			tcu::IVec4(0)			},
328 				{ tcu::Vec4(-40.0f),		tcu::Vec4(-40.0f),		tcu::Vec4(-40.0f),		tcu::Vec4(-40.0f)		}
329 			}
330 		},
331 		{	{ -915.7f },
332 			{
333 				{ tcu::IVec4(1),			tcu::IVec4(5),			tcu::IVec4(10),			tcu::IVec4(15)			},
334 				{ tcu::Vec4(-915.7f),		tcu::Vec4(-915.7f),		tcu::Vec4(-915.7f),		tcu::Vec4(-915.7f)		}
335 			}
336 		},
337 		{	{ -2548675.1f },
338 			{
339 				{ tcu::IVec4(15),			tcu::IVec4(1),			tcu::IVec4(9),			tcu::IVec4(13)			},
340 				{ tcu::Vec4(-2548675.1f),	tcu::Vec4(-2548675.1f),	tcu::Vec4(-2548675.1f),	tcu::Vec4(-2548675.1f)	}
341 			}
342 		},
343 	};
344 
345 	std::string desc = std::string(getTestTypeName(cmdType)) + " (float)";
346 
347 	de::MovePtr<tcu::TestCaseGroup>	staticTests		(new tcu::TestCaseGroup(testCtx, "static", (desc + " with static input").c_str()));
348 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
349 	{
350 		DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
351 		DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
352 		DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
353 		DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
354 
355 		const std::string name = "test_" + de::toString(ndx + 1);
356 		staticTests->addChild(new FillUpdateCopyBufferTestCase<tcu::Vec4>(
357 							testCtx, name.c_str(), testData[ndx].fillValue.uint, testData[ndx].data, cmdType, cmdBufferType));
358 	}
359 
360 	/* Add a few randomized tests */
361 	de::MovePtr<tcu::TestCaseGroup>	randomTests		(new tcu::TestCaseGroup(testCtx, "random", (desc + " with random input").c_str()));
362 	const int						testCount		= 10;
363 	de::Random						rnd				(testCtx.getCommandLine().getBaseSeed());
364 	for (int ndx = 0; ndx < testCount; ++ndx)
365 	{
366 		const std::string	name		= "test_" + de::toString(ndx + 1);
367 		const union {
368 			float		flt;
369 			deUint32	uint;
370 		}					fillValue	= { rnd.getFloat(std::numeric_limits<float>::min(), std::numeric_limits<float>::max() - 1) };
371 
372 		tcu::Vec4			refValue	(fillValue.flt);
373 		ValidationDataVec4	data		=
374 		{
375 			{ tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
376 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
377 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
378 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)) },
379 			{ refValue, refValue, refValue, refValue }
380 		};
381 
382 		DE_ASSERT(data.positions[0].x() < MAX_POSITION);
383 		DE_ASSERT(data.positions[1].x() < MAX_POSITION);
384 		DE_ASSERT(data.positions[2].x() < MAX_POSITION);
385 		DE_ASSERT(data.positions[3].x() < MAX_POSITION);
386 
387 		randomTests->addChild(new FillUpdateCopyBufferTestCase<tcu::Vec4>(testCtx, name.c_str(), fillValue.uint, data, cmdType, cmdBufferType));
388 	}
389 
390 	const std::string				groupName		= getCmdBufferTypeStr(cmdBufferType);
391 	de::MovePtr<tcu::TestCaseGroup>	primaryGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), (desc + " using " + groupName.c_str() + " command buffer").c_str()));
392 	primaryGroup->addChild(staticTests.release());
393 	primaryGroup->addChild(randomTests.release());
394 
395 	return primaryGroup.release();
396 }
397 
createFillUpdateCopyBufferFloatTests(tcu::TestContext & testCtx,CmdType cmdType)398 tcu::TestCaseGroup*	createFillUpdateCopyBufferFloatTests (tcu::TestContext& testCtx, CmdType cmdType)
399 {
400 	const std::string desc = std::string(getTestTypeName(cmdType)) + " (float)";
401 	de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "float_buffer", desc.c_str()));
402 	testGroup->addChild(createFillUpdateCopyBufferFloatTests(testCtx, cmdType, CMD_BUFFER_PRIMARY));
403 	testGroup->addChild(createFillUpdateCopyBufferFloatTests(testCtx, cmdType, CMD_BUFFER_SECONDARY));
404 	return testGroup.release();
405 }
406 
createFillUpdateCopyBufferIntegerTests(tcu::TestContext & testCtx,CmdType cmdType,CmdBufferType cmdBufferType)407 tcu::TestCaseGroup*	createFillUpdateCopyBufferIntegerTests (tcu::TestContext& testCtx, CmdType cmdType, CmdBufferType cmdBufferType)
408 {
409 	struct {
410 		const union {
411 			deInt32		integer;
412 			deUint32	uint;
413 		}							fillValue;
414 		const ValidationDataIVec4	data;
415 	} testData[] = {
416 		{	{ 3 },
417 			{
418 				{ tcu::IVec4(1),			tcu::IVec4(2),			tcu::IVec4(3),			tcu::IVec4(4)			},
419 				{ tcu::IVec4(3),			tcu::IVec4(3),			tcu::IVec4(3),			tcu::IVec4(3)			}
420 			}
421 		},
422 		{	{ 18 },
423 			{
424 				{ tcu::IVec4(5),			tcu::IVec4(6),			tcu::IVec4(7),			tcu::IVec4(8)			},
425 				{ tcu::IVec4(18),			tcu::IVec4(18),			tcu::IVec4(18),			tcu::IVec4(18)			}
426 			}
427 		},
428 		{	{ 669154 },
429 			{
430 				{ tcu::IVec4(9),			tcu::IVec4(10),			tcu::IVec4(11),			tcu::IVec4(12)			},
431 				{ tcu::IVec4(669154),		tcu::IVec4(669154),		tcu::IVec4(669154),		tcu::IVec4(669154)		}
432 			}
433 		},
434 		{	{ -40 },
435 			{
436 				{ tcu::IVec4(13),			tcu::IVec4(14),			tcu::IVec4(15),			tcu::IVec4(0)			},
437 				{ tcu::IVec4(-40),			tcu::IVec4(-40),		tcu::IVec4(-40),		tcu::IVec4(-40)			}
438 			}
439 		},
440 		{	{ -915 },
441 			{
442 				{ tcu::IVec4(1),			tcu::IVec4(5),			tcu::IVec4(10),			tcu::IVec4(15)			},
443 				{ tcu::IVec4(-915),			tcu::IVec4(-915),		tcu::IVec4(-915),		tcu::IVec4(-915)		}
444 			}
445 		},
446 		{	{ -2548675 },
447 			{
448 				{ tcu::IVec4(15),			tcu::IVec4(1),			tcu::IVec4(9),			tcu::IVec4(13)			},
449 				{ tcu::IVec4(-2548675),		tcu::IVec4(-2548675),	tcu::IVec4(-2548675),	tcu::IVec4(-2548675)	}
450 			}
451 		},
452 	};
453 
454 
455 	std::string desc = std::string(getTestTypeName(cmdType)) + " (integer)";
456 	de::MovePtr<tcu::TestCaseGroup>	staticTests		(new tcu::TestCaseGroup(testCtx, "static", (desc + " with static input").c_str()));
457 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
458 	{
459 		DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
460 		DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
461 		DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
462 		DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
463 
464 		const std::string name = "test_" + de::toString(ndx + 1);
465 		staticTests->addChild(new FillUpdateCopyBufferTestCase<tcu::IVec4>(
466 							testCtx, name.c_str(), testData[ndx].fillValue.uint, testData[ndx].data, cmdType, cmdBufferType));
467 	}
468 
469 	/* Add a few randomized tests */
470 	de::MovePtr<tcu::TestCaseGroup>	randomTests		(new tcu::TestCaseGroup(testCtx, "random", (desc + " with random input").c_str()));
471 	const int						testCount		= 10;
472 	de::Random						rnd				(testCtx.getCommandLine().getBaseSeed());
473 	for (int ndx = 0; ndx < testCount; ++ndx)
474 	{
475 		const std::string	name		= "test_" + de::toString(ndx + 1);
476 		const union {
477 			deInt32		integer;
478 			deUint32	uint;
479 		}					fillValue	= { rnd.getInt(std::numeric_limits<deInt32>::min(), std::numeric_limits<deInt32>::max() - 1) };
480 
481 		tcu::IVec4			refValue	(fillValue.integer);
482 		ValidationDataIVec4	data		=
483 		{
484 			{ tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
485 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
486 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
487 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)) },
488 			{ refValue, refValue, refValue, refValue }
489 		};
490 
491 		DE_ASSERT(data.positions[0].x() < MAX_POSITION);
492 		DE_ASSERT(data.positions[1].x() < MAX_POSITION);
493 		DE_ASSERT(data.positions[2].x() < MAX_POSITION);
494 		DE_ASSERT(data.positions[3].x() < MAX_POSITION);
495 
496 		randomTests->addChild(new FillUpdateCopyBufferTestCase<tcu::IVec4>(testCtx, name.c_str(), fillValue.uint, data, cmdType, cmdBufferType));
497 	}
498 
499 	const std::string				groupName		= getCmdBufferTypeStr(cmdBufferType);
500 	de::MovePtr<tcu::TestCaseGroup>	primaryGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), (desc + " using " + groupName.c_str() + " command buffer").c_str()));
501 	primaryGroup->addChild(staticTests.release());
502 	primaryGroup->addChild(randomTests.release());
503 
504 	return primaryGroup.release();
505 }
506 
createFillUpdateCopyBufferIntegerTests(tcu::TestContext & testCtx,CmdType cmdType)507 tcu::TestCaseGroup*	createFillUpdateCopyBufferIntegerTests (tcu::TestContext& testCtx, CmdType cmdType)
508 {
509 	const std::string desc = std::string(getTestTypeName(cmdType)) + " (integer)";
510 	de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "integer_buffer", desc.c_str()));
511 	testGroup->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, cmdType, CMD_BUFFER_PRIMARY));
512 	testGroup->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, cmdType, CMD_BUFFER_SECONDARY));
513 	return testGroup.release();
514 }
515 
createFillUpdateCopyBufferUnsignedTests(tcu::TestContext & testCtx,CmdType cmdType,CmdBufferType cmdBufferType)516 tcu::TestCaseGroup*	createFillUpdateCopyBufferUnsignedTests (tcu::TestContext& testCtx, CmdType cmdType, CmdBufferType cmdBufferType)
517 {
518 	struct {
519 		deUint32					fillValue;
520 		const ValidationDataUVec4	data;
521 	} testData[] = {
522 		{	3u,
523 			{
524 				{ tcu::IVec4(1),			tcu::IVec4(2),			tcu::IVec4(3),			tcu::IVec4(4)			},
525 				{ tcu::UVec4(3u),			tcu::UVec4(3u),			tcu::UVec4(3u),			tcu::UVec4(3u)			}
526 			}
527 		},
528 		{	18u,
529 			{
530 				{ tcu::IVec4(8),			tcu::IVec4(7),			tcu::IVec4(6),			tcu::IVec4(5)			},
531 				{ tcu::UVec4(18u),			tcu::UVec4(18u),		tcu::UVec4(18u),		tcu::UVec4(18u)			}
532 			}
533 		},
534 		{	669154u,
535 			{
536 				{ tcu::IVec4(9),			tcu::IVec4(10),			tcu::IVec4(11),			tcu::IVec4(12)			},
537 				{ tcu::UVec4(669154u),		tcu::UVec4(669154u),	tcu::UVec4(669154u),	tcu::UVec4(669154u)		}
538 			}
539 		},
540 		{	40u,
541 			{
542 				{ tcu::IVec4(13),			tcu::IVec4(14),			tcu::IVec4(15),			tcu::IVec4(0)			},
543 				{ tcu::UVec4(40u),			tcu::UVec4(40u),		tcu::UVec4(40u),		tcu::UVec4(40u)			}
544 			}
545 		},
546 		{	915u,
547 			{
548 				{ tcu::IVec4(1),			tcu::IVec4(7),			tcu::IVec4(13),			tcu::IVec4(11)			},
549 				{ tcu::UVec4(915u),			tcu::UVec4(915u),		tcu::UVec4(915u),		tcu::UVec4(915u)		}
550 			}
551 		},
552 		{	2548675u,
553 			{
554 				{ tcu::IVec4(15),			tcu::IVec4(1),			tcu::IVec4(9),			tcu::IVec4(13)			},
555 				{ tcu::UVec4(2548675u),		tcu::UVec4(2548675u),	tcu::UVec4(2548675u),	tcu::UVec4(2548675u)	}
556 			}
557 		},
558 	};
559 
560 	std::string desc = std::string(getTestTypeName(cmdType)) + " (unsigned)";
561 	de::MovePtr<tcu::TestCaseGroup>	staticTests		(new tcu::TestCaseGroup(testCtx, "static", (desc + " with static input").c_str()));
562 
563 	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
564 	{
565 		DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
566 		DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
567 		DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
568 		DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
569 
570 		const std::string name = "test_" + de::toString(ndx + 1);
571 		staticTests->addChild(new FillUpdateCopyBufferTestCase<tcu::UVec4>(
572 							testCtx, name.c_str(), testData[ndx].fillValue, testData[ndx].data, cmdType, cmdBufferType));
573 	}
574 
575 	/* Add a few randomized tests */
576 	de::MovePtr<tcu::TestCaseGroup>	randomTests		(new tcu::TestCaseGroup(testCtx, "random", (desc + " with random input").c_str()));
577 	const int						testCount		= 10;
578 	de::Random						rnd				(testCtx.getCommandLine().getBaseSeed());
579 	for (int ndx = 0; ndx < testCount; ++ndx)
580 	{
581 		const std::string	name		= "test_" + de::toString(ndx + 1);
582 		deUint32			fillValue	= rnd.getUint32();
583 		tcu::UVec4			refValue	(fillValue);
584 		ValidationDataUVec4	data		=
585 		{
586 			{ tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
587 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
588 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)),
589 			  tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1)) },
590 			{ refValue, refValue, refValue, refValue }
591 		};
592 
593 		DE_ASSERT(data.positions[0].x() < MAX_POSITION);
594 		DE_ASSERT(data.positions[1].x() < MAX_POSITION);
595 		DE_ASSERT(data.positions[2].x() < MAX_POSITION);
596 		DE_ASSERT(data.positions[3].x() < MAX_POSITION);
597 
598 		randomTests->addChild(new FillUpdateCopyBufferTestCase<tcu::UVec4>(testCtx, name.c_str(), fillValue, data, cmdType, cmdBufferType));
599 	}
600 
601 	const std::string				groupName		= getCmdBufferTypeStr(cmdBufferType);
602 	de::MovePtr<tcu::TestCaseGroup>	testGroup	(new tcu::TestCaseGroup(testCtx, groupName.c_str(), (desc + " using " + groupName.c_str() + " command buffer").c_str()));
603 	testGroup->addChild(staticTests.release());
604 	testGroup->addChild(randomTests.release());
605 
606 	return testGroup.release();
607 }
608 
createFillUpdateCopyBufferUnsignedTests(tcu::TestContext & testCtx,CmdType cmdType)609 tcu::TestCaseGroup*	createFillUpdateCopyBufferUnsignedTests (tcu::TestContext& testCtx, CmdType cmdType)
610 {
611 	const std::string desc = std::string(getTestTypeName(cmdType)) + " (unsinged)";
612 	de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "unsigned_buffer", desc.c_str()));
613 	testGroup->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, cmdType, CMD_BUFFER_PRIMARY));
614 	testGroup->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, cmdType, CMD_BUFFER_SECONDARY));
615 	return testGroup.release();
616 }
617 
618 } // anonymous
619 
createFillBufferTests(tcu::TestContext & testCtx)620 tcu::TestCaseGroup*	createFillBufferTests (tcu::TestContext& testCtx)
621 {
622 	de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "fill", "Fill Buffer Tests"));
623 
624 	testGroup->addChild(createFillUpdateCopyBufferFloatTests(testCtx, FILL_BUFFER));
625 	testGroup->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, FILL_BUFFER));
626 	testGroup->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, FILL_BUFFER));
627 
628 	return testGroup.release();
629 }
630 
createUpdateBufferTests(tcu::TestContext & testCtx)631 tcu::TestCaseGroup*	createUpdateBufferTests (tcu::TestContext& testCtx)
632 {
633 	de::MovePtr<tcu::TestCaseGroup> updateTests (new tcu::TestCaseGroup(testCtx, "update", "Update Buffer Tests"));
634 
635 	updateTests->addChild(createFillUpdateCopyBufferFloatTests(testCtx, UPDATE_BUFFER));
636 	updateTests->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, UPDATE_BUFFER));
637 	updateTests->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, UPDATE_BUFFER));
638 
639 	return updateTests.release();
640 }
641 
createCopyBufferTests(tcu::TestContext & testCtx)642 tcu::TestCaseGroup*	createCopyBufferTests (tcu::TestContext& testCtx)
643 {
644 	de::MovePtr<tcu::TestCaseGroup> copyTests (new tcu::TestCaseGroup(testCtx, "copy", "Copy Buffer Tests"));
645 
646 	copyTests->addChild(createFillUpdateCopyBufferFloatTests(testCtx, COPY_BUFFER));
647 	copyTests->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, COPY_BUFFER));
648 	copyTests->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, COPY_BUFFER));
649 
650 	return copyTests.release();
651 }
652 
653 } // ProtectedMem
654 } // vkt
655