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