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