1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2018 The Khronos Group Inc.
6 * Copyright (c) 2018 Intel Corporation
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_external_memory_host extension tests.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktMemoryExternalMemoryHostTests.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28
29 #include "deMath.h"
30
31 #include "vkQueryUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkBuilderUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkObjUtil.hpp"
36 #include "vkTypeUtil.hpp"
37 #include "vkCmdUtil.hpp"
38
39
40 #include "tcuTestLog.hpp"
41 #include "tcuImageCompare.hpp"
42
43 namespace vkt
44 {
45 namespace memory
46 {
47 namespace
48 {
49
50 using namespace vk;
51
getBit(deUint32 src,int ndx)52 inline deUint32 getBit (deUint32 src, int ndx)
53 {
54 return (src >> ndx) & 1;
55 }
56
isBitSet(deUint32 src,int ndx)57 inline bool isBitSet (deUint32 src, int ndx)
58 {
59 return getBit(src, ndx) != 0;
60 }
61
62 struct TestParams
63 {
64 VkFormat m_format;
65 bool m_useOffset;
66
TestParamsvkt::memory::__anon67350ce20111::TestParams67 TestParams (VkFormat f, bool offset = false) : m_format(f) , m_useOffset(offset) {}
68 };
69
70 class ExternalMemoryHostBaseTestInstance : public TestInstance
71 {
72 public:
73 ExternalMemoryHostBaseTestInstance (Context& context, VkDeviceSize allocationSize);
74 ~ExternalMemoryHostBaseTestInstance (void);
75 protected:
76 virtual tcu::TestStatus iterate (void);
77 VkDeviceSize getMinImportedHostPointerAlignment (void);
78 deUint32 getHostPointerMemoryTypeBits (void* hostPointer);
79 Move<VkDeviceMemory> allocateMemoryFromHostPointer (deUint32 memoryTypeIndex);
80 void logMemoryTypeIndexPropertyFlags (deUint32 index);
81 bool findCompatibleMemoryTypeIndexToTest (deUint32 resourceMemoryTypeBits, deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest);
82 bool findMemoryTypeIndexToTest (deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest);
83
84 const InstanceInterface& m_vki;
85 const DeviceInterface& m_vkd;
86 tcu::TestLog& m_log;
87 const VkDevice m_device;
88 const VkPhysicalDevice m_physicalDevice;
89 const VkQueue m_queue;
90 const vk::VkPhysicalDeviceMemoryProperties m_memoryProps;
91 VkDeviceSize m_minImportedHostPointerAlignment;
92 VkDeviceSize m_allocationSize;
93 void* m_hostMemoryAlloc;
94 Allocator& m_allocator;
95 Move<VkDeviceMemory> m_deviceMemoryAllocatedFromHostPointer;
96 };
97
98 class ExternalMemoryHostRenderImageTestInstance : public ExternalMemoryHostBaseTestInstance
99 {
100 public:
101 ExternalMemoryHostRenderImageTestInstance (Context& context, TestParams testParams);
102 protected:
103 virtual tcu::TestStatus iterate (void);
104 Move<VkImage> createImage (VkImageTiling tiling);
105 Move<VkImageView> createImageView (void);
106 Move<VkBuffer> createBindMemoryInitializeVertexBuffer (void);
107 Move<VkBuffer> createBindMemoryResultBuffer (void);
108 Move<VkFramebuffer> createFramebuffer (void);
109 Move<VkDescriptorSet> createAndUpdateDescriptorSet (void);
110 Move<VkPipelineLayout> createPipelineLayout (void);
111 Move<VkPipeline> createPipeline (void);
112 Move<VkRenderPass> createRenderPass (void);
113 void clear (VkClearColorValue color);
114 void draw (void);
115 void copyResultImagetoBuffer (void);
116 void prepareReferenceImage (tcu::PixelBufferAccess& reference);
117
118 TestParams m_testParams;
119 Move<VkImage> m_image;
120 Move<VkImageView> m_imageView;
121 Move<VkRenderPass> m_renderPass;
122 Move<VkFramebuffer> m_framebuffer;
123 Move<VkBuffer> m_vertexBuffer;
124 Move<VkBuffer> m_resultBuffer;
125 de::MovePtr<Allocation> m_vertexBufferAllocation;
126 de::MovePtr<Allocation> m_resultBufferAllocation;
127 Move<VkDescriptorPool> m_descriptorPool;
128 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
129 Move<VkDescriptorSet> m_descriptorSet;
130 Move<VkShaderModule> m_vertexShaderModule;
131 Move<VkShaderModule> m_fragmentShaderModule;
132 Move<VkPipelineLayout> m_pipelineLayout;
133 Move<VkPipeline> m_pipeline;
134 Move<VkCommandPool> m_cmdPool;
135 Move<VkCommandBuffer> m_cmdBuffer;
136 };
137
138 class ExternalMemoryHostSynchronizationTestInstance : public ExternalMemoryHostRenderImageTestInstance
139 {
140 public:
141 ExternalMemoryHostSynchronizationTestInstance (Context& context, TestParams testParams);
142 protected:
143 virtual tcu::TestStatus iterate (void);
144 void prepareBufferForHostAccess (void);
145 void copyResultBuffertoBuffer (void);
146 void submitCommands (VkCommandBuffer commandBuffer, VkFence fence);
147 Move<VkBuffer> createDataBuffer (void);
148 void fillBuffer (void);
149
150 Move<VkBuffer> m_dataBuffer;
151 Move<VkCommandPool> m_cmdPoolCopy;
152 Move<VkCommandBuffer> m_cmdBufferCopy;
153 Move<VkFence> m_fence_1;
154 Move<VkFence> m_fence_2;
155 Move<VkEvent> m_event;
156 };
157
ExternalMemoryHostBaseTestInstance(Context & context,VkDeviceSize allocationSize)158 ExternalMemoryHostBaseTestInstance::ExternalMemoryHostBaseTestInstance (Context& context, VkDeviceSize allocationSize)
159 : TestInstance (context)
160 , m_vki (m_context.getInstanceInterface())
161 , m_vkd (m_context.getDeviceInterface())
162 , m_log (m_context.getTestContext().getLog())
163 , m_device (m_context.getDevice())
164 , m_physicalDevice (m_context.getPhysicalDevice())
165 , m_queue (m_context.getUniversalQueue())
166 , m_memoryProps (getPhysicalDeviceMemoryProperties(m_vki, m_physicalDevice))
167 , m_minImportedHostPointerAlignment (getMinImportedHostPointerAlignment())
168 , m_allocationSize (m_minImportedHostPointerAlignment * allocationSize)
169 , m_allocator (m_context.getDefaultAllocator())
170 {
171 if (!isDeviceExtensionSupported(context.getUsedApiVersion(), context.getDeviceExtensions(), "VK_EXT_external_memory_host"))
172 throw tcu::NotSupportedError("VK_EXT_external_memory_host is not supported");
173
174 m_hostMemoryAlloc = deAlignedMalloc((size_t)m_allocationSize, (size_t)m_minImportedHostPointerAlignment);
175
176 if (!m_hostMemoryAlloc)
177 TCU_FAIL("Failed to allocate memory block.");
178
179 DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));
180 }
181
~ExternalMemoryHostBaseTestInstance(void)182 ExternalMemoryHostBaseTestInstance::~ExternalMemoryHostBaseTestInstance (void)
183 {
184 deAlignedFree(m_hostMemoryAlloc);
185 }
186
getMinImportedHostPointerAlignment(void)187 VkDeviceSize ExternalMemoryHostBaseTestInstance::getMinImportedHostPointerAlignment (void)
188 {
189 VkPhysicalDeviceExternalMemoryHostPropertiesEXT externalMemoryHostProperties =
190 {
191 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT, //VkStructureType sType
192 DE_NULL, //void* pNext
193 0 //VkDeviceSize minImportedHostPointerAlignment
194 };
195
196 VkPhysicalDeviceProperties2 propertiesDeviceProperties2;
197 propertiesDeviceProperties2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
198 propertiesDeviceProperties2.pNext = &externalMemoryHostProperties;
199
200 m_vki.getPhysicalDeviceProperties2(m_physicalDevice, &propertiesDeviceProperties2);
201
202 m_log << tcu::TestLog::Message << "VkPhysicalDeviceExternalMemoryHostPropertiesEXT::minImportedHostPointerAlignment is "
203 << externalMemoryHostProperties.minImportedHostPointerAlignment << tcu::TestLog::EndMessage;
204
205 if (externalMemoryHostProperties.minImportedHostPointerAlignment > 65536)
206 TCU_FAIL("minImportedHostPointerAlignment is exceeding the supported limit");
207
208 return externalMemoryHostProperties.minImportedHostPointerAlignment;
209 }
210
getHostPointerMemoryTypeBits(void * hostPointer)211 deUint32 ExternalMemoryHostBaseTestInstance::getHostPointerMemoryTypeBits (void* hostPointer)
212 {
213 VkExternalMemoryHandleTypeFlagBits externalMemoryHandleTypeFlagBits = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
214
215 VkMemoryHostPointerPropertiesEXT memoryHostPointerProperties;
216 memoryHostPointerProperties.sType = VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT;
217 memoryHostPointerProperties.pNext = DE_NULL;
218
219 VK_CHECK(m_vkd.getMemoryHostPointerPropertiesEXT(m_device, externalMemoryHandleTypeFlagBits, hostPointer, &memoryHostPointerProperties));
220
221 m_log << tcu::TestLog::Message << "memoryTypeBits value: " << memoryHostPointerProperties.memoryTypeBits << tcu::TestLog::EndMessage;
222
223 return memoryHostPointerProperties.memoryTypeBits;
224 }
225
allocateMemoryFromHostPointer(deUint32 memoryTypeIndex)226 Move<VkDeviceMemory> ExternalMemoryHostBaseTestInstance::allocateMemoryFromHostPointer (deUint32 memoryTypeIndex)
227 {
228 VkImportMemoryHostPointerInfoEXT importMemoryHostPointerInfo;
229 importMemoryHostPointerInfo.sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT;
230 importMemoryHostPointerInfo.pNext = DE_NULL;
231 importMemoryHostPointerInfo.handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT;
232 importMemoryHostPointerInfo.pHostPointer = m_hostMemoryAlloc;
233
234 VkMemoryAllocateInfo memoryAllocateInfo;
235 memoryAllocateInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
236 memoryAllocateInfo.pNext = &importMemoryHostPointerInfo;
237 memoryAllocateInfo.allocationSize = m_allocationSize;
238 memoryAllocateInfo.memoryTypeIndex = memoryTypeIndex;
239
240 return allocateMemory(m_vkd, m_device, &memoryAllocateInfo, DE_NULL);
241 }
242
logMemoryTypeIndexPropertyFlags(deUint32 index)243 void ExternalMemoryHostBaseTestInstance::logMemoryTypeIndexPropertyFlags (deUint32 index)
244 {
245 m_log << tcu::TestLog::Message << "Memory Type index " << index << " property flags:" << tcu::TestLog::EndMessage;
246 m_log << tcu::TestLog::Message << getMemoryPropertyFlagsStr(m_memoryProps.memoryTypes[index].propertyFlags) << tcu::TestLog::EndMessage;
247 }
248
findCompatibleMemoryTypeIndexToTest(deUint32 resourceMemoryTypeBits,deUint32 hostPointerMemoryTypeBits,deUint32 * outMemoryTypeIndexToTest)249 bool ExternalMemoryHostBaseTestInstance::findCompatibleMemoryTypeIndexToTest (deUint32 resourceMemoryTypeBits, deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest)
250 {
251 for (deUint32 bitMaskPosition = 0; bitMaskPosition < VK_MAX_MEMORY_TYPES; bitMaskPosition++)
252 {
253 if (isBitSet(resourceMemoryTypeBits & hostPointerMemoryTypeBits, bitMaskPosition))
254 {
255 logMemoryTypeIndexPropertyFlags(bitMaskPosition);
256 *outMemoryTypeIndexToTest = bitMaskPosition;
257 return true;
258 }
259 }
260 return false;
261 }
262
findMemoryTypeIndexToTest(deUint32 hostPointerMemoryTypeBits,deUint32 * outMemoryTypeIndexToTest)263 bool ExternalMemoryHostBaseTestInstance::findMemoryTypeIndexToTest (deUint32 hostPointerMemoryTypeBits, deUint32* outMemoryTypeIndexToTest)
264 {
265 return findCompatibleMemoryTypeIndexToTest(~0u, hostPointerMemoryTypeBits, outMemoryTypeIndexToTest);
266 }
267
iterate(void)268 tcu::TestStatus ExternalMemoryHostBaseTestInstance::iterate (void)
269 {
270 deUint32 hostPointerMemoryTypeBits;
271 deUint32 memoryTypeIndexToTest;
272
273 //realocate to meet requirements for host memory alignment
274 m_hostMemoryAlloc = deAlignedRealloc(m_hostMemoryAlloc, (size_t)m_minImportedHostPointerAlignment, (size_t)m_minImportedHostPointerAlignment);
275 m_allocationSize = m_minImportedHostPointerAlignment;
276
277 //check if reallocation is successfull
278 if (!m_hostMemoryAlloc)
279 TCU_FAIL("Failed to reallocate memory block.");
280
281 DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));
282
283 //find the usable memory type index
284 hostPointerMemoryTypeBits = getHostPointerMemoryTypeBits(m_hostMemoryAlloc);
285 if (findMemoryTypeIndexToTest(hostPointerMemoryTypeBits, &memoryTypeIndexToTest))
286 m_deviceMemoryAllocatedFromHostPointer = allocateMemoryFromHostPointer(memoryTypeIndexToTest);
287 else
288 return tcu::TestStatus::fail("Fail");
289
290 return tcu::TestStatus::pass("Pass");
291 }
292
ExternalMemoryHostRenderImageTestInstance(Context & context,TestParams testParams)293 ExternalMemoryHostRenderImageTestInstance::ExternalMemoryHostRenderImageTestInstance (Context& context, TestParams testParams)
294 : ExternalMemoryHostBaseTestInstance (context, 1)
295 , m_testParams (testParams)
296 {
297 }
298
iterate()299 tcu::TestStatus ExternalMemoryHostRenderImageTestInstance::iterate ()
300 {
301 VkClearColorValue clearColorBlue = { { 0.0f, 0.0f, 1.0f, 1.0f } };
302 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
303 deUint32 hostPointerMemoryTypeBits;
304 deUint32 memoryTypeIndexToTest;
305 VkMemoryRequirements imageMemoryRequirements;
306
307 m_image = createImage(VK_IMAGE_TILING_OPTIMAL);
308
309 //check memory requirements and reallocate memory if needed
310 imageMemoryRequirements = getImageMemoryRequirements(m_vkd, m_device, *m_image);
311
312 if (m_testParams.m_useOffset == false)
313 {
314 VkDeviceSize requiredSize = imageMemoryRequirements.size;
315 if (requiredSize > m_allocationSize)
316 {
317 //calculate new size, this must me a multiple of minImportedHostPointerAlignment
318 VkDeviceSize newHostAllocationSize = VkDeviceSize(deCeilFloatToInt32((float(requiredSize) / float(m_minImportedHostPointerAlignment))) * m_minImportedHostPointerAlignment);
319
320 m_log << tcu::TestLog::Message << "Realloc needed (required size: " << requiredSize << "). " << "New host allocation size: " << newHostAllocationSize << ")."
321 << tcu::TestLog::EndMessage;
322 //realocate
323 m_hostMemoryAlloc = deAlignedRealloc(m_hostMemoryAlloc, (size_t)newHostAllocationSize, (size_t)m_minImportedHostPointerAlignment);
324 m_allocationSize = newHostAllocationSize;
325 }
326 }
327
328 if (m_testParams.m_useOffset == true)
329 {
330 VkDeviceSize requiredSize = imageMemoryRequirements.size + imageMemoryRequirements.alignment;
331 if (requiredSize > m_allocationSize)
332 {
333 VkDeviceSize newHostAllocationSize = VkDeviceSize(deCeilFloatToInt32((float(requiredSize) / float(m_minImportedHostPointerAlignment))) * m_minImportedHostPointerAlignment);
334
335 m_log << tcu::TestLog::Message << "Realloc needed (required size: " << requiredSize << "). " << "New host allocation size: " << newHostAllocationSize << ")."
336 << tcu::TestLog::EndMessage;
337 m_hostMemoryAlloc = deAlignedRealloc(m_hostMemoryAlloc, (size_t)newHostAllocationSize, (size_t)m_minImportedHostPointerAlignment);
338 m_allocationSize = newHostAllocationSize;
339 }
340 }
341 //check if reallocation is successfull
342 if (!m_hostMemoryAlloc)
343 TCU_FAIL("Failed to reallocate memory block.");
344
345 DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));
346
347 //find the usable memory type index
348 hostPointerMemoryTypeBits = getHostPointerMemoryTypeBits(m_hostMemoryAlloc);
349 if (findCompatibleMemoryTypeIndexToTest(imageMemoryRequirements.memoryTypeBits, hostPointerMemoryTypeBits, &memoryTypeIndexToTest))
350 m_deviceMemoryAllocatedFromHostPointer = allocateMemoryFromHostPointer(memoryTypeIndexToTest);
351 else
352 TCU_THROW(NotSupportedError, "Compatible memory type not found");
353
354 VK_CHECK(m_vkd.bindImageMemory(m_device, *m_image, *m_deviceMemoryAllocatedFromHostPointer, (m_testParams.m_useOffset ? imageMemoryRequirements.alignment : 0)));
355
356 m_imageView = createImageView();
357 m_renderPass = createRenderPass();
358 m_framebuffer = createFramebuffer();
359 m_vertexBuffer = createBindMemoryInitializeVertexBuffer();
360 m_resultBuffer = createBindMemoryResultBuffer();
361
362 vk::DescriptorSetLayoutBuilder builder;
363
364 builder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_ALL);
365
366 m_descriptorSetLayout = builder.build(m_vkd, m_device, (vk::VkDescriptorSetLayoutCreateFlags)0);
367
368 m_descriptorPool = DescriptorPoolBuilder().addType(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
369 .build(m_vkd, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
370
371 m_pipelineLayout = createPipelineLayout();
372 m_descriptorSet = createAndUpdateDescriptorSet();
373
374 m_vertexShaderModule = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("position_only.vert"), 0);
375 m_fragmentShaderModule = createShaderModule(m_vkd, m_device, m_context.getBinaryCollection().get("only_color_out.frag"), 0);
376
377
378 m_pipeline = createPipeline();
379
380 m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
381 m_cmdBuffer = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
382
383
384 beginCommandBuffer(m_vkd, *m_cmdBuffer);
385
386 clear(clearColorBlue);
387 draw();
388 copyResultImagetoBuffer();
389
390 endCommandBuffer(m_vkd, *m_cmdBuffer);
391
392 submitCommandsAndWait(m_vkd, m_device, m_queue, *m_cmdBuffer);
393
394 tcu::ConstPixelBufferAccess result(mapVkFormat(m_testParams.m_format), tcu::IVec3(100,100,1), m_resultBufferAllocation->getHostPtr());
395
396 std::vector<float> referenceData(40000, 0);
397 tcu::PixelBufferAccess reference(mapVkFormat(m_testParams.m_format), tcu::IVec3(100, 100, 1), referenceData.data());
398
399 prepareReferenceImage(reference);
400
401 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
402 return tcu::TestStatus::fail("Fail");
403
404 return tcu::TestStatus::pass("Pass");
405 }
406
createImage(VkImageTiling tiling)407 Move<VkImage> ExternalMemoryHostRenderImageTestInstance::createImage (VkImageTiling tiling)
408 {
409 const VkImageCreateInfo imageCreateInfo =
410 {
411 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
412 DE_NULL, // const void* pNext
413 DE_NULL, // VkImageCreateFlags flags
414 VK_IMAGE_TYPE_2D, // VkImageType imageType
415 m_testParams.m_format, // VkFormat format
416 { 100, 100, 1 }, // VkExtent3D extent
417 1, // deUint32 mipLevels
418 1, // deUint32 arrayLayers
419 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
420 tiling, // VkImageTiling tiling
421 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
422 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
423 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage
424 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
425 0, // deUint32 queueFamilyIndexCount
426 DE_NULL, // const deUint32* pQueueFamilyIndices
427 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout
428 };
429
430 return vk::createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL);
431 }
432
createFramebuffer()433 Move<VkFramebuffer> ExternalMemoryHostRenderImageTestInstance::createFramebuffer ()
434 {
435 const VkFramebufferCreateInfo framebufferCreateInfo =
436 {
437 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
438 DE_NULL, // const void* pNext
439 (VkFramebufferCreateFlags)0,
440 *m_renderPass, // VkRenderPass renderPass
441 1, // deUint32 attachmentCount
442 &m_imageView.get(), // const VkImageView* pAttachments
443 100, // deUint32 width
444 100, // deUint32 height
445 1 // deUint32 layers
446 };
447 return vk::createFramebuffer(m_vkd, m_device, &framebufferCreateInfo);
448 }
449
createImageView()450 Move<VkImageView> ExternalMemoryHostRenderImageTestInstance::createImageView ()
451 {
452 const VkImageViewCreateInfo imageViewCreateInfo =
453 {
454 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
455 DE_NULL, // const void* pNext
456 0, // VkImageViewCreateFlags flags
457 *m_image, // VkImage image
458 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
459 m_testParams.m_format, // VkFormat format
460 { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A}, // VkComponentMapping components
461 { VK_IMAGE_ASPECT_COLOR_BIT, 0, 1, 0, 1 } // VkImageSubresourceRange subresourceRange
462 };
463 return vk::createImageView(m_vkd, m_device, &imageViewCreateInfo);
464 }
465
createBindMemoryInitializeVertexBuffer()466 Move<VkBuffer> ExternalMemoryHostRenderImageTestInstance::createBindMemoryInitializeVertexBuffer ()
467 {
468 Move<VkBuffer> buffer;
469 float triangleData[] = { -1.0f, -1.0f, 0.0f, 1.0f,
470 -1.0f, 1.0f, 0.0f, 1.0f,
471 0.0f, 1.0f, 0.0f, 1.0f,
472 0.0f, -1.0f, 0.0f, 1.0f };
473 const VkBufferCreateInfo vertexBufferCreateInfo =
474 {
475 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
476 DE_NULL, // const void* pNext
477 0, // VkBufferCreateFlags flag
478 sizeof(triangleData), // VkDeviceSize size
479 VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // VkBufferUsageFlags usage
480 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
481 0, // deUint32 queueFamilyCount
482 DE_NULL // const deUint32* pQueueFamilyIndices
483 };
484 buffer = vk::createBuffer(m_vkd, m_device, &vertexBufferCreateInfo, DE_NULL);
485 const VkMemoryRequirements bufferMemoryRequirements = getBufferMemoryRequirements(m_vkd, m_device, *buffer);
486 m_vertexBufferAllocation = m_allocator.allocate(bufferMemoryRequirements, MemoryRequirement::HostVisible);
487
488 VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, m_vertexBufferAllocation->getMemory(), m_vertexBufferAllocation->getOffset()));
489
490 void* const mapPtr = m_vertexBufferAllocation->getHostPtr();
491
492 deMemcpy(mapPtr, triangleData, sizeof(triangleData));
493 flushMappedMemoryRange(m_vkd, m_device, m_vertexBufferAllocation->getMemory(), m_vertexBufferAllocation->getOffset(), sizeof(triangleData));
494
495 return buffer;
496 }
497
createBindMemoryResultBuffer()498 Move<VkBuffer> ExternalMemoryHostRenderImageTestInstance::createBindMemoryResultBuffer ()
499 {
500 Move<VkBuffer> buffer;
501 VkDeviceSize size = 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
502
503 const VkBufferCreateInfo resultBufferCreateInfo =
504 {
505 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
506 DE_NULL, // const void* pNext
507 0, // VkBufferCreateFlags flags
508 size, // VkDeviceSize size
509 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
510 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage
511 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
512 0, // deUint32 queueFamilyCount
513 DE_NULL // const deUint32* pQueueFamilyIndices
514 };
515 buffer = vk::createBuffer(m_vkd, m_device, &resultBufferCreateInfo, DE_NULL);
516
517 const VkMemoryRequirements bufferMemoryRequirements = getBufferMemoryRequirements(m_vkd, m_device, *buffer);
518 m_resultBufferAllocation = m_allocator.allocate(bufferMemoryRequirements, MemoryRequirement::HostVisible);
519
520 VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, m_resultBufferAllocation->getMemory(), m_resultBufferAllocation->getOffset()));
521
522 return buffer;
523 }
524
createAndUpdateDescriptorSet()525 Move<VkDescriptorSet> ExternalMemoryHostRenderImageTestInstance::createAndUpdateDescriptorSet ()
526 {
527 Move<VkDescriptorSet> descriptorSet;
528 VkDescriptorBufferInfo descriptorInfo;
529
530 const VkDescriptorSetAllocateInfo allocInfo =
531 {
532 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
533 DE_NULL, // const void* pNext
534 *m_descriptorPool, // VkDescriptorPool descriptorPool
535 1u, // deUint32 setLayoutCount
536 &(m_descriptorSetLayout.get()) // const VkDescriptorSetLayout* pSetLayouts
537 };
538
539 descriptorSet = allocateDescriptorSet(m_vkd, m_device, &allocInfo);
540 descriptorInfo = makeDescriptorBufferInfo(*m_vertexBuffer, (VkDeviceSize)0u, sizeof(float) * 16);
541
542 DescriptorSetUpdateBuilder()
543 .writeSingle(*descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u), VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &descriptorInfo)
544 .update(m_vkd, m_device);
545
546 return descriptorSet;
547 }
548
createPipelineLayout()549 Move<VkPipelineLayout> ExternalMemoryHostRenderImageTestInstance::createPipelineLayout ()
550 {
551 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
552 {
553 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
554 DE_NULL, // const void* pNext
555 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags
556 1u, // deUint32 descriptorSetCount
557 &(m_descriptorSetLayout.get()), // const VkDescriptorSetLayout* pSetLayouts
558 0u, // deUint32 pushConstantRangeCount
559 DE_NULL // const VkPushConstantRange* pPushConstantRanges
560 };
561
562 return vk::createPipelineLayout(m_vkd, m_device, &pipelineLayoutParams);
563 }
564
createPipeline()565 Move<VkPipeline> ExternalMemoryHostRenderImageTestInstance::createPipeline ()
566 {
567 Move<VkPipeline> pipeline;
568 const std::vector<VkViewport> viewports(1, makeViewport(tcu::UVec2(100,100)));
569 const std::vector<VkRect2D> scissors(1, makeRect2D(tcu::UVec2(100, 100)));
570 const VkPrimitiveTopology topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_FAN;
571 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
572 {
573 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
574 DE_NULL, // const void* pNext
575 0u, // vkPipelineVertexInputStateCreateFlags flags
576 0u, // deUint32 bindingCount
577 DE_NULL, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
578 0u, // deUint32 attributeCount
579 DE_NULL, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
580 };
581
582 return makeGraphicsPipeline( m_vkd, // const DeviceInterface& vk
583 m_device, // const VkDevice device
584 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
585 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
586 DE_NULL, // const VkShaderModule tessellationControlShaderModule
587 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
588 DE_NULL, // const VkShaderModule geometryShaderModule
589 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
590 *m_renderPass, // const VkRenderPass renderPass
591 viewports, // const std::vector<VkViewport>& viewports
592 scissors, // const std::vector<VkRect2D>& scissors
593 topology, // const VkPrimitiveTopology topology
594 0u, // const deUint32 subpass
595 0u, // const deUint32 patchControlPoints
596 &vertexInputStateParams); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
597 }
598
clear(VkClearColorValue color)599 void ExternalMemoryHostRenderImageTestInstance::clear (VkClearColorValue color)
600 {
601 const struct VkImageSubresourceRange subRangeColor =
602 {
603 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
604 0u, // deUint32 baseMipLevel
605 1u, // deUint32 mipLevels
606 0u, // deUint32 baseArrayLayer
607 1u, // deUint32 arraySize
608 };
609 const VkImageMemoryBarrier imageBarrier =
610 {
611 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
612 DE_NULL, // const void* pNext
613 0u, // VkAccessFlags srcAccessMask
614 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
615 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout
616 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout
617 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex
618 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex
619 *m_image, // VkImage image
620 subRangeColor // VkImageSubresourceRange subresourceRange
621 };
622
623 m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, DE_FALSE, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
624 m_vkd.cmdClearColorImage(*m_cmdBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &color, 1, &subRangeColor);
625 }
626
draw()627 void ExternalMemoryHostRenderImageTestInstance::draw ()
628 {
629 const struct VkImageSubresourceRange subRangeColor =
630 {
631 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
632 0u, // deUint32 baseMipLevel
633 1u, // deUint32 mipLevels
634 0u, // deUint32 baseArrayLayer
635 1u, // deUint32 arraySize
636 };
637 const VkImageMemoryBarrier imageBarrier =
638 {
639 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType
640 DE_NULL, // const void* pNext
641 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
642 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask
643 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout
644 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout
645 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex
646 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex
647 *m_image, // VkImage image
648 subRangeColor // VkImageSubresourceRange subresourceRange
649 };
650 m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, DE_FALSE, 0u, DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
651
652 beginRenderPass(m_vkd, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, 75, 100), tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f));
653 m_vkd.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
654 m_vkd.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &(*m_descriptorSet), 0, DE_NULL);
655 m_vkd.cmdDraw(*m_cmdBuffer, 4, 1, 0, 0);
656 endRenderPass(m_vkd, *m_cmdBuffer);
657 }
658
copyResultImagetoBuffer()659 void ExternalMemoryHostRenderImageTestInstance::copyResultImagetoBuffer ()
660 {
661 copyImageToBuffer(m_vkd, *m_cmdBuffer, *m_image, *m_resultBuffer, tcu::IVec2(100, 100));
662 }
663
prepareReferenceImage(tcu::PixelBufferAccess & reference)664 void ExternalMemoryHostRenderImageTestInstance::prepareReferenceImage (tcu::PixelBufferAccess& reference)
665 {
666 for (int w=0; w < 100; w++)
667 for (int h = 0; h < 100; h++)
668 {
669 if (w < 50) reference.setPixel(tcu::Vec4(0, 1, 0, 1), w, h);
670 if ((w >= 50) && (w < 75)) reference.setPixel(tcu::Vec4(1, 0, 0, 1), w, h);
671 if (w >=75) reference.setPixel(tcu::Vec4(0, 0, 1, 1), w, h);
672 }
673 }
674
createRenderPass()675 Move<VkRenderPass> ExternalMemoryHostRenderImageTestInstance::createRenderPass ()
676 {
677 const VkAttachmentDescription colorAttachmentDescription =
678 {
679 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
680 m_testParams.m_format, // VkFormat format
681 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
682 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp
683 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
684 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
685 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
686 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout
687 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
688 };
689
690 std::vector<VkAttachmentDescription> attachmentDescriptions;
691 attachmentDescriptions.push_back(colorAttachmentDescription);
692
693 const VkAttachmentReference colorAttachmentRef =
694 {
695 0u, // deUint32 attachment
696 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout
697 };
698
699 const VkSubpassDescription subpassDescription =
700 {
701 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
702 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
703 0u, // deUint32 inputAttachmentCount
704 DE_NULL, // const VkAttachmentReference* pInputAttachments
705 1u, // deUint32 colorAttachmentCount
706 &colorAttachmentRef, // const VkAttachmentReference* pColorAttachments
707 DE_NULL, // const VkAttachmentReference* pResolveAttachments
708 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
709 0u, // deUint32 preserveAttachmentCount
710 DE_NULL // const deUint32* pPreserveAttachments
711 };
712
713 const VkRenderPassCreateInfo renderPassInfo =
714 {
715 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType
716 DE_NULL, // const void* pNext
717 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
718 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount
719 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments
720 1u, // deUint32 subpassCount
721 &subpassDescription, // const VkSubpassDescription* pSubpasses
722 0u, // deUint32 dependencyCount
723 DE_NULL // const VkSubpassDependency* pDependencies
724 };
725
726 return vk::createRenderPass(m_vkd, m_device, &renderPassInfo);
727 }
728
ExternalMemoryHostSynchronizationTestInstance(Context & context,TestParams testParams)729 ExternalMemoryHostSynchronizationTestInstance::ExternalMemoryHostSynchronizationTestInstance (Context& context, TestParams testParams)
730 : ExternalMemoryHostRenderImageTestInstance (context, testParams)
731 {
732 }
733
iterate()734 tcu::TestStatus ExternalMemoryHostSynchronizationTestInstance::iterate ()
735 {
736 DE_ASSERT(m_testParams.m_format == VK_FORMAT_R8G8B8A8_UNORM);
737
738 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
739 const VkDeviceSize dataBufferSize = 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
740 void* pointerReturnedByMapMemory;
741 deUint32 hostPointerMemoryTypeBits;
742 deUint32 memoryTypeIndexToTest;
743 VkMemoryRequirements bufferMemoryRequirements;
744
745 m_dataBuffer = createDataBuffer();
746
747 //check memory requirements
748 bufferMemoryRequirements = getBufferMemoryRequirements(m_vkd, m_device, *m_dataBuffer);
749 VkDeviceSize requiredSize = bufferMemoryRequirements.size;
750 //reallocate memory if needed
751 if (requiredSize > m_allocationSize)
752 {
753 VkDeviceSize newHostAllocationSize = VkDeviceSize(deCeilFloatToInt32((float(requiredSize) / float(m_minImportedHostPointerAlignment))) * m_minImportedHostPointerAlignment);
754
755 m_log << tcu::TestLog::Message << "Realloc needed (required size: " << requiredSize << "). "
756 << "New host allocation size: " << newHostAllocationSize << ")." << tcu::TestLog::EndMessage;
757
758 m_hostMemoryAlloc = deAlignedRealloc(m_hostMemoryAlloc, (size_t)newHostAllocationSize, (size_t)m_minImportedHostPointerAlignment);
759 m_allocationSize = newHostAllocationSize;
760 }
761
762 //check if reallocation is successfull
763 if (!m_hostMemoryAlloc)
764 TCU_FAIL("Failed to reallocate memory block.");
765
766 DE_ASSERT(deIsAlignedPtr(m_hostMemoryAlloc, (deUintptr)m_minImportedHostPointerAlignment));
767
768 //find the usable memory type index
769 hostPointerMemoryTypeBits = getHostPointerMemoryTypeBits(m_hostMemoryAlloc);
770 if (findCompatibleMemoryTypeIndexToTest(bufferMemoryRequirements.memoryTypeBits, hostPointerMemoryTypeBits, &memoryTypeIndexToTest))
771 m_deviceMemoryAllocatedFromHostPointer = allocateMemoryFromHostPointer(memoryTypeIndexToTest);
772 else
773 TCU_THROW(NotSupportedError, "Compatible memory type not found");
774
775 VK_CHECK(m_vkd.bindBufferMemory(m_device, *m_dataBuffer, *m_deviceMemoryAllocatedFromHostPointer, 0));
776
777 m_resultBuffer = createBindMemoryResultBuffer();
778 m_cmdPool = createCommandPool(m_vkd, m_device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
779 m_cmdBuffer = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
780 m_cmdBufferCopy = allocateCommandBuffer(m_vkd, m_device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
781
782 m_event = createEvent(m_vkd, m_device);
783 m_fence_1 = createFence(m_vkd, m_device);
784 m_fence_2 = createFence(m_vkd, m_device);
785
786 //record first command buffer
787 beginCommandBuffer(m_vkd, *m_cmdBuffer);
788 fillBuffer();
789 prepareBufferForHostAccess();
790 endCommandBuffer(m_vkd, *m_cmdBuffer);
791
792 //record second command buffer
793 beginCommandBuffer(m_vkd, *m_cmdBufferCopy);
794 copyResultBuffertoBuffer();
795 endCommandBuffer(m_vkd, *m_cmdBufferCopy);
796
797 submitCommands(*m_cmdBuffer, *m_fence_1);
798 submitCommands(*m_cmdBufferCopy, *m_fence_2);
799
800 //wait for fence_1 and modify image on host
801 VK_CHECK(m_vkd.waitForFences(m_device, 1u, &m_fence_1.get(), DE_TRUE, ~0ull));
802 pointerReturnedByMapMemory = mapMemory(m_vkd, m_device, *m_deviceMemoryAllocatedFromHostPointer, 0, dataBufferSize, 0);
803 invalidateMappedMemoryRange(m_vkd, m_device, *m_deviceMemoryAllocatedFromHostPointer, 0, dataBufferSize);
804 tcu::PixelBufferAccess bufferSurface(mapVkFormat(m_testParams.m_format), 100, 100, 1, (100 * vk::mapVkFormat(m_testParams.m_format).getPixelSize()), 0, m_hostMemoryAlloc);
805 prepareReferenceImage(bufferSurface);
806 flushMappedMemoryRange(m_vkd, m_device, *m_deviceMemoryAllocatedFromHostPointer, 0, dataBufferSize);
807 //compare memory pointed by both pointers
808 if (deMemCmp(m_hostMemoryAlloc, pointerReturnedByMapMemory, (size_t)dataBufferSize) != 0)
809 TCU_FAIL("Failed memcmp check.");
810 m_vkd.unmapMemory(m_device, *m_deviceMemoryAllocatedFromHostPointer);
811 VK_CHECK(m_vkd.setEvent(m_device, *m_event));
812
813 //wait for fence_2 before checking result
814 VK_CHECK(m_vkd.waitForFences(m_device, 1u, &m_fence_2.get(), DE_TRUE, ~0ull));
815
816 void * bufferDataPointer = static_cast<char*>(m_resultBufferAllocation->getHostPtr()) + m_resultBufferAllocation->getOffset();
817 tcu::ConstPixelBufferAccess result(mapVkFormat(m_testParams.m_format), tcu::IVec3(100, 100, 1), bufferDataPointer);
818
819 std::vector<float> referenceData((unsigned int)dataBufferSize, 0);
820 tcu::PixelBufferAccess reference(mapVkFormat(m_testParams.m_format), tcu::IVec3(100, 100, 1), referenceData.data());
821
822 prepareReferenceImage(reference);
823
824 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Comparison", "Comparison", reference, result, tcu::Vec4(0.01f), tcu::COMPARE_LOG_ON_ERROR))
825 return tcu::TestStatus::fail("Fail");
826
827 return tcu::TestStatus::pass("Pass");
828 }
829
prepareBufferForHostAccess()830 void ExternalMemoryHostSynchronizationTestInstance::prepareBufferForHostAccess ()
831 {
832 VkDeviceSize size = 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
833 const VkBufferMemoryBarrier bufferBarrier =
834 {
835 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
836 DE_NULL, // const void* pNext;
837 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
838 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags dstAccessMask;
839 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
840 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
841 *m_dataBuffer, // VkBuffer buffer;
842 0u, // VkDeviceSize offset;
843 size // VkDeviceSize size;
844 };
845
846 m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT, DE_FALSE, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
847 }
848
copyResultBuffertoBuffer()849 void ExternalMemoryHostSynchronizationTestInstance::copyResultBuffertoBuffer ()
850 {
851 VkDeviceSize size = 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
852 const VkBufferMemoryBarrier bufferBarrier =
853 {
854 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
855 DE_NULL, // const void* pNext;
856 VK_ACCESS_HOST_WRITE_BIT, // VkAccessFlags srcAccessMask;
857 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask;
858 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
859 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
860 *m_dataBuffer, // VkBuffer buffer;
861 0u, // VkDeviceSize offset;
862 size // VkDeviceSize size;
863 };
864
865 const VkBufferCopy region_all =
866 {
867 0, //VkDeviceSize srcOffset;
868 0, //VkDeviceSize dstOffset;
869 size //VkDeviceSize size;
870 };
871
872 m_vkd.cmdWaitEvents(*m_cmdBufferCopy, 1, &m_event.get(), VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, DE_NULL, 1, &bufferBarrier, 0, DE_NULL);
873 m_vkd.cmdCopyBuffer(*m_cmdBufferCopy, *m_dataBuffer, *m_resultBuffer, 1, ®ion_all);
874 }
875
submitCommands(VkCommandBuffer commandBuffer,VkFence fence)876 void ExternalMemoryHostSynchronizationTestInstance::submitCommands (VkCommandBuffer commandBuffer, VkFence fence)
877 {
878 const VkSubmitInfo submitInfo =
879 {
880 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType
881 DE_NULL, // const void* pNext
882 0u, // deUint32 waitSemaphoreCount
883 DE_NULL, // const VkSemaphore* pWaitSemaphores
884 (const VkPipelineStageFlags*)DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask
885 1u, // deUint32 commandBufferCount
886 &commandBuffer, // const VkCommandBuffer* pCommandBuffers
887 0u, // deUint32 signalSemaphoreCount
888 DE_NULL, // const VkSemaphore* pSignalSemaphores
889 };
890
891 VK_CHECK(m_vkd.queueSubmit(m_queue, 1u, &submitInfo, fence));
892 }
893
createDataBuffer()894 Move<VkBuffer> ExternalMemoryHostSynchronizationTestInstance::createDataBuffer ()
895 {
896 VkDeviceSize size = 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
897 const VkBufferCreateInfo dataBufferCreateInfo =
898 {
899 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
900 DE_NULL, // const void* pNext
901 0, // VkBufferCreateFlags flag
902 size, // VkDeviceSize size
903 VK_BUFFER_USAGE_TRANSFER_DST_BIT |
904 VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // VkBufferUsageFlags usage
905 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
906 0, // deUint32 queueFamilyCount
907 DE_NULL // const deUint32* pQueueFamilyIndices
908 };
909 return vk::createBuffer(m_vkd, m_device, &dataBufferCreateInfo, DE_NULL);
910 }
911
fillBuffer()912 void ExternalMemoryHostSynchronizationTestInstance::fillBuffer ()
913 {
914 VkDeviceSize size = 10000 * vk::mapVkFormat(m_testParams.m_format).getPixelSize();
915 const VkBufferMemoryBarrier bufferBarrier =
916 {
917 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
918 DE_NULL, // const void* pNext;
919 0u, // VkAccessFlags srcAccessMask;
920 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
921 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
922 VK_QUEUE_FAMILY_IGNORED, // deUint32 dstQueueFamilyIndex;
923 *m_dataBuffer, // VkBuffer buffer;
924 0u, // VkDeviceSize offset;
925 size // VkDeviceSize size;
926 };
927
928 m_vkd.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, DE_FALSE, 0u, DE_NULL, 1u, &bufferBarrier, 0u, DE_NULL);
929 m_vkd.cmdFillBuffer(*m_cmdBuffer, *m_dataBuffer, 0, size, 0xFFFFFFFF);
930 }
931
932 struct AddPrograms
933 {
initvkt::memory::__anon67350ce20111::AddPrograms934 void init (vk::SourceCollections& sources, TestParams testParams) const
935 {
936 //unused parameter
937 DE_UNREF(testParams);
938
939 const char* const vertexShader =
940 "#version 430\n"
941
942 "layout(std430, binding = 0) buffer BufferPos {\n"
943 "vec4 p[100];\n"
944 "} pos;\n"
945
946 "out gl_PerVertex{\n"
947 "vec4 gl_Position;\n"
948 "};\n"
949
950 "void main() {\n"
951 "gl_Position = pos.p[gl_VertexIndex];\n"
952 "}\n";
953
954 sources.glslSources.add("position_only.vert")
955 << glu::VertexSource(vertexShader);
956
957 const char* const fragmentShader =
958 "#version 430\n"
959
960 "layout(location = 0) out vec4 my_FragColor;\n"
961
962 "void main() {\n"
963 "my_FragColor = vec4(0,1,0,1);\n"
964 "}\n";
965
966 sources.glslSources.add("only_color_out.frag")
967 << glu::FragmentSource(fragmentShader);
968 }
969 };
970
971 } // unnamed namespace
972
createMemoryExternalMemoryHostTests(tcu::TestContext & testCtx)973 tcu::TestCaseGroup* createMemoryExternalMemoryHostTests (tcu::TestContext& testCtx)
974 {
975 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "external_memory_host", "VK_EXT_external_memory_host extension tests."));
976 de::MovePtr<tcu::TestCaseGroup> simpleAllocation(new tcu::TestCaseGroup(testCtx, "simple_allocation", "simple allocation tests."));
977 de::MovePtr<tcu::TestCaseGroup> bind_image_memory_and_render(new tcu::TestCaseGroup(testCtx, "bind_image_memory_and_render", "render tests."));
978 de::MovePtr<tcu::TestCaseGroup> with_zero_offset(new tcu::TestCaseGroup(testCtx, "with_zero_offset", "bind object with zero offset specified"));
979 de::MovePtr<tcu::TestCaseGroup> with_non_zero_offset(new tcu::TestCaseGroup(testCtx, "with_non_zero_offset", "bind object with zero offset specified"));
980 de::MovePtr<tcu::TestCaseGroup> synchronization(new tcu::TestCaseGroup(testCtx, "synchronization", "synchronization tests."));
981
982 //test cases:
983 simpleAllocation->addChild(new InstanceFactory1<ExternalMemoryHostBaseTestInstance, VkDeviceSize> (testCtx, tcu::NODETYPE_SELF_VALIDATE, "minImportedHostPointerAlignment_x1",
984 "allocate minImportedHostPointerAlignment multiplied by 1", 1));
985 simpleAllocation->addChild(new InstanceFactory1<ExternalMemoryHostBaseTestInstance, VkDeviceSize> (testCtx, tcu::NODETYPE_SELF_VALIDATE, "minImportedHostPointerAlignment_x3",
986 "allocate minImportedHostPointerAlignment multiplied by 3", 3));
987 group ->addChild(simpleAllocation.release());
988
989 const VkFormat testFormats[] = {
990 VK_FORMAT_R8G8B8A8_UNORM,
991 VK_FORMAT_R16G16B16A16_UNORM,
992 VK_FORMAT_R16G16B16A16_SFLOAT,
993 VK_FORMAT_R32G32B32A32_SFLOAT
994 };
995
996 const std::string testNames[] = {
997 "r8g8b8a8_unorm",
998 "r16g16b16a16_unorm",
999 "r16g16b16a16_sfloat",
1000 "r32g32b32a32_sfloat"
1001 };
1002
1003 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(testFormats); formatNdx++)
1004 {
1005 std::string testName = testNames[formatNdx];
1006 with_zero_offset->addChild(new InstanceFactory1<ExternalMemoryHostRenderImageTestInstance, TestParams, AddPrograms> (testCtx, tcu::NODETYPE_SELF_VALIDATE,
1007 testName, testName, AddPrograms(),
1008 TestParams(testFormats[formatNdx])));
1009 }
1010 bind_image_memory_and_render->addChild(with_zero_offset.release());
1011
1012 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(testFormats); formatNdx++)
1013 {
1014 std::string testName = testNames[formatNdx];
1015 with_non_zero_offset->addChild(new InstanceFactory1<ExternalMemoryHostRenderImageTestInstance, TestParams, AddPrograms> (testCtx, tcu::NODETYPE_SELF_VALIDATE,
1016 testName, testName, AddPrograms(),
1017 TestParams(testFormats[formatNdx], true)));
1018 }
1019 bind_image_memory_and_render->addChild(with_non_zero_offset.release());
1020
1021 group->addChild(bind_image_memory_and_render.release());
1022
1023 synchronization->addChild(new InstanceFactory1<ExternalMemoryHostSynchronizationTestInstance, TestParams, AddPrograms> (testCtx, tcu::NODETYPE_SELF_VALIDATE,
1024 "synchronization", "synchronization", AddPrograms(),
1025 TestParams(testFormats[0], true)));
1026 group->addChild(synchronization.release());
1027 return group.release();
1028 }
1029
1030 } // memory
1031 } // vkt
1032