• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2017 The Khronos Group Inc.
6  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *//*!
21  * \file
22  * \brief Protected memory fill/update/copy buffer tests
23  *//*--------------------------------------------------------------------*/
24 
25 #include "vktProtectedMemFillUpdateCopyBufferTests.hpp"
26 
27 #include <limits>
28 #include "deRandom.hpp"
29 #include "tcuTestLog.hpp"
30 #include "tcuVector.hpp"
31 
32 #include "vkPrograms.hpp"
33 #include "vktTestCase.hpp"
34 #include "vktTestGroupUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkCmdUtil.hpp"
38 
39 #include "vktProtectedMemContext.hpp"
40 #include "vktProtectedMemUtils.hpp"
41 #include "vktProtectedMemBufferValidator.hpp"
42 
43 namespace vkt
44 {
45 namespace ProtectedMem
46 {
47 
48 namespace
49 {
50 
51 enum
52 {
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 nullptr;
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             nullptr,
188             VK_NULL_HANDLE,                        // renderPass
189             0u,                                    // subpass
190             VK_NULL_HANDLE,                        // 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             nullptr,                                     // 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, nullptr, 1, &copyBufferBarrier, 0, nullptr);
235 
236         // Copy buffer
237         const vk::VkBufferCopy copyBufferRegion = {
238             0ull,      // VkDeviceSize srcOffset;
239             0ull,      // VkDeviceSize dstOffset;
240             bufferSize // VkDeviceSize size;
241         };
242         vk.cmdCopyBuffer(targetCmdBuffer, **srcBuffer, **dstBuffer, 1u, &copyBufferRegion);
243         break;
244     }
245 
246     default:
247         DE_ASSERT(false);
248         break;
249     }
250 
251     {
252         // Buffer validator reads buffer in compute shader
253         const vk::VkBufferMemoryBarrier endBufferBarrier = {
254             vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType        sType
255             nullptr,                                     // const void*            pNext
256             vk::VK_ACCESS_TRANSFER_WRITE_BIT,            // VkAccessFlags        srcAccessMask
257             vk::VK_ACCESS_SHADER_READ_BIT,               // VkAccessFlags        dstAccessMask
258             queueFamilyIndex,                            // uint32_t                srcQueueFamilyIndex
259             queueFamilyIndex,                            // uint32_t                dstQueueFamilyIndex
260             **dstBuffer,                                 // VkBuffer                buffer
261             0u,                                          // VkDeviceSize            offset
262             VK_WHOLE_SIZE,                               // VkDeviceSize            size
263         };
264         vk.cmdPipelineBarrier(targetCmdBuffer, vk::VK_PIPELINE_STAGE_TRANSFER_BIT,
265                               vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0, 0, nullptr, 1,
266                               &endBufferBarrier, 0, nullptr);
267     }
268 
269     if (m_cmdBufferType == CMD_BUFFER_SECONDARY)
270     {
271         endCommandBuffer(vk, *secondaryCmdBuffer);
272         vk.cmdExecuteCommands(*cmdBuffer, 1u, &secondaryCmdBuffer.get());
273     }
274 
275     endCommandBuffer(vk, *cmdBuffer);
276 
277     // Submit command buffer
278     const vk::Unique<vk::VkFence> fence(vk::createFence(vk, device));
279     VK_CHECK(queueSubmit(ctx, PROTECTION_ENABLED, queue, *cmdBuffer, *fence, ~0ull));
280 
281     // Log out test data
282     ctx.getTestContext().getLog() << tcu::TestLog::Message << "Fill value: " << m_fillValue << tcu::TestLog::EndMessage;
283 
284     // Validate resulting buffer
285     if (m_validator.validateBuffer(ctx, **dstBuffer))
286         return tcu::TestStatus::pass("Everything went OK");
287     else
288         return tcu::TestStatus::fail("Something went really wrong");
289 }
290 
createFillUpdateCopyBufferFloatTests(tcu::TestContext & testCtx,CmdType cmdType,CmdBufferType cmdBufferType)291 tcu::TestCaseGroup *createFillUpdateCopyBufferFloatTests(tcu::TestContext &testCtx, CmdType cmdType,
292                                                          CmdBufferType cmdBufferType)
293 {
294     struct
295     {
296         const union
297         {
298             float flt;
299             uint32_t uint;
300         } fillValue;
301         const ValidationDataVec4 data;
302     } testData[] = {
303         {{3.2f},
304          {{tcu::IVec4(1), tcu::IVec4(2), tcu::IVec4(3), tcu::IVec4(4)},
305           {tcu::Vec4(3.2f), tcu::Vec4(3.2f), tcu::Vec4(3.2f), tcu::Vec4(3.2f)}}},
306         {{18.8f},
307          {{tcu::IVec4(5), tcu::IVec4(6), tcu::IVec4(7), tcu::IVec4(8)},
308           {tcu::Vec4(18.8f), tcu::Vec4(18.8f), tcu::Vec4(18.8f), tcu::Vec4(18.8f)}}},
309         {{669154.6f},
310          {{tcu::IVec4(9), tcu::IVec4(10), tcu::IVec4(11), tcu::IVec4(12)},
311           {tcu::Vec4(669154.6f), tcu::Vec4(669154.6f), tcu::Vec4(669154.6f), tcu::Vec4(669154.6f)}}},
312         {{-40.0f},
313          {{tcu::IVec4(13), tcu::IVec4(14), tcu::IVec4(15), tcu::IVec4(0)},
314           {tcu::Vec4(-40.0f), tcu::Vec4(-40.0f), tcu::Vec4(-40.0f), tcu::Vec4(-40.0f)}}},
315         {{-915.7f},
316          {{tcu::IVec4(1), tcu::IVec4(5), tcu::IVec4(10), tcu::IVec4(15)},
317           {tcu::Vec4(-915.7f), tcu::Vec4(-915.7f), tcu::Vec4(-915.7f), tcu::Vec4(-915.7f)}}},
318         {{-2548675.1f},
319          {{tcu::IVec4(15), tcu::IVec4(1), tcu::IVec4(9), tcu::IVec4(13)},
320           {tcu::Vec4(-2548675.1f), tcu::Vec4(-2548675.1f), tcu::Vec4(-2548675.1f), tcu::Vec4(-2548675.1f)}}},
321     };
322 
323     std::string desc = std::string(getTestTypeName(cmdType)) + " (float)";
324 
325     de::MovePtr<tcu::TestCaseGroup> staticTests(new tcu::TestCaseGroup(testCtx, "static"));
326     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
327     {
328         DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
329         DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
330         DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
331         DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
332 
333         const std::string name = "test_" + de::toString(ndx + 1);
334         staticTests->addChild(new FillUpdateCopyBufferTestCase<tcu::Vec4>(
335             testCtx, name.c_str(), testData[ndx].fillValue.uint, testData[ndx].data, cmdType, cmdBufferType,
336             vk::VK_FORMAT_R32G32B32A32_SFLOAT));
337     }
338 
339     /* Add a few randomized tests */
340     de::MovePtr<tcu::TestCaseGroup> randomTests(new tcu::TestCaseGroup(testCtx, "random"));
341     const int testCount = 10;
342     de::Random rnd(testCtx.getCommandLine().getBaseSeed());
343     for (int ndx = 0; ndx < testCount; ++ndx)
344     {
345         const std::string name = "test_" + de::toString(ndx + 1);
346         const union
347         {
348             float flt;
349             uint32_t uint;
350         } fillValue = {rnd.getFloat(std::numeric_limits<float>::min(), std::numeric_limits<float>::max() - 1)};
351 
352         const tcu::Vec4 refValue(fillValue.flt);
353         const tcu::IVec4 vec0 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
354         const tcu::IVec4 vec1 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
355         const tcu::IVec4 vec2 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
356         const tcu::IVec4 vec3 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
357 
358         ValidationDataVec4 data = {{vec0, vec1, vec2, vec3}, {refValue, refValue, refValue, refValue}};
359 
360         DE_ASSERT(data.positions[0].x() < MAX_POSITION);
361         DE_ASSERT(data.positions[1].x() < MAX_POSITION);
362         DE_ASSERT(data.positions[2].x() < MAX_POSITION);
363         DE_ASSERT(data.positions[3].x() < MAX_POSITION);
364 
365         randomTests->addChild(new FillUpdateCopyBufferTestCase<tcu::Vec4>(
366             testCtx, name.c_str(), fillValue.uint, data, cmdType, cmdBufferType, vk::VK_FORMAT_R32G32B32A32_SFLOAT));
367     }
368 
369     const std::string groupName = getCmdBufferTypeStr(cmdBufferType);
370     de::MovePtr<tcu::TestCaseGroup> primaryGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
371     primaryGroup->addChild(staticTests.release());
372     primaryGroup->addChild(randomTests.release());
373 
374     return primaryGroup.release();
375 }
376 
createFillUpdateCopyBufferFloatTests(tcu::TestContext & testCtx,CmdType cmdType)377 tcu::TestCaseGroup *createFillUpdateCopyBufferFloatTests(tcu::TestContext &testCtx, CmdType cmdType)
378 {
379     const std::string desc = std::string(getTestTypeName(cmdType)) + " (float)";
380     de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "float_buffer"));
381     testGroup->addChild(createFillUpdateCopyBufferFloatTests(testCtx, cmdType, CMD_BUFFER_PRIMARY));
382     testGroup->addChild(createFillUpdateCopyBufferFloatTests(testCtx, cmdType, CMD_BUFFER_SECONDARY));
383     return testGroup.release();
384 }
385 
createFillUpdateCopyBufferIntegerTests(tcu::TestContext & testCtx,CmdType cmdType,CmdBufferType cmdBufferType)386 tcu::TestCaseGroup *createFillUpdateCopyBufferIntegerTests(tcu::TestContext &testCtx, CmdType cmdType,
387                                                            CmdBufferType cmdBufferType)
388 {
389     struct
390     {
391         const union
392         {
393             int32_t integer;
394             uint32_t uint;
395         } fillValue;
396         const ValidationDataIVec4 data;
397     } testData[] = {
398         {{3},
399          {{tcu::IVec4(1), tcu::IVec4(2), tcu::IVec4(3), tcu::IVec4(4)},
400           {tcu::IVec4(3), tcu::IVec4(3), tcu::IVec4(3), tcu::IVec4(3)}}},
401         {{18},
402          {{tcu::IVec4(5), tcu::IVec4(6), tcu::IVec4(7), tcu::IVec4(8)},
403           {tcu::IVec4(18), tcu::IVec4(18), tcu::IVec4(18), tcu::IVec4(18)}}},
404         {{669154},
405          {{tcu::IVec4(9), tcu::IVec4(10), tcu::IVec4(11), tcu::IVec4(12)},
406           {tcu::IVec4(669154), tcu::IVec4(669154), tcu::IVec4(669154), tcu::IVec4(669154)}}},
407         {{-40},
408          {{tcu::IVec4(13), tcu::IVec4(14), tcu::IVec4(15), tcu::IVec4(0)},
409           {tcu::IVec4(-40), tcu::IVec4(-40), tcu::IVec4(-40), tcu::IVec4(-40)}}},
410         {{-915},
411          {{tcu::IVec4(1), tcu::IVec4(5), tcu::IVec4(10), tcu::IVec4(15)},
412           {tcu::IVec4(-915), tcu::IVec4(-915), tcu::IVec4(-915), tcu::IVec4(-915)}}},
413         {{-2548675},
414          {{tcu::IVec4(15), tcu::IVec4(1), tcu::IVec4(9), tcu::IVec4(13)},
415           {tcu::IVec4(-2548675), tcu::IVec4(-2548675), tcu::IVec4(-2548675), tcu::IVec4(-2548675)}}},
416     };
417 
418     std::string desc = std::string(getTestTypeName(cmdType)) + " (integer)";
419     de::MovePtr<tcu::TestCaseGroup> staticTests(new tcu::TestCaseGroup(testCtx, "static"));
420     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
421     {
422         DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
423         DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
424         DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
425         DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
426 
427         const std::string name = "test_" + de::toString(ndx + 1);
428         staticTests->addChild(new FillUpdateCopyBufferTestCase<tcu::IVec4>(
429             testCtx, name.c_str(), testData[ndx].fillValue.uint, testData[ndx].data, cmdType, cmdBufferType,
430             vk::VK_FORMAT_R32G32B32A32_SINT));
431     }
432 
433     /* Add a few randomized tests */
434     de::MovePtr<tcu::TestCaseGroup> randomTests(new tcu::TestCaseGroup(testCtx, "random"));
435     const int testCount = 10;
436     de::Random rnd(testCtx.getCommandLine().getBaseSeed());
437     for (int ndx = 0; ndx < testCount; ++ndx)
438     {
439         const std::string name = "test_" + de::toString(ndx + 1);
440         const union
441         {
442             int32_t integer;
443             uint32_t uint;
444         } fillValue = {rnd.getInt(std::numeric_limits<int32_t>::min(), std::numeric_limits<int32_t>::max() - 1)};
445 
446         const tcu::IVec4 refValue(fillValue.integer);
447         const tcu::IVec4 v0 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
448         const tcu::IVec4 v1 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
449         const tcu::IVec4 v2 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
450         const tcu::IVec4 v3 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
451 
452         ValidationDataIVec4 data = {{v0, v1, v2, v3}, {refValue, refValue, refValue, refValue}};
453 
454         DE_ASSERT(data.positions[0].x() < MAX_POSITION);
455         DE_ASSERT(data.positions[1].x() < MAX_POSITION);
456         DE_ASSERT(data.positions[2].x() < MAX_POSITION);
457         DE_ASSERT(data.positions[3].x() < MAX_POSITION);
458 
459         randomTests->addChild(new FillUpdateCopyBufferTestCase<tcu::IVec4>(
460             testCtx, name.c_str(), fillValue.uint, data, cmdType, cmdBufferType, vk::VK_FORMAT_R32G32B32A32_SINT));
461     }
462 
463     const std::string groupName = getCmdBufferTypeStr(cmdBufferType);
464     de::MovePtr<tcu::TestCaseGroup> primaryGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
465     primaryGroup->addChild(staticTests.release());
466     primaryGroup->addChild(randomTests.release());
467 
468     return primaryGroup.release();
469 }
470 
createFillUpdateCopyBufferIntegerTests(tcu::TestContext & testCtx,CmdType cmdType)471 tcu::TestCaseGroup *createFillUpdateCopyBufferIntegerTests(tcu::TestContext &testCtx, CmdType cmdType)
472 {
473     const std::string desc = std::string(getTestTypeName(cmdType)) + " (integer)";
474     de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "integer_buffer"));
475     testGroup->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, cmdType, CMD_BUFFER_PRIMARY));
476     testGroup->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, cmdType, CMD_BUFFER_SECONDARY));
477     return testGroup.release();
478 }
479 
createFillUpdateCopyBufferUnsignedTests(tcu::TestContext & testCtx,CmdType cmdType,CmdBufferType cmdBufferType)480 tcu::TestCaseGroup *createFillUpdateCopyBufferUnsignedTests(tcu::TestContext &testCtx, CmdType cmdType,
481                                                             CmdBufferType cmdBufferType)
482 {
483     struct
484     {
485         uint32_t fillValue;
486         const ValidationDataUVec4 data;
487     } testData[] = {
488         {3u,
489          {{tcu::IVec4(1), tcu::IVec4(2), tcu::IVec4(3), tcu::IVec4(4)},
490           {tcu::UVec4(3u), tcu::UVec4(3u), tcu::UVec4(3u), tcu::UVec4(3u)}}},
491         {18u,
492          {{tcu::IVec4(8), tcu::IVec4(7), tcu::IVec4(6), tcu::IVec4(5)},
493           {tcu::UVec4(18u), tcu::UVec4(18u), tcu::UVec4(18u), tcu::UVec4(18u)}}},
494         {669154u,
495          {{tcu::IVec4(9), tcu::IVec4(10), tcu::IVec4(11), tcu::IVec4(12)},
496           {tcu::UVec4(669154u), tcu::UVec4(669154u), tcu::UVec4(669154u), tcu::UVec4(669154u)}}},
497         {40u,
498          {{tcu::IVec4(13), tcu::IVec4(14), tcu::IVec4(15), tcu::IVec4(0)},
499           {tcu::UVec4(40u), tcu::UVec4(40u), tcu::UVec4(40u), tcu::UVec4(40u)}}},
500         {915u,
501          {{tcu::IVec4(1), tcu::IVec4(7), tcu::IVec4(13), tcu::IVec4(11)},
502           {tcu::UVec4(915u), tcu::UVec4(915u), tcu::UVec4(915u), tcu::UVec4(915u)}}},
503         {2548675u,
504          {{tcu::IVec4(15), tcu::IVec4(1), tcu::IVec4(9), tcu::IVec4(13)},
505           {tcu::UVec4(2548675u), tcu::UVec4(2548675u), tcu::UVec4(2548675u), tcu::UVec4(2548675u)}}},
506     };
507 
508     std::string desc = std::string(getTestTypeName(cmdType)) + " (unsigned)";
509     de::MovePtr<tcu::TestCaseGroup> staticTests(new tcu::TestCaseGroup(testCtx, "static"));
510 
511     for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(testData); ++ndx)
512     {
513         DE_ASSERT(testData[ndx].data.positions[0].x() < MAX_POSITION);
514         DE_ASSERT(testData[ndx].data.positions[1].x() < MAX_POSITION);
515         DE_ASSERT(testData[ndx].data.positions[2].x() < MAX_POSITION);
516         DE_ASSERT(testData[ndx].data.positions[3].x() < MAX_POSITION);
517 
518         const std::string name = "test_" + de::toString(ndx + 1);
519         staticTests->addChild(new FillUpdateCopyBufferTestCase<tcu::UVec4>(
520             testCtx, name.c_str(), testData[ndx].fillValue, testData[ndx].data, cmdType, cmdBufferType,
521             vk::VK_FORMAT_R32G32B32A32_UINT));
522     }
523 
524     /* Add a few randomized tests */
525     de::MovePtr<tcu::TestCaseGroup> randomTests(new tcu::TestCaseGroup(testCtx, "random"));
526     const int testCount = 10;
527     de::Random rnd(testCtx.getCommandLine().getBaseSeed());
528     for (int ndx = 0; ndx < testCount; ++ndx)
529     {
530         const std::string name   = "test_" + de::toString(ndx + 1);
531         const uint32_t fillValue = rnd.getUint32();
532         const tcu::UVec4 refValue(fillValue);
533         const tcu::IVec4 v0 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
534         const tcu::IVec4 v1 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
535         const tcu::IVec4 v2 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
536         const tcu::IVec4 v3 = tcu::IVec4(rnd.getInt(0, MAX_POSITION - 1));
537 
538         ValidationDataUVec4 data = {{v0, v1, v2, v3}, {refValue, refValue, refValue, refValue}};
539 
540         DE_ASSERT(data.positions[0].x() < MAX_POSITION);
541         DE_ASSERT(data.positions[1].x() < MAX_POSITION);
542         DE_ASSERT(data.positions[2].x() < MAX_POSITION);
543         DE_ASSERT(data.positions[3].x() < MAX_POSITION);
544 
545         randomTests->addChild(new FillUpdateCopyBufferTestCase<tcu::UVec4>(
546             testCtx, name.c_str(), fillValue, data, cmdType, cmdBufferType, vk::VK_FORMAT_R32G32B32A32_UINT));
547     }
548 
549     const std::string groupName = getCmdBufferTypeStr(cmdBufferType);
550     de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, groupName.c_str()));
551     testGroup->addChild(staticTests.release());
552     testGroup->addChild(randomTests.release());
553 
554     return testGroup.release();
555 }
556 
createFillUpdateCopyBufferUnsignedTests(tcu::TestContext & testCtx,CmdType cmdType)557 tcu::TestCaseGroup *createFillUpdateCopyBufferUnsignedTests(tcu::TestContext &testCtx, CmdType cmdType)
558 {
559     const std::string desc = std::string(getTestTypeName(cmdType)) + " (unsinged)";
560     de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "unsigned_buffer"));
561     testGroup->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, cmdType, CMD_BUFFER_PRIMARY));
562     testGroup->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, cmdType, CMD_BUFFER_SECONDARY));
563     return testGroup.release();
564 }
565 
566 } // namespace
567 
createFillBufferTests(tcu::TestContext & testCtx)568 tcu::TestCaseGroup *createFillBufferTests(tcu::TestContext &testCtx)
569 {
570     // Fill Buffer Tests
571     de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "fill"));
572 
573     testGroup->addChild(createFillUpdateCopyBufferFloatTests(testCtx, FILL_BUFFER));
574     testGroup->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, FILL_BUFFER));
575     testGroup->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, FILL_BUFFER));
576 
577     return testGroup.release();
578 }
579 
createUpdateBufferTests(tcu::TestContext & testCtx)580 tcu::TestCaseGroup *createUpdateBufferTests(tcu::TestContext &testCtx)
581 {
582     // Update Buffer Tests
583     de::MovePtr<tcu::TestCaseGroup> updateTests(new tcu::TestCaseGroup(testCtx, "update"));
584 
585     updateTests->addChild(createFillUpdateCopyBufferFloatTests(testCtx, UPDATE_BUFFER));
586     updateTests->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, UPDATE_BUFFER));
587     updateTests->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, UPDATE_BUFFER));
588 
589     return updateTests.release();
590 }
591 
createCopyBufferTests(tcu::TestContext & testCtx)592 tcu::TestCaseGroup *createCopyBufferTests(tcu::TestContext &testCtx)
593 {
594     de::MovePtr<tcu::TestCaseGroup> copyTests(new tcu::TestCaseGroup(testCtx, "copy"));
595 
596     copyTests->addChild(createFillUpdateCopyBufferFloatTests(testCtx, COPY_BUFFER));
597     copyTests->addChild(createFillUpdateCopyBufferIntegerTests(testCtx, COPY_BUFFER));
598     copyTests->addChild(createFillUpdateCopyBufferUnsignedTests(testCtx, COPY_BUFFER));
599 
600     return copyTests.release();
601 }
602 
603 } // namespace ProtectedMem
604 } // namespace vkt
605