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