1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Buffer and image memory requirements tests.
22 *//*--------------------------------------------------------------------*/
24 #include "vktMemoryRequirementsTests.hpp"
25 #include "vktTestCaseUtil.hpp"
26 #include "vktTestGroupUtil.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkStrUtil.hpp"
34 #include "vkTypeUtil.hpp"
36 #include "deUniquePtr.hpp"
37 #include "deStringUtil.hpp"
38 #include "deSTLUtil.hpp"
40 #include "tcuResultCollector.hpp"
41 #include "tcuTestLog.hpp"
52 Move<VkBuffer> makeBuffer (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
54 const VkBufferCreateInfo createInfo =
56 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
57 DE_NULL, // const void* pNext;
58 flags, // VkBufferCreateFlags flags;
59 size, // VkDeviceSize size;
60 usage, // VkBufferUsageFlags usage;
61 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
62 0u, // uint32_t queueFamilyIndexCount;
63 DE_NULL, // const uint32_t* pQueueFamilyIndices;
65 return createBuffer(vk, device, &createInfo);
68 VkMemoryRequirements getBufferMemoryRequirements (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage)
70 const Unique<VkBuffer> buffer(makeBuffer(vk, device, size, flags, usage));
71 return getBufferMemoryRequirements(vk, device, *buffer);
74 VkMemoryRequirements getBufferMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkDeviceSize size, const VkBufferCreateFlags flags, const VkBufferUsageFlags usage, void* next = DE_NULL)
76 const Unique<VkBuffer> buffer (makeBuffer(vk, device, size, flags, usage));
77 VkBufferMemoryRequirementsInfo2KHR info =
79 VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR, // VkStructureType sType
80 DE_NULL, // const void* pNext
81 *buffer // VkBuffer buffer
83 VkMemoryRequirements2KHR req2 =
85 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType sType
87 {0, 0, 0} // VkMemoryRequirements memoryRequirements
90 vk.getBufferMemoryRequirements2KHR(device, &info, &req2);
92 return req2.memoryRequirements;
95 VkMemoryRequirements getImageMemoryRequirements2 (const DeviceInterface& vk, const VkDevice device, const VkImageCreateInfo& createInfo, void* next = DE_NULL)
97 const Unique<VkImage> image(createImage(vk, device, &createInfo));
99 VkImageMemoryRequirementsInfo2KHR info =
101 VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR, // VkStructureType sType
102 DE_NULL, // const void* pNext
103 *image // VkImage image
105 VkMemoryRequirements2KHR req2 =
107 VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR, // VkStructureType sType
109 {0, 0, 0} // VkMemoryRequirements memoryRequirements
112 vk.getImageMemoryRequirements2KHR(device, &info, &req2);
114 return req2.memoryRequirements;
117 //! Get an index of each set bit, starting from the least significant bit.
118 std::vector<deUint32> bitsToIndices (deUint32 bits)
120 std::vector<deUint32> indices;
121 for (deUint32 i = 0u; bits != 0u; ++i, bits >>= 1)
124 indices.push_back(i);
132 return static_cast<T>(static_cast<deUint32>(value) + 1);
139 return static_cast<T>(static_cast<deUint32>(value) << 1);
141 return static_cast<T>(1);
145 T nextFlagExcluding (T value, T excludedFlags)
147 deUint32 tmp = static_cast<deUint32>(value);
148 while ((tmp = nextFlag(tmp)) & static_cast<deUint32>(excludedFlags));
149 return static_cast<T>(tmp);
152 bool validValueVkBool32 (const VkBool32 value)
154 return (value == VK_FALSE || value == VK_TRUE);
157 class IBufferMemoryRequirements
160 virtual void populateTestGroup (tcu::TestCaseGroup* group) = 0;
163 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
164 const std::string& name,
165 const std::string& desc,
166 VkBufferCreateFlags arg0) = 0;
168 virtual tcu::TestStatus execTest (Context& context,
169 const VkBufferCreateFlags bufferFlags) = 0;
171 virtual void preTestChecks (Context& context,
172 const InstanceInterface& vki,
173 const VkPhysicalDevice physDevice,
174 const VkBufferCreateFlags flags) = 0;
176 virtual void updateMemoryRequirements (const DeviceInterface& vk,
177 const VkDevice device,
178 const VkDeviceSize size,
179 const VkBufferCreateFlags flags,
180 const VkBufferUsageFlags usage,
183 virtual void verifyMemoryRequirements (tcu::ResultCollector& result,
184 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
185 const VkPhysicalDeviceLimits& limits,
186 const VkBufferCreateFlags bufferFlags,
187 const VkBufferUsageFlags usage) = 0;
190 class BufferMemoryRequirementsOriginal : public IBufferMemoryRequirements
192 static tcu::TestStatus testEntryPoint (Context& context,
193 const VkBufferCreateFlags bufferFlags);
196 virtual void populateTestGroup (tcu::TestCaseGroup* group);
199 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
200 const std::string& name,
201 const std::string& desc,
202 VkBufferCreateFlags arg0);
204 virtual tcu::TestStatus execTest (Context& context,
205 const VkBufferCreateFlags bufferFlags);
207 virtual void preTestChecks (Context& context,
208 const InstanceInterface& vki,
209 const VkPhysicalDevice physDevice,
210 const VkBufferCreateFlags flags);
212 virtual void updateMemoryRequirements (const DeviceInterface& vk,
213 const VkDevice device,
214 const VkDeviceSize size,
215 const VkBufferCreateFlags flags,
216 const VkBufferUsageFlags usage,
219 virtual void verifyMemoryRequirements (tcu::ResultCollector& result,
220 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
221 const VkPhysicalDeviceLimits& limits,
222 const VkBufferCreateFlags bufferFlags,
223 const VkBufferUsageFlags usage);
226 VkMemoryRequirements m_allUsageFlagsRequirements;
227 VkMemoryRequirements m_currentTestRequirements;
231 tcu::TestStatus BufferMemoryRequirementsOriginal::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
233 BufferMemoryRequirementsOriginal test;
235 return test.execTest(context, bufferFlags);
238 void BufferMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
242 VkBufferCreateFlags flags;
243 const char* const name;
246 { (VkBufferCreateFlags)0, "regular" },
247 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT, "sparse" },
248 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT, "sparse_residency" },
249 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, "sparse_aliased" },
250 { VK_BUFFER_CREATE_SPARSE_BINDING_BIT | VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT | VK_BUFFER_CREATE_SPARSE_ALIASED_BIT, "sparse_residency_aliased" },
253 de::MovePtr<tcu::TestCaseGroup> bufferGroup(new tcu::TestCaseGroup(group->getTestContext(), "buffer", ""));
255 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(bufferCases); ++ndx)
256 addFunctionTestCase(bufferGroup.get(), bufferCases[ndx].name, "", bufferCases[ndx].flags);
258 group->addChild(bufferGroup.release());
261 void BufferMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup* group,
262 const std::string& name,
263 const std::string& desc,
264 VkBufferCreateFlags arg0)
266 addFunctionCase(group, name, desc, testEntryPoint, arg0);
269 tcu::TestStatus BufferMemoryRequirementsOriginal::execTest (Context& context, const VkBufferCreateFlags bufferFlags)
271 const DeviceInterface& vk = context.getDeviceInterface();
272 const InstanceInterface& vki = context.getInstanceInterface();
273 const VkDevice device = context.getDevice();
274 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
276 preTestChecks(context, vki, physDevice, bufferFlags);
278 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physDevice);
279 const VkPhysicalDeviceLimits limits = getPhysicalDeviceProperties(vki, physDevice).limits;
280 const VkBufferUsageFlags allUsageFlags = static_cast<VkBufferUsageFlags>((VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT << 1) - 1);
281 tcu::TestLog& log = context.getTestContext().getLog();
284 const VkDeviceSize sizeCases[] =
292 // Updates m_allUsageFlags* fields
293 updateMemoryRequirements(vk, device, 1024, bufferFlags, allUsageFlags, true); // doesn't depend on size
295 for (VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; usage <= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; usage = nextFlag(usage))
297 deUint32 previousMemoryTypeBits = 0u;
298 VkDeviceSize previousAlignment = 0u;
300 log << tcu::TestLog::Message << "Verify a buffer with usage flags: " << de::toString(getBufferUsageFlagsStr(usage)) << tcu::TestLog::EndMessage;
302 for (const VkDeviceSize* pSize = sizeCases; pSize < sizeCases + DE_LENGTH_OF_ARRAY(sizeCases); ++pSize)
304 log << tcu::TestLog::Message << "- size " << *pSize << " bytes" << tcu::TestLog::EndMessage;
306 tcu::ResultCollector result(log, "ERROR: ");
308 // Updates m_allUsageFlags* fields
309 updateMemoryRequirements(vk, device, *pSize, bufferFlags, usage, false);
312 // - requirements for a particular buffer usage
313 // - memoryTypeBits are a subset of bits for requirements with all usage flags combined
314 verifyMemoryRequirements(result, memoryProperties, limits, bufferFlags, usage);
316 // Check that for the same usage and create flags:
317 // - memoryTypeBits are the same
318 // - alignment is the same
319 if (pSize > sizeCases)
321 result.check(m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits,
322 "memoryTypeBits differ from the ones in the previous buffer size");
324 result.check(m_currentTestRequirements.alignment == previousAlignment,
325 "alignment differs from the one in the previous buffer size");
328 if (result.getResult() != QP_TEST_RESULT_PASS)
331 previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
332 previousAlignment = m_currentTestRequirements.alignment;
339 return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
342 void BufferMemoryRequirementsOriginal::preTestChecks (Context& ,
343 const InstanceInterface& vki,
344 const VkPhysicalDevice physDevice,
345 const VkBufferCreateFlags flags)
347 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
349 if ((flags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
350 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
352 if ((flags & VK_BUFFER_CREATE_SPARSE_RESIDENCY_BIT) && !features.sparseResidencyBuffer)
353 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyBuffer");
355 if ((flags & VK_BUFFER_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
356 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
359 void BufferMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface& vk,
360 const VkDevice device,
361 const VkDeviceSize size,
362 const VkBufferCreateFlags flags,
363 const VkBufferUsageFlags usage,
368 m_allUsageFlagsRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage);
372 m_currentTestRequirements = getBufferMemoryRequirements(vk, device, size, flags, usage);
376 void BufferMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector& result,
377 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
378 const VkPhysicalDeviceLimits& limits,
379 const VkBufferCreateFlags bufferFlags,
380 const VkBufferUsageFlags usage)
382 if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
384 typedef std::vector<deUint32>::const_iterator IndexIterator;
385 const std::vector<deUint32> usedMemoryTypeIndices = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
386 bool deviceLocalMemoryFound = false;
387 bool hostVisibleCoherentMemoryFound = false;
389 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
391 if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
393 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
397 const VkMemoryPropertyFlags memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
399 if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
400 deviceLocalMemoryFound = true;
402 if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
403 hostVisibleCoherentMemoryFound = true;
405 result.check((memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT) == 0u,
406 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT");
409 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
410 "VkMemoryRequirements alignment isn't power of two");
412 if (usage & (VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT))
414 result.check(m_currentTestRequirements.alignment >= limits.minTexelBufferOffsetAlignment,
415 "VkMemoryRequirements alignment doesn't respect minTexelBufferOffsetAlignment");
418 if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT)
420 result.check(m_currentTestRequirements.alignment >= limits.minUniformBufferOffsetAlignment,
421 "VkMemoryRequirements alignment doesn't respect minUniformBufferOffsetAlignment");
424 if (usage & VK_BUFFER_USAGE_STORAGE_BUFFER_BIT)
426 result.check(m_currentTestRequirements.alignment >= limits.minStorageBufferOffsetAlignment,
427 "VkMemoryRequirements alignment doesn't respect minStorageBufferOffsetAlignment");
430 result.check(deviceLocalMemoryFound,
431 "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
433 result.check((bufferFlags & VK_BUFFER_CREATE_SPARSE_BINDING_BIT) || hostVisibleCoherentMemoryFound,
434 "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
436 result.check((m_currentTestRequirements.memoryTypeBits & m_allUsageFlagsRequirements.memoryTypeBits) == m_allUsageFlagsRequirements.memoryTypeBits,
437 "Memory type bits aren't a superset of memory type bits for all usage flags combined");
441 class BufferMemoryRequirementsExtended : public BufferMemoryRequirementsOriginal
443 static tcu::TestStatus testEntryPoint (Context& context,
444 const VkBufferCreateFlags bufferFlags);
447 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
448 const std::string& name,
449 const std::string& desc,
450 VkBufferCreateFlags arg0);
452 virtual void preTestChecks (Context& context,
453 const InstanceInterface& vki,
454 const VkPhysicalDevice physDevice,
455 const VkBufferCreateFlags flags);
457 virtual void updateMemoryRequirements (const DeviceInterface& vk,
458 const VkDevice device,
459 const VkDeviceSize size,
460 const VkBufferCreateFlags flags,
461 const VkBufferUsageFlags usage,
465 tcu::TestStatus BufferMemoryRequirementsExtended::testEntryPoint (Context& context, const VkBufferCreateFlags bufferFlags)
467 BufferMemoryRequirementsExtended test;
469 return test.execTest(context, bufferFlags);
472 void BufferMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup* group,
473 const std::string& name,
474 const std::string& desc,
475 VkBufferCreateFlags arg0)
477 addFunctionCase(group, name, desc, testEntryPoint, arg0);
480 void BufferMemoryRequirementsExtended::preTestChecks (Context& context,
481 const InstanceInterface& vki,
482 const VkPhysicalDevice physDevice,
483 const VkBufferCreateFlags flags)
485 const std::string extensionName("VK_KHR_get_memory_requirements2");
487 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
488 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
490 BufferMemoryRequirementsOriginal::preTestChecks(context, vki, physDevice, flags);
493 void BufferMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface& vk,
494 const VkDevice device,
495 const VkDeviceSize size,
496 const VkBufferCreateFlags flags,
497 const VkBufferUsageFlags usage,
502 m_allUsageFlagsRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage);
506 m_currentTestRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage);
511 class BufferMemoryRequirementsDedicatedAllocation : public BufferMemoryRequirementsExtended
513 static tcu::TestStatus testEntryPoint (Context& context,
514 const VkBufferCreateFlags bufferFlags);
517 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
518 const std::string& name,
519 const std::string& desc,
520 VkBufferCreateFlags arg0);
522 virtual void preTestChecks (Context& context,
523 const InstanceInterface& vki,
524 const VkPhysicalDevice physDevice,
525 const VkBufferCreateFlags flags);
527 virtual void updateMemoryRequirements (const DeviceInterface& vk,
528 const VkDevice device,
529 const VkDeviceSize size,
530 const VkBufferCreateFlags flags,
531 const VkBufferUsageFlags usage,
534 virtual void verifyMemoryRequirements (tcu::ResultCollector& result,
535 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
536 const VkPhysicalDeviceLimits& limits,
537 const VkBufferCreateFlags bufferFlags,
538 const VkBufferUsageFlags usage);
541 VkBool32 m_allUsageFlagsPrefersDedicatedAllocation;
542 VkBool32 m_allUsageFlagsRequiresDedicatedAllocation;
544 VkBool32 m_currentTestPrefersDedicatedAllocation;
545 VkBool32 m_currentTestRequiresDedicatedAllocation;
549 tcu::TestStatus BufferMemoryRequirementsDedicatedAllocation::testEntryPoint(Context& context, const VkBufferCreateFlags bufferFlags)
551 BufferMemoryRequirementsDedicatedAllocation test;
553 return test.execTest(context, bufferFlags);
556 void BufferMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup* group,
557 const std::string& name,
558 const std::string& desc,
559 VkBufferCreateFlags arg0)
561 addFunctionCase(group, name, desc, testEntryPoint, arg0);
564 void BufferMemoryRequirementsDedicatedAllocation::preTestChecks (Context& context,
565 const InstanceInterface& vki,
566 const VkPhysicalDevice physDevice,
567 const VkBufferCreateFlags flags)
569 const std::string extensionName("VK_KHR_dedicated_allocation");
571 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
572 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
574 BufferMemoryRequirementsExtended::preTestChecks(context, vki, physDevice, flags);
577 void BufferMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface& vk,
578 const VkDevice device,
579 const VkDeviceSize size,
580 const VkBufferCreateFlags flags,
581 const VkBufferUsageFlags usage,
584 const deUint32 invalidVkBool32 = static_cast<deUint32>(~0);
586 VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
588 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR, // VkStructureType sType
589 DE_NULL, // void* pNext
590 invalidVkBool32, // VkBool32 prefersDedicatedAllocation
591 invalidVkBool32 // VkBool32 requiresDedicatedAllocation
596 m_allUsageFlagsRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
597 m_allUsageFlagsPrefersDedicatedAllocation = dedicatedRequirements.prefersDedicatedAllocation;
598 m_allUsageFlagsRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation;
600 TCU_CHECK(validValueVkBool32(m_allUsageFlagsPrefersDedicatedAllocation));
601 // Test design expects m_allUsageFlagsRequiresDedicatedAllocation to be false
602 TCU_CHECK(m_allUsageFlagsRequiresDedicatedAllocation == VK_FALSE);
606 m_currentTestRequirements = getBufferMemoryRequirements2(vk, device, size, flags, usage, &dedicatedRequirements);
607 m_currentTestPrefersDedicatedAllocation = dedicatedRequirements.prefersDedicatedAllocation;
608 m_currentTestRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation;
612 void BufferMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector& result,
613 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties,
614 const VkPhysicalDeviceLimits& limits,
615 const VkBufferCreateFlags bufferFlags,
616 const VkBufferUsageFlags usage)
618 BufferMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties, limits, bufferFlags, usage);
620 result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
621 "Invalid VkBool32 value in m_currentTestPrefersDedicatedAllocation");
623 result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
624 "Regular (non-shared) objects must not require dedicated allocations");
626 result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
627 "Preferred and required flags for dedicated memory cannot be set to true at the same time");
631 struct ImageTestParams
633 VkImageCreateFlags flags;
634 VkImageTiling tiling;
638 class IImageMemoryRequirements
641 virtual void populateTestGroup (tcu::TestCaseGroup* group) = 0;
644 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
645 const std::string& name,
646 const std::string& desc,
647 const ImageTestParams arg0) = 0;
649 virtual tcu::TestStatus execTest (Context& context,
650 const ImageTestParams bufferFlags) = 0;
652 virtual void preTestChecks (Context& context,
653 const InstanceInterface& vki,
654 const VkPhysicalDevice physDevice,
655 const VkImageCreateFlags flags) = 0;
657 virtual void updateMemoryRequirements (const DeviceInterface& vk,
658 const VkDevice device) = 0;
660 virtual void verifyMemoryRequirements (tcu::ResultCollector& result,
661 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties) = 0;
664 class ImageMemoryRequirementsOriginal : public IImageMemoryRequirements
666 static tcu::TestStatus testEntryPoint (Context& context,
667 const ImageTestParams params);
670 virtual void populateTestGroup (tcu::TestCaseGroup* group);
673 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
674 const std::string& name,
675 const std::string& desc,
676 const ImageTestParams arg0);
678 virtual tcu::TestStatus execTest (Context& context,
679 const ImageTestParams params);
681 virtual void preTestChecks (Context& context,
682 const InstanceInterface& vki,
683 const VkPhysicalDevice physDevice,
684 const VkImageCreateFlags flags);
686 virtual void updateMemoryRequirements (const DeviceInterface& vk,
687 const VkDevice device);
689 virtual void verifyMemoryRequirements (tcu::ResultCollector& result,
690 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties);
693 virtual bool isUsageMatchesFeatures (const VkImageUsageFlags usage,
694 const VkFormatFeatureFlags featureFlags);
696 virtual bool isImageSupported (const InstanceInterface& vki,
697 const VkPhysicalDevice physDevice,
698 const VkImageCreateInfo& info);
700 virtual VkExtent3D makeExtentForImage (const VkImageType imageType);
702 virtual bool isFormatMatchingAspect (const VkFormat format,
703 const VkImageAspectFlags aspect);
706 virtual std::string getImageInfoString (const VkImageCreateInfo& imageInfo);
709 VkImageCreateInfo m_currentTestImageInfo;
710 VkMemoryRequirements m_currentTestRequirements;
714 tcu::TestStatus ImageMemoryRequirementsOriginal::testEntryPoint (Context& context, const ImageTestParams params)
716 ImageMemoryRequirementsOriginal test;
718 return test.execTest(context, params);
721 void ImageMemoryRequirementsOriginal::populateTestGroup (tcu::TestCaseGroup* group)
725 VkImageCreateFlags flags;
727 const char* const name;
728 } imageFlagsCases[] =
730 { (VkImageCreateFlags)0, false, "regular" },
731 { (VkImageCreateFlags)0, true, "transient" },
732 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT, false, "sparse" },
733 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT, false, "sparse_residency" },
734 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_aliased" },
735 { VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT, false, "sparse_residency_aliased" },
738 de::MovePtr<tcu::TestCaseGroup> imageGroup(new tcu::TestCaseGroup(group->getTestContext(), "image", ""));
740 for (int flagsNdx = 0; flagsNdx < DE_LENGTH_OF_ARRAY(imageFlagsCases); ++flagsNdx)
741 for (int tilingNdx = 0; tilingNdx <= 1; ++tilingNdx)
743 ImageTestParams params;
744 std::ostringstream caseName;
746 params.flags = imageFlagsCases[flagsNdx].flags;
747 params.transient = imageFlagsCases[flagsNdx].transient;
748 caseName << imageFlagsCases[flagsNdx].name;
752 params.tiling = VK_IMAGE_TILING_OPTIMAL;
753 caseName << "_tiling_optimal";
757 params.tiling = VK_IMAGE_TILING_LINEAR;
758 caseName << "_tiling_linear";
761 if ((params.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && (params.tiling == VK_IMAGE_TILING_LINEAR))
764 addFunctionTestCase(imageGroup.get(), caseName.str(), "", params);
767 group->addChild(imageGroup.release());
770 void ImageMemoryRequirementsOriginal::addFunctionTestCase (tcu::TestCaseGroup* group,
771 const std::string& name,
772 const std::string& desc,
773 const ImageTestParams arg0)
775 addFunctionCase(group, name, desc, testEntryPoint, arg0);
778 void ImageMemoryRequirementsOriginal::preTestChecks (Context& ,
779 const InstanceInterface& vki,
780 const VkPhysicalDevice physDevice,
781 const VkImageCreateFlags createFlags)
783 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
785 if ((createFlags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && !features.sparseBinding)
786 TCU_THROW(NotSupportedError, "Feature not supported: sparseBinding");
788 if ((createFlags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) && !(features.sparseResidencyImage2D || features.sparseResidencyImage3D))
789 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyImage (2D and 3D)");
791 if ((createFlags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && !features.sparseResidencyAliased)
792 TCU_THROW(NotSupportedError, "Feature not supported: sparseResidencyAliased");
795 void ImageMemoryRequirementsOriginal::updateMemoryRequirements (const DeviceInterface& vk,
796 const VkDevice device)
798 const Unique<VkImage> image(createImage(vk, device, &m_currentTestImageInfo));
800 m_currentTestRequirements = getImageMemoryRequirements(vk, device, *image);
803 void ImageMemoryRequirementsOriginal::verifyMemoryRequirements (tcu::ResultCollector& result,
804 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties)
806 if (result.check(m_currentTestRequirements.memoryTypeBits != 0, "VkMemoryRequirements memoryTypeBits has no bits set"))
808 typedef std::vector<deUint32>::const_iterator IndexIterator;
809 const std::vector<deUint32> usedMemoryTypeIndices = bitsToIndices(m_currentTestRequirements.memoryTypeBits);
810 bool deviceLocalMemoryFound = false;
811 bool hostVisibleCoherentMemoryFound = false;
813 for (IndexIterator memoryTypeNdx = usedMemoryTypeIndices.begin(); memoryTypeNdx != usedMemoryTypeIndices.end(); ++memoryTypeNdx)
815 if (*memoryTypeNdx >= deviceMemoryProperties.memoryTypeCount)
817 result.fail("VkMemoryRequirements memoryTypeBits contains bits for non-existing memory types");
821 const VkMemoryPropertyFlags memoryPropertyFlags = deviceMemoryProperties.memoryTypes[*memoryTypeNdx].propertyFlags;
823 if (memoryPropertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT)
824 deviceLocalMemoryFound = true;
826 if (memoryPropertyFlags & (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT))
827 hostVisibleCoherentMemoryFound = true;
829 if (memoryPropertyFlags & VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT)
831 result.check((m_currentTestImageInfo.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) != 0u,
832 "Memory type includes VK_MEMORY_PROPERTY_LAZILY_ALLOCATED_BIT for a non-transient attachment image");
836 result.check(deIsPowerOfTwo64(static_cast<deUint64>(m_currentTestRequirements.alignment)) == DE_TRUE,
837 "VkMemoryRequirements alignment isn't power of two");
839 result.check(deviceLocalMemoryFound,
840 "None of the required memory types included VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT");
842 result.check(m_currentTestImageInfo.tiling == VK_IMAGE_TILING_OPTIMAL || hostVisibleCoherentMemoryFound,
843 "Required memory type doesn't include VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT and VK_MEMORY_PROPERTY_HOST_COHERENT_BIT");
847 bool ImageMemoryRequirementsOriginal::isUsageMatchesFeatures (const VkImageUsageFlags usage, const VkFormatFeatureFlags featureFlags)
849 if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
851 if ((usage & VK_IMAGE_USAGE_STORAGE_BIT) && (featureFlags & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
853 if ((usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) && (featureFlags & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
855 if ((usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) && (featureFlags & VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT))
861 //! This catches both invalid as well as legal but unsupported combinations of image parameters
862 bool ImageMemoryRequirementsOriginal::isImageSupported (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkImageCreateInfo& info)
864 DE_ASSERT(info.extent.width >= 1u && info.extent.height >= 1u && info.extent.depth >= 1u);
866 if (info.imageType == VK_IMAGE_TYPE_1D)
868 DE_ASSERT(info.extent.height == 1u && info.extent.depth == 1u);
870 else if (info.imageType == VK_IMAGE_TYPE_2D)
872 DE_ASSERT(info.extent.depth == 1u);
874 if (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
876 DE_ASSERT(info.extent.width == info.extent.height);
877 DE_ASSERT(info.arrayLayers >= 6u && (info.arrayLayers % 6u) == 0u);
881 if ((info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && info.imageType != VK_IMAGE_TYPE_2D)
884 if ((info.samples != VK_SAMPLE_COUNT_1_BIT) &&
885 (info.imageType != VK_IMAGE_TYPE_2D || (info.flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) || info.tiling != VK_IMAGE_TILING_OPTIMAL || info.mipLevels > 1u))
888 if ((info.usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) &&
889 (info.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) == 0u)
892 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
894 if (info.flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT)
896 DE_ASSERT(info.tiling == VK_IMAGE_TILING_OPTIMAL);
898 if (info.imageType == VK_IMAGE_TYPE_2D && !features.sparseResidencyImage2D)
900 if (info.imageType == VK_IMAGE_TYPE_3D && !features.sparseResidencyImage3D)
902 if (info.samples == VK_SAMPLE_COUNT_2_BIT && !features.sparseResidency2Samples)
904 if (info.samples == VK_SAMPLE_COUNT_4_BIT && !features.sparseResidency4Samples)
906 if (info.samples == VK_SAMPLE_COUNT_8_BIT && !features.sparseResidency8Samples)
908 if (info.samples == VK_SAMPLE_COUNT_16_BIT && !features.sparseResidency16Samples)
910 if (info.samples == VK_SAMPLE_COUNT_32_BIT || info.samples == VK_SAMPLE_COUNT_64_BIT)
914 if (info.samples != VK_SAMPLE_COUNT_1_BIT && (info.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !features.shaderStorageImageMultisample)
919 case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
920 case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
921 case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
922 case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
923 case VK_FORMAT_BC2_UNORM_BLOCK:
924 case VK_FORMAT_BC2_SRGB_BLOCK:
925 case VK_FORMAT_BC3_UNORM_BLOCK:
926 case VK_FORMAT_BC3_SRGB_BLOCK:
927 case VK_FORMAT_BC4_UNORM_BLOCK:
928 case VK_FORMAT_BC4_SNORM_BLOCK:
929 case VK_FORMAT_BC5_UNORM_BLOCK:
930 case VK_FORMAT_BC5_SNORM_BLOCK:
931 case VK_FORMAT_BC6H_UFLOAT_BLOCK:
932 case VK_FORMAT_BC6H_SFLOAT_BLOCK:
933 case VK_FORMAT_BC7_UNORM_BLOCK:
934 case VK_FORMAT_BC7_SRGB_BLOCK:
935 if (!features.textureCompressionBC)
939 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
940 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
941 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
942 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
943 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
944 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
945 case VK_FORMAT_EAC_R11_UNORM_BLOCK:
946 case VK_FORMAT_EAC_R11_SNORM_BLOCK:
947 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
948 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
949 if (!features.textureCompressionETC2)
953 case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
954 case VK_FORMAT_ASTC_4x4_SRGB_BLOCK:
955 case VK_FORMAT_ASTC_5x4_UNORM_BLOCK:
956 case VK_FORMAT_ASTC_5x4_SRGB_BLOCK:
957 case VK_FORMAT_ASTC_5x5_UNORM_BLOCK:
958 case VK_FORMAT_ASTC_5x5_SRGB_BLOCK:
959 case VK_FORMAT_ASTC_6x5_UNORM_BLOCK:
960 case VK_FORMAT_ASTC_6x5_SRGB_BLOCK:
961 case VK_FORMAT_ASTC_6x6_UNORM_BLOCK:
962 case VK_FORMAT_ASTC_6x6_SRGB_BLOCK:
963 case VK_FORMAT_ASTC_8x5_UNORM_BLOCK:
964 case VK_FORMAT_ASTC_8x5_SRGB_BLOCK:
965 case VK_FORMAT_ASTC_8x6_UNORM_BLOCK:
966 case VK_FORMAT_ASTC_8x6_SRGB_BLOCK:
967 case VK_FORMAT_ASTC_8x8_UNORM_BLOCK:
968 case VK_FORMAT_ASTC_8x8_SRGB_BLOCK:
969 case VK_FORMAT_ASTC_10x5_UNORM_BLOCK:
970 case VK_FORMAT_ASTC_10x5_SRGB_BLOCK:
971 case VK_FORMAT_ASTC_10x6_UNORM_BLOCK:
972 case VK_FORMAT_ASTC_10x6_SRGB_BLOCK:
973 case VK_FORMAT_ASTC_10x8_UNORM_BLOCK:
974 case VK_FORMAT_ASTC_10x8_SRGB_BLOCK:
975 case VK_FORMAT_ASTC_10x10_UNORM_BLOCK:
976 case VK_FORMAT_ASTC_10x10_SRGB_BLOCK:
977 case VK_FORMAT_ASTC_12x10_UNORM_BLOCK:
978 case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
979 case VK_FORMAT_ASTC_12x12_UNORM_BLOCK:
980 case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
981 if (!features.textureCompressionASTC_LDR)
989 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(vki, physDevice, info.format);
990 const VkFormatFeatureFlags formatFeatures = (info.tiling == VK_IMAGE_TILING_LINEAR ? formatProperties.linearTilingFeatures
991 : formatProperties.optimalTilingFeatures);
993 if (!isUsageMatchesFeatures(info.usage, formatFeatures))
996 VkImageFormatProperties imageFormatProperties;
997 const VkResult result = vki.getPhysicalDeviceImageFormatProperties(
998 physDevice, info.format, info.imageType, info.tiling, info.usage, info.flags, &imageFormatProperties);
1000 if (result == VK_SUCCESS)
1002 if (info.arrayLayers > imageFormatProperties.maxArrayLayers)
1004 if (info.mipLevels > imageFormatProperties.maxMipLevels)
1006 if ((info.samples & imageFormatProperties.sampleCounts) == 0u)
1010 return result == VK_SUCCESS;
1013 VkExtent3D ImageMemoryRequirementsOriginal::makeExtentForImage (const VkImageType imageType)
1015 VkExtent3D extent = { 64u, 64u, 4u };
1017 if (imageType == VK_IMAGE_TYPE_1D)
1018 extent.height = extent.depth = 1u;
1019 else if (imageType == VK_IMAGE_TYPE_2D)
1025 bool ImageMemoryRequirementsOriginal::isFormatMatchingAspect (const VkFormat format, const VkImageAspectFlags aspect)
1027 DE_ASSERT(aspect == VK_IMAGE_ASPECT_COLOR_BIT || aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT));
1029 // D/S formats are laid out next to each other in the enum
1030 const bool isDepthStencilFormat = (format >= VK_FORMAT_D16_UNORM && format <= VK_FORMAT_D32_SFLOAT_S8_UINT);
1032 return (aspect == (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) == isDepthStencilFormat;
1035 std::string ImageMemoryRequirementsOriginal::getImageInfoString (const VkImageCreateInfo& imageInfo)
1037 std::ostringstream str;
1039 switch (imageInfo.imageType)
1041 case VK_IMAGE_TYPE_1D: str << "1D "; break;
1042 case VK_IMAGE_TYPE_2D: str << "2D "; break;
1043 case VK_IMAGE_TYPE_3D: str << "3D "; break;
1047 switch (imageInfo.tiling)
1049 case VK_IMAGE_TILING_OPTIMAL: str << "(optimal) "; break;
1050 case VK_IMAGE_TILING_LINEAR: str << "(linear) "; break;
1054 str << "extent:[" << imageInfo.extent.width << ", " << imageInfo.extent.height << ", " << imageInfo.extent.depth << "] ";
1055 str << imageInfo.format << " ";
1056 str << "samples:" << static_cast<deUint32>(imageInfo.samples) << " ";
1057 str << "flags:" << static_cast<deUint32>(imageInfo.flags) << " ";
1058 str << "usage:" << static_cast<deUint32>(imageInfo.usage) << " ";
1063 tcu::TestStatus ImageMemoryRequirementsOriginal::execTest (Context& context, const ImageTestParams params)
1065 const DeviceInterface& vk = context.getDeviceInterface();
1066 const InstanceInterface& vki = context.getInstanceInterface();
1067 const VkDevice device = context.getDevice();
1068 const VkPhysicalDevice physDevice = context.getPhysicalDevice();
1069 const VkImageCreateFlags sparseFlags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_ALIASED_BIT;
1070 const VkImageUsageFlags transientFlags = VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
1072 preTestChecks(context, vki, physDevice, params.flags);
1074 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physDevice);
1075 const deUint32 notInitializedBits = ~0u;
1076 const VkImageAspectFlags colorAspect = VK_IMAGE_ASPECT_COLOR_BIT;
1077 const VkImageAspectFlags depthStencilAspect = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
1078 const VkImageAspectFlags allAspects[2] = { colorAspect, depthStencilAspect };
1079 tcu::TestLog& log = context.getTestContext().getLog();
1080 bool allPass = true;
1081 deUint32 numCheckedImages = 0u;
1083 log << tcu::TestLog::Message << "Verify memory requirements for the following parameter combinations:" << tcu::TestLog::EndMessage;
1085 for (deUint32 loopAspectNdx = 0u; loopAspectNdx < DE_LENGTH_OF_ARRAY(allAspects); ++loopAspectNdx)
1087 const VkImageAspectFlags aspect = allAspects[loopAspectNdx];
1088 deUint32 previousMemoryTypeBits = notInitializedBits;
1090 for (VkFormat loopFormat = VK_FORMAT_R4G4_UNORM_PACK8; loopFormat <= VK_FORMAT_ASTC_12x12_SRGB_BLOCK; loopFormat = nextEnum(loopFormat))
1091 if (isFormatMatchingAspect(loopFormat, aspect))
1093 // memoryTypeBits may differ between depth/stencil formats
1094 if (aspect == depthStencilAspect)
1095 previousMemoryTypeBits = notInitializedBits;
1097 for (VkImageType loopImageType = VK_IMAGE_TYPE_1D; loopImageType != VK_IMAGE_TYPE_LAST; loopImageType = nextEnum(loopImageType))
1098 for (VkImageCreateFlags loopCreateFlags = (VkImageCreateFlags)0; loopCreateFlags <= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT; loopCreateFlags = nextFlagExcluding(loopCreateFlags, sparseFlags))
1099 for (VkImageUsageFlags loopUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT; loopUsageFlags <= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT; loopUsageFlags = nextFlagExcluding(loopUsageFlags, transientFlags))
1100 for (VkSampleCountFlagBits loopSampleCount = VK_SAMPLE_COUNT_1_BIT; loopSampleCount <= VK_SAMPLE_COUNT_16_BIT; loopSampleCount = nextFlag(loopSampleCount))
1102 const VkImageCreateFlags actualCreateFlags = loopCreateFlags | params.flags;
1103 const VkImageUsageFlags actualUsageFlags = loopUsageFlags | (params.transient ? VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT : (VkImageUsageFlagBits)0);
1104 const bool isCube = (actualCreateFlags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) != 0u;
1105 const VkImageCreateInfo imageInfo =
1107 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1108 DE_NULL, // const void* pNext;
1109 actualCreateFlags, // VkImageCreateFlags flags;
1110 loopImageType, // VkImageType imageType;
1111 loopFormat, // VkFormat format;
1112 makeExtentForImage(loopImageType), // VkExtent3D extent;
1113 1u, // uint32_t mipLevels;
1114 (isCube ? 6u : 1u), // uint32_t arrayLayers;
1115 loopSampleCount, // VkSampleCountFlagBits samples;
1116 params.tiling, // VkImageTiling tiling;
1117 actualUsageFlags, // VkImageUsageFlags usage;
1118 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1119 0u, // uint32_t queueFamilyIndexCount;
1120 DE_NULL, // const uint32_t* pQueueFamilyIndices;
1121 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
1124 m_currentTestImageInfo = imageInfo;
1126 if (!isImageSupported(vki, physDevice, m_currentTestImageInfo))
1129 log << tcu::TestLog::Message << "- " << getImageInfoString(m_currentTestImageInfo) << tcu::TestLog::EndMessage;
1132 tcu::ResultCollector result(log, "ERROR: ");
1134 updateMemoryRequirements(vk, device);
1136 verifyMemoryRequirements(result, memoryProperties);
1138 // For the same tiling, transient usage, and sparse flags, (and format, if D/S) memoryTypeBits must be the same for all images
1139 result.check((previousMemoryTypeBits == notInitializedBits) || (m_currentTestRequirements.memoryTypeBits == previousMemoryTypeBits),
1140 "memoryTypeBits differ from the ones in the previous image configuration");
1142 if (result.getResult() != QP_TEST_RESULT_PASS)
1145 previousMemoryTypeBits = m_currentTestRequirements.memoryTypeBits;
1150 if (numCheckedImages == 0u)
1151 log << tcu::TestLog::Message << "NOTE: No supported image configurations -- nothing to check" << tcu::TestLog::EndMessage;
1153 return allPass ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Some memory requirements were incorrect");
1157 class ImageMemoryRequirementsExtended : public ImageMemoryRequirementsOriginal
1160 static tcu::TestStatus testEntryPoint (Context& context,
1161 const ImageTestParams params);
1164 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
1165 const std::string& name,
1166 const std::string& desc,
1167 const ImageTestParams arg0);
1169 virtual void preTestChecks (Context& context,
1170 const InstanceInterface& vki,
1171 const VkPhysicalDevice physDevice,
1172 const VkImageCreateFlags flags);
1174 virtual void updateMemoryRequirements (const DeviceInterface& vk,
1175 const VkDevice device);
1179 tcu::TestStatus ImageMemoryRequirementsExtended::testEntryPoint (Context& context, const ImageTestParams params)
1181 ImageMemoryRequirementsExtended test;
1183 return test.execTest(context, params);
1186 void ImageMemoryRequirementsExtended::addFunctionTestCase (tcu::TestCaseGroup* group,
1187 const std::string& name,
1188 const std::string& desc,
1189 const ImageTestParams arg0)
1191 addFunctionCase(group, name, desc, testEntryPoint, arg0);
1194 void ImageMemoryRequirementsExtended::preTestChecks (Context& context,
1195 const InstanceInterface& vki,
1196 const VkPhysicalDevice physDevice,
1197 const VkImageCreateFlags createFlags)
1199 const std::string extensionName("VK_KHR_get_memory_requirements2");
1201 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1202 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1204 ImageMemoryRequirementsOriginal::preTestChecks (context, vki, physDevice, createFlags);
1207 void ImageMemoryRequirementsExtended::updateMemoryRequirements (const DeviceInterface& vk,
1208 const VkDevice device)
1210 m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo);
1214 class ImageMemoryRequirementsDedicatedAllocation : public ImageMemoryRequirementsExtended
1217 static tcu::TestStatus testEntryPoint (Context& context,
1218 const ImageTestParams params);
1221 virtual void addFunctionTestCase (tcu::TestCaseGroup* group,
1222 const std::string& name,
1223 const std::string& desc,
1224 const ImageTestParams arg0);
1226 virtual void preTestChecks (Context& context,
1227 const InstanceInterface& vki,
1228 const VkPhysicalDevice physDevice,
1229 const VkImageCreateFlags flags);
1231 virtual void updateMemoryRequirements (const DeviceInterface& vk,
1232 const VkDevice device);
1234 virtual void verifyMemoryRequirements (tcu::ResultCollector& result,
1235 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties);
1238 VkBool32 m_currentTestPrefersDedicatedAllocation;
1239 VkBool32 m_currentTestRequiresDedicatedAllocation;
1243 tcu::TestStatus ImageMemoryRequirementsDedicatedAllocation::testEntryPoint (Context& context, const ImageTestParams params)
1245 ImageMemoryRequirementsDedicatedAllocation test;
1247 return test.execTest(context, params);
1250 void ImageMemoryRequirementsDedicatedAllocation::addFunctionTestCase (tcu::TestCaseGroup* group,
1251 const std::string& name,
1252 const std::string& desc,
1253 const ImageTestParams arg0)
1255 addFunctionCase(group, name, desc, testEntryPoint, arg0);
1258 void ImageMemoryRequirementsDedicatedAllocation::preTestChecks (Context& context,
1259 const InstanceInterface& vki,
1260 const VkPhysicalDevice physDevice,
1261 const VkImageCreateFlags createFlags)
1263 const std::string extensionName("VK_KHR_dedicated_allocation");
1265 if (!de::contains(context.getDeviceExtensions().begin(), context.getDeviceExtensions().end(), extensionName))
1266 TCU_THROW(NotSupportedError, std::string(extensionName + " is not supported").c_str());
1268 ImageMemoryRequirementsExtended::preTestChecks (context, vki, physDevice, createFlags);
1272 void ImageMemoryRequirementsDedicatedAllocation::updateMemoryRequirements (const DeviceInterface& vk,
1273 const VkDevice device)
1275 const deUint32 invalidVkBool32 = static_cast<deUint32>(~0);
1277 VkMemoryDedicatedRequirementsKHR dedicatedRequirements =
1279 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR, // VkStructureType sType
1280 DE_NULL, // void* pNext
1281 invalidVkBool32, // VkBool32 prefersDedicatedAllocation
1282 invalidVkBool32 // VkBool32 requiresDedicatedAllocation
1285 m_currentTestRequirements = getImageMemoryRequirements2(vk, device, m_currentTestImageInfo, &dedicatedRequirements);
1286 m_currentTestPrefersDedicatedAllocation = dedicatedRequirements.prefersDedicatedAllocation;
1287 m_currentTestRequiresDedicatedAllocation = dedicatedRequirements.requiresDedicatedAllocation;
1290 void ImageMemoryRequirementsDedicatedAllocation::verifyMemoryRequirements (tcu::ResultCollector& result,
1291 const VkPhysicalDeviceMemoryProperties& deviceMemoryProperties)
1293 ImageMemoryRequirementsExtended::verifyMemoryRequirements(result, deviceMemoryProperties);
1295 result.check(validValueVkBool32(m_currentTestPrefersDedicatedAllocation),
1296 "Non-bool value in m_currentTestPrefersDedicatedAllocation");
1298 result.check(m_currentTestRequiresDedicatedAllocation == VK_FALSE,
1299 "Test design expects m_currentTestRequiresDedicatedAllocation to be false");
1301 result.check(m_currentTestPrefersDedicatedAllocation == VK_FALSE || m_currentTestPrefersDedicatedAllocation == VK_FALSE,
1302 "Preferred and required flags for dedicated memory cannot be set to true at the same time");
1305 void populateCoreTestGroup (tcu::TestCaseGroup* group)
1307 BufferMemoryRequirementsOriginal bufferTest;
1308 ImageMemoryRequirementsOriginal imageTest;
1310 bufferTest.populateTestGroup(group);
1311 imageTest.populateTestGroup(group);
1314 void populateExtendedTestGroup (tcu::TestCaseGroup* group)
1316 BufferMemoryRequirementsExtended bufferTest;
1317 ImageMemoryRequirementsExtended imageTest;
1319 bufferTest.populateTestGroup(group);
1320 imageTest.populateTestGroup(group);
1323 void populateDedicatedAllocationTestGroup(tcu::TestCaseGroup* group)
1325 BufferMemoryRequirementsDedicatedAllocation bufferTest;
1326 ImageMemoryRequirementsDedicatedAllocation imageTest;
1328 bufferTest.populateTestGroup(group);
1329 imageTest.populateTestGroup(group);
1335 tcu::TestCaseGroup* createRequirementsTests (tcu::TestContext& testCtx)
1337 de::MovePtr<tcu::TestCaseGroup> requirementsGroup(new tcu::TestCaseGroup(testCtx, "requirements", "Buffer and image memory requirements"));
1339 requirementsGroup->addChild(createTestGroup(testCtx, "core", "Memory requirements tests with core functionality", populateCoreTestGroup));
1340 requirementsGroup->addChild(createTestGroup(testCtx, "extended", "Memory requirements tests with extension VK_KHR_get_memory_requirements2", populateExtendedTestGroup));
1341 requirementsGroup->addChild(createTestGroup(testCtx, "dedicated_allocation", "Memory requirements tests with extension VK_KHR_dedicated_allocation", populateDedicatedAllocationTestGroup));
1343 return requirementsGroup.release();