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