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, ©BufferBarrier,
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, ©BufferRegion);
244 break;
245 }
246
247 default:
248 DE_ASSERT(false);
249 break;
250 }
251
252 {
253 // Buffer validator reads buffer in compute shader
254 const vk::VkBufferMemoryBarrier endBufferBarrier = {
255 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