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, ©BufferBarrier,
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, ©BufferRegion);
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