1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 The Khronos Group Inc.
6 *
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
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 *//*!
20 * \file
21 * \brief Memory binding test excercising VK_KHR_bind_memory2 extension.
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktMemoryBindingTests.hpp"
25
26 #include "vktTestCase.hpp"
27 #include "tcuTestLog.hpp"
28 #include "vktCustomInstancesDevices.hpp"
29
30 #include "vkPlatform.hpp"
31 #include "tcuCommandLine.hpp"
32 #include "gluVarType.hpp"
33 #include "deStringUtil.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkRefUtil.hpp"
37 #include "deSharedPtr.hpp"
38 #include "vktTestCase.hpp"
39 #include "vkTypeUtil.hpp"
40 #include "vkCmdUtil.hpp"
41 #include "vkImageUtil.hpp"
42
43 #include <algorithm>
44
45 namespace vkt
46 {
47 namespace memory
48 {
49 namespace
50 {
51
52 using namespace vk;
53
54 typedef const VkMemoryDedicatedAllocateInfo ConstDedicatedInfo;
55 typedef de::SharedPtr<Move<VkDeviceMemory> > MemoryRegionPtr;
56 typedef std::vector<MemoryRegionPtr> MemoryRegionsList;
57 typedef de::SharedPtr<Move<VkBuffer> > BufferPtr;
58 typedef std::vector<BufferPtr> BuffersList;
59 typedef de::SharedPtr<Move<VkImage> > ImagePtr;
60 typedef std::vector<ImagePtr> ImagesList;
61 typedef std::vector<VkBindBufferMemoryInfo> BindBufferMemoryInfosList;
62 typedef std::vector<VkBindImageMemoryInfo> BindImageMemoryInfosList;
63
64 class MemoryMappingRAII
65 {
66 public:
MemoryMappingRAII(const DeviceInterface & deviceInterface,const VkDevice & device,VkDeviceMemory deviceMemory,VkDeviceSize offset,VkDeviceSize size,VkMemoryMapFlags flags)67 MemoryMappingRAII (const DeviceInterface& deviceInterface,
68 const VkDevice& device,
69 VkDeviceMemory deviceMemory,
70 VkDeviceSize offset,
71 VkDeviceSize size,
72 VkMemoryMapFlags flags)
73 : vk (deviceInterface)
74 , dev (device)
75 , memory (deviceMemory)
76 , hostPtr (DE_NULL)
77
78 {
79 vk.mapMemory(dev, memory, offset, size, flags, &hostPtr);
80 }
81
~MemoryMappingRAII()82 ~MemoryMappingRAII ()
83 {
84 vk.unmapMemory(dev, memory);
85 hostPtr = DE_NULL;
86 }
87
ptr()88 void* ptr ()
89 {
90 return hostPtr;
91 }
92
flush()93 void flush ()
94 {
95 const VkMappedMemoryRange range = makeMemoryRange(0, VK_WHOLE_SIZE);
96 VK_CHECK(vk.flushMappedMemoryRanges(dev, 1u, &range));
97 }
98
invalidate()99 void invalidate ()
100 {
101 const VkMappedMemoryRange range = makeMemoryRange(0, VK_WHOLE_SIZE);
102 VK_CHECK(vk.invalidateMappedMemoryRanges(dev, 1u, &range));
103 }
104
105
106 protected:
107 const DeviceInterface& vk;
108 const VkDevice& dev;
109 VkDeviceMemory memory;
110 void* hostPtr;
111
makeMemoryRange(VkDeviceSize offset,VkDeviceSize size)112 const VkMappedMemoryRange makeMemoryRange (VkDeviceSize offset,
113 VkDeviceSize size)
114 {
115 const VkMappedMemoryRange range =
116 {
117 VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
118 DE_NULL,
119 memory,
120 offset,
121 size
122 };
123 return range;
124 }
125 };
126
127 class SimpleRandomGenerator
128 {
129 public:
SimpleRandomGenerator(deUint32 seed)130 SimpleRandomGenerator (deUint32 seed)
131 : value (seed)
132 {}
getNext()133 deUint32 getNext ()
134 {
135 value += 1;
136 value ^= (value << 21);
137 value ^= (value >> 15);
138 value ^= (value << 4);
139 return value;
140 }
141 protected:
142 deUint32 value;
143 };
144
145 enum PriorityMode
146 {
147 PRIORITY_MODE_DEFAULT,
148 PRIORITY_MODE_STATIC,
149 PRIORITY_MODE_DYNAMIC,
150 };
151
152 struct BindingCaseParameters
153 {
154 VkBufferCreateFlags flags;
155 VkBufferUsageFlags usage;
156 VkSharingMode sharing;
157 VkDeviceSize bufferSize;
158 VkExtent3D imageSize;
159 deUint32 targetsCount;
160 VkImageCreateFlags imageCreateFlags;
161 PriorityMode priorityMode;
162 };
163
makeBindingCaseParameters(deUint32 targetsCount,deUint32 width,deUint32 height,VkImageCreateFlags imageCreateFlags,PriorityMode priorityMode)164 BindingCaseParameters makeBindingCaseParameters (deUint32 targetsCount,
165 deUint32 width,
166 deUint32 height,
167 VkImageCreateFlags imageCreateFlags,
168 PriorityMode priorityMode)
169 {
170 BindingCaseParameters params;
171 deMemset(¶ms, 0, sizeof(BindingCaseParameters));
172 params.imageSize.width = width;
173 params.imageSize.height = height;
174 params.imageSize.depth = 1;
175 params.bufferSize = params.imageSize.width * params.imageSize.height * params.imageSize.depth * sizeof(deUint32);
176 params.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
177 params.targetsCount = targetsCount;
178 params.imageCreateFlags = imageCreateFlags;
179 params.priorityMode = priorityMode;
180 return params;
181 }
182
makeBindingCaseParameters(deUint32 targetsCount,VkBufferUsageFlags usage,VkSharingMode sharing,VkDeviceSize bufferSize,VkImageCreateFlags imageCreateFlags,PriorityMode priorityMode)183 BindingCaseParameters makeBindingCaseParameters (deUint32 targetsCount,
184 VkBufferUsageFlags usage,
185 VkSharingMode sharing,
186 VkDeviceSize bufferSize,
187 VkImageCreateFlags imageCreateFlags,
188 PriorityMode priorityMode)
189 {
190 BindingCaseParameters params =
191 {
192 0, // VkBufferCreateFlags flags;
193 usage, // VkBufferUsageFlags usage;
194 sharing, // VkSharingMode sharing;
195 bufferSize, // VkDeviceSize bufferSize;
196 {0u, 0u, 0u}, // VkExtent3D imageSize;
197 targetsCount, // deUint32 targetsCount;
198 imageCreateFlags, // VkImageCreateFlags imageCreateFlags
199 priorityMode, // PriorityMode priorityMode
200 };
201 return params;
202 }
203
makeImageCreateInfo(BindingCaseParameters & params)204 VkImageCreateInfo makeImageCreateInfo (BindingCaseParameters& params)
205 {
206 const VkImageCreateInfo imageParams =
207 {
208 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
209 DE_NULL, // const void* pNext;
210 params.imageCreateFlags, // VkImageCreateFlags flags;
211 VK_IMAGE_TYPE_2D, // VkImageType imageType;
212 VK_FORMAT_R8G8B8A8_UINT, // VkFormat format;
213 params.imageSize, // VkExtent3D extent;
214 1u, // deUint32 mipLevels;
215 1u, // deUint32 arrayLayers;
216 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
217 VK_IMAGE_TILING_LINEAR, // VkImageTiling tiling;
218 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
219 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
220 0u, // deUint32 queueFamilyIndexCount;
221 DE_NULL, // const deUint32* pQueueFamilyIndices;
222 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
223 };
224 return imageParams;
225 }
226
makeBufferCreateInfo(Context & ctx,BindingCaseParameters & params)227 VkBufferCreateInfo makeBufferCreateInfo (Context& ctx,
228 BindingCaseParameters& params)
229 {
230 const deUint32 queueFamilyIndex = ctx.getUniversalQueueFamilyIndex();
231 VkBufferCreateInfo bufferParams =
232 {
233 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
234 DE_NULL, // const void* pNext;
235 params.flags, // VkBufferCreateFlags flags;
236 params.bufferSize, // VkDeviceSize size;
237 params.usage, // VkBufferUsageFlags usage;
238 params.sharing, // VkSharingMode sharingMode;
239 1u, // uint32_t queueFamilyIndexCount;
240 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
241 };
242 return bufferParams;
243 }
244
makeMemoryAllocateInfo(VkMemoryRequirements & memReqs,const void * next)245 const VkMemoryAllocateInfo makeMemoryAllocateInfo (VkMemoryRequirements& memReqs,
246 const void* next)
247 {
248 const deUint32 heapTypeIndex = (deUint32)deCtz32(memReqs.memoryTypeBits);
249 const VkMemoryAllocateInfo allocateParams =
250 {
251 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
252 next, // const void* pNext;
253 memReqs.size, // VkDeviceSize allocationSize;
254 heapTypeIndex, // uint32_t memoryTypeIndex;
255 };
256 return allocateParams;
257 }
258
259 enum MemoryHostVisibility
260 {
261 MemoryAny,
262 MemoryHostVisible
263 };
264
selectMatchingMemoryType(Context & ctx,VkMemoryRequirements & memReqs,MemoryHostVisibility memoryVisibility)265 deUint32 selectMatchingMemoryType (Context& ctx,
266 VkMemoryRequirements& memReqs,
267 MemoryHostVisibility memoryVisibility)
268 {
269 const VkPhysicalDevice vkPhysicalDevice = ctx.getPhysicalDevice();
270 const InstanceInterface& vkInstance = ctx.getInstanceInterface();
271 VkPhysicalDeviceMemoryProperties memoryProperties;
272
273 vkInstance.getPhysicalDeviceMemoryProperties(vkPhysicalDevice, &memoryProperties);
274 if (memoryVisibility == MemoryHostVisible)
275 {
276 for (deUint32 typeNdx = 0; typeNdx < memoryProperties.memoryTypeCount; ++typeNdx)
277 {
278 const deBool isInAllowed = (memReqs.memoryTypeBits & (1u << typeNdx)) != 0u;
279 const deBool hasRightProperties = (memoryProperties.memoryTypes[typeNdx].propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) != 0u;
280 if (isInAllowed && hasRightProperties)
281 return typeNdx;
282 }
283 }
284 return (deUint32)deCtz32(memReqs.memoryTypeBits);
285 }
286
makeMemoryAllocateInfo(Context & ctx,VkMemoryRequirements & memReqs,MemoryHostVisibility memoryVisibility)287 const VkMemoryAllocateInfo makeMemoryAllocateInfo (Context& ctx,
288 VkMemoryRequirements& memReqs,
289 MemoryHostVisibility memoryVisibility)
290 {
291 const deUint32 heapTypeIndex = selectMatchingMemoryType(ctx, memReqs, memoryVisibility);
292 const VkMemoryAllocateInfo allocateParams =
293 {
294 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
295 DE_NULL, // const void* pNext;
296 memReqs.size, // VkDeviceSize allocationSize;
297 heapTypeIndex, // uint32_t memoryTypeIndex;
298 };
299 return allocateParams;
300 }
301
makeDedicatedAllocationInfo(VkBuffer buffer)302 ConstDedicatedInfo makeDedicatedAllocationInfo (VkBuffer buffer)
303 {
304 ConstDedicatedInfo dedicatedAllocationInfo =
305 {
306 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // VkStructureType sType
307 DE_NULL, // const void* pNext
308 DE_NULL, // VkImage image
309 buffer // VkBuffer buffer
310 };
311 return dedicatedAllocationInfo;
312 }
313
makeDedicatedAllocationInfo(VkImage image)314 ConstDedicatedInfo makeDedicatedAllocationInfo (VkImage image)
315 {
316 ConstDedicatedInfo dedicatedAllocationInfo =
317 {
318 VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, // VkStructureType sType
319 DE_NULL, // const void* pNext
320 image, // VkImage image
321 DE_NULL // VkBuffer buffer
322 };
323 return dedicatedAllocationInfo;
324 }
325
makeBufferMemoryBindingInfo(VkBuffer buffer,VkDeviceMemory memory)326 const VkBindBufferMemoryInfo makeBufferMemoryBindingInfo (VkBuffer buffer,
327 VkDeviceMemory memory)
328 {
329 const VkBindBufferMemoryInfo bufferMemoryBinding =
330 {
331 VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO, // VkStructureType sType;
332 DE_NULL, // const void* pNext;
333 buffer, // VkBuffer buffer;
334 memory, // VkDeviceMemory memory;
335 0u, // VkDeviceSize memoryOffset;
336 };
337 return bufferMemoryBinding;
338 }
339
makeImageMemoryBindingInfo(VkImage image,VkDeviceMemory memory)340 const VkBindImageMemoryInfo makeImageMemoryBindingInfo (VkImage image,
341 VkDeviceMemory memory)
342 {
343 const VkBindImageMemoryInfo imageMemoryBinding =
344 {
345 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO, // VkStructureType sType;
346 DE_NULL, // const void* pNext;
347 image, // VkImage image;
348 memory, // VkDeviceMemory memory;
349 0u, // VkDeviceSize memoryOffset;
350 };
351 return imageMemoryBinding;
352 }
353
354 #ifndef CTS_USES_VULKANSC
makeMemoryPriorityAllocateInfo(const void * pNext,float priority)355 const VkMemoryPriorityAllocateInfoEXT makeMemoryPriorityAllocateInfo (const void * pNext,
356 float priority)
357 {
358 const VkMemoryPriorityAllocateInfoEXT info =
359 {
360 VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT, // VkStructureType sType;
361 pNext, // const void* pNext;
362 priority, // float priority
363 };
364 return info;
365 }
366 #endif
367
368 enum TransferDirection
369 {
370 TransferToResource = 0,
371 TransferFromResource = 1
372 };
373
makeMemoryBarrierInfo(VkBuffer buffer,VkDeviceSize size,TransferDirection direction)374 const VkBufferMemoryBarrier makeMemoryBarrierInfo (VkBuffer buffer,
375 VkDeviceSize size,
376 TransferDirection direction)
377 {
378 const deBool fromRes = direction == TransferFromResource;
379 const VkAccessFlags srcMask = static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_HOST_WRITE_BIT : VK_ACCESS_TRANSFER_WRITE_BIT);
380 const VkAccessFlags dstMask = static_cast<VkAccessFlags>(fromRes ? VK_ACCESS_TRANSFER_READ_BIT : VK_ACCESS_HOST_READ_BIT);
381 const VkBufferMemoryBarrier bufferBarrier =
382 {
383 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
384 DE_NULL, // const void* pNext;
385 srcMask, // VkAccessFlags srcAccessMask;
386 dstMask, // VkAccessFlags dstAccessMask;
387 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
388 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
389 buffer, // VkBuffer buffer;
390 0u, // VkDeviceSize offset;
391 size // VkDeviceSize size;
392 };
393 return bufferBarrier;
394 }
395
makeMemoryBarrierInfo(VkImage image,VkAccessFlags srcAccess,VkAccessFlags dstAccess,VkImageLayout oldLayout,VkImageLayout newLayout)396 const VkImageMemoryBarrier makeMemoryBarrierInfo (VkImage image,
397 VkAccessFlags srcAccess,
398 VkAccessFlags dstAccess,
399 VkImageLayout oldLayout,
400 VkImageLayout newLayout)
401 {
402 const VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT;
403 const VkImageMemoryBarrier imageBarrier =
404 {
405 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
406 DE_NULL, // const void* pNext;
407 srcAccess, // VkAccessFlags srcAccessMask;
408 dstAccess, // VkAccessFlags dstAccessMask;
409 oldLayout, // VkImageLayout oldLayout;
410 newLayout, // VkImageLayout newLayout;
411 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
412 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
413 image, // VkImage image;
414 { // VkImageSubresourceRange subresourceRange;
415 aspect, // VkImageAspectFlags aspect;
416 0u, // deUint32 baseMipLevel;
417 1u, // deUint32 mipLevels;
418 0u, // deUint32 baseArraySlice;
419 1u, // deUint32 arraySize;
420 }
421 };
422 return imageBarrier;
423 }
424
createCommandBuffer(const DeviceInterface & vk,VkDevice device,VkCommandPool commandPool)425 Move<VkCommandBuffer> createCommandBuffer (const DeviceInterface& vk,
426 VkDevice device,
427 VkCommandPool commandPool)
428 {
429 const VkCommandBufferAllocateInfo allocInfo =
430 {
431 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
432 DE_NULL,
433 commandPool,
434 VK_COMMAND_BUFFER_LEVEL_PRIMARY,
435 1
436 };
437 return allocateCommandBuffer(vk, device, &allocInfo);
438 }
439
440 class BaseTestInstance : public TestInstance
441 {
442 public:
BaseTestInstance(Context & ctx,BindingCaseParameters params)443 BaseTestInstance (Context& ctx,
444 BindingCaseParameters params)
445 : TestInstance (ctx)
446 , m_params (params)
447 {
448 #ifndef CTS_USES_VULKANSC
449 if (m_params.priorityMode == PRIORITY_MODE_DYNAMIC)
450 {
451 VkInstance instance (m_context.getInstance());
452 InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance);
453 const float queuePriority = 1.0f;
454
455 VkPhysicalDevicePageableDeviceLocalMemoryFeaturesEXT pageableDeviceLocalMemoryFeature =
456 {
457 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PAGEABLE_DEVICE_LOCAL_MEMORY_FEATURES_EXT, // VkStructureType sType
458 DE_NULL, // const void* pNext
459 VK_FALSE, // VkBool32 pageableDeviceLocalMemory;
460 };
461
462 VkPhysicalDeviceFeatures features;
463 deMemset(&features, 0, sizeof(vk::VkPhysicalDeviceFeatures));
464
465 VkPhysicalDeviceFeatures2 features2 =
466 {
467 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, // VkStructureType sType
468 &pageableDeviceLocalMemoryFeature, // const void* pNext
469 features // VkPhysicalDeviceFeatures features
470 };
471
472 instanceDriver.getPhysicalDeviceFeatures2(m_context.getPhysicalDevice(), &features2);
473
474 if (!pageableDeviceLocalMemoryFeature.pageableDeviceLocalMemory)
475 TCU_FAIL("pageableDeviceLocalMemory feature not supported but VK_EXT_pageable_device_local_memory advertised");
476
477 pageableDeviceLocalMemoryFeature.pageableDeviceLocalMemory = VK_TRUE;
478
479 std::vector<const char*> deviceExtensions;
480 deviceExtensions.push_back("VK_EXT_memory_priority");
481 deviceExtensions.push_back("VK_EXT_pageable_device_local_memory");
482
483 VkDeviceQueueCreateInfo queueInfo =
484 {
485 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
486 DE_NULL, // const void* pNext;
487 0u, // VkDeviceQueueCreateFlags flags;
488 0u, // deUint32 queueFamilyIndex;
489 1u, // deUint32 queueCount;
490 &queuePriority // const float* pQueuePriorities;
491 };
492
493 const VkDeviceCreateInfo deviceInfo =
494 {
495 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
496 &features2, // const void* pNext;
497 (VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
498 1u, // uint32_t queueCreateInfoCount;
499 &queueInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
500 0u, // uint32_t enabledLayerCount;
501 DE_NULL, // const char* const* ppEnabledLayerNames;
502 deUint32(deviceExtensions.size()), // uint32_t enabledExtensionCount;
503 (deviceExtensions.empty()) ? DE_NULL : deviceExtensions.data(), // const char* const* ppEnabledExtensionNames;
504 DE_NULL // const VkPhysicalDeviceFeatures* pEnabledFeatures;
505 };
506
507 m_logicalDevice = createCustomDevice(m_context.getTestContext().getCommandLine().isValidationEnabled(), m_context.getPlatformInterface(), instance, instanceDriver, m_context.getPhysicalDevice(), &deviceInfo);
508 }
509 #endif // CTS_USES_VULKANSC
510 m_logicalDeviceInterface = de::MovePtr<DeviceDriver>(new DeviceDriver(m_context.getPlatformInterface(), m_context.getInstance(), getDevice(), m_context.getUsedApiVersion()));
511 m_logicalDeviceInterface->getDeviceQueue(getDevice(), m_context.getUniversalQueueFamilyIndex(), 0, &m_logicalDeviceQueue);
512 };
513
514 protected:
getDevice(void)515 vk::VkDevice getDevice (void) { return (m_params.priorityMode == PRIORITY_MODE_DYNAMIC) ? m_logicalDevice.get() : m_context.getDevice(); }
getDeviceInterface(void)516 const DeviceInterface& getDeviceInterface (void) { return (m_params.priorityMode == PRIORITY_MODE_DYNAMIC) ? *m_logicalDeviceInterface.get() : m_context.getDeviceInterface(); }
getUniversalQueue(void)517 VkQueue getUniversalQueue (void) { return (m_params.priorityMode == PRIORITY_MODE_DYNAMIC) ? m_logicalDeviceQueue : m_context.getUniversalQueue(); }
518
519 template<typename TTarget>
520 void createBindingTargets (std::vector<de::SharedPtr<Move<TTarget> > >& targets);
521
522 template<typename TTarget, deBool TDedicated>
523 void createMemory (std::vector<de::SharedPtr<Move<TTarget> > >& targets,
524 MemoryRegionsList& memory);
525
526 template<typename TTarget>
527 void makeBinding (std::vector<de::SharedPtr<Move<TTarget> > >& targets,
528 MemoryRegionsList& memory);
529
530 template <typename TTarget>
531 void fillUpResource (Move<VkBuffer>& source,
532 Move<TTarget>& target);
533
534 template <typename TTarget>
535 void readUpResource (Move<TTarget>& source,
536 Move<VkBuffer>& target);
537
538 template <typename TTarget>
539 void layoutTransitionResource (Move<TTarget>& target);
540
541 void createBuffer (Move<VkBuffer>& buffer,
542 Move<VkDeviceMemory>& memory,
543 VkDeviceSize* memorySize);
544
545 void pushData (VkDeviceMemory memory,
546 deUint32 dataSeed,
547 VkDeviceSize size);
548
549 deBool checkData (VkDeviceMemory memory,
550 deUint32 dataSeed,
551 VkDeviceSize size);
552
553 BindingCaseParameters m_params;
554
555 private:
556 vk::Move<vk::VkDevice> m_logicalDevice;
557 de::MovePtr<DeviceDriver> m_logicalDeviceInterface;
558 VkQueue m_logicalDeviceQueue;
559 };
560
561 template<>
createBindingTargets(BuffersList & targets)562 void BaseTestInstance::createBindingTargets<VkBuffer> (BuffersList& targets)
563 {
564 const deUint32 count = m_params.targetsCount;
565 const VkDevice vkDevice = getDevice();
566 const DeviceInterface& vk = getDeviceInterface();
567
568 targets.reserve(count);
569 for (deUint32 i = 0u; i < count; ++i)
570 {
571 VkBufferCreateInfo bufferParams = makeBufferCreateInfo(m_context, m_params);
572 targets.push_back(BufferPtr(new Move<VkBuffer>(vk::createBuffer(vk, vkDevice, &bufferParams))));
573 }
574 }
575
576 template<>
createBindingTargets(ImagesList & targets)577 void BaseTestInstance::createBindingTargets<VkImage> (ImagesList& targets)
578 {
579 const deUint32 count = m_params.targetsCount;
580 const VkDevice vkDevice = getDevice();
581 const DeviceInterface& vk = getDeviceInterface();
582
583 targets.reserve(count);
584 for (deUint32 i = 0u; i < count; ++i)
585 {
586 VkImageCreateInfo imageParams = makeImageCreateInfo(m_params);
587 targets.push_back(ImagePtr(new Move<VkImage>(createImage(vk, vkDevice, &imageParams))));
588 }
589 }
590
591 template<>
createMemory(BuffersList & targets,MemoryRegionsList & memory)592 void BaseTestInstance::createMemory<VkBuffer, DE_FALSE> (BuffersList& targets,
593 MemoryRegionsList& memory)
594 {
595 const deUint32 count = static_cast<deUint32>(targets.size());
596 const DeviceInterface& vk = getDeviceInterface();
597 const VkDevice vkDevice = getDevice();
598
599 memory.reserve(count);
600 for (deUint32 i = 0; i < count; ++i)
601 {
602 VkMemoryRequirements memReqs;
603
604 vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
605
606 #ifdef CTS_USES_VULKANSC
607 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, DE_NULL);
608 #else
609 VkMemoryPriorityAllocateInfoEXT priority = makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
610 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, (m_params.priorityMode == PRIORITY_MODE_STATIC) ? &priority : DE_NULL);
611 #endif
612 VkDeviceMemory rawMemory = DE_NULL;
613
614 vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
615
616 #ifndef CTS_USES_VULKANSC
617 if (m_params.priorityMode == PRIORITY_MODE_DYNAMIC)
618 vk.setDeviceMemoryPriorityEXT(vkDevice, rawMemory, priority.priority);
619 #endif // CTS_USES_VULKANSC
620
621 memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
622 }
623 }
624
625 template<>
createMemory(ImagesList & targets,MemoryRegionsList & memory)626 void BaseTestInstance::createMemory<VkImage, DE_FALSE> (ImagesList& targets,
627 MemoryRegionsList& memory)
628 {
629 const deUint32 count = static_cast<deUint32>(targets.size());
630 const DeviceInterface& vk = getDeviceInterface();
631 const VkDevice vkDevice = getDevice();
632
633 memory.reserve(count);
634 for (deUint32 i = 0; i < count; ++i)
635 {
636 VkMemoryRequirements memReqs;
637 vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
638
639 #ifdef CTS_USES_VULKANSC
640 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, DE_NULL);
641 #else
642 VkMemoryPriorityAllocateInfoEXT priority = makeMemoryPriorityAllocateInfo(DE_NULL, ((float)i)/((float)count));
643 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, (m_params.priorityMode == PRIORITY_MODE_STATIC) ? &priority : DE_NULL);
644 #endif
645
646 VkDeviceMemory rawMemory = DE_NULL;
647
648 vk.allocateMemory(vkDevice, &memAlloc, (VkAllocationCallbacks*)DE_NULL, &rawMemory);
649
650 #ifndef CTS_USES_VULKANSC
651 if (m_params.priorityMode == PRIORITY_MODE_DYNAMIC)
652 vk.setDeviceMemoryPriorityEXT(vkDevice, rawMemory, priority.priority);
653 #endif // CTS_USES_VULKANSC
654
655 memory.push_back(de::SharedPtr<Move<VkDeviceMemory> >(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
656 }
657 }
658
659 template<>
createMemory(BuffersList & targets,MemoryRegionsList & memory)660 void BaseTestInstance::createMemory<VkBuffer, DE_TRUE> (BuffersList& targets,
661 MemoryRegionsList& memory)
662 {
663 const deUint32 count = static_cast<deUint32>(targets.size());
664 const DeviceInterface& vk = getDeviceInterface();
665 const VkDevice vkDevice = getDevice();
666
667 memory.reserve(count);
668 for (deUint32 i = 0; i < count; ++i)
669 {
670 VkMemoryRequirements memReqs;
671
672 vk.getBufferMemoryRequirements(vkDevice, **targets[i], &memReqs);
673
674 ConstDedicatedInfo dedicatedAllocationInfo = makeDedicatedAllocationInfo(**targets[i]);
675 #ifdef CTS_USES_VULKANSC
676 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, (const void *)&dedicatedAllocationInfo);
677 #else
678 VkMemoryPriorityAllocateInfoEXT priority = makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
679 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, (m_params.priorityMode == PRIORITY_MODE_STATIC) ? &priority : (const void *)&dedicatedAllocationInfo);
680 #endif
681
682 VkDeviceMemory rawMemory = DE_NULL;
683
684 vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
685
686 #ifndef CTS_USES_VULKANSC
687 if (m_params.priorityMode == PRIORITY_MODE_DYNAMIC)
688 vk.setDeviceMemoryPriorityEXT(vkDevice, rawMemory, priority.priority);
689 #endif // CTS_USES_VULKANSC
690
691 memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
692 }
693 }
694
695 template<>
createMemory(ImagesList & targets,MemoryRegionsList & memory)696 void BaseTestInstance::createMemory<VkImage, DE_TRUE> (ImagesList& targets,
697 MemoryRegionsList& memory)
698 {
699 const deUint32 count = static_cast<deUint32>(targets.size());
700 const DeviceInterface& vk = getDeviceInterface();
701 const VkDevice vkDevice = getDevice();
702
703 memory.reserve(count);
704 for (deUint32 i = 0; i < count; ++i)
705 {
706 VkMemoryRequirements memReqs;
707 vk.getImageMemoryRequirements(vkDevice, **targets[i], &memReqs);
708
709 ConstDedicatedInfo dedicatedAllocationInfo = makeDedicatedAllocationInfo(**targets[i]);
710
711 #ifdef CTS_USES_VULKANSC
712 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, (const void *)&dedicatedAllocationInfo);
713 #else
714 VkMemoryPriorityAllocateInfoEXT priority = makeMemoryPriorityAllocateInfo(&dedicatedAllocationInfo, ((float)i)/((float)count));
715 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(memReqs, m_params.priorityMode ? &priority : (const void *)&dedicatedAllocationInfo);
716 #endif
717
718 VkDeviceMemory rawMemory = DE_NULL;
719
720 vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
721
722 #ifndef CTS_USES_VULKANSC
723 if (m_params.priorityMode == PRIORITY_MODE_DYNAMIC)
724 vk.setDeviceMemoryPriorityEXT(vkDevice, rawMemory, priority.priority);
725 #endif // CTS_USES_VULKANSC
726
727 memory.push_back(MemoryRegionPtr(new Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL))));
728 }
729 }
730
731 template<>
makeBinding(BuffersList & targets,MemoryRegionsList & memory)732 void BaseTestInstance::makeBinding<VkBuffer> (BuffersList& targets,
733 MemoryRegionsList& memory)
734 {
735 const deUint32 count = static_cast<deUint32>(targets.size());
736 const VkDevice vkDevice = getDevice();
737 const DeviceInterface& vk = getDeviceInterface();
738 BindBufferMemoryInfosList bindMemoryInfos;
739
740 for (deUint32 i = 0; i < count; ++i)
741 {
742 bindMemoryInfos.push_back(makeBufferMemoryBindingInfo(**targets[i], **memory[i]));
743 }
744
745 VK_CHECK(vk.bindBufferMemory2(vkDevice, count, &bindMemoryInfos.front()));
746 }
747
748 template<>
makeBinding(ImagesList & targets,MemoryRegionsList & memory)749 void BaseTestInstance::makeBinding<VkImage> (ImagesList& targets,
750 MemoryRegionsList& memory)
751 {
752 const deUint32 count = static_cast<deUint32>(targets.size());
753 const VkDevice vkDevice = getDevice();
754 const DeviceInterface& vk = getDeviceInterface();
755 BindImageMemoryInfosList bindMemoryInfos;
756
757 for (deUint32 i = 0; i < count; ++i)
758 {
759 bindMemoryInfos.push_back(makeImageMemoryBindingInfo(**targets[i], **memory[i]));
760 }
761
762 VK_CHECK(vk.bindImageMemory2(vkDevice, count, &bindMemoryInfos.front()));
763 }
764
765 template <>
fillUpResource(Move<VkBuffer> & source,Move<VkBuffer> & target)766 void BaseTestInstance::fillUpResource<VkBuffer> (Move<VkBuffer>& source,
767 Move<VkBuffer>& target)
768 {
769 const DeviceInterface& vk = getDeviceInterface();
770 const VkDevice vkDevice = getDevice();
771 const VkQueue queue = getUniversalQueue();
772
773 const VkBufferMemoryBarrier srcBufferBarrier = makeMemoryBarrierInfo(*source, m_params.bufferSize, TransferFromResource);
774 const VkBufferMemoryBarrier dstBufferBarrier = makeMemoryBarrierInfo(*target, m_params.bufferSize, TransferToResource);
775
776 Move<VkCommandPool> commandPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
777 Move<VkCommandBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, *commandPool);
778 VkBufferCopy bufferCopy = { 0u, 0u, m_params.bufferSize };
779
780 beginCommandBuffer(vk, *cmdBuffer);
781 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
782 vk.cmdCopyBuffer(*cmdBuffer, *source, *target, 1, &bufferCopy);
783 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &dstBufferBarrier, 0, (const VkImageMemoryBarrier*)DE_NULL);
784 endCommandBuffer(vk, *cmdBuffer);
785
786 submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
787 }
788
789 template <>
fillUpResource(Move<VkBuffer> & source,Move<VkImage> & target)790 void BaseTestInstance::fillUpResource<VkImage> (Move<VkBuffer>& source,
791 Move<VkImage>& target)
792 {
793 const DeviceInterface& vk = getDeviceInterface();
794 const VkDevice vkDevice = getDevice();
795 const VkQueue queue = getUniversalQueue();
796
797 const VkBufferMemoryBarrier srcBufferBarrier = makeMemoryBarrierInfo(*source, m_params.bufferSize, TransferFromResource);
798 const VkImageMemoryBarrier preImageBarrier = makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
799 const VkImageMemoryBarrier dstImageBarrier = makeMemoryBarrierInfo(*target, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
800
801 Move<VkCommandPool> commandPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
802 Move<VkCommandBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, *commandPool);
803
804 const VkBufferImageCopy copyRegion =
805 {
806 0u, // VkDeviceSize bufferOffset;
807 m_params.imageSize.width, // deUint32 bufferRowLength;
808 m_params.imageSize.height, // deUint32 bufferImageHeight;
809 {
810 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspect;
811 0u, // deUint32 mipLevel;
812 0u, // deUint32 baseArrayLayer;
813 1u, // deUint32 layerCount;
814 }, // VkImageSubresourceLayers imageSubresource;
815 { 0, 0, 0 }, // VkOffset3D imageOffset;
816 m_params.imageSize // VkExtent3D imageExtent;
817 };
818
819 beginCommandBuffer(vk, *cmdBuffer);
820 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 1, &srcBufferBarrier, 1, &preImageBarrier);
821 vk.cmdCopyBufferToImage(*cmdBuffer, *source, *target, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, (©Region));
822 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &dstImageBarrier);
823 endCommandBuffer(vk, *cmdBuffer);
824
825 submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
826 }
827
828 template <>
readUpResource(Move<VkBuffer> & source,Move<VkBuffer> & target)829 void BaseTestInstance::readUpResource (Move<VkBuffer>& source,
830 Move<VkBuffer>& target)
831 {
832 fillUpResource(source, target);
833 }
834
835 template <>
readUpResource(Move<VkImage> & source,Move<VkBuffer> & target)836 void BaseTestInstance::readUpResource (Move<VkImage>& source,
837 Move<VkBuffer>& target)
838 {
839 const DeviceInterface& vk = getDeviceInterface();
840 const VkDevice vkDevice = getDevice();
841 const VkQueue queue = getUniversalQueue();
842
843 Move<VkCommandPool> commandPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
844 Move<VkCommandBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, *commandPool);
845
846 beginCommandBuffer(vk, *cmdBuffer);
847 copyImageToBuffer(vk, *cmdBuffer, *source, *target, tcu::IVec2(m_params.imageSize.width, m_params.imageSize.height), VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
848 endCommandBuffer(vk, *cmdBuffer);
849
850 submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
851 }
852
853 template <>
layoutTransitionResource(Move<VkBuffer> & target)854 void BaseTestInstance::layoutTransitionResource (Move<VkBuffer>& target)
855 {
856 DE_UNREF(target);
857 }
858
859 template <>
layoutTransitionResource(Move<VkImage> & target)860 void BaseTestInstance::layoutTransitionResource<VkImage> (Move<VkImage>& target)
861 {
862 const DeviceInterface& vk = getDeviceInterface();
863 const VkDevice vkDevice = getDevice();
864 const VkQueue queue = getUniversalQueue();
865
866 const VkImageMemoryBarrier preImageBarrier = makeMemoryBarrierInfo(*target, 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
867
868 Move<VkCommandPool> commandPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, 0);
869 Move<VkCommandBuffer> cmdBuffer = createCommandBuffer(vk, vkDevice, *commandPool);
870
871 beginCommandBuffer(vk, *cmdBuffer);
872 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &preImageBarrier);
873 endCommandBuffer(vk, *cmdBuffer);
874
875 submitCommandsAndWait(vk, vkDevice, queue, *cmdBuffer);
876 }
877
878
createBuffer(Move<VkBuffer> & buffer,Move<VkDeviceMemory> & memory,VkDeviceSize * memorySize)879 void BaseTestInstance::createBuffer (Move<VkBuffer>& buffer,
880 Move<VkDeviceMemory>& memory,
881 VkDeviceSize* memorySize)
882 {
883 const DeviceInterface& vk = getDeviceInterface();
884 const VkDevice vkDevice = getDevice();
885 VkBufferCreateInfo bufferParams = makeBufferCreateInfo(m_context, m_params);
886 VkMemoryRequirements memReqs;
887
888 buffer = vk::createBuffer(vk, vkDevice, &bufferParams);
889 vk.getBufferMemoryRequirements(vkDevice, *buffer, &memReqs);
890 *memorySize = memReqs.size;
891
892 const VkMemoryAllocateInfo memAlloc = makeMemoryAllocateInfo(m_context, memReqs, MemoryHostVisible);
893 VkDeviceMemory rawMemory = DE_NULL;
894
895 vk.allocateMemory(vkDevice, &memAlloc, static_cast<VkAllocationCallbacks*>(DE_NULL), &rawMemory);
896 memory = Move<VkDeviceMemory>(check<VkDeviceMemory>(rawMemory), Deleter<VkDeviceMemory>(vk, vkDevice, DE_NULL));
897 VK_CHECK(vk.bindBufferMemory(vkDevice, *buffer, *memory, 0u));
898 }
899
pushData(VkDeviceMemory memory,deUint32 dataSeed,VkDeviceSize size)900 void BaseTestInstance::pushData (VkDeviceMemory memory,
901 deUint32 dataSeed,
902 VkDeviceSize size)
903 {
904 const DeviceInterface& vk = getDeviceInterface();
905 const VkDevice vkDevice = getDevice();
906 MemoryMappingRAII hostMemory (vk, vkDevice, memory, 0u, size, 0u);
907 deUint8* hostBuffer = static_cast<deUint8*>(hostMemory.ptr());
908 SimpleRandomGenerator random (dataSeed);
909
910 for (deUint32 i = 0u; i < size; ++i)
911 {
912 hostBuffer[i] = static_cast<deUint8>(random.getNext() & 0xFFu);
913 }
914 hostMemory.flush();
915 }
916
checkData(VkDeviceMemory memory,deUint32 dataSeed,VkDeviceSize size)917 deBool BaseTestInstance::checkData (VkDeviceMemory memory,
918 deUint32 dataSeed,
919 VkDeviceSize size)
920 {
921 const DeviceInterface& vk = getDeviceInterface();
922 const VkDevice vkDevice = getDevice();
923 MemoryMappingRAII hostMemory (vk, vkDevice, memory, 0u, size, 0u);
924 deUint8* hostBuffer = static_cast<deUint8*>(hostMemory.ptr());
925 SimpleRandomGenerator random (dataSeed);
926
927 hostMemory.invalidate();
928
929 for (deUint32 i = 0u; i < m_params.bufferSize; ++i)
930 {
931 if (hostBuffer[i] != static_cast<deUint8>(random.getNext() & 0xFFu) )
932 return DE_FALSE;
933 }
934 return DE_TRUE;
935 }
936
937 template<typename TTarget, deBool TDedicated>
938 class MemoryBindingInstance : public BaseTestInstance
939 {
940 public:
MemoryBindingInstance(Context & ctx,BindingCaseParameters params)941 MemoryBindingInstance (Context& ctx,
942 BindingCaseParameters params)
943 : BaseTestInstance (ctx, params)
944 {
945 }
946
iterate(void)947 virtual tcu::TestStatus iterate (void)
948 {
949 const InstanceInterface& vkInstance = m_context.getInstanceInterface();
950 const VkPhysicalDevice vkPhysicalDevice = m_context.getPhysicalDevice();
951 VkPhysicalDeviceProperties properties;
952 vkInstance.getPhysicalDeviceProperties(vkPhysicalDevice, &properties);
953 std::vector<de::SharedPtr<Move<TTarget> > >
954 targets;
955 MemoryRegionsList memory;
956
957 createBindingTargets<TTarget>(targets);
958 createMemory<TTarget, TDedicated>(targets, memory);
959 makeBinding<TTarget>(targets, memory);
960
961 Move<VkBuffer> srcBuffer;
962 Move<VkDeviceMemory> srcMemory;
963 VkDeviceSize srcMemorySize;
964
965 createBuffer(srcBuffer, srcMemory, &srcMemorySize);
966 pushData(*srcMemory, 1, srcMemorySize);
967
968 Move<VkBuffer> dstBuffer;
969 Move<VkDeviceMemory> dstMemory;
970 VkDeviceSize dstMemorySize;
971
972 createBuffer(dstBuffer, dstMemory, &dstMemorySize);
973
974 deBool passed = DE_TRUE;
975 for (deUint32 i = 0; i < m_params.targetsCount; ++i)
976 {
977 fillUpResource(srcBuffer, *targets[i]);
978 readUpResource(*targets[i], dstBuffer);
979 passed = checkData(*dstMemory, 1, dstMemorySize) && passed;
980 }
981
982 return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
983 }
984 };
985
986 template<typename TTarget, deBool TDedicated>
987 class AliasedMemoryBindingInstance : public BaseTestInstance
988 {
989 public:
AliasedMemoryBindingInstance(Context & ctx,BindingCaseParameters params)990 AliasedMemoryBindingInstance (Context& ctx,
991 BindingCaseParameters params)
992 : BaseTestInstance (ctx, params)
993 {
994 }
995
iterate(void)996 virtual tcu::TestStatus iterate (void)
997 {
998 const InstanceInterface& vkInstance = m_context.getInstanceInterface();
999 const VkPhysicalDevice vkPhysicalDevice = m_context.getPhysicalDevice();
1000 VkPhysicalDeviceProperties properties;
1001 vkInstance.getPhysicalDeviceProperties(vkPhysicalDevice, &properties);
1002 std::vector<de::SharedPtr<Move<TTarget> > >
1003 targets[2];
1004 MemoryRegionsList memory;
1005
1006 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
1007 createBindingTargets<TTarget>(targets[i]);
1008 createMemory<TTarget, TDedicated>(targets[0], memory);
1009 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(targets); ++i)
1010 makeBinding<TTarget>(targets[i], memory);
1011
1012 Move<VkBuffer> srcBuffer;
1013 Move<VkDeviceMemory> srcMemory;
1014 VkDeviceSize srcMemorySize;
1015
1016 createBuffer(srcBuffer, srcMemory, &srcMemorySize);
1017 pushData(*srcMemory, 2, srcMemorySize);
1018
1019 Move<VkBuffer> dstBuffer;
1020 Move<VkDeviceMemory> dstMemory;
1021 VkDeviceSize dstMemorySize;
1022
1023 createBuffer(dstBuffer, dstMemory, &dstMemorySize);
1024
1025 deBool passed = DE_TRUE;
1026 for (deUint32 i = 0; i < m_params.targetsCount; ++i)
1027 {
1028 // Do a layout transition on alias 1 before we transition and write to alias 0
1029 layoutTransitionResource(*(targets[1][i]));
1030 fillUpResource(srcBuffer, *(targets[0][i]));
1031 readUpResource(*(targets[1][i]), dstBuffer);
1032 passed = checkData(*dstMemory, 2, dstMemorySize) && passed;
1033 }
1034
1035 return passed ? tcu::TestStatus::pass("Pass") : tcu::TestStatus::fail("Failed");
1036 }
1037 };
1038
1039 template<typename TInstance>
1040 class MemoryBindingTest : public TestCase
1041 {
1042 public:
MemoryBindingTest(tcu::TestContext & testCtx,const std::string & name,BindingCaseParameters params)1043 MemoryBindingTest (tcu::TestContext& testCtx,
1044 const std::string& name,
1045 BindingCaseParameters params)
1046 : TestCase (testCtx, name)
1047 , m_params (params)
1048 {
1049 }
1050
~MemoryBindingTest(void)1051 virtual ~MemoryBindingTest (void)
1052 {
1053 }
1054
createInstance(Context & ctx) const1055 virtual TestInstance* createInstance (Context& ctx) const
1056 {
1057 return new TInstance(ctx, m_params);
1058 }
1059
checkSupport(Context & ctx) const1060 virtual void checkSupport (Context& ctx) const
1061 {
1062 ctx.requireDeviceFunctionality("VK_KHR_bind_memory2");
1063
1064 #ifndef CTS_USES_VULKANSC
1065 if ((m_params.priorityMode != PRIORITY_MODE_DEFAULT) && !ctx.getMemoryPriorityFeaturesEXT().memoryPriority)
1066 TCU_THROW(NotSupportedError, "VK_EXT_memory_priority Not supported");
1067 if ((m_params.priorityMode == PRIORITY_MODE_DYNAMIC) && !ctx.isDeviceFunctionalitySupported("VK_EXT_pageable_device_local_memory"))
1068 TCU_THROW(NotSupportedError, "VK_EXT_pageable_device_local_memory Not supported");
1069 #endif
1070 }
1071
1072 private:
1073 BindingCaseParameters m_params;
1074 };
1075
1076 } // unnamed namespace
1077
createMemoryBindingTests(tcu::TestContext & testCtx)1078 tcu::TestCaseGroup* createMemoryBindingTests (tcu::TestContext& testCtx)
1079 {
1080 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "binding"));
1081
1082 #ifdef CTS_USES_VULKANSC
1083 const int iterations = 1;
1084 #else
1085 const int iterations = 3;
1086 #endif
1087
1088 for (int i = 0; i < iterations; ++i)
1089 {
1090 PriorityMode priorityMode = PriorityMode(i);
1091
1092 // Basic memory binding tests.
1093 de::MovePtr<tcu::TestCaseGroup> regular (new tcu::TestCaseGroup(testCtx, "regular"));
1094 de::MovePtr<tcu::TestCaseGroup> aliasing (new tcu::TestCaseGroup(testCtx, "aliasing", "Memory binding tests with aliasing of two resources."));
1095
1096 de::MovePtr<tcu::TestCaseGroup> regular_suballocated (new tcu::TestCaseGroup(testCtx, "suballocated", "Basic memory binding tests with suballocated memory."));
1097 de::MovePtr<tcu::TestCaseGroup> regular_dedicated (new tcu::TestCaseGroup(testCtx, "dedicated", "Basic memory binding tests with deditatedly allocated memory."));
1098
1099 de::MovePtr<tcu::TestCaseGroup> aliasing_suballocated (new tcu::TestCaseGroup(testCtx, "suballocated", "Memory binding tests with aliasing of two resources with suballocated mamory."));
1100
1101 const VkDeviceSize allocationSizes[] = { 33, 257, 4087, 8095, 1*1024*1024 + 1 };
1102
1103 for (deUint32 sizeNdx = 0u; sizeNdx < DE_LENGTH_OF_ARRAY(allocationSizes); ++sizeNdx )
1104 {
1105 const VkDeviceSize bufferSize = allocationSizes[sizeNdx];
1106 const BindingCaseParameters params = makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize, 0u, priorityMode);
1107 const BindingCaseParameters aliasparams = makeBindingCaseParameters(10, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_SHARING_MODE_EXCLUSIVE, bufferSize, VK_IMAGE_CREATE_ALIAS_BIT, priorityMode);
1108 std::ostringstream testName;
1109
1110 testName << "buffer_" << bufferSize;
1111 regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(),params));
1112 regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkBuffer, DE_TRUE> >(testCtx, testName.str(),params));
1113 aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkBuffer, DE_FALSE> >(testCtx, testName.str(),aliasparams));
1114 }
1115
1116 const deUint32 imageSizes[] = { 8, 33, 257 };
1117
1118 for (deUint32 widthNdx = 0u; widthNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++widthNdx )
1119 for (deUint32 heightNdx = 0u; heightNdx < DE_LENGTH_OF_ARRAY(imageSizes); ++heightNdx )
1120 {
1121 const deUint32 width = imageSizes[widthNdx];
1122 const deUint32 height = imageSizes[heightNdx];
1123 const BindingCaseParameters regularparams = makeBindingCaseParameters(10, width, height, 0u, priorityMode);
1124 const BindingCaseParameters aliasparams = makeBindingCaseParameters(10, width, height, VK_IMAGE_CREATE_ALIAS_BIT, priorityMode);
1125 std::ostringstream testName;
1126
1127 testName << "image_" << width << '_' << height;
1128 regular_suballocated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(),regularparams));
1129 regular_dedicated->addChild(new MemoryBindingTest<MemoryBindingInstance<VkImage, DE_TRUE> >(testCtx, testName.str(), regularparams));
1130 aliasing_suballocated->addChild(new MemoryBindingTest<AliasedMemoryBindingInstance<VkImage, DE_FALSE> >(testCtx, testName.str(),aliasparams));
1131 }
1132
1133 regular->addChild(regular_suballocated.release());
1134 regular->addChild(regular_dedicated.release());
1135
1136 aliasing->addChild(aliasing_suballocated.release());
1137 if (priorityMode != PRIORITY_MODE_DEFAULT) {
1138 de::MovePtr<tcu::TestCaseGroup> priority (new tcu::TestCaseGroup(testCtx, (priorityMode == PRIORITY_MODE_DYNAMIC) ? "priority_dynamic" : "priority"));
1139 priority->addChild(regular.release());
1140 priority->addChild(aliasing.release());
1141 group->addChild(priority.release());
1142 } else {
1143 group->addChild(regular.release());
1144 group->addChild(aliasing.release());
1145 }
1146 }
1147
1148 return group.release();
1149 }
1150
1151 } // memory
1152 } // vkt
1153