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, ©BufferBarrier, 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, ©BufferRegion);
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