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