1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Vulkan Buffers Tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktApiBufferTests.hpp"
26 #include "gluVarType.hpp"
27 #include "deStringUtil.hpp"
28 #include "tcuTestLog.hpp"
29 #include "vkPlatform.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vktTestCase.hpp"
47 ALLOCATION_KIND_SUBALLOCATED = 0,
48 ALLOCATION_KIND_DEDICATED,
53 struct BufferCaseParameters
55 VkBufferUsageFlags usage;
56 VkBufferCreateFlags flags;
57 VkSharingMode sharingMode;
60 class BufferTestInstance : public TestInstance
63 BufferTestInstance (Context& ctx,
64 BufferCaseParameters testCase)
66 , m_testCase (testCase)
67 , m_sparseContext (createSparseContext())
70 virtual tcu::TestStatus iterate (void);
71 virtual tcu::TestStatus bufferCreateAndAllocTest (VkDeviceSize size);
74 BufferCaseParameters m_testCase;
76 // Wrapper functions around m_context calls to support sparse cases.
77 VkPhysicalDevice getPhysicalDevice (void) const
79 // Same in sparse and regular case
80 return m_context.getPhysicalDevice();
83 VkDevice getDevice (void) const
87 return *(m_sparseContext->m_device);
89 return m_context.getDevice();
92 const InstanceInterface& getInstanceInterface (void) const
94 // Same in sparse and regular case
95 return m_context.getInstanceInterface();
98 const DeviceInterface& getDeviceInterface (void) const
102 return m_sparseContext->m_deviceInterface;
104 return m_context.getDeviceInterface();
107 deUint32 getUniversalQueueFamilyIndex (void) const
111 return m_sparseContext->m_queueFamilyIndex;
113 return m_context.getUniversalQueueFamilyIndex();
117 // Custom context for sparse cases
120 SparseContext (Move<VkDevice>& device,
121 const deUint32 queueFamilyIndex,
122 const InstanceInterface& interface)
124 , m_queueFamilyIndex (queueFamilyIndex)
125 , m_deviceInterface (interface, *m_device)
129 Unique<VkDevice> m_device;
130 const deUint32 m_queueFamilyIndex;
131 DeviceDriver m_deviceInterface;
134 de::UniquePtr<SparseContext> m_sparseContext;
136 static deUint32 findQueueFamilyIndexWithCaps (const InstanceInterface& vkInstance,
137 VkPhysicalDevice physicalDevice,
138 VkQueueFlags requiredCaps)
140 const std::vector<vk::VkQueueFamilyProperties>
141 queueProps = getPhysicalDeviceQueueFamilyProperties(vkInstance, physicalDevice);
143 for (size_t queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
145 if ((queueProps[queueNdx].queueFlags & requiredCaps) == requiredCaps)
147 return (deUint32)queueNdx;
151 TCU_THROW(NotSupportedError, "No matching queue found");
154 // Create the sparseContext
155 SparseContext* createSparseContext (void) const
157 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
158 || (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT)
159 || (m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT))
161 const InstanceInterface& vk = getInstanceInterface();
162 const VkPhysicalDevice physicalDevice = getPhysicalDevice();
163 const vk::VkPhysicalDeviceFeatures
164 deviceFeatures = getPhysicalDeviceFeatures(vk, physicalDevice);
165 const deUint32 queueIndex = findQueueFamilyIndexWithCaps(vk, physicalDevice, VK_QUEUE_GRAPHICS_BIT|VK_QUEUE_SPARSE_BINDING_BIT);
166 const float queuePriority = 1.0f;
167 VkDeviceQueueCreateInfo queueInfo =
169 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO,
171 static_cast<VkDeviceQueueCreateFlags>(0u),
176 VkDeviceCreateInfo deviceInfo =
178 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
180 static_cast<VkDeviceQueueCreateFlags>(0u),
190 Move<VkDevice> device = createDevice(vk, physicalDevice, &deviceInfo);
192 return new SparseContext(device, queueIndex, vk);
199 class DedicatedAllocationBufferTestInstance : public BufferTestInstance
202 DedicatedAllocationBufferTestInstance
204 BufferCaseParameters testCase)
205 : BufferTestInstance (ctx, testCase)
208 virtual tcu::TestStatus bufferCreateAndAllocTest (VkDeviceSize size);
211 class BuffersTestCase : public TestCase
214 BuffersTestCase (tcu::TestContext& testCtx,
215 const std::string& name,
216 const std::string& description,
217 BufferCaseParameters testCase)
218 : TestCase (testCtx, name, description)
219 , m_testCase (testCase)
223 virtual ~BuffersTestCase (void)
227 virtual TestInstance* createInstance (Context& ctx) const
229 tcu::TestLog& log = m_testCtx.getLog();
230 log << tcu::TestLog::Message << getBufferUsageFlagsStr(m_testCase.usage) << tcu::TestLog::EndMessage;
231 return new BufferTestInstance(ctx, m_testCase);
235 BufferCaseParameters m_testCase;
238 class DedicatedAllocationBuffersTestCase : public TestCase
241 DedicatedAllocationBuffersTestCase
242 (tcu::TestContext& testCtx,
243 const std::string& name,
244 const std::string& description,
245 BufferCaseParameters testCase)
246 : TestCase (testCtx, name, description)
247 , m_testCase (testCase)
251 virtual ~DedicatedAllocationBuffersTestCase
256 virtual TestInstance* createInstance (Context& ctx) const
258 tcu::TestLog& log = m_testCtx.getLog();
259 log << tcu::TestLog::Message << getBufferUsageFlagsStr(m_testCase.usage) << tcu::TestLog::EndMessage;
260 const std::vector<std::string>& extensions = ctx.getDeviceExtensions();
261 const deBool isSupported = std::find(extensions.begin(), extensions.end(), "VK_KHR_dedicated_allocation") != extensions.end();
264 TCU_THROW(NotSupportedError, "Not supported");
266 return new DedicatedAllocationBufferTestInstance(ctx, m_testCase);
270 BufferCaseParameters m_testCase;
273 tcu::TestStatus BufferTestInstance::bufferCreateAndAllocTest (VkDeviceSize size)
275 const VkPhysicalDevice vkPhysicalDevice = getPhysicalDevice();
276 const InstanceInterface& vkInstance = getInstanceInterface();
277 const VkDevice vkDevice = getDevice();
278 const DeviceInterface& vk = getDeviceInterface();
279 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
280 const VkPhysicalDeviceMemoryProperties
281 memoryProperties = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice);
282 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vkInstance, vkPhysicalDevice).limits;
283 Move<VkBuffer> buffer;
284 Move<VkDeviceMemory> memory;
285 VkMemoryRequirements memReqs;
287 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0)
289 size = std::min(size, limits.sparseAddressSpaceSize);
292 // Create the test buffer and a memory allocation for it
294 // Create a minimal buffer first to get the supported memory types
295 VkBufferCreateInfo bufferParams =
297 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
298 DE_NULL, // const void* pNext;
299 m_testCase.flags, // VkBufferCreateFlags flags;
300 1u, // VkDeviceSize size;
301 m_testCase.usage, // VkBufferUsageFlags usage;
302 m_testCase.sharingMode, // VkSharingMode sharingMode;
303 1u, // uint32_t queueFamilyIndexCount;
304 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
307 buffer = createBuffer(vk, vkDevice, &bufferParams);
308 vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);
310 const deUint32 heapTypeIndex = (deUint32)deCtz32(memReqs.memoryTypeBits);
311 const VkMemoryType memoryType = memoryProperties.memoryTypes[heapTypeIndex];
312 const VkMemoryHeap memoryHeap = memoryProperties.memoryHeaps[memoryType.heapIndex];
313 const VkDeviceSize maxBufferSize = deAlign64(memoryHeap.size >> 1u, memReqs.alignment);
314 const deUint32 shrinkBits = 4u; // number of bits to shift when reducing the size with each iteration
316 size = std::min(size, maxBufferSize);
318 while (*memory == DE_NULL)
322 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
323 VkBuffer rawBuffer = DE_NULL;
325 bufferParams.size = size;
326 buffer = Move<VkBuffer>(); // free the previous buffer, if any
327 result = vk.createBuffer(vkDevice, &bufferParams, (vk::VkAllocationCallbacks*)DE_NULL, &rawBuffer);
329 if (result != VK_SUCCESS)
331 size = deAlign64(size >> shrinkBits, memReqs.alignment);
333 if (size == 0 || bufferParams.size == memReqs.alignment)
335 return tcu::TestStatus::fail("Buffer creation failed! (" + de::toString(getResultName(result)) + ")");
338 continue; // didn't work, try with a smaller buffer
341 buffer = Move<VkBuffer>(check<VkBuffer>(rawBuffer), Deleter<VkBuffer>(vk, vkDevice, DE_NULL));
344 vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs); // get the proper size requirement
346 if (size > memReqs.size)
348 std::ostringstream errorMsg;
349 errorMsg << "Requied memory size (" << memReqs.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
350 return tcu::TestStatus::fail(errorMsg.str());
353 // Allocate the memory
355 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
356 VkDeviceMemory rawMemory = DE_NULL;
358 const VkMemoryAllocateInfo
361 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
362 NULL, // const void* pNext;
363 memReqs.size, // VkDeviceSize allocationSize;
364 heapTypeIndex, // uint32_t memoryTypeIndex;
367 result = vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
369 if (result != VK_SUCCESS)
371 size = deAlign64(size >> shrinkBits, memReqs.alignment);
373 if (size == 0 || memReqs.size == memReqs.alignment)
375 return tcu::TestStatus::fail("Unable to allocate " + de::toString(memReqs.size) + " bytes of memory");
378 continue; // didn't work, try with a smaller allocation (and a smaller buffer)
381 memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
387 if ((m_testCase.flags & (VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)) != 0)
389 const VkQueue queue = getDeviceQueue(vk, vkDevice, queueFamilyIndex, 0);
391 const VkSparseMemoryBind sparseMemoryBind =
393 0, // VkDeviceSize resourceOffset;
394 memReqs.size, // VkDeviceSize size;
395 *memory, // VkDeviceMemory memory;
396 0, // VkDeviceSize memoryOffset;
397 0 // VkSparseMemoryBindFlags flags;
400 const VkSparseBufferMemoryBindInfo
401 sparseBufferMemoryBindInfo =
403 *buffer, // VkBuffer buffer;
404 1u, // deUint32 bindCount;
405 &sparseMemoryBind // const VkSparseMemoryBind* pBinds;
408 const VkBindSparseInfo bindSparseInfo =
410 VK_STRUCTURE_TYPE_BIND_SPARSE_INFO, // VkStructureType sType;
411 DE_NULL, // const void* pNext;
412 0, // deUint32 waitSemaphoreCount;
413 DE_NULL, // const VkSemaphore* pWaitSemaphores;
414 1u, // deUint32 bufferBindCount;
415 &sparseBufferMemoryBindInfo, // const VkSparseBufferMemoryBindInfo* pBufferBinds;
416 0, // deUint32 imageOpaqueBindCount;
417 DE_NULL, // const VkSparseImageOpaqueMemoryBindInfo* pImageOpaqueBinds;
418 0, // deUint32 imageBindCount;
419 DE_NULL, // const VkSparseImageMemoryBindInfo* pImageBinds;
420 0, // deUint32 signalSemaphoreCount;
421 DE_NULL, // const VkSemaphore* pSignalSemaphores;
424 const vk::Unique<vk::VkFence> fence (vk::createFence(vk, vkDevice));
426 if (vk.queueBindSparse(queue, 1, &bindSparseInfo, *fence) != VK_SUCCESS)
427 return tcu::TestStatus::fail("Bind sparse buffer memory failed! (requested memory size: " + de::toString(size) + ")");
429 VK_CHECK(vk.waitForFences(vkDevice, 1, &fence.get(), VK_TRUE, ~(0ull) /* infinity */));
431 else if (vk.bindBufferMemory(vkDevice, *buffer, *memory, 0) != VK_SUCCESS)
432 return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")");
434 return tcu::TestStatus::pass("Pass");
437 tcu::TestStatus BufferTestInstance::iterate (void)
439 const VkPhysicalDeviceFeatures& physicalDeviceFeatures = getPhysicalDeviceFeatures(getInstanceInterface(), getPhysicalDevice());
441 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT ) && !physicalDeviceFeatures.sparseBinding)
442 TCU_THROW(NotSupportedError, "Sparse bindings feature is not supported");
444 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT ) && !physicalDeviceFeatures.sparseResidencyBuffer)
445 TCU_THROW(NotSupportedError, "Sparse buffer residency feature is not supported");
447 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT ) && !physicalDeviceFeatures.sparseResidencyAliased)
448 TCU_THROW(NotSupportedError, "Sparse aliased residency feature is not supported");
450 const VkDeviceSize testSizes[] =
456 ~0ull, // try to exercise a very large buffer too (will be clamped to a sensible size later)
459 for (int i = 0; i < DE_LENGTH_OF_ARRAY(testSizes); ++i)
461 const tcu::TestStatus testStatus = bufferCreateAndAllocTest(testSizes[i]);
463 if (testStatus.getCode() != QP_TEST_RESULT_PASS)
467 return tcu::TestStatus::pass("Pass");
470 tcu::TestStatus DedicatedAllocationBufferTestInstance::bufferCreateAndAllocTest
473 const VkPhysicalDevice vkPhysicalDevice = getPhysicalDevice();
474 const InstanceInterface& vkInstance = getInstanceInterface();
475 const VkDevice vkDevice = getDevice();
476 const DeviceInterface& vk = getDeviceInterface();
477 const deUint32 queueFamilyIndex = getUniversalQueueFamilyIndex();
478 const VkPhysicalDeviceMemoryProperties
479 memoryProperties = getPhysicalDeviceMemoryProperties(vkInstance, vkPhysicalDevice);
480 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vkInstance, vkPhysicalDevice).limits;
482 VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
484 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR, // VkStructureType sType;
485 DE_NULL, // const void* pNext;
486 false, // VkBool32 prefersDedicatedAllocation
487 false // VkBool32 requiresDedicatedAllocation
489 VkMemoryRequirements2KHR memReqs =
491 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType sType
492 &dedicatedRequirements, // void* pNext
493 {0, 0, 0} // VkMemoryRequirements memoryRequirements
496 if ((m_testCase.flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) != 0)
497 size = std::min(size, limits.sparseAddressSpaceSize);
499 // Create a minimal buffer first to get the supported memory types
500 VkBufferCreateInfo bufferParams =
502 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
503 DE_NULL, // const void* pNext
504 m_testCase.flags, // VkBufferCreateFlags flags
505 1u, // VkDeviceSize size
506 m_testCase.usage, // VkBufferUsageFlags usage
507 m_testCase.sharingMode, // VkSharingMode sharingMode
508 1u, // uint32_t queueFamilyIndexCount
509 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
512 Move<VkBuffer> buffer = createBuffer(vk, vkDevice, &bufferParams);
514 VkBufferMemoryRequirementsInfo2KHR info =
516 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, // VkStructureType sType
517 DE_NULL, // const void* pNext
518 *buffer // VkBuffer buffer
521 vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs);
523 if (dedicatedRequirements.requiresDedicatedAllocation == VK_TRUE)
525 std::ostringstream errorMsg;
526 errorMsg << "Nonexternal objects cannot require dedicated allocation.";
527 return tcu::TestStatus::fail(errorMsg.str());
530 const deUint32 heapTypeIndex = static_cast<deUint32>(deCtz32(memReqs.memoryRequirements.memoryTypeBits));
531 const VkMemoryType memoryType = memoryProperties.memoryTypes[heapTypeIndex];
532 const VkMemoryHeap memoryHeap = memoryProperties.memoryHeaps[memoryType.heapIndex];
533 const VkDeviceSize maxBufferSize = deAlign64(memoryHeap.size >> 1u, memReqs.memoryRequirements.alignment);
534 const deUint32 shrinkBits = 4u; // number of bits to shift when reducing the size with each iteration
536 Move<VkDeviceMemory> memory;
537 size = std::min(size, maxBufferSize);
538 while (*memory == DE_NULL)
542 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
543 VkBuffer rawBuffer = DE_NULL;
545 bufferParams.size = size;
546 buffer = Move<VkBuffer>(); // free the previous buffer, if any
547 result = vk.createBuffer(vkDevice, &bufferParams, (VkAllocationCallbacks*)DE_NULL, &rawBuffer);
549 if (result != VK_SUCCESS)
551 size = deAlign64(size >> shrinkBits, memReqs.memoryRequirements.alignment);
553 if (size == 0 || bufferParams.size == memReqs.memoryRequirements.alignment)
554 return tcu::TestStatus::fail("Buffer creation failed! (" + de::toString(getResultName(result)) + ")");
556 continue; // didn't work, try with a smaller buffer
559 buffer = Move<VkBuffer>(check<VkBuffer>(rawBuffer), Deleter<VkBuffer>(vk, vkDevice, DE_NULL));
562 info.buffer = *buffer;
563 vk.getBufferMemoryRequirements2KHR(vkDevice, &info, &memReqs); // get the proper size requirement
565 if (size > memReqs.memoryRequirements.size)
567 std::ostringstream errorMsg;
568 errorMsg << "Requied memory size (" << memReqs.memoryRequirements.size << " bytes) smaller than the buffer's size (" << size << " bytes)!";
569 return tcu::TestStatus::fail(errorMsg.str());
572 // Allocate the memory
574 VkResult result = VK_ERROR_OUT_OF_HOST_MEMORY;
575 VkDeviceMemory rawMemory = DE_NULL;
577 vk::VkMemoryDedicatedAllocateInfoKHR
580 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, // VkStructureType sType
581 DE_NULL, // const void* pNext
582 DE_NULL, // VkImage image
583 *buffer // VkBuffer buffer
586 VkMemoryAllocateInfo memoryAllocateInfo =
588 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType
589 &dedicatedInfo, // const void* pNext
590 memReqs.memoryRequirements.size, // VkDeviceSize allocationSize
591 heapTypeIndex, // deUint32 memoryTypeIndex
594 result = vk.allocateMemory(vkDevice, &memoryAllocateInfo, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
596 if (result != VK_SUCCESS)
598 size = deAlign64(size >> shrinkBits, memReqs.memoryRequirements.alignment);
600 if (size == 0 || memReqs.memoryRequirements.size == memReqs.memoryRequirements.alignment)
601 return tcu::TestStatus::fail("Unable to allocate " + de::toString(memReqs.memoryRequirements.size) + " bytes of memory");
603 continue; // didn't work, try with a smaller allocation (and a smaller buffer)
606 memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
610 if (vk.bindBufferMemory(vkDevice, *buffer, *memory, 0) != VK_SUCCESS)
611 return tcu::TestStatus::fail("Bind buffer memory failed! (requested memory size: " + de::toString(size) + ")");
613 return tcu::TestStatus::pass("Pass");
616 std::string getBufferUsageFlagsName (const VkBufferUsageFlags flags)
620 case VK_BUFFER_USAGE_TRANSFER_SRC_BIT: return "transfer_src";
621 case VK_BUFFER_USAGE_TRANSFER_DST_BIT: return "transfer_dst";
622 case VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT: return "uniform_texel";
623 case VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT: return "storage_texel";
624 case VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT: return "uniform";
625 case VK_BUFFER_USAGE_STORAGE_BUFFER_BIT: return "storage";
626 case VK_BUFFER_USAGE_INDEX_BUFFER_BIT: return "index";
627 case VK_BUFFER_USAGE_VERTEX_BUFFER_BIT: return "vertex";
628 case VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT: return "indirect";
630 DE_FATAL("Unknown buffer usage flag");
635 std::string getBufferCreateFlagsName (const VkBufferCreateFlags flags)
637 std::ostringstream name;
639 if (flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT)
641 if (flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT)
642 name << "_residency";
643 if (flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT)
648 DE_ASSERT(!name.str().empty());
650 return name.str().substr(1);
653 // Create all VkBufferUsageFlags combinations recursively
654 void createBufferUsageCases (tcu::TestCaseGroup& testGroup, const deUint32 firstNdx, const deUint32 bufferUsageFlags, const AllocationKind allocationKind)
656 const VkBufferUsageFlags bufferUsageModes[] =
658 VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
659 VK_BUFFER_USAGE_TRANSFER_DST_BIT,
660 VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT,
661 VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT,
662 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
663 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT,
664 VK_BUFFER_USAGE_INDEX_BUFFER_BIT,
665 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT,
666 VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT
669 tcu::TestContext& testCtx = testGroup.getTestContext();
672 for (deUint32 currentNdx = firstNdx; currentNdx < DE_LENGTH_OF_ARRAY(bufferUsageModes); currentNdx++)
674 const deUint32 newBufferUsageFlags = bufferUsageFlags | bufferUsageModes[currentNdx];
675 const std::string newGroupName = getBufferUsageFlagsName(bufferUsageModes[currentNdx]);
676 de::MovePtr<tcu::TestCaseGroup> newTestGroup (new tcu::TestCaseGroup(testCtx, newGroupName.c_str(), ""));
678 createBufferUsageCases(*newTestGroup, currentNdx + 1u, newBufferUsageFlags, allocationKind);
679 testGroup.addChild(newTestGroup.release());
683 if (bufferUsageFlags != 0u)
685 // \note SPARSE_RESIDENCY and SPARSE_ALIASED have to be used together with the SPARSE_BINDING flag.
686 const VkBufferCreateFlags bufferCreateFlags[] =
689 VK_BUFFER_CREATE_SPARSE_BINDING_BIT,
690 VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT,
691 VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,
692 VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT,
695 // Dedicated allocation does not support sparse feature
696 const int numBufferCreateFlags = (allocationKind == ALLOCATION_KIND_SUBALLOCATED) ? DE_LENGTH_OF_ARRAY(bufferCreateFlags) : 1;
698 de::MovePtr<tcu::TestCaseGroup> newTestGroup (new tcu::TestCaseGroup(testCtx, "create", ""));
700 for (int bufferCreateFlagsNdx = 0; bufferCreateFlagsNdx < numBufferCreateFlags; bufferCreateFlagsNdx++)
702 const BufferCaseParameters testParams =
705 bufferCreateFlags[bufferCreateFlagsNdx],
706 VK_SHARING_MODE_EXCLUSIVE
709 const std::string allocStr = (allocationKind == ALLOCATION_KIND_SUBALLOCATED) ? "suballocation of " : "dedicated alloc. of ";
710 const std::string caseName = getBufferCreateFlagsName(bufferCreateFlags[bufferCreateFlagsNdx]);
711 const std::string caseDesc = "vkCreateBuffer test: " + allocStr + de::toString(bufferUsageFlags) + " " + de::toString(testParams.flags);
713 switch (allocationKind)
715 case ALLOCATION_KIND_SUBALLOCATED:
716 newTestGroup->addChild(new BuffersTestCase(testCtx, caseName.c_str(), caseDesc.c_str(), testParams));
718 case ALLOCATION_KIND_DEDICATED:
719 newTestGroup->addChild(new DedicatedAllocationBuffersTestCase(testCtx, caseName.c_str(), caseDesc.c_str(), testParams));
722 DE_FATAL("Unknown test type");
725 testGroup.addChild(newTestGroup.release());
731 tcu::TestCaseGroup* createBufferTests (tcu::TestContext& testCtx)
733 de::MovePtr<tcu::TestCaseGroup> buffersTests (new tcu::TestCaseGroup(testCtx, "buffer", "Buffer Tests"));
736 de::MovePtr<tcu::TestCaseGroup> regularAllocation (new tcu::TestCaseGroup(testCtx, "suballocation", "Regular suballocation of memory."));
737 createBufferUsageCases(*regularAllocation, 0u, 0u, ALLOCATION_KIND_SUBALLOCATED);
738 buffersTests->addChild(regularAllocation.release());
742 de::MovePtr<tcu::TestCaseGroup> dedicatedAllocation (new tcu::TestCaseGroup(testCtx, "dedicated_alloc", "Dedicated allocation of memory."));
743 createBufferUsageCases(*dedicatedAllocation, 0u, 0u, ALLOCATION_KIND_DEDICATED);
744 buffersTests->addChild(dedicatedAllocation.release());
747 return buffersTests.release();