1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2020 The Khronos Group Inc.
6 * Copyright (c) 2020 Google LLC
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief VK_EXT_device_memory_report extension tests.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktMemoryDeviceMemoryReportTests.hpp"
26
27 #include "vktCustomInstancesDevices.hpp"
28 #include "vktExternalMemoryUtil.hpp"
29 #include "vktTestCaseUtil.hpp"
30
31 #include "vkDeviceUtil.hpp"
32 #include "vkObjUtil.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36
37 #include "tcuCommandLine.hpp"
38 #include "tcuTestCase.hpp"
39 #include "tcuTestLog.hpp"
40
41 #include "deSharedPtr.hpp"
42
43 #include <set>
44 #include <vector>
45 #include <limits>
46
47 namespace vkt
48 {
49 namespace memory
50 {
51 namespace
52 {
53
54 #define VK_DESCRIPTOR_TYPE_LAST (VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT + 1)
55
56 using namespace vk;
57 using namespace vkt::ExternalMemoryUtil;
58 using de::MovePtr;
59 using de::SharedPtr;
60
61 enum CallbackMarker
62 {
63 MARKER_UNKNOWN = 0,
64 MARKER_ALLOCATE,
65 MARKER_FREE,
66 MARKER_IMPORT,
67 MARKER_UNIMPORT,
68 MARKER_ALLOCATION_FAILED
69 };
70
71 class CallbackRecorder
72 {
73 public:
CallbackRecorder(void)74 CallbackRecorder(void) : mMarker(MARKER_UNKNOWN)
75 {
76 }
77 ~CallbackRecorder(void) = default;
78
79 typedef std::vector<std::pair<VkDeviceMemoryReportCallbackDataEXT, CallbackMarker>>::const_iterator RecordIterator;
80
getRecordsBegin(void) const81 RecordIterator getRecordsBegin(void) const
82 {
83 return mRecords.begin();
84 }
85
getRecordsEnd(void) const86 RecordIterator getRecordsEnd(void) const
87 {
88 return mRecords.end();
89 }
90
getNumRecords(void) const91 std::size_t getNumRecords(void) const
92 {
93 return mRecords.size();
94 }
95
setCallbackMarker(CallbackMarker marker)96 void setCallbackMarker(CallbackMarker marker)
97 {
98 mMarker = marker;
99 }
100
callbackInternal(const VkDeviceMemoryReportCallbackDataEXT * pCallbackData)101 void callbackInternal(const VkDeviceMemoryReportCallbackDataEXT *pCallbackData)
102 {
103 mRecords.emplace_back(*pCallbackData, mMarker);
104 }
105
callback(const struct VkDeviceMemoryReportCallbackDataEXT * pCallbackData,void * pUserData)106 static VKAPI_ATTR void VKAPI_CALL callback(const struct VkDeviceMemoryReportCallbackDataEXT *pCallbackData,
107 void *pUserData)
108 {
109 reinterpret_cast<CallbackRecorder *>(pUserData)->callbackInternal(pCallbackData);
110 }
111
112 private:
113 typedef std::vector<std::pair<VkDeviceMemoryReportCallbackDataEXT, CallbackMarker>> Records;
114
115 Records mRecords;
116 CallbackMarker mMarker;
117 };
118
119 struct Environment
120 {
121 const PlatformInterface &vkp;
122 const InstanceInterface &vki;
123 VkInstance instance;
124 VkPhysicalDevice physicalDevice;
125 const DeviceInterface &vkd;
126 VkDevice device;
127 uint32_t queueFamilyIndex;
128 const BinaryCollection &programBinaries;
129 const uint32_t usedApiVersion;
130 const tcu::CommandLine &commandLine;
131 const CallbackRecorder *recorder;
132
Environmentvkt::memory::__anon71c481e30111::Environment133 Environment(const PlatformInterface &vkp_, const InstanceInterface &vki_, VkInstance instance_,
134 VkPhysicalDevice physicalDevice_, const DeviceInterface &vkd_, VkDevice device_,
135 uint32_t queueFamilyIndex_, const BinaryCollection &programBinaries_, const uint32_t usedApiVersion_,
136 const tcu::CommandLine &commandLine_, const CallbackRecorder *recorder_)
137 : vkp(vkp_)
138 , vki(vki_)
139 , instance(instance_)
140 , physicalDevice(physicalDevice_)
141 , vkd(vkd_)
142 , device(device_)
143 , queueFamilyIndex(queueFamilyIndex_)
144 , programBinaries(programBinaries_)
145 , usedApiVersion(usedApiVersion_)
146 , commandLine(commandLine_)
147 , recorder(recorder_)
148 {
149 }
150 };
151
152 template <typename Case>
153 struct Dependency
154 {
155 typename Case::Resources resources;
156 Unique<typename Case::Type> object;
157
Dependencyvkt::memory::__anon71c481e30111::Dependency158 Dependency(const Environment &env, const typename Case::Parameters ¶ms)
159 : resources(env, params)
160 , object(Case::create(env, resources, params))
161 {
162 }
163 };
164
createDeviceWithMemoryReport(bool isValidationEnabled,const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,const CallbackRecorder * recorder)165 static Move<VkDevice> createDeviceWithMemoryReport(bool isValidationEnabled, const PlatformInterface &vkp,
166 VkInstance instance, const InstanceInterface &vki,
167 VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex,
168 const CallbackRecorder *recorder)
169 {
170 const uint32_t queueCount = 1;
171 const float queuePriority = 1.0f;
172 const char *const enabledExtensions[] = {"VK_EXT_device_memory_report"};
173 const VkPhysicalDeviceDeviceMemoryReportFeaturesEXT deviceMemoryReportFeatures = {
174 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, // VkStructureType sType;
175 DE_NULL, // void* pNext;
176 VK_TRUE // VkBool32 deviceMemoryReport;
177 };
178 const VkDeviceDeviceMemoryReportCreateInfoEXT deviceMemoryReportCreateInfo = {
179 VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT, // VkStructureType sType;
180 &deviceMemoryReportFeatures, // void* pNext;
181 (VkDeviceMemoryReportFlagsEXT)0, // VkDeviceMemoryReportFlagsEXT flags;
182 recorder->callback, // PFN_vkDeviceMemoryReportCallbackEXT pfnUserCallback;
183 (void *)recorder, // void* pUserData;
184 };
185 const VkDeviceQueueCreateInfo queueCreateInfo = {
186 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
187 DE_NULL, // const void* pNext;
188 (VkDeviceQueueCreateFlags)0, // VkDeviceQueueCreateFlags flags;
189 queueFamilyIndex, // uint32_t queueFamilyIndex;
190 queueCount, // uint32_t queueCount;
191 &queuePriority, // const float* pQueuePriorities;
192 };
193 // Enable all available features since some tests require them to be enabled, VK_IMAGE_VIEW_CUBE_ARRAY for example
194 vk::VkPhysicalDeviceFeatures2 enabledFeatures = vk::initVulkanStructure();
195 vki.getPhysicalDeviceFeatures(physicalDevice, &enabledFeatures.features);
196 const VkDeviceCreateInfo deviceCreateInfo = {
197 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
198 &deviceMemoryReportCreateInfo, // const void* pNext;
199 (VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
200 queueCount, // uint32_t queueCreateInfoCount;
201 &queueCreateInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
202 0u, // uint32_t enabledLayerCount
203 DE_NULL, // const char* const* ppEnabledLayerNames
204 DE_LENGTH_OF_ARRAY(enabledExtensions), // uint32_t enabledExtensionCount
205 DE_ARRAY_BEGIN(enabledExtensions), // const char* const* ppEnabledExtensionNames
206 &enabledFeatures.features, // const VkPhysicalDeviceFeatures* pEnabledFeatures
207 };
208
209 return createCustomDevice(isValidationEnabled, vkp, instance, vki, physicalDevice, &deviceCreateInfo);
210 }
211
212 struct Device
213 {
214 typedef VkDevice Type;
215
216 struct Parameters
217 {
Parametersvkt::memory::__anon71c481e30111::Device::Parameters218 Parameters(void)
219 {
220 }
221 };
222
223 struct Resources
224 {
Resourcesvkt::memory::__anon71c481e30111::Device::Resources225 Resources(const Environment &, const Parameters &)
226 {
227 }
228 };
229
createvkt::memory::__anon71c481e30111::Device230 static Move<VkDevice> create(const Environment &env, const Resources &, const Parameters &)
231 {
232 return createDeviceWithMemoryReport(env.commandLine.isValidationEnabled(), env.vkp, env.instance, env.vki,
233 env.physicalDevice, env.queueFamilyIndex, env.recorder);
234 }
235 };
236
237 struct DeviceMemory
238 {
239 typedef VkDeviceMemory Type;
240
241 struct Parameters
242 {
243 VkDeviceSize size;
244 uint32_t memoryTypeIndex;
245
Parametersvkt::memory::__anon71c481e30111::DeviceMemory::Parameters246 Parameters(VkDeviceSize size_, uint32_t memoryTypeIndex_) : size(size_), memoryTypeIndex(memoryTypeIndex_)
247 {
248 DE_ASSERT(memoryTypeIndex < VK_MAX_MEMORY_TYPES);
249 }
250 };
251
252 struct Resources
253 {
Resourcesvkt::memory::__anon71c481e30111::DeviceMemory::Resources254 Resources(const Environment &, const Parameters &)
255 {
256 }
257 };
258
createvkt::memory::__anon71c481e30111::DeviceMemory259 static Move<VkDeviceMemory> create(const Environment &env, const Resources &, const Parameters ¶ms)
260 {
261 const VkMemoryAllocateInfo memoryAllocateInfo = {
262 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
263 DE_NULL, // const void* pNext;
264 params.size, // VkDeviceSize allocationSize;
265 params.memoryTypeIndex, // uint32_t memoryTypeIndex;
266 };
267
268 return allocateMemory(env.vkd, env.device, &memoryAllocateInfo);
269 }
270 };
271
getDeviceMemoryParameters(const VkMemoryRequirements & memReqs)272 DeviceMemory::Parameters getDeviceMemoryParameters(const VkMemoryRequirements &memReqs)
273 {
274 return DeviceMemory::Parameters(memReqs.size, deCtz32(memReqs.memoryTypeBits));
275 }
276
getDeviceMemoryParameters(const Environment & env,VkImage image)277 DeviceMemory::Parameters getDeviceMemoryParameters(const Environment &env, VkImage image)
278 {
279 return getDeviceMemoryParameters(getImageMemoryRequirements(env.vkd, env.device, image));
280 }
281
getDeviceMemoryParameters(const Environment & env,VkBuffer buffer)282 DeviceMemory::Parameters getDeviceMemoryParameters(const Environment &env, VkBuffer buffer)
283 {
284 return getDeviceMemoryParameters(getBufferMemoryRequirements(env.vkd, env.device, buffer));
285 }
286
287 struct Buffer
288 {
289 typedef VkBuffer Type;
290
291 struct Parameters
292 {
293 VkDeviceSize size;
294 VkBufferUsageFlags usage;
295
Parametersvkt::memory::__anon71c481e30111::Buffer::Parameters296 Parameters(VkDeviceSize size_, VkBufferUsageFlags usage_) : size(size_), usage(usage_)
297 {
298 }
299 };
300
301 struct Resources
302 {
Resourcesvkt::memory::__anon71c481e30111::Buffer::Resources303 Resources(const Environment &, const Parameters &)
304 {
305 }
306 };
307
createvkt::memory::__anon71c481e30111::Buffer308 static Move<VkBuffer> create(const Environment &env, const Resources &, const Parameters ¶ms)
309 {
310 const VkBufferCreateInfo bufferCreateInfo = {
311 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
312 DE_NULL, // const void* pNext;
313 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
314 params.size, // VkDeviceSize size;
315 params.usage, // VkBufferUsageFlags usage;
316 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
317 1u, // uint32_t queueFamilyIndexCount;
318 &env.queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
319 };
320
321 return createBuffer(env.vkd, env.device, &bufferCreateInfo);
322 }
323 };
324
325 struct BufferView
326 {
327 typedef VkBufferView Type;
328
329 struct Parameters
330 {
331 Buffer::Parameters buffer;
332 VkFormat format;
333 VkDeviceSize offset;
334 VkDeviceSize range;
335
Parametersvkt::memory::__anon71c481e30111::BufferView::Parameters336 Parameters(const Buffer::Parameters &buffer_, VkFormat format_, VkDeviceSize offset_, VkDeviceSize range_)
337 : buffer(buffer_)
338 , format(format_)
339 , offset(offset_)
340 , range(range_)
341 {
342 }
343 };
344
345 struct Resources
346 {
347 Dependency<Buffer> buffer;
348 Dependency<DeviceMemory> memory;
349
Resourcesvkt::memory::__anon71c481e30111::BufferView::Resources350 Resources(const Environment &env, const Parameters ¶ms)
351 : buffer(env, params.buffer)
352 , memory(env, getDeviceMemoryParameters(env, *buffer.object))
353 {
354 VK_CHECK(env.vkd.bindBufferMemory(env.device, *buffer.object, *memory.object, 0));
355 }
356 };
357
createvkt::memory::__anon71c481e30111::BufferView358 static Move<VkBufferView> create(const Environment &env, const Resources &res, const Parameters ¶ms)
359 {
360 const VkBufferViewCreateInfo bufferViewCreateInfo = {
361 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType;
362 DE_NULL, // const void* pNext;
363 (VkBufferViewCreateFlags)0, // VkBufferViewCreateFlags flags;
364 *res.buffer.object, // VkBuffer buffer;
365 params.format, // VkFormat format;
366 params.offset, // VkDeviceSize offset;
367 params.range, // VkDeviceSize range;
368 };
369
370 return createBufferView(env.vkd, env.device, &bufferViewCreateInfo);
371 }
372 };
373
374 struct Image
375 {
376 typedef VkImage Type;
377
378 struct Parameters
379 {
380 VkImageCreateFlags flags;
381 VkImageType imageType;
382 VkFormat format;
383 VkExtent3D extent;
384 uint32_t mipLevels;
385 uint32_t arraySize;
386 VkSampleCountFlagBits samples;
387 VkImageTiling tiling;
388 VkImageUsageFlags usage;
389 VkImageLayout initialLayout;
390
Parametersvkt::memory::__anon71c481e30111::Image::Parameters391 Parameters(VkImageCreateFlags flags_, VkImageType imageType_, VkFormat format_, VkExtent3D extent_,
392 uint32_t mipLevels_, uint32_t arraySize_, VkSampleCountFlagBits samples_, VkImageTiling tiling_,
393 VkImageUsageFlags usage_, VkImageLayout initialLayout_)
394 : flags(flags_)
395 , imageType(imageType_)
396 , format(format_)
397 , extent(extent_)
398 , mipLevels(mipLevels_)
399 , arraySize(arraySize_)
400 , samples(samples_)
401 , tiling(tiling_)
402 , usage(usage_)
403 , initialLayout(initialLayout_)
404 {
405 }
406 };
407
408 struct Resources
409 {
Resourcesvkt::memory::__anon71c481e30111::Image::Resources410 Resources(const Environment &, const Parameters &)
411 {
412 }
413 };
414
createvkt::memory::__anon71c481e30111::Image415 static Move<VkImage> create(const Environment &env, const Resources &, const Parameters ¶ms)
416 {
417 const VkImageCreateInfo imageCreateInfo = {
418 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
419 DE_NULL, // const void* pNext;
420 params.flags, // VkImageCreateFlags flags;
421 params.imageType, // VkImageType imageType;
422 params.format, // VkFormat format;
423 params.extent, // VkExtent3D extent;
424 params.mipLevels, // uint32_t mipLevels;
425 params.arraySize, // uint32_t arrayLayers;
426 params.samples, // VkSampleCountFlagBits samples;
427 params.tiling, // VkImageTiling tiling;
428 params.usage, // VkImageUsageFlags usage;
429 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
430 1u, // uint32_t queueFamilyIndexCount;
431 &env.queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
432 params.initialLayout, // VkImageLayout initialLayout;
433 };
434
435 return createImage(env.vkd, env.device, &imageCreateInfo);
436 }
437 };
438
439 struct ImageView
440 {
441 typedef VkImageView Type;
442
443 struct Parameters
444 {
445 Image::Parameters image;
446 VkImageViewType viewType;
447 VkFormat format;
448 VkComponentMapping components;
449 VkImageSubresourceRange subresourceRange;
450
Parametersvkt::memory::__anon71c481e30111::ImageView::Parameters451 Parameters(const Image::Parameters &image_, VkImageViewType viewType_, VkFormat format_,
452 VkComponentMapping components_, VkImageSubresourceRange subresourceRange_)
453 : image(image_)
454 , viewType(viewType_)
455 , format(format_)
456 , components(components_)
457 , subresourceRange(subresourceRange_)
458 {
459 }
460 };
461
462 struct Resources
463 {
464 Dependency<Image> image;
465 Dependency<DeviceMemory> memory;
466
Resourcesvkt::memory::__anon71c481e30111::ImageView::Resources467 Resources(const Environment &env, const Parameters ¶ms)
468 : image(env, params.image)
469 , memory(env, getDeviceMemoryParameters(env, *image.object))
470 {
471 VK_CHECK(env.vkd.bindImageMemory(env.device, *image.object, *memory.object, 0));
472 }
473 };
474
createvkt::memory::__anon71c481e30111::ImageView475 static Move<VkImageView> create(const Environment &env, const Resources &res, const Parameters ¶ms)
476 {
477 const VkImageViewCreateInfo imageViewCreateInfo = {
478 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
479 DE_NULL, // const void* pNext;
480 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
481 *res.image.object, // VkImage image;
482 params.viewType, // VkImageViewType viewType;
483 params.format, // VkFormat format;
484 params.components, // VkComponentMapping components;
485 params.subresourceRange, // VkImageSubresourceRange subresourceRange;
486 };
487
488 return createImageView(env.vkd, env.device, &imageViewCreateInfo);
489 }
490 };
491
492 struct Semaphore
493 {
494 typedef VkSemaphore Type;
495
496 struct Parameters
497 {
498 VkSemaphoreCreateFlags flags;
499
Parametersvkt::memory::__anon71c481e30111::Semaphore::Parameters500 Parameters(VkSemaphoreCreateFlags flags_) : flags(flags_)
501 {
502 }
503 };
504
505 struct Resources
506 {
Resourcesvkt::memory::__anon71c481e30111::Semaphore::Resources507 Resources(const Environment &, const Parameters &)
508 {
509 }
510 };
511
createvkt::memory::__anon71c481e30111::Semaphore512 static Move<VkSemaphore> create(const Environment &env, const Resources &, const Parameters ¶ms)
513 {
514 const VkSemaphoreCreateInfo semaphoreCreateInfo = {
515 VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, // VkStructureType sType;
516 DE_NULL, // const void* pNext;
517 params.flags, // VkSemaphoreCreateFlags flags;
518 };
519
520 return createSemaphore(env.vkd, env.device, &semaphoreCreateInfo);
521 }
522 };
523
524 struct Fence
525 {
526 typedef VkFence Type;
527
528 struct Parameters
529 {
530 VkFenceCreateFlags flags;
531
Parametersvkt::memory::__anon71c481e30111::Fence::Parameters532 Parameters(VkFenceCreateFlags flags_) : flags(flags_)
533 {
534 }
535 };
536
537 struct Resources
538 {
Resourcesvkt::memory::__anon71c481e30111::Fence::Resources539 Resources(const Environment &, const Parameters &)
540 {
541 }
542 };
543
createvkt::memory::__anon71c481e30111::Fence544 static Move<VkFence> create(const Environment &env, const Resources &, const Parameters ¶ms)
545 {
546 const VkFenceCreateInfo fenceCreateInfo = {
547 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
548 DE_NULL, // const void* pNext;
549 params.flags, // VkFenceCreateFlags flags;
550 };
551
552 return createFence(env.vkd, env.device, &fenceCreateInfo);
553 }
554 };
555
556 struct Event
557 {
558 typedef VkEvent Type;
559
560 struct Parameters
561 {
562 VkEventCreateFlags flags;
563
Parametersvkt::memory::__anon71c481e30111::Event::Parameters564 Parameters(VkEventCreateFlags flags_) : flags(flags_)
565 {
566 }
567 };
568
569 struct Resources
570 {
Resourcesvkt::memory::__anon71c481e30111::Event::Resources571 Resources(const Environment &, const Parameters &)
572 {
573 }
574 };
575
createvkt::memory::__anon71c481e30111::Event576 static Move<VkEvent> create(const Environment &env, const Resources &, const Parameters ¶ms)
577 {
578 const VkEventCreateInfo eventCreateInfo = {
579 VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // VkStructureType sType;
580 DE_NULL, // const void* pNext;
581 params.flags, // VkEventCreateFlags flags;
582 };
583
584 return createEvent(env.vkd, env.device, &eventCreateInfo);
585 }
586 };
587
588 struct QueryPool
589 {
590 typedef VkQueryPool Type;
591
592 struct Parameters
593 {
594 VkQueryType queryType;
595 uint32_t entryCount;
596 VkQueryPipelineStatisticFlags pipelineStatistics;
597
Parametersvkt::memory::__anon71c481e30111::QueryPool::Parameters598 Parameters(VkQueryType queryType_, uint32_t entryCount_, VkQueryPipelineStatisticFlags pipelineStatistics_)
599 : queryType(queryType_)
600 , entryCount(entryCount_)
601 , pipelineStatistics(pipelineStatistics_)
602 {
603 }
604 };
605
606 struct Resources
607 {
Resourcesvkt::memory::__anon71c481e30111::QueryPool::Resources608 Resources(const Environment &, const Parameters &)
609 {
610 }
611 };
612
createvkt::memory::__anon71c481e30111::QueryPool613 static Move<VkQueryPool> create(const Environment &env, const Resources &, const Parameters ¶ms)
614 {
615 const VkQueryPoolCreateInfo queryPoolCreateInfo = {
616 VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO, // VkStructureType sType;
617 DE_NULL, // const void* pNext;
618 (VkQueryPoolCreateFlags)0, // VkQueryPoolCreateFlags flags;
619 params.queryType, // VkQueryType queryType;
620 params.entryCount, // uint32_t queryCount;
621 params.pipelineStatistics, // VkQueryPipelineStatisticFlags pipelineStatistics;
622 };
623
624 return createQueryPool(env.vkd, env.device, &queryPoolCreateInfo);
625 }
626 };
627
628 struct ShaderModule
629 {
630 typedef VkShaderModule Type;
631
632 struct Parameters
633 {
634 VkShaderStageFlagBits shaderStage;
635 std::string binaryName;
636
Parametersvkt::memory::__anon71c481e30111::ShaderModule::Parameters637 Parameters(VkShaderStageFlagBits shaderStage_, const std::string &binaryName_)
638 : shaderStage(shaderStage_)
639 , binaryName(binaryName_)
640 {
641 }
642 };
643
644 struct Resources
645 {
646 const ProgramBinary &binary;
647
Resourcesvkt::memory::__anon71c481e30111::ShaderModule::Resources648 Resources(const Environment &env, const Parameters ¶ms) : binary(env.programBinaries.get(params.binaryName))
649 {
650 }
651 };
652
getSourcevkt::memory::__anon71c481e30111::ShaderModule653 static const char *getSource(VkShaderStageFlagBits stage)
654 {
655 switch (stage)
656 {
657 case VK_SHADER_STAGE_VERTEX_BIT:
658 return "#version 310 es\n"
659 "layout(location = 0) in highp vec4 a_position;\n"
660 "void main () { gl_Position = a_position; }\n";
661
662 case VK_SHADER_STAGE_FRAGMENT_BIT:
663 return "#version 310 es\n"
664 "layout(location = 0) out mediump vec4 o_color;\n"
665 "void main () { o_color = vec4(1.0, 0.5, 0.25, 1.0); }";
666
667 case VK_SHADER_STAGE_COMPUTE_BIT:
668 return "#version 310 es\n"
669 "layout(binding = 0) buffer Input { highp uint dataIn[]; };\n"
670 "layout(binding = 1) buffer Output { highp uint dataOut[]; };\n"
671 "void main (void)\n"
672 "{\n"
673 " dataOut[gl_GlobalInvocationID.x] = ~dataIn[gl_GlobalInvocationID.x];\n"
674 "}\n";
675
676 default:
677 DE_FATAL("Not implemented");
678 return DE_NULL;
679 }
680 }
681
initProgramsvkt::memory::__anon71c481e30111::ShaderModule682 static void initPrograms(SourceCollections &dst, Parameters params)
683 {
684 const char *const source = getSource(params.shaderStage);
685
686 DE_ASSERT(source);
687
688 dst.glslSources.add(params.binaryName) << glu::ShaderSource(getGluShaderType(params.shaderStage), source);
689 }
690
createvkt::memory::__anon71c481e30111::ShaderModule691 static Move<VkShaderModule> create(const Environment &env, const Resources &res, const Parameters &)
692 {
693 const VkShaderModuleCreateInfo shaderModuleCreateInfo = {
694 VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, // VkStructureType sType;
695 DE_NULL, // const void* pNext;
696 (VkShaderModuleCreateFlags)0, // VkShaderModuleCreateFlags flags;
697 res.binary.getSize(), // size_t codeSize;
698 (const uint32_t *)res.binary.getBinary(), // const uint32_t* pCode;
699 };
700
701 return createShaderModule(env.vkd, env.device, &shaderModuleCreateInfo);
702 }
703 };
704
705 struct PipelineCache
706 {
707 typedef VkPipelineCache Type;
708
709 struct Parameters
710 {
Parametersvkt::memory::__anon71c481e30111::PipelineCache::Parameters711 Parameters(void)
712 {
713 }
714 };
715
716 struct Resources
717 {
Resourcesvkt::memory::__anon71c481e30111::PipelineCache::Resources718 Resources(const Environment &, const Parameters &)
719 {
720 }
721 };
722
createvkt::memory::__anon71c481e30111::PipelineCache723 static Move<VkPipelineCache> create(const Environment &env, const Resources &, const Parameters &)
724 {
725 const VkPipelineCacheCreateInfo pipelineCacheCreateInfo = {
726 VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO, // VkStructureType sType;
727 DE_NULL, // const void* pNext;
728 #ifndef CTS_USES_VULKANSC
729 (VkPipelineCacheCreateFlags)0u, // VkPipelineCacheCreateFlags flags;
730 0, // size_t initialDataSize;
731 DE_NULL // const void* pInitialData;
732 #else
733 VK_PIPELINE_CACHE_CREATE_READ_ONLY_BIT |
734 VK_PIPELINE_CACHE_CREATE_USE_APPLICATION_STORAGE_BIT, // VkPipelineCacheCreateFlags flags;
735 env.resourceInterface->getCacheDataSize(), // uintptr_t initialDataSize;
736 env.resourceInterface->getCacheData() // const void* pInitialData;
737 #endif // CTS_USES_VULKANSC
738 };
739
740 return createPipelineCache(env.vkd, env.device, &pipelineCacheCreateInfo);
741 }
742 };
743
744 struct Sampler
745 {
746 typedef VkSampler Type;
747
748 struct Parameters
749 {
750 VkFilter magFilter;
751 VkFilter minFilter;
752 VkSamplerMipmapMode mipmapMode;
753 VkSamplerAddressMode addressModeU;
754 VkSamplerAddressMode addressModeV;
755 VkSamplerAddressMode addressModeW;
756 float mipLodBias;
757 VkBool32 anisotropyEnable;
758 float maxAnisotropy;
759 VkBool32 compareEnable;
760 VkCompareOp compareOp;
761 float minLod;
762 float maxLod;
763 VkBorderColor borderColor;
764 VkBool32 unnormalizedCoordinates;
765
Parametersvkt::memory::__anon71c481e30111::Sampler::Parameters766 Parameters(void)
767 : magFilter(VK_FILTER_NEAREST)
768 , minFilter(VK_FILTER_NEAREST)
769 , mipmapMode(VK_SAMPLER_MIPMAP_MODE_NEAREST)
770 , addressModeU(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
771 , addressModeV(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
772 , addressModeW(VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE)
773 , mipLodBias(0.0f)
774 , anisotropyEnable(VK_FALSE)
775 , maxAnisotropy(1.0f)
776 , compareEnable(VK_FALSE)
777 , compareOp(VK_COMPARE_OP_ALWAYS)
778 , minLod(-1000.f)
779 , maxLod(+1000.f)
780 , borderColor(VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK)
781 , unnormalizedCoordinates(VK_FALSE)
782 {
783 }
784 };
785
786 struct Resources
787 {
Resourcesvkt::memory::__anon71c481e30111::Sampler::Resources788 Resources(const Environment &, const Parameters &)
789 {
790 }
791 };
792
createvkt::memory::__anon71c481e30111::Sampler793 static Move<VkSampler> create(const Environment &env, const Resources &, const Parameters ¶ms)
794 {
795 const VkSamplerCreateInfo samplerCreateInfo = {
796 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
797 DE_NULL, // const void* pNext;
798 (VkSamplerCreateFlags)0, // VkSamplerCreateFlags flags;
799 params.magFilter, // VkFilter magFilter;
800 params.minFilter, // VkFilter minFilter;
801 params.mipmapMode, // VkSamplerMipmapMode mipmapMode;
802 params.addressModeU, // VkSamplerAddressMode addressModeU;
803 params.addressModeV, // VkSamplerAddressMode addressModeV;
804 params.addressModeW, // VkSamplerAddressMode addressModeW;
805 params.mipLodBias, // float mipLodBias;
806 params.anisotropyEnable, // VkBool32 anisotropyEnable;
807 params.maxAnisotropy, // float maxAnisotropy;
808 params.compareEnable, // VkBool32 compareEnable;
809 params.compareOp, // VkCompareOp compareOp;
810 params.minLod, // float minLod;
811 params.maxLod, // float maxLod;
812 params.borderColor, // VkBorderColor borderColor;
813 params.unnormalizedCoordinates, // VkBool32 unnormalizedCoordinates;
814 };
815
816 return createSampler(env.vkd, env.device, &samplerCreateInfo);
817 }
818 };
819
820 struct DescriptorSetLayout
821 {
822 typedef VkDescriptorSetLayout Type;
823
824 struct Parameters
825 {
826 struct Binding
827 {
828 uint32_t binding;
829 VkDescriptorType descriptorType;
830 uint32_t descriptorCount;
831 VkShaderStageFlags stageFlags;
832 bool useImmutableSampler;
833
Bindingvkt::memory::__anon71c481e30111::DescriptorSetLayout::Parameters::Binding834 Binding(uint32_t binding_, VkDescriptorType descriptorType_, uint32_t descriptorCount_,
835 VkShaderStageFlags stageFlags_, bool useImmutableSampler_)
836 : binding(binding_)
837 , descriptorType(descriptorType_)
838 , descriptorCount(descriptorCount_)
839 , stageFlags(stageFlags_)
840 , useImmutableSampler(useImmutableSampler_)
841 {
842 }
843
Bindingvkt::memory::__anon71c481e30111::DescriptorSetLayout::Parameters::Binding844 Binding(void)
845 {
846 }
847 };
848
849 std::vector<Binding> bindings;
850
Parametersvkt::memory::__anon71c481e30111::DescriptorSetLayout::Parameters851 Parameters(const std::vector<Binding> &bindings_) : bindings(bindings_)
852 {
853 }
854
emptyvkt::memory::__anon71c481e30111::DescriptorSetLayout::Parameters855 static Parameters empty(void)
856 {
857 return Parameters(std::vector<Binding>());
858 }
859
singlevkt::memory::__anon71c481e30111::DescriptorSetLayout::Parameters860 static Parameters single(uint32_t binding, VkDescriptorType descriptorType, uint32_t descriptorCount,
861 VkShaderStageFlags stageFlags, bool useImmutableSampler = false)
862 {
863 std::vector<Binding> bindings;
864 bindings.push_back(Binding(binding, descriptorType, descriptorCount, stageFlags, useImmutableSampler));
865 return Parameters(bindings);
866 }
867 };
868
869 struct Resources
870 {
871 std::vector<VkDescriptorSetLayoutBinding> bindings;
872 MovePtr<Dependency<Sampler>> immutableSampler;
873 std::vector<VkSampler> immutableSamplersPtr;
874
Resourcesvkt::memory::__anon71c481e30111::DescriptorSetLayout::Resources875 Resources(const Environment &env, const Parameters ¶ms)
876 {
877 for (std::vector<Parameters::Binding>::const_iterator cur = params.bindings.begin();
878 cur != params.bindings.end(); cur++)
879 {
880 if (cur->useImmutableSampler && !immutableSampler)
881 {
882 immutableSampler = de::newMovePtr<Dependency<Sampler>>(env, Sampler::Parameters());
883
884 if (cur->useImmutableSampler && immutableSamplersPtr.size() < (size_t)cur->descriptorCount)
885 immutableSamplersPtr.resize(cur->descriptorCount, *immutableSampler->object);
886 }
887 }
888
889 for (std::vector<Parameters::Binding>::const_iterator cur = params.bindings.begin();
890 cur != params.bindings.end(); cur++)
891 {
892 const VkDescriptorSetLayoutBinding binding = {
893 cur->binding, // uint32_t binding;
894 cur->descriptorType, // VkDescriptorType descriptorType;
895 cur->descriptorCount, // uint32_t descriptorCount;
896 cur->stageFlags, // VkShaderStageFlags stageFlags;
897 (cur->useImmutableSampler ? &immutableSamplersPtr[0] :
898 DE_NULL), // const VkSampler* pImmutableSamplers;
899 };
900
901 bindings.push_back(binding);
902 }
903 }
904 };
905
createvkt::memory::__anon71c481e30111::DescriptorSetLayout906 static Move<VkDescriptorSetLayout> create(const Environment &env, const Resources &res, const Parameters &)
907 {
908 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = {
909 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType;
910 DE_NULL, // const void* pNext;
911 (VkDescriptorSetLayoutCreateFlags)0, // VkDescriptorSetLayoutCreateFlags flags;
912 (uint32_t)res.bindings.size(), // uint32_t bindingCount;
913 (res.bindings.empty() ? DE_NULL : &res.bindings[0]), // const VkDescriptorSetLayoutBinding* pBindings;
914 };
915
916 return createDescriptorSetLayout(env.vkd, env.device, &descriptorSetLayoutCreateInfo);
917 }
918 };
919
920 struct PipelineLayout
921 {
922 typedef VkPipelineLayout Type;
923
924 struct Parameters
925 {
926 std::vector<DescriptorSetLayout::Parameters> descriptorSetLayouts;
927 std::vector<VkPushConstantRange> pushConstantRanges;
928
Parametersvkt::memory::__anon71c481e30111::PipelineLayout::Parameters929 Parameters(void)
930 {
931 }
932
emptyvkt::memory::__anon71c481e30111::PipelineLayout::Parameters933 static Parameters empty(void)
934 {
935 return Parameters();
936 }
937
singleDescriptorSetvkt::memory::__anon71c481e30111::PipelineLayout::Parameters938 static Parameters singleDescriptorSet(const DescriptorSetLayout::Parameters &descriptorSetLayout)
939 {
940 Parameters params;
941 params.descriptorSetLayouts.push_back(descriptorSetLayout);
942 return params;
943 }
944 };
945
946 struct Resources
947 {
948 typedef SharedPtr<Dependency<DescriptorSetLayout>> DescriptorSetLayoutDepSp;
949 typedef std::vector<DescriptorSetLayoutDepSp> DescriptorSetLayouts;
950
951 DescriptorSetLayouts descriptorSetLayouts;
952 std::vector<VkDescriptorSetLayout> pSetLayouts;
953
Resourcesvkt::memory::__anon71c481e30111::PipelineLayout::Resources954 Resources(const Environment &env, const Parameters ¶ms)
955 {
956 for (std::vector<DescriptorSetLayout::Parameters>::const_iterator dsParams =
957 params.descriptorSetLayouts.begin();
958 dsParams != params.descriptorSetLayouts.end(); ++dsParams)
959 {
960 descriptorSetLayouts.push_back(
961 DescriptorSetLayoutDepSp(new Dependency<DescriptorSetLayout>(env, *dsParams)));
962 pSetLayouts.push_back(*descriptorSetLayouts.back()->object);
963 }
964 }
965 };
966
createvkt::memory::__anon71c481e30111::PipelineLayout967 static Move<VkPipelineLayout> create(const Environment &env, const Resources &res, const Parameters ¶ms)
968 {
969 const VkPipelineLayoutCreateInfo pipelineLayoutCreateInfo = {
970 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
971 DE_NULL, // const void* pNext;
972 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
973 (uint32_t)res.pSetLayouts.size(), // uint32_t setLayoutCount;
974 (res.pSetLayouts.empty() ? DE_NULL : &res.pSetLayouts[0]), // const VkDescriptorSetLayout* pSetLayouts;
975 (uint32_t)params.pushConstantRanges.size(), // uint32_t pushConstantRangeCount;
976 (params.pushConstantRanges.empty() ?
977 DE_NULL :
978 ¶ms.pushConstantRanges[0]), // const VkPushConstantRange* pPushConstantRanges;
979 };
980
981 return createPipelineLayout(env.vkd, env.device, &pipelineLayoutCreateInfo);
982 }
983 };
984
985 struct RenderPass
986 {
987 typedef VkRenderPass Type;
988
989 struct Parameters
990 {
Parametersvkt::memory::__anon71c481e30111::RenderPass::Parameters991 Parameters(void)
992 {
993 }
994 };
995
996 struct Resources
997 {
Resourcesvkt::memory::__anon71c481e30111::RenderPass::Resources998 Resources(const Environment &, const Parameters &)
999 {
1000 }
1001 };
1002
createvkt::memory::__anon71c481e30111::RenderPass1003 static Move<VkRenderPass> create(const Environment &env, const Resources &, const Parameters &)
1004 {
1005 return makeRenderPass(
1006 env.vkd, env.device, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_D16_UNORM, VK_ATTACHMENT_LOAD_OP_CLEAR,
1007 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1008 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL);
1009 }
1010 };
1011
1012 struct GraphicsPipeline
1013 {
1014 typedef VkPipeline Type;
1015
1016 struct Parameters
1017 {
Parametersvkt::memory::__anon71c481e30111::GraphicsPipeline::Parameters1018 Parameters(void)
1019 {
1020 }
1021 };
1022
1023 struct Resources
1024 {
1025 Dependency<ShaderModule> vertexShader;
1026 Dependency<ShaderModule> fragmentShader;
1027 Dependency<PipelineLayout> layout;
1028 Dependency<RenderPass> renderPass;
1029 Dependency<PipelineCache> pipelineCache;
1030
Resourcesvkt::memory::__anon71c481e30111::GraphicsPipeline::Resources1031 Resources(const Environment &env, const Parameters &)
1032 : vertexShader(env, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert"))
1033 , fragmentShader(env, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag"))
1034 , layout(env, PipelineLayout::Parameters::singleDescriptorSet(DescriptorSetLayout::Parameters::single(
1035 0u, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u, VK_SHADER_STAGE_FRAGMENT_BIT, true)))
1036 , renderPass(env, RenderPass::Parameters())
1037 , pipelineCache(env, PipelineCache::Parameters())
1038 {
1039 }
1040 };
1041
initProgramsvkt::memory::__anon71c481e30111::GraphicsPipeline1042 static void initPrograms(SourceCollections &dst, Parameters)
1043 {
1044 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_VERTEX_BIT, "vert"));
1045 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_FRAGMENT_BIT, "frag"));
1046 }
1047
createvkt::memory::__anon71c481e30111::GraphicsPipeline1048 static Move<VkPipeline> create(const Environment &env, const Resources &res, const Parameters &)
1049 {
1050 const VkPipelineShaderStageCreateInfo stages[] = {
1051 {
1052 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1053 DE_NULL, // const void* pNext;
1054 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1055 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
1056 *res.vertexShader.object, // VkShaderModule module;
1057 "main", // const char* pName;
1058 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
1059 },
1060 {
1061 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1062 DE_NULL, // const void* pNext;
1063 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1064 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
1065 *res.fragmentShader.object, // VkShaderModule module;
1066 "main", // const char* pName;
1067 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
1068 }};
1069 const VkVertexInputBindingDescription vertexBindings[] = {{
1070 0u, // uint32_t binding;
1071 16u, // uint32_t stride;
1072 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
1073 }};
1074 const VkVertexInputAttributeDescription vertexAttribs[] = {{
1075 0u, // uint32_t location;
1076 0u, // uint32_t binding;
1077 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1078 0u, // uint32_t offset;
1079 }};
1080 const VkPipelineVertexInputStateCreateInfo vertexInputState = {
1081 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1082 DE_NULL, // const void* pNext;
1083 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
1084 DE_LENGTH_OF_ARRAY(vertexBindings), // uint32_t vertexBindingDescriptionCount;
1085 vertexBindings, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1086 DE_LENGTH_OF_ARRAY(vertexAttribs), // uint32_t vertexAttributeDescriptionCount;
1087 vertexAttribs, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1088 };
1089 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = {
1090 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
1091 DE_NULL, // const void* pNext;
1092 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
1093 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
1094 VK_FALSE, // VkBool32 primitiveRestartEnable;
1095 };
1096 const VkViewport viewport = makeViewport(tcu::UVec2(64));
1097 const VkRect2D scissor = makeRect2D(tcu::UVec2(64));
1098
1099 const VkPipelineViewportStateCreateInfo viewportState = {
1100 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
1101 DE_NULL, // const void* pNext;
1102 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
1103 1u, // uint32_t viewportCount;
1104 &viewport, // const VkViewport* pViewports;
1105 1u, // uint32_t scissorCount;
1106 &scissor, // const VkRect2D* pScissors;
1107 };
1108 const VkPipelineRasterizationStateCreateInfo rasterState = {
1109 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
1110 DE_NULL, // const void* pNext;
1111 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
1112 VK_FALSE, // VkBool32 depthClampEnable;
1113 VK_FALSE, // VkBool32 rasterizerDiscardEnable;
1114 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
1115 VK_CULL_MODE_BACK_BIT, // VkCullModeFlags cullMode;
1116 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
1117 VK_FALSE, // VkBool32 depthBiasEnable;
1118 0.0f, // float depthBiasConstantFactor;
1119 0.0f, // float depthBiasClamp;
1120 0.0f, // float depthBiasSlopeFactor;
1121 1.0f, // float lineWidth;
1122 };
1123 const VkPipelineMultisampleStateCreateInfo multisampleState = {
1124 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
1125 DE_NULL, // const void* pNext;
1126 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
1127 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1128 VK_FALSE, // VkBool32 sampleShadingEnable;
1129 1.0f, // float minSampleShading;
1130 DE_NULL, // const VkSampleMask* pSampleMask;
1131 VK_FALSE, // VkBool32 alphaToCoverageEnable;
1132 VK_FALSE, // VkBool32 alphaToOneEnable;
1133 };
1134 const VkPipelineDepthStencilStateCreateInfo depthStencilState = {
1135 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
1136 DE_NULL, // const void* pNext;
1137 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
1138 VK_TRUE, // VkBool32 depthTestEnable;
1139 VK_TRUE, // VkBool32 depthWriteEnable;
1140 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
1141 VK_FALSE, // VkBool32 depthBoundsTestEnable;
1142 VK_FALSE, // VkBool32 stencilTestEnable;
1143 {
1144 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
1145 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
1146 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
1147 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1148 0u, // uint32_t compareMask;
1149 0u, // uint32_t writeMask;
1150 0u, // uint32_t reference;
1151 },
1152 {
1153 VK_STENCIL_OP_KEEP, // VkStencilOp failOp;
1154 VK_STENCIL_OP_KEEP, // VkStencilOp passOp;
1155 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp;
1156 VK_COMPARE_OP_ALWAYS, // VkCompareOp compareOp;
1157 0u, // uint32_t compareMask;
1158 0u, // uint32_t writeMask;
1159 0u, // uint32_t reference;
1160 },
1161 0.0f, // float minDepthBounds;
1162 1.0f, // float maxDepthBounds;
1163 };
1164 const VkPipelineColorBlendAttachmentState colorBlendAttState[] = {{
1165 VK_FALSE, // VkBool32 blendEnable;
1166 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
1167 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
1168 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
1169 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
1170 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
1171 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
1172 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT |
1173 VK_COLOR_COMPONENT_A_BIT, // VkColorComponentFlags colorWriteMask;
1174 }};
1175 const VkPipelineColorBlendStateCreateInfo colorBlendState = {
1176 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1177 DE_NULL, // const void* pNext;
1178 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
1179 VK_FALSE, // VkBool32 logicOpEnable;
1180 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1181 DE_LENGTH_OF_ARRAY(colorBlendAttState), // uint32_t attachmentCount;
1182 colorBlendAttState, // const VkPipelineColorBlendAttachmentState* pAttachments;
1183 {0.0f, 0.0f, 0.0f, 0.0f}, // float blendConstants[4];
1184 };
1185 const VkGraphicsPipelineCreateInfo pipelineCreateInfo = {
1186 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
1187 DE_NULL, // const void* pNext;
1188 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1189 DE_LENGTH_OF_ARRAY(stages), // uint32_t stageCount;
1190 stages, // const VkPipelineShaderStageCreateInfo* pStages;
1191 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
1192 &inputAssemblyState, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
1193 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
1194 &viewportState, // const VkPipelineViewportStateCreateInfo* pViewportState;
1195 &rasterState, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
1196 &multisampleState, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
1197 &depthStencilState, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
1198 &colorBlendState, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
1199 (const VkPipelineDynamicStateCreateInfo *)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
1200 *res.layout.object, // VkPipelineLayout layout;
1201 *res.renderPass.object, // VkRenderPass renderPass;
1202 0u, // uint32_t subpass;
1203 (VkPipeline)0, // VkPipeline basePipelineHandle;
1204 0, // int32_t basePipelineIndex;
1205 };
1206
1207 return createGraphicsPipeline(env.vkd, env.device, *res.pipelineCache.object, &pipelineCreateInfo);
1208 }
1209 };
1210
1211 struct ComputePipeline
1212 {
1213 typedef VkPipeline Type;
1214
1215 struct Parameters
1216 {
Parametersvkt::memory::__anon71c481e30111::ComputePipeline::Parameters1217 Parameters(void)
1218 {
1219 }
1220 };
1221
1222 struct Resources
1223 {
1224 Dependency<ShaderModule> shaderModule;
1225 Dependency<PipelineLayout> layout;
1226 Dependency<PipelineCache> pipelineCache;
1227
getDescriptorSetLayoutvkt::memory::__anon71c481e30111::ComputePipeline::Resources1228 static DescriptorSetLayout::Parameters getDescriptorSetLayout(void)
1229 {
1230 typedef DescriptorSetLayout::Parameters::Binding Binding;
1231
1232 std::vector<Binding> bindings;
1233
1234 bindings.push_back(Binding(0, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false));
1235 bindings.push_back(Binding(1, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 1u, VK_SHADER_STAGE_COMPUTE_BIT, false));
1236
1237 return DescriptorSetLayout::Parameters(bindings);
1238 }
1239
Resourcesvkt::memory::__anon71c481e30111::ComputePipeline::Resources1240 Resources(const Environment &env, const Parameters &)
1241 : shaderModule(env, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"))
1242 , layout(env, PipelineLayout::Parameters::singleDescriptorSet(getDescriptorSetLayout()))
1243 , pipelineCache(env, PipelineCache::Parameters())
1244 {
1245 }
1246 };
1247
initProgramsvkt::memory::__anon71c481e30111::ComputePipeline1248 static void initPrograms(SourceCollections &dst, Parameters)
1249 {
1250 ShaderModule::initPrograms(dst, ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "comp"));
1251 }
1252
createvkt::memory::__anon71c481e30111::ComputePipeline1253 static Move<VkPipeline> create(const Environment &env, const Resources &res, const Parameters &)
1254 {
1255 const VkComputePipelineCreateInfo pipelineCreateInfo = {
1256 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
1257 DE_NULL, // const void* pNext;
1258 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
1259 {
1260 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
1261 DE_NULL, // const void* pNext;
1262 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
1263 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
1264 *res.shaderModule.object, // VkShaderModule module;
1265 "main", // const char* pName;
1266 DE_NULL, // const VkSpecializationInfo* pSpecializationInfo;
1267 },
1268 *res.layout.object, // VkPipelineLayout layout;
1269 (VkPipeline)0, // VkPipeline basePipelineHandle;
1270 0u, // int32_t basePipelineIndex;
1271 };
1272
1273 return createComputePipeline(env.vkd, env.device, *res.pipelineCache.object, &pipelineCreateInfo);
1274 }
1275 };
1276
1277 struct DescriptorPool
1278 {
1279 typedef VkDescriptorPool Type;
1280
1281 struct Parameters
1282 {
1283 VkDescriptorPoolCreateFlags flags;
1284 uint32_t maxSets;
1285 std::vector<VkDescriptorPoolSize> poolSizes;
1286
Parametersvkt::memory::__anon71c481e30111::DescriptorPool::Parameters1287 Parameters(VkDescriptorPoolCreateFlags flags_, uint32_t maxSets_,
1288 const std::vector<VkDescriptorPoolSize> &poolSizes_)
1289 : flags(flags_)
1290 , maxSets(maxSets_)
1291 , poolSizes(poolSizes_)
1292 {
1293 }
1294
singleTypevkt::memory::__anon71c481e30111::DescriptorPool::Parameters1295 static Parameters singleType(VkDescriptorPoolCreateFlags flags, uint32_t maxSets, VkDescriptorType type,
1296 uint32_t count)
1297 {
1298 std::vector<VkDescriptorPoolSize> poolSizes;
1299 poolSizes.push_back(makeDescriptorPoolSize(type, count));
1300 return Parameters(flags, maxSets, poolSizes);
1301 }
1302 };
1303
1304 struct Resources
1305 {
Resourcesvkt::memory::__anon71c481e30111::DescriptorPool::Resources1306 Resources(const Environment &, const Parameters &)
1307 {
1308 }
1309 };
1310
createvkt::memory::__anon71c481e30111::DescriptorPool1311 static Move<VkDescriptorPool> create(const Environment &env, const Resources &, const Parameters ¶ms)
1312 {
1313 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
1314 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType;
1315 DE_NULL, // const void* pNext;
1316 params.flags, // VkDescriptorPoolCreateFlags flags;
1317 params.maxSets, // uint32_t maxSets;
1318 (uint32_t)params.poolSizes.size(), // uint32_t poolSizeCount;
1319 (params.poolSizes.empty() ? DE_NULL : ¶ms.poolSizes[0]), // const VkDescriptorPoolSize* pPoolSizes;
1320 };
1321
1322 return createDescriptorPool(env.vkd, env.device, &descriptorPoolCreateInfo);
1323 }
1324 };
1325
1326 struct DescriptorSet
1327 {
1328 typedef VkDescriptorSet Type;
1329
1330 struct Parameters
1331 {
1332 DescriptorSetLayout::Parameters descriptorSetLayout;
1333
Parametersvkt::memory::__anon71c481e30111::DescriptorSet::Parameters1334 Parameters(const DescriptorSetLayout::Parameters &descriptorSetLayout_)
1335 : descriptorSetLayout(descriptorSetLayout_)
1336 {
1337 }
1338 };
1339
1340 struct Resources
1341 {
1342 Dependency<DescriptorPool> descriptorPool;
1343 Dependency<DescriptorSetLayout> descriptorSetLayout;
1344
computePoolSizesvkt::memory::__anon71c481e30111::DescriptorSet::Resources1345 static std::vector<VkDescriptorPoolSize> computePoolSizes(const DescriptorSetLayout::Parameters &layout,
1346 int maxSets)
1347 {
1348 uint32_t countByType[VK_DESCRIPTOR_TYPE_LAST];
1349 std::vector<VkDescriptorPoolSize> typeCounts;
1350
1351 std::fill(DE_ARRAY_BEGIN(countByType), DE_ARRAY_END(countByType), 0u);
1352
1353 for (std::vector<DescriptorSetLayout::Parameters::Binding>::const_iterator cur = layout.bindings.begin();
1354 cur != layout.bindings.end(); cur++)
1355 {
1356 DE_ASSERT((uint32_t)cur->descriptorType < VK_DESCRIPTOR_TYPE_LAST);
1357 countByType[cur->descriptorType] += cur->descriptorCount * maxSets;
1358 }
1359
1360 for (uint32_t type = 0; type < VK_DESCRIPTOR_TYPE_LAST; type++)
1361 {
1362 if (countByType[type] > 0)
1363 typeCounts.push_back(makeDescriptorPoolSize((VkDescriptorType)type, countByType[type]));
1364 }
1365
1366 return typeCounts;
1367 }
1368
Resourcesvkt::memory::__anon71c481e30111::DescriptorSet::Resources1369 Resources(const Environment &env, const Parameters ¶ms)
1370 : descriptorPool(env, DescriptorPool::Parameters(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u,
1371 computePoolSizes(params.descriptorSetLayout, 1u)))
1372 , descriptorSetLayout(env, params.descriptorSetLayout)
1373 {
1374 }
1375 };
1376
createvkt::memory::__anon71c481e30111::DescriptorSet1377 static Move<VkDescriptorSet> create(const Environment &env, const Resources &res, const Parameters &)
1378 {
1379 const VkDescriptorSetAllocateInfo allocateInfo = {
1380 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
1381 DE_NULL, // const void* pNext;
1382 *res.descriptorPool.object, // VkDescriptorPool descriptorPool;
1383 1u, // uint32_t descriptorSetCount;
1384 &(*res.descriptorSetLayout.object), // const VkDescriptorSetLayout* pSetLayouts;
1385 };
1386
1387 return allocateDescriptorSet(env.vkd, env.device, &allocateInfo);
1388 }
1389 };
1390
1391 struct Framebuffer
1392 {
1393 typedef VkFramebuffer Type;
1394
1395 struct Parameters
1396 {
Parametersvkt::memory::__anon71c481e30111::Framebuffer::Parameters1397 Parameters(void)
1398 {
1399 }
1400 };
1401
1402 struct Resources
1403 {
1404 Dependency<ImageView> colorAttachment;
1405 Dependency<ImageView> depthStencilAttachment;
1406 Dependency<RenderPass> renderPass;
1407
Resourcesvkt::memory::__anon71c481e30111::Framebuffer::Resources1408 Resources(const Environment &env, const Parameters &)
1409 : colorAttachment(
1410 env, ImageView::Parameters(
1411 Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(256, 256, 1),
1412 1u, 1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
1413 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_UNDEFINED),
1414 VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeComponentMappingRGBA(),
1415 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u)))
1416 , depthStencilAttachment(
1417 env, ImageView::Parameters(
1418 Image::Parameters(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_D16_UNORM, makeExtent3D(256, 256, 1), 1u,
1419 1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
1420 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT, VK_IMAGE_LAYOUT_UNDEFINED),
1421 VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM, makeComponentMappingRGBA(),
1422 makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u)))
1423 , renderPass(env, RenderPass::Parameters())
1424 {
1425 }
1426 };
1427
createvkt::memory::__anon71c481e30111::Framebuffer1428 static Move<VkFramebuffer> create(const Environment &env, const Resources &res, const Parameters &)
1429 {
1430 const VkImageView attachments[] = {
1431 *res.colorAttachment.object,
1432 *res.depthStencilAttachment.object,
1433 };
1434 const VkFramebufferCreateInfo framebufferCreateInfo = {
1435 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1436 DE_NULL, // const void* pNext;
1437 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
1438 *res.renderPass.object, // VkRenderPass renderPass;
1439 (uint32_t)DE_LENGTH_OF_ARRAY(attachments), // uint32_t attachmentCount;
1440 attachments, // const VkImageView* pAttachments;
1441 256u, // uint32_t width;
1442 256u, // uint32_t height;
1443 1u, // uint32_t layers;
1444 };
1445
1446 return createFramebuffer(env.vkd, env.device, &framebufferCreateInfo);
1447 }
1448 };
1449
1450 struct CommandPool
1451 {
1452 typedef VkCommandPool Type;
1453
1454 struct Parameters
1455 {
1456 VkCommandPoolCreateFlags flags;
1457
Parametersvkt::memory::__anon71c481e30111::CommandPool::Parameters1458 Parameters(VkCommandPoolCreateFlags flags_) : flags(flags_)
1459 {
1460 }
1461 };
1462
1463 struct Resources
1464 {
Resourcesvkt::memory::__anon71c481e30111::CommandPool::Resources1465 Resources(const Environment &, const Parameters &)
1466 {
1467 }
1468 };
1469
createvkt::memory::__anon71c481e30111::CommandPool1470 static Move<VkCommandPool> create(const Environment &env, const Resources &, const Parameters ¶ms)
1471 {
1472 const VkCommandPoolCreateInfo commandPoolCreateInfo = {
1473 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
1474 DE_NULL, // const void* pNext;
1475 params.flags, // VkCommandPoolCreateFlags flags;
1476 env.queueFamilyIndex, // uint32_t queueFamilyIndex;
1477 };
1478
1479 return createCommandPool(env.vkd, env.device, &commandPoolCreateInfo);
1480 }
1481 };
1482
1483 struct CommandBuffer
1484 {
1485 typedef VkCommandBuffer Type;
1486
1487 struct Parameters
1488 {
1489 CommandPool::Parameters commandPool;
1490 VkCommandBufferLevel level;
1491
Parametersvkt::memory::__anon71c481e30111::CommandBuffer::Parameters1492 Parameters(const CommandPool::Parameters &commandPool_, VkCommandBufferLevel level_)
1493 : commandPool(commandPool_)
1494 , level(level_)
1495 {
1496 }
1497 };
1498
1499 struct Resources
1500 {
1501 Dependency<CommandPool> commandPool;
1502
Resourcesvkt::memory::__anon71c481e30111::CommandBuffer::Resources1503 Resources(const Environment &env, const Parameters ¶ms) : commandPool(env, params.commandPool)
1504 {
1505 }
1506 };
1507
createvkt::memory::__anon71c481e30111::CommandBuffer1508 static Move<VkCommandBuffer> create(const Environment &env, const Resources &res, const Parameters ¶ms)
1509 {
1510 const VkCommandBufferAllocateInfo allocateInfo = {
1511 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
1512 DE_NULL, // const void* pNext;
1513 *res.commandPool.object, // VkCommandPool commandPool;
1514 params.level, // VkCommandBufferLevel level;
1515 1, // uint32_t commandBufferCount;
1516 };
1517
1518 return allocateCommandBuffer(env.vkd, env.device, &allocateInfo);
1519 }
1520 };
1521
1522 template <typename Object>
1523 struct NamedParameters
1524 {
1525 const char *name;
1526 typename Object::Parameters parameters;
1527 };
1528
1529 template <typename Object>
1530 struct CaseDescription
1531 {
1532 typename FunctionInstance1<typename Object::Parameters>::Function function;
1533 const NamedParameters<Object> *paramsBegin;
1534 const NamedParameters<Object> *paramsEnd;
1535 };
1536
1537 #define CASE_DESC(FUNCTION, CASES) \
1538 { \
1539 FUNCTION, DE_ARRAY_BEGIN(CASES), DE_ARRAY_END(CASES) \
1540 }
1541
1542 struct CaseDescriptions
1543 {
1544 CaseDescription<Device> device;
1545 CaseDescription<DeviceMemory> deviceMemory;
1546 CaseDescription<Buffer> buffer;
1547 CaseDescription<BufferView> bufferView;
1548 CaseDescription<Image> image;
1549 CaseDescription<ImageView> imageView;
1550 CaseDescription<Semaphore> semaphore;
1551 CaseDescription<Event> event;
1552 CaseDescription<Fence> fence;
1553 CaseDescription<QueryPool> queryPool;
1554 CaseDescription<ShaderModule> shaderModule;
1555 CaseDescription<PipelineCache> pipelineCache;
1556 CaseDescription<Sampler> sampler;
1557 CaseDescription<DescriptorSetLayout> descriptorSetLayout;
1558 CaseDescription<PipelineLayout> pipelineLayout;
1559 CaseDescription<RenderPass> renderPass;
1560 CaseDescription<GraphicsPipeline> graphicsPipeline;
1561 CaseDescription<ComputePipeline> computePipeline;
1562 CaseDescription<DescriptorPool> descriptorPool;
1563 CaseDescription<DescriptorSet> descriptorSet;
1564 CaseDescription<Framebuffer> framebuffer;
1565 CaseDescription<CommandPool> commandPool;
1566 CaseDescription<CommandBuffer> commandBuffer;
1567 };
1568
checkSupport(Context & context)1569 static void checkSupport(Context &context)
1570 {
1571 const auto &extensions =
1572 enumerateCachedDeviceExtensionProperties(context.getInstanceInterface(), context.getPhysicalDevice());
1573
1574 for (size_t extNdx = 0; extNdx < extensions.size(); extNdx++)
1575 {
1576 if (deStringEqual("VK_EXT_device_memory_report", extensions[extNdx].extensionName))
1577 {
1578 VkPhysicalDeviceDeviceMemoryReportFeaturesEXT deviceMemoryReportFeatures = {
1579 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, DE_NULL, VK_FALSE};
1580
1581 VkPhysicalDeviceFeatures2 availFeatures;
1582 availFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1583 availFeatures.pNext = &deviceMemoryReportFeatures;
1584
1585 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &availFeatures);
1586
1587 if (deviceMemoryReportFeatures.deviceMemoryReport == VK_FALSE)
1588 {
1589 TCU_THROW(NotSupportedError, "VK_EXT_device_memory_report not supported");
1590 }
1591 return;
1592 }
1593 }
1594
1595 TCU_THROW(NotSupportedError, "VK_EXT_device_memory_report not supported");
1596 }
1597
1598 template <typename Object>
checkSupport(Context & context,typename Object::Parameters)1599 void checkSupport(Context &context, typename Object::Parameters)
1600 {
1601 checkSupport(context);
1602 }
1603
1604 template <>
checkSupport(Context & context,ImageView::Parameters parameters)1605 void checkSupport<ImageView>(Context &context, ImageView::Parameters parameters)
1606 {
1607 if (parameters.viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
1608 context.requireDeviceCoreFeature(vkt::DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);
1609
1610 context.requireDeviceFunctionality("VK_EXT_device_memory_report");
1611 }
1612
1613 template <typename Object>
addCases(const MovePtr<tcu::TestCaseGroup> & group,const CaseDescription<Object> & cases)1614 void addCases(const MovePtr<tcu::TestCaseGroup> &group, const CaseDescription<Object> &cases)
1615 {
1616 for (const NamedParameters<Object> *cur = cases.paramsBegin; cur != cases.paramsEnd; cur++)
1617 {
1618 addFunctionCase(group.get(), cur->name, checkSupport<Object>, cases.function, cur->parameters);
1619 }
1620 }
1621
1622 template <typename Object>
addCasesWithProgs(const MovePtr<tcu::TestCaseGroup> & group,const CaseDescription<Object> & cases)1623 void addCasesWithProgs(const MovePtr<tcu::TestCaseGroup> &group, const CaseDescription<Object> &cases)
1624 {
1625 for (const NamedParameters<Object> *cur = cases.paramsBegin; cur != cases.paramsEnd; cur++)
1626 {
1627 addFunctionCaseWithPrograms(group.get(), cur->name, checkSupport<Object>, Object::initPrograms, cases.function,
1628 cur->parameters);
1629 }
1630 }
1631
createObjectTestsGroup(tcu::TestContext & testCtx,const char * name,const CaseDescriptions & cases)1632 tcu::TestCaseGroup *createObjectTestsGroup(tcu::TestContext &testCtx, const char *name, const CaseDescriptions &cases)
1633 {
1634 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, name));
1635
1636 addCases(group, cases.device);
1637 addCases(group, cases.deviceMemory);
1638 addCases(group, cases.buffer);
1639 addCases(group, cases.bufferView);
1640 addCases(group, cases.image);
1641 addCases(group, cases.imageView);
1642 addCases(group, cases.semaphore);
1643 addCases(group, cases.event);
1644 addCases(group, cases.fence);
1645 addCases(group, cases.queryPool);
1646 addCasesWithProgs(group, cases.shaderModule);
1647 addCases(group, cases.pipelineCache);
1648 addCases(group, cases.sampler);
1649 addCases(group, cases.descriptorSetLayout);
1650 addCases(group, cases.pipelineLayout);
1651 addCases(group, cases.renderPass);
1652 addCasesWithProgs(group, cases.graphicsPipeline);
1653 addCasesWithProgs(group, cases.computePipeline);
1654 addCases(group, cases.descriptorPool);
1655 addCases(group, cases.descriptorSet);
1656 addCases(group, cases.framebuffer);
1657 addCases(group, cases.commandPool);
1658 addCases(group, cases.commandBuffer);
1659
1660 return group.release();
1661 }
1662
validateCallbackRecords(Context & context,const CallbackRecorder & recorder)1663 static bool validateCallbackRecords(Context &context, const CallbackRecorder &recorder)
1664 {
1665 tcu::TestLog &log = context.getTestContext().getLog();
1666 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1667 const InstanceInterface &vki = context.getInstanceInterface();
1668 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physicalDevice);
1669 std::set<std::pair<uint64_t, uint64_t>> memoryObjectSet;
1670
1671 for (auto iter = recorder.getRecordsBegin(); iter != recorder.getRecordsEnd(); iter++)
1672 {
1673 const VkDeviceMemoryReportCallbackDataEXT &record = iter->first;
1674
1675 if ((record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT ||
1676 record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT) &&
1677 record.heapIndex >= memoryProperties.memoryHeapCount)
1678 {
1679 log << tcu::TestLog::Message << "memoryHeapCount: " << memoryProperties.memoryHeapCount
1680 << tcu::TestLog::EndMessage;
1681 log << tcu::TestLog::Message << record << tcu::TestLog::EndMessage;
1682 return false;
1683 }
1684
1685 if (record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATION_FAILED_EXT)
1686 {
1687 log << tcu::TestLog::Message << "Observed ALLOCATION_FAILED event" << tcu::TestLog::EndMessage;
1688 log << tcu::TestLog::Message << record << tcu::TestLog::EndMessage;
1689 continue;
1690 }
1691
1692 if (record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT ||
1693 record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT)
1694 {
1695 memoryObjectSet.insert(std::make_pair(record.memoryObjectId, record.objectHandle));
1696 continue;
1697 }
1698
1699 if (record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT ||
1700 record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT)
1701 {
1702 const auto objectPair = std::make_pair(record.memoryObjectId, record.objectHandle);
1703 if (!memoryObjectSet.count(objectPair))
1704 {
1705 log << tcu::TestLog::Message << "Unpaired or out-of-order free/unimport event"
1706 << tcu::TestLog::EndMessage;
1707 log << tcu::TestLog::Message << record << tcu::TestLog::EndMessage;
1708 return false;
1709 }
1710 memoryObjectSet.erase(objectPair);
1711 }
1712 }
1713
1714 if (!memoryObjectSet.empty())
1715 {
1716 log << tcu::TestLog::Message << "Unpaired alloc/import event" << tcu::TestLog::EndMessage;
1717 return false;
1718 }
1719
1720 return true;
1721 }
1722
1723 struct EnvClone
1724 {
1725 Unique<VkDevice> device;
1726 DeviceDriver vkd;
1727 Environment env;
1728
EnvClonevkt::memory::__anon71c481e30111::EnvClone1729 EnvClone(const Environment &parent)
1730 : device(Device::create(parent, Device::Resources(parent, Device::Parameters()), Device::Parameters()))
1731 , vkd(parent.vkp, parent.instance, *device, parent.usedApiVersion, parent.commandLine)
1732 , env(parent.vkp, parent.vki, parent.instance, parent.physicalDevice, vkd, *device, parent.queueFamilyIndex,
1733 parent.programBinaries, parent.usedApiVersion, parent.commandLine, nullptr)
1734 {
1735 }
1736 };
1737
1738 template <typename Object>
createDestroyObjectTest(Context & context,typename Object::Parameters params)1739 tcu::TestStatus createDestroyObjectTest(Context &context, typename Object::Parameters params)
1740 {
1741 CallbackRecorder recorder;
1742 const Environment env(context.getPlatformInterface(), context.getInstanceInterface(), context.getInstance(),
1743 context.getPhysicalDevice(), context.getDeviceInterface(), context.getDevice(),
1744 context.getUniversalQueueFamilyIndex(), context.getBinaryCollection(),
1745 context.getUsedApiVersion(), context.getTestContext().getCommandLine(), &recorder);
1746
1747 if (std::is_same<Object, Device>::value)
1748 {
1749 const typename Object::Resources res(env, params);
1750 Unique<typename Object::Type> obj(Object::create(env, res, params));
1751 }
1752 else
1753 {
1754 const EnvClone envWithCustomDevice(env);
1755 const typename Object::Resources res(envWithCustomDevice.env, params);
1756 Unique<typename Object::Type> obj(Object::create(envWithCustomDevice.env, res, params));
1757 }
1758
1759 if (!validateCallbackRecords(context, recorder))
1760 {
1761 return tcu::TestStatus::fail("Invalid device memory report callback");
1762 }
1763
1764 return tcu::TestStatus::pass("Ok");
1765 }
1766
vkDeviceMemoryAllocateAndFreeTest(Context & context)1767 tcu::TestStatus vkDeviceMemoryAllocateAndFreeTest(Context &context)
1768 {
1769 CallbackRecorder recorder;
1770 const PlatformInterface &vkp = context.getPlatformInterface();
1771 const VkInstance instance = context.getInstance();
1772 const InstanceInterface &vki = context.getInstanceInterface();
1773 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1774 const uint32_t queueFamilyIndex = context.getUniversalQueueFamilyIndex();
1775 const bool isValidationEnabled = context.getTestContext().getCommandLine().isValidationEnabled();
1776 const Unique<VkDevice> device(createDeviceWithMemoryReport(isValidationEnabled, vkp, instance, vki, physicalDevice,
1777 queueFamilyIndex, &recorder));
1778 const DeviceDriver vkd(vkp, instance, *device, context.getUsedApiVersion(),
1779 context.getTestContext().getCommandLine());
1780 const VkPhysicalDeviceMemoryProperties memoryProperties = getPhysicalDeviceMemoryProperties(vki, physicalDevice);
1781 const VkDeviceSize testSize = 1024;
1782 const uint32_t testTypeIndex = 0;
1783 const uint32_t testHeapIndex = memoryProperties.memoryTypes[testTypeIndex].heapIndex;
1784 uint64_t objectHandle = 0;
1785
1786 {
1787 recorder.setCallbackMarker(MARKER_ALLOCATE);
1788
1789 VkResult result = VK_SUCCESS;
1790 VkDeviceMemory memory = DE_NULL;
1791 const VkMemoryAllocateInfo memoryAllocateInfo = {
1792 VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, // VkStructureType sType;
1793 DE_NULL, // const void* pNext;
1794 testSize, // VkDeviceSize allocationSize;
1795 testTypeIndex, // uint32_t memoryTypeIndex;
1796 };
1797
1798 result = vkd.allocateMemory(*device, &memoryAllocateInfo, (const VkAllocationCallbacks *)DE_NULL, &memory);
1799 if (result != VK_SUCCESS)
1800 {
1801 return tcu::TestStatus::fail("Unable to allocate " + de::toString(testSize) + " bytes of memory");
1802 }
1803 objectHandle = memory.getInternal();
1804
1805 recorder.setCallbackMarker(MARKER_FREE);
1806 vkd.freeMemory(*device, memory, (const VkAllocationCallbacks *)DE_NULL);
1807 }
1808
1809 recorder.setCallbackMarker(MARKER_UNKNOWN);
1810
1811 bool allocateEvent = false;
1812 bool freeEvent = false;
1813 uint64_t memoryObjectId = 0;
1814
1815 for (auto iter = recorder.getRecordsBegin(); iter != recorder.getRecordsEnd(); iter++)
1816 {
1817 const VkDeviceMemoryReportCallbackDataEXT &record = iter->first;
1818 const CallbackMarker marker = iter->second;
1819
1820 if (record.objectHandle == objectHandle && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT)
1821 {
1822 TCU_CHECK(marker == MARKER_ALLOCATE);
1823 TCU_CHECK(record.objectType == VK_OBJECT_TYPE_DEVICE_MEMORY);
1824 TCU_CHECK(memoryObjectId == 0);
1825 TCU_CHECK(record.memoryObjectId != 0);
1826 TCU_CHECK_MSG(
1827 record.size >= testSize,
1828 ("record.size=" + de::toString(record.size) + ", testSize=" + de::toString(testSize)).c_str());
1829 TCU_CHECK(record.heapIndex == testHeapIndex);
1830
1831 memoryObjectId = record.memoryObjectId;
1832 allocateEvent = true;
1833 }
1834 else if (record.objectHandle == objectHandle && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT)
1835 {
1836 TCU_CHECK(marker == MARKER_FREE);
1837 TCU_CHECK_MSG(record.memoryObjectId == memoryObjectId,
1838 ("record.memoryObjectId=" + de::toString(record.memoryObjectId) +
1839 ", memoryObjectId=" + de::toString(memoryObjectId))
1840 .c_str());
1841
1842 freeEvent = true;
1843 }
1844 }
1845
1846 TCU_CHECK(allocateEvent);
1847 TCU_CHECK(freeEvent);
1848
1849 return tcu::TestStatus::pass("Ok");
1850 }
1851
createVkDeviceMemoryTestsGroup(tcu::TestContext & testCtx,const char * name)1852 tcu::TestCaseGroup *createVkDeviceMemoryTestsGroup(tcu::TestContext &testCtx, const char *name)
1853 {
1854 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, name));
1855
1856 addFunctionCase(group.get(), "allocate_and_free", checkSupport, vkDeviceMemoryAllocateAndFreeTest);
1857
1858 return group.release();
1859 }
1860
checkSupport(Context & context,VkExternalMemoryHandleTypeFlagBits externalMemoryType)1861 static void checkSupport(Context &context, VkExternalMemoryHandleTypeFlagBits externalMemoryType)
1862 {
1863 checkSupport(context);
1864
1865 context.requireInstanceFunctionality("VK_KHR_external_memory_capabilities");
1866 context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
1867 context.requireDeviceFunctionality("VK_KHR_get_memory_requirements2");
1868
1869 if (externalMemoryType &
1870 (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT))
1871 {
1872 context.requireDeviceFunctionality("VK_KHR_external_memory_fd");
1873 }
1874
1875 if (externalMemoryType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)
1876 {
1877 context.requireDeviceFunctionality("VK_EXT_external_memory_dma_buf");
1878 }
1879
1880 if (externalMemoryType &
1881 (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT |
1882 VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT |
1883 VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT))
1884 {
1885 context.requireDeviceFunctionality("VK_KHR_external_memory_win32");
1886 }
1887
1888 if (externalMemoryType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1889 {
1890 context.requireDeviceFunctionality("VK_ANDROID_external_memory_android_hardware_buffer");
1891 }
1892 }
1893
getInstanceExtensions(const uint32_t instanceVersion)1894 static std::vector<std::string> getInstanceExtensions(const uint32_t instanceVersion)
1895 {
1896 std::vector<std::string> instanceExtensions;
1897
1898 if (!isCoreInstanceExtension(instanceVersion, "VK_KHR_get_physical_device_properties2"))
1899 instanceExtensions.push_back("VK_KHR_get_physical_device_properties2");
1900
1901 if (!isCoreInstanceExtension(instanceVersion, "VK_KHR_external_memory_capabilities"))
1902 instanceExtensions.push_back("VK_KHR_external_memory_capabilities");
1903
1904 return instanceExtensions;
1905 }
1906
createExternalMemoryDevice(bool isValidationEnabled,const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,uint32_t apiVersion,uint32_t queueFamilyIndex,VkExternalMemoryHandleTypeFlagBits externalMemoryType,const CallbackRecorder * recorder)1907 static Move<VkDevice> createExternalMemoryDevice(bool isValidationEnabled, const PlatformInterface &vkp,
1908 VkInstance instance, const InstanceInterface &vki,
1909 VkPhysicalDevice physicalDevice, uint32_t apiVersion,
1910 uint32_t queueFamilyIndex,
1911 VkExternalMemoryHandleTypeFlagBits externalMemoryType,
1912 const CallbackRecorder *recorder)
1913 {
1914 const uint32_t queueCount = 1;
1915 const float queuePriority = 1.0f;
1916 std::vector<const char *> enabledExtensions = {"VK_EXT_device_memory_report"};
1917
1918 if (!isCoreDeviceExtension(apiVersion, "VK_KHR_dedicated_allocation"))
1919 {
1920 enabledExtensions.push_back("VK_KHR_dedicated_allocation");
1921 }
1922 if (!isCoreDeviceExtension(apiVersion, "VK_KHR_get_memory_requirements2"))
1923 {
1924 enabledExtensions.push_back("VK_KHR_get_memory_requirements2");
1925 }
1926
1927 if (externalMemoryType &
1928 (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT))
1929 {
1930 if (!isCoreDeviceExtension(apiVersion, "VK_KHR_external_memory_fd"))
1931 {
1932 enabledExtensions.push_back("VK_KHR_external_memory_fd");
1933 }
1934 }
1935
1936 if (externalMemoryType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT)
1937 {
1938 enabledExtensions.push_back("VK_EXT_external_memory_dma_buf");
1939 }
1940
1941 if (externalMemoryType &
1942 (VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT |
1943 VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D11_TEXTURE_KMT_BIT |
1944 VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_HEAP_BIT | VK_EXTERNAL_MEMORY_HANDLE_TYPE_D3D12_RESOURCE_BIT))
1945 {
1946 enabledExtensions.push_back("VK_KHR_external_memory_win32");
1947 }
1948
1949 if (externalMemoryType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)
1950 {
1951 enabledExtensions.push_back("VK_ANDROID_external_memory_android_hardware_buffer");
1952 enabledExtensions.push_back("VK_EXT_queue_family_foreign");
1953 if (!isCoreDeviceExtension(apiVersion, "VK_KHR_sampler_ycbcr_conversion"))
1954 {
1955 enabledExtensions.push_back("VK_KHR_sampler_ycbcr_conversion");
1956 }
1957 }
1958
1959 const VkPhysicalDeviceDeviceMemoryReportFeaturesEXT deviceMemoryReportFeatures = {
1960 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEVICE_MEMORY_REPORT_FEATURES_EXT, // VkStructureType sType;
1961 DE_NULL, // void* pNext;
1962 VK_TRUE // VkBool32 deviceMemoryReport;
1963 };
1964 const VkDeviceDeviceMemoryReportCreateInfoEXT deviceMemoryReportCreateInfo = {
1965 VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT, // VkStructureType sType;
1966 &deviceMemoryReportFeatures, // void* pNext;
1967 (VkDeviceMemoryReportFlagsEXT)0, // VkDeviceMemoryReportFlagsEXT flags;
1968 recorder->callback, // PFN_vkDeviceMemoryReportCallbackEXT pfnUserCallback;
1969 (void *)recorder, // void* pUserData;
1970 };
1971 const VkDeviceQueueCreateInfo queueCreateInfo = {
1972 VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // VkStructureType sType;
1973 DE_NULL, // const void* pNext;
1974 (VkDeviceQueueCreateFlags)0, // VkDeviceQueueCreateFlags flags;
1975 queueFamilyIndex, // uint32_t queueFamilyIndex;
1976 queueCount, // uint32_t queueCount;
1977 &queuePriority, // const float* pQueuePriorities;
1978 };
1979 const VkDeviceCreateInfo deviceCreateInfo = {
1980 VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // VkStructureType sType;
1981 &deviceMemoryReportCreateInfo, // const void* pNext;
1982 (VkDeviceCreateFlags)0, // VkDeviceCreateFlags flags;
1983 queueCount, // uint32_t queueCreateInfoCount;
1984 &queueCreateInfo, // const VkDeviceQueueCreateInfo* pQueueCreateInfos;
1985 0u, // uint32_t enabledLayerCount;
1986 DE_NULL, // const char* const* ppEnabledLayerNames;
1987 (uint32_t)enabledExtensions.size(), // uint32_t enabledExtensionCount;
1988 enabledExtensions.data(), // const char* const* ppEnabledExtensionNames;
1989 DE_NULL, // const VkPhysicalDeviceFeatures* pEnabledFeatures;
1990 };
1991
1992 return createCustomDevice(isValidationEnabled, vkp, instance, vki, physicalDevice, &deviceCreateInfo);
1993 }
1994
checkBufferSupport(const InstanceInterface & vki,VkPhysicalDevice device,VkBufferUsageFlags usage,VkExternalMemoryHandleTypeFlagBits externalMemoryType)1995 static void checkBufferSupport(const InstanceInterface &vki, VkPhysicalDevice device, VkBufferUsageFlags usage,
1996 VkExternalMemoryHandleTypeFlagBits externalMemoryType)
1997 {
1998 const VkPhysicalDeviceExternalBufferInfo info = {
1999 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO, // VkStructureType sType;
2000 DE_NULL, // void* pNext;
2001 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
2002 usage, // VkBufferUsageFlags usage;
2003 externalMemoryType, // VkExternalMemoryHandleTypeFlagBits handleType;
2004 };
2005 VkExternalBufferProperties properties = {
2006 VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES, // VkStructureType sType;
2007 DE_NULL, // void* pNext;
2008 {0u, 0u, 0u}, // VkExternalMemoryProperties externalMemoryProperties;
2009 };
2010
2011 vki.getPhysicalDeviceExternalBufferProperties(device, &info, &properties);
2012
2013 if ((properties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT) == 0)
2014 TCU_THROW(NotSupportedError, "External handle type doesn't support exporting buffer");
2015
2016 if ((properties.externalMemoryProperties.externalMemoryFeatures & VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT) == 0)
2017 TCU_THROW(NotSupportedError, "External handle type doesn't support importing buffer");
2018 }
2019
testImportAndUnimportExternalMemory(Context & context,VkExternalMemoryHandleTypeFlagBits externalMemoryType)2020 tcu::TestStatus testImportAndUnimportExternalMemory(Context &context,
2021 VkExternalMemoryHandleTypeFlagBits externalMemoryType)
2022 {
2023 CallbackRecorder recorder;
2024 const PlatformInterface &vkp(context.getPlatformInterface());
2025 const CustomInstance instance(
2026 createCustomInstanceWithExtensions(context, getInstanceExtensions(context.getUsedApiVersion())));
2027 const InstanceDriver &vki(instance.getDriver());
2028 const VkPhysicalDevice physicalDevice(chooseDevice(vki, instance, context.getTestContext().getCommandLine()));
2029 const uint32_t queueFamilyIndex(context.getUniversalQueueFamilyIndex());
2030 const Unique<VkDevice> device(createExternalMemoryDevice(
2031 context.getTestContext().getCommandLine().isValidationEnabled(), vkp, instance, vki, physicalDevice,
2032 context.getUsedApiVersion(), queueFamilyIndex, externalMemoryType, &recorder));
2033 const DeviceDriver vkd(vkp, instance, *device, context.getUsedApiVersion(),
2034 context.getTestContext().getCommandLine());
2035 const VkBufferUsageFlags usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT;
2036 const VkDeviceSize bufferSize = 1024;
2037
2038 checkBufferSupport(vki, physicalDevice, usage, externalMemoryType);
2039
2040 const Unique<VkBuffer> buffer(
2041 createExternalBuffer(vkd, *device, queueFamilyIndex, externalMemoryType, bufferSize, 0u, usage));
2042 const VkMemoryRequirements requirements(getBufferMemoryRequirements(vkd, *device, *buffer));
2043 const uint32_t memoryTypeIndex(chooseMemoryType(requirements.memoryTypeBits));
2044 uint64_t objectHandle = 0;
2045 uint64_t objectHandleA = 0;
2046 uint64_t objectHandleB = 0;
2047
2048 {
2049 recorder.setCallbackMarker(MARKER_ALLOCATE);
2050 const Unique<VkDeviceMemory> memory(
2051 allocateExportableMemory(vkd, *device, requirements.size, memoryTypeIndex, externalMemoryType, *buffer));
2052 objectHandle = (*memory).getInternal();
2053 NativeHandle handleA;
2054
2055 getMemoryNative(vkd, *device, *memory, externalMemoryType, handleA);
2056
2057 NativeHandle handleB(handleA);
2058 const Unique<VkBuffer> bufferA(
2059 createExternalBuffer(vkd, *device, queueFamilyIndex, externalMemoryType, bufferSize, 0u, usage));
2060 const Unique<VkBuffer> bufferB(
2061 createExternalBuffer(vkd, *device, queueFamilyIndex, externalMemoryType, bufferSize, 0u, usage));
2062
2063 {
2064 recorder.setCallbackMarker(MARKER_IMPORT);
2065 const Unique<VkDeviceMemory> memoryA(importDedicatedMemory(vkd, *device, *bufferA, requirements,
2066 externalMemoryType, memoryTypeIndex, handleA));
2067 const Unique<VkDeviceMemory> memoryB(importDedicatedMemory(vkd, *device, *bufferB, requirements,
2068 externalMemoryType, memoryTypeIndex, handleB));
2069 objectHandleA = (*memoryA).getInternal();
2070 objectHandleB = (*memoryB).getInternal();
2071 recorder.setCallbackMarker(MARKER_UNIMPORT);
2072 }
2073
2074 recorder.setCallbackMarker(MARKER_FREE);
2075 }
2076
2077 recorder.setCallbackMarker(MARKER_UNKNOWN);
2078
2079 bool allocateEvent = false;
2080 bool freeEvent = false;
2081 bool importA = false;
2082 bool importB = false;
2083 bool unimportA = false;
2084 bool unimportB = false;
2085 uint64_t memoryObjectId = 0;
2086
2087 for (auto iter = recorder.getRecordsBegin(); iter != recorder.getRecordsEnd(); iter++)
2088 {
2089 const VkDeviceMemoryReportCallbackDataEXT &record = iter->first;
2090 const CallbackMarker marker = iter->second;
2091
2092 if (record.objectHandle == objectHandle && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_ALLOCATE_EXT)
2093 {
2094 TCU_CHECK(marker == MARKER_ALLOCATE);
2095 TCU_CHECK(record.objectType == VK_OBJECT_TYPE_DEVICE_MEMORY);
2096 TCU_CHECK(memoryObjectId == 0);
2097 TCU_CHECK(record.memoryObjectId != 0);
2098 TCU_CHECK_MSG(record.size >= requirements.size, ("size: record=" + de::toString(record.size) +
2099 ", requirements=" + de::toString(requirements.size))
2100 .c_str());
2101
2102 allocateEvent = true;
2103 memoryObjectId = record.memoryObjectId;
2104 }
2105 else if (record.objectHandle == objectHandleA && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT)
2106 {
2107 TCU_CHECK(marker == MARKER_IMPORT);
2108 TCU_CHECK(record.objectType == VK_OBJECT_TYPE_DEVICE_MEMORY);
2109 TCU_CHECK_MSG(record.size >= requirements.size, ("sizeA: record=" + de::toString(record.size) +
2110 ", requirements=" + de::toString(requirements.size))
2111 .c_str());
2112 TCU_CHECK_MSG(record.memoryObjectId == memoryObjectId,
2113 ("memoryObjectIdA: record=" + de::toString(record.memoryObjectId) +
2114 ", original=" + de::toString(memoryObjectId))
2115 .c_str());
2116
2117 importA = true;
2118 }
2119 else if (record.objectHandle == objectHandleB && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_IMPORT_EXT)
2120 {
2121 TCU_CHECK(marker == MARKER_IMPORT);
2122 TCU_CHECK(record.objectType == VK_OBJECT_TYPE_DEVICE_MEMORY);
2123 TCU_CHECK_MSG(record.size >= requirements.size, ("sizeB: record=" + de::toString(record.size) +
2124 ", requirements=" + de::toString(requirements.size))
2125 .c_str());
2126 TCU_CHECK_MSG(record.memoryObjectId == memoryObjectId,
2127 ("memoryObjectIdB: record=" + de::toString(record.memoryObjectId) +
2128 ", original=" + de::toString(memoryObjectId))
2129 .c_str());
2130
2131 importB = true;
2132 }
2133 else if (record.objectHandle == objectHandleB && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT)
2134 {
2135 TCU_CHECK(marker == MARKER_UNIMPORT);
2136 TCU_CHECK_MSG(record.memoryObjectId == memoryObjectId,
2137 ("memoryObjectIdA: record=" + de::toString(record.memoryObjectId) +
2138 ", original=" + de::toString(memoryObjectId))
2139 .c_str());
2140
2141 unimportB = true;
2142 }
2143 else if (record.objectHandle == objectHandleA && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_UNIMPORT_EXT)
2144 {
2145 TCU_CHECK(marker == MARKER_UNIMPORT);
2146 TCU_CHECK_MSG(record.memoryObjectId == memoryObjectId,
2147 ("memoryObjectIdB: record=" + de::toString(record.memoryObjectId) +
2148 ", original=" + de::toString(memoryObjectId))
2149 .c_str());
2150
2151 unimportA = true;
2152 }
2153 else if (record.objectHandle == objectHandle && record.type == VK_DEVICE_MEMORY_REPORT_EVENT_TYPE_FREE_EXT)
2154 {
2155 TCU_CHECK(marker == MARKER_FREE);
2156 TCU_CHECK_MSG(record.memoryObjectId == memoryObjectId,
2157 ("memoryObjectId: record=" + de::toString(record.memoryObjectId) +
2158 ", original=" + de::toString(memoryObjectId))
2159 .c_str());
2160
2161 freeEvent = true;
2162 }
2163 }
2164
2165 TCU_CHECK(allocateEvent);
2166 TCU_CHECK(importA);
2167 TCU_CHECK(importB);
2168 TCU_CHECK(unimportB);
2169 TCU_CHECK(unimportA);
2170 TCU_CHECK(freeEvent);
2171
2172 return tcu::TestStatus::pass("Pass");
2173 }
2174
createExternalMemoryTestsGroup(tcu::TestContext & testCtx,const char * name)2175 tcu::TestCaseGroup *createExternalMemoryTestsGroup(tcu::TestContext &testCtx, const char *name)
2176 {
2177 MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, name));
2178
2179 const std::vector<VkExternalMemoryHandleTypeFlagBits> externalMemoryTypes = {
2180 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT,
2181 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT,
2182 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID,
2183 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT};
2184
2185 for (const auto externalMemoryType : externalMemoryTypes)
2186 {
2187 const std::string testName =
2188 std::string("import_and_unimport_") + std::string(externalMemoryTypeToName(externalMemoryType));
2189
2190 addFunctionCase(group.get(), testName.c_str(), checkSupport, testImportAndUnimportExternalMemory,
2191 externalMemoryType);
2192 }
2193
2194 return group.release();
2195 }
2196
2197 } // namespace
2198
createDeviceMemoryReportTests(tcu::TestContext & testCtx)2199 tcu::TestCaseGroup *createDeviceMemoryReportTests(tcu::TestContext &testCtx)
2200 {
2201 MovePtr<tcu::TestCaseGroup> deviceMemoryReportTests(new tcu::TestCaseGroup(testCtx, "device_memory_report"));
2202
2203 const Image::Parameters img1D(0u, VK_IMAGE_TYPE_1D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(256, 1, 1), 1u, 4u,
2204 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT,
2205 VK_IMAGE_LAYOUT_UNDEFINED);
2206 const Image::Parameters img2D(0u, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(64, 64, 1), 1u, 12u,
2207 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
2208 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
2209 VK_IMAGE_LAYOUT_UNDEFINED);
2210 const Image::Parameters imgCube(VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT, VK_IMAGE_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM,
2211 makeExtent3D(64, 64, 1), 1u, 12u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
2212 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
2213 VK_IMAGE_LAYOUT_UNDEFINED);
2214 const Image::Parameters img3D(0u, VK_IMAGE_TYPE_3D, VK_FORMAT_R8G8B8A8_UNORM, makeExtent3D(64, 64, 4), 1u, 1u,
2215 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, VK_IMAGE_USAGE_SAMPLED_BIT,
2216 VK_IMAGE_LAYOUT_UNDEFINED);
2217 const ImageView::Parameters imgView1D(img1D, VK_IMAGE_VIEW_TYPE_1D, img1D.format, makeComponentMappingRGBA(),
2218 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
2219 const ImageView::Parameters imgView1DArr(img1D, VK_IMAGE_VIEW_TYPE_1D_ARRAY, img1D.format,
2220 makeComponentMappingRGBA(),
2221 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 4u));
2222 const ImageView::Parameters imgView2D(img2D, VK_IMAGE_VIEW_TYPE_2D, img2D.format, makeComponentMappingRGBA(),
2223 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
2224 const ImageView::Parameters imgView2DArr(img2D, VK_IMAGE_VIEW_TYPE_2D_ARRAY, img2D.format,
2225 makeComponentMappingRGBA(),
2226 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 8u));
2227 const ImageView::Parameters imgViewCube(imgCube, VK_IMAGE_VIEW_TYPE_CUBE, img2D.format, makeComponentMappingRGBA(),
2228 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 6u));
2229 const ImageView::Parameters imgViewCubeArr(imgCube, VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, img2D.format,
2230 makeComponentMappingRGBA(),
2231 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 12u));
2232 const ImageView::Parameters imgView3D(img3D, VK_IMAGE_VIEW_TYPE_3D, img3D.format, makeComponentMappingRGBA(),
2233 makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u));
2234
2235 const DescriptorSetLayout::Parameters singleUboDescLayout =
2236 DescriptorSetLayout::Parameters::single(0u, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1u, VK_SHADER_STAGE_VERTEX_BIT);
2237
2238 const NamedParameters<Device> s_deviceCases[] = {
2239 {"device", Device::Parameters()},
2240 };
2241 static const NamedParameters<DeviceMemory> s_deviceMemCases[] = {
2242 {"device_memory_small", DeviceMemory::Parameters(1024, 0u)},
2243 };
2244 static const NamedParameters<Buffer> s_bufferCases[] = {
2245 {
2246 "buffer_uniform_small",
2247 Buffer::Parameters(1024u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
2248 },
2249 {
2250 "buffer_uniform_large",
2251 Buffer::Parameters(1024u * 1024u * 16u, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT),
2252 },
2253 {
2254 "buffer_storage_small",
2255 Buffer::Parameters(1024u, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
2256 },
2257 {
2258 "buffer_storage_large",
2259 Buffer::Parameters(1024u * 1024u * 16u, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT),
2260 },
2261 };
2262 static const NamedParameters<BufferView> s_bufferViewCases[] = {
2263 {"buffer_view_uniform_r8g8b8a8_unorm",
2264 BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT),
2265 VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u)},
2266 {"buffer_view_storage_r8g8b8a8_unorm",
2267 BufferView::Parameters(Buffer::Parameters(8192u, VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT),
2268 VK_FORMAT_R8G8B8A8_UNORM, 0u, 4096u)},
2269 };
2270 static const NamedParameters<Image> s_imageCases[] = {
2271 {"image_1d", img1D},
2272 {"image_2d", img2D},
2273 {"image_3d", img3D},
2274 };
2275 static const NamedParameters<ImageView> s_imageViewCases[] = {
2276 {"image_view_1d", imgView1D}, {"image_view_1d_arr", imgView1DArr},
2277 {"image_view_2d", imgView2D}, {"image_view_2d_arr", imgView2DArr},
2278 {"image_view_cube", imgViewCube}, {"image_view_cube_arr", imgViewCubeArr},
2279 {"image_view_3d", imgView3D},
2280 };
2281 static const NamedParameters<Semaphore> s_semaphoreCases[] = {{
2282 "semaphore",
2283 Semaphore::Parameters(0u),
2284 }};
2285 static const NamedParameters<Event> s_eventCases[] = {{"event", Event::Parameters(0u)}};
2286 static const NamedParameters<Fence> s_fenceCases[] = {
2287 {"fence", Fence::Parameters(0u)}, {"fence_signaled", Fence::Parameters(VK_FENCE_CREATE_SIGNALED_BIT)}};
2288 static const NamedParameters<QueryPool> s_queryPoolCases[] = {
2289 {"query_pool", QueryPool::Parameters(VK_QUERY_TYPE_OCCLUSION, 1u, 0u)}};
2290 static const NamedParameters<ShaderModule> s_shaderModuleCases[] = {
2291 {"shader_module", ShaderModule::Parameters(VK_SHADER_STAGE_COMPUTE_BIT, "test")}};
2292 static const NamedParameters<PipelineCache> s_pipelineCacheCases[] = {
2293 {"pipeline_cache", PipelineCache::Parameters()}};
2294 static const NamedParameters<Sampler> s_samplerCases[] = {{"sampler", Sampler::Parameters()}};
2295 static const NamedParameters<DescriptorSetLayout> s_descriptorSetLayoutCases[] = {
2296 {"descriptor_set_layout_empty", DescriptorSetLayout::Parameters::empty()},
2297 {"descriptor_set_layout_single", singleUboDescLayout}};
2298 static const NamedParameters<PipelineLayout> s_pipelineLayoutCases[] = {
2299 {"pipeline_layout_empty", PipelineLayout::Parameters::empty()},
2300 {"pipeline_layout_single", PipelineLayout::Parameters::singleDescriptorSet(singleUboDescLayout)}};
2301 static const NamedParameters<RenderPass> s_renderPassCases[] = {{"render_pass", RenderPass::Parameters()}};
2302 static const NamedParameters<GraphicsPipeline> s_graphicsPipelineCases[] = {
2303 {"graphics_pipeline", GraphicsPipeline::Parameters()}};
2304 static const NamedParameters<ComputePipeline> s_computePipelineCases[] = {
2305 {"compute_pipeline", ComputePipeline::Parameters()}};
2306 static const NamedParameters<DescriptorPool> s_descriptorPoolCases[] = {
2307 {"descriptor_pool", DescriptorPool::Parameters::singleType((VkDescriptorPoolCreateFlags)0, 4u,
2308 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u)},
2309 {"descriptor_pool_free_descriptor_set",
2310 DescriptorPool::Parameters::singleType(VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 4u,
2311 VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 3u)}};
2312 static const NamedParameters<DescriptorSet> s_descriptorSetCases[] = {
2313 {"descriptor_set", DescriptorSet::Parameters(singleUboDescLayout)}};
2314 static const NamedParameters<Framebuffer> s_framebufferCases[] = {{"framebuffer", Framebuffer::Parameters()}};
2315 static const NamedParameters<CommandPool> s_commandPoolCases[] = {
2316 {"command_pool", CommandPool::Parameters((VkCommandPoolCreateFlags)0)},
2317 {"command_pool_transient", CommandPool::Parameters(VK_COMMAND_POOL_CREATE_TRANSIENT_BIT)}};
2318 static const NamedParameters<CommandBuffer> s_commandBufferCases[] = {
2319 {"command_buffer_primary", CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u),
2320 VK_COMMAND_BUFFER_LEVEL_PRIMARY)},
2321 {"command_buffer_secondary", CommandBuffer::Parameters(CommandPool::Parameters((VkCommandPoolCreateFlags)0u),
2322 VK_COMMAND_BUFFER_LEVEL_SECONDARY)}};
2323
2324 const CaseDescriptions s_createDestroyObjectGroup = {
2325 CASE_DESC(createDestroyObjectTest<Device>, s_deviceCases),
2326 CASE_DESC(createDestroyObjectTest<DeviceMemory>, s_deviceMemCases),
2327 CASE_DESC(createDestroyObjectTest<Buffer>, s_bufferCases),
2328 CASE_DESC(createDestroyObjectTest<BufferView>, s_bufferViewCases),
2329 CASE_DESC(createDestroyObjectTest<Image>, s_imageCases),
2330 CASE_DESC(createDestroyObjectTest<ImageView>, s_imageViewCases),
2331 CASE_DESC(createDestroyObjectTest<Semaphore>, s_semaphoreCases),
2332 CASE_DESC(createDestroyObjectTest<Event>, s_eventCases),
2333 CASE_DESC(createDestroyObjectTest<Fence>, s_fenceCases),
2334 CASE_DESC(createDestroyObjectTest<QueryPool>, s_queryPoolCases),
2335 CASE_DESC(createDestroyObjectTest<ShaderModule>, s_shaderModuleCases),
2336 CASE_DESC(createDestroyObjectTest<PipelineCache>, s_pipelineCacheCases),
2337 CASE_DESC(createDestroyObjectTest<Sampler>, s_samplerCases),
2338 CASE_DESC(createDestroyObjectTest<DescriptorSetLayout>, s_descriptorSetLayoutCases),
2339 CASE_DESC(createDestroyObjectTest<PipelineLayout>, s_pipelineLayoutCases),
2340 CASE_DESC(createDestroyObjectTest<RenderPass>, s_renderPassCases),
2341 CASE_DESC(createDestroyObjectTest<GraphicsPipeline>, s_graphicsPipelineCases),
2342 CASE_DESC(createDestroyObjectTest<ComputePipeline>, s_computePipelineCases),
2343 CASE_DESC(createDestroyObjectTest<DescriptorPool>, s_descriptorPoolCases),
2344 CASE_DESC(createDestroyObjectTest<DescriptorSet>, s_descriptorSetCases),
2345 CASE_DESC(createDestroyObjectTest<Framebuffer>, s_framebufferCases),
2346 CASE_DESC(createDestroyObjectTest<CommandPool>, s_commandPoolCases),
2347 CASE_DESC(createDestroyObjectTest<CommandBuffer>, s_commandBufferCases),
2348 };
2349 // Check emitted callbacks are properly paired
2350 deviceMemoryReportTests->addChild(
2351 createObjectTestsGroup(testCtx, "create_and_destroy_object", s_createDestroyObjectGroup));
2352 // Check callbacks are emitted properly for VkDeviceMemory
2353 deviceMemoryReportTests->addChild(createVkDeviceMemoryTestsGroup(testCtx, "vk_device_memory"));
2354 // Check callbacks are emitted properly for external memory
2355 deviceMemoryReportTests->addChild(createExternalMemoryTestsGroup(testCtx, "external_memory"));
2356
2357 return deviceMemoryReportTests.release();
2358 }
2359
2360 } // namespace memory
2361 } // namespace vkt
2362