1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 Google Inc.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Platform Synchronization tests
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSynchronizationSmokeTests.hpp"
25
26 #include "vktTestCaseUtil.hpp"
27 #include "vktCustomInstancesDevices.hpp"
28
29 #include "vkPlatform.hpp"
30 #include "vkStrUtil.hpp"
31 #include "vkRef.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkDeviceUtil.hpp"
34 #include "vkCmdUtil.hpp"
35
36 #include "tcuTestLog.hpp"
37 #include "tcuFormatUtil.hpp"
38 #include "tcuCommandLine.hpp"
39
40 #include "deUniquePtr.hpp"
41 #include "deThread.hpp"
42 #include "vkMemUtil.hpp"
43 #include "vkQueryUtil.hpp"
44 #include "vkPrograms.hpp"
45 #include "vkTypeUtil.hpp"
46 #include "vkCmdUtil.hpp"
47
48 #include <limits>
49
50 namespace vkt
51 {
52 namespace synchronization
53 {
54
55 using namespace vk;
56 using namespace tcu;
57
58 namespace
59 {
60
61 using std::vector;
62 using std::string;
63 using tcu::TestLog;
64 using de::UniquePtr;
65 using de::MovePtr;
66
67 static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds
68
buildShaders(SourceCollections & shaderCollection)69 void buildShaders (SourceCollections& shaderCollection)
70 {
71 shaderCollection.glslSources.add("glslvert") <<
72 glu::VertexSource(
73 "#version 310 es\n"
74 "precision mediump float;\n"
75 "layout (location = 0) in vec4 vertexPosition;\n"
76 "void main()\n"
77 "{\n"
78 " gl_Position = vertexPosition;\n"
79 "}\n");
80
81 shaderCollection.glslSources.add("glslfrag") <<
82 glu::FragmentSource(
83 "#version 310 es\n"
84 "precision mediump float;\n"
85 "layout (location = 0) out vec4 outputColor;\n"
86 "void main()\n"
87 "{\n"
88 " outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
89 "}\n");
90 }
91
createTestDevice(const PlatformInterface & vkp,VkInstance instance,const InstanceInterface & vki,VkPhysicalDevice physicalDevice,bool validationEnabled,deUint32 * outQueueFamilyIndex)92 Move<VkDevice> createTestDevice (const PlatformInterface& vkp, VkInstance instance, const InstanceInterface& vki, VkPhysicalDevice physicalDevice, bool validationEnabled, deUint32 *outQueueFamilyIndex)
93 {
94 VkDeviceQueueCreateInfo queueInfo;
95 VkDeviceCreateInfo deviceInfo;
96 size_t queueNdx;
97 const deUint32 queueCount = 2u;
98 const float queuePriority[queueCount] = { 1.0f, 1.0f };
99
100 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
101 const VkPhysicalDeviceFeatures physicalDeviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice);
102
103 for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
104 {
105 if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && (queueProps[queueNdx].queueCount >= queueCount))
106 break;
107 }
108
109 if (queueNdx >= queueProps.size())
110 {
111 // No queue family index found
112 std::ostringstream msg;
113 msg << "Cannot create device with " << queueCount << " graphics queues";
114
115 throw tcu::NotSupportedError(msg.str());
116 }
117
118 deMemset(&queueInfo, 0, sizeof(queueInfo));
119 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
120
121 deMemset(&queueInfo, 0xcd, sizeof(queueInfo));
122 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
123 queueInfo.pNext = DE_NULL;
124 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
125 queueInfo.queueFamilyIndex = (deUint32)queueNdx;
126 queueInfo.queueCount = queueCount;
127 queueInfo.pQueuePriorities = queuePriority;
128
129 deMemset(&deviceInfo, 0xcd, sizeof(deviceInfo));
130 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
131 deviceInfo.pNext = DE_NULL;
132 deviceInfo.flags = (VkDeviceCreateFlags)0u;
133 deviceInfo.queueCreateInfoCount = 1u;
134 deviceInfo.pQueueCreateInfos = &queueInfo;
135 deviceInfo.enabledExtensionCount = 0u;
136 deviceInfo.ppEnabledExtensionNames = DE_NULL;
137 deviceInfo.enabledLayerCount = 0u;
138 deviceInfo.ppEnabledLayerNames = DE_NULL;
139 deviceInfo.pEnabledFeatures = &physicalDeviceFeatures;
140
141 *outQueueFamilyIndex = queueInfo.queueFamilyIndex;
142
143 return createCustomDevice(validationEnabled, vkp, instance, vki, physicalDevice, &deviceInfo);
144 };
145
146 struct BufferParameters
147 {
148 const void* memory;
149 VkDeviceSize size;
150 VkBufferUsageFlags usage;
151 VkSharingMode sharingMode;
152 deUint32 queueFamilyCount;
153 const deUint32* queueFamilyIndex;
154 VkAccessFlags inputBarrierFlags;
155 };
156
157 struct Buffer
158 {
159 MovePtr<Allocation> allocation;
160 vector<VkMemoryBarrier> memoryBarrier;
161 vk::Move<VkBuffer> buffer;
162 };
163
createVulkanBuffer(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const BufferParameters & bufferParameters,Buffer & buffer,MemoryRequirement visibility)164 void createVulkanBuffer (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
165 {
166 VkBufferCreateInfo bufferCreateParams;
167
168 deMemset(&bufferCreateParams, 0xcd, sizeof(bufferCreateParams));
169 bufferCreateParams.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
170 bufferCreateParams.pNext = DE_NULL;
171 bufferCreateParams.flags = 0;
172 bufferCreateParams.size = bufferParameters.size;
173 bufferCreateParams.usage = bufferParameters.usage;
174 bufferCreateParams.sharingMode = bufferParameters.sharingMode;
175 bufferCreateParams.queueFamilyIndexCount = bufferParameters.queueFamilyCount;
176 bufferCreateParams.pQueueFamilyIndices = bufferParameters.queueFamilyIndex;
177
178 buffer.buffer = createBuffer(vkd, device, &bufferCreateParams);
179 buffer.allocation = allocator.allocate(getBufferMemoryRequirements(vkd, device, *buffer.buffer), visibility);
180
181 VK_CHECK(vkd.bindBufferMemory(device, *buffer.buffer, buffer.allocation->getMemory(), buffer.allocation->getOffset()));
182
183 // If caller provides a host memory buffer for the allocation, then go
184 // ahead and copy the provided data into the allocation and update the
185 // barrier list with the associated access
186 if (bufferParameters.memory != DE_NULL)
187 {
188 VkMemoryBarrier barrier;
189
190 deMemcpy(buffer.allocation->getHostPtr(), bufferParameters.memory, (size_t)bufferParameters.size);
191 flushAlloc(vkd, device, *buffer.allocation);
192
193 deMemset(&barrier, 0xcd, sizeof(barrier));
194 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
195 barrier.pNext = DE_NULL;
196 barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
197 barrier.dstAccessMask = bufferParameters.inputBarrierFlags;
198
199 buffer.memoryBarrier.push_back(barrier);
200 }
201 }
202
203 struct ImageParameters
204 {
205 VkImageType imageType;
206 VkFormat format;
207 VkExtent3D extent3D;
208 deUint32 mipLevels;
209 VkSampleCountFlagBits samples;
210 VkImageTiling tiling;
211 VkBufferUsageFlags usage;
212 VkSharingMode sharingMode;
213 deUint32 queueFamilyCount;
214 const deUint32* queueFamilyNdxList;
215 VkImageLayout initialLayout;
216 VkImageLayout finalLayout;
217 VkAccessFlags barrierInputMask;
218 };
219
220 struct Image
221 {
222 vk::Move<VkImage> image;
223 vk::Move<VkImageView> imageView;
224 MovePtr<Allocation> allocation;
225 vector<VkImageMemoryBarrier> imageMemoryBarrier;
226 };
227
createVulkanImage(const DeviceInterface & vkd,VkDevice device,Allocator & allocator,const ImageParameters & imageParameters,Image & image,MemoryRequirement visibility)228 void createVulkanImage (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
229 {
230 VkComponentMapping componentMap;
231 VkImageSubresourceRange subresourceRange;
232 VkImageViewCreateInfo imageViewCreateInfo;
233 VkImageCreateInfo imageCreateParams;
234 VkImageMemoryBarrier imageBarrier;
235
236 deMemset(&imageCreateParams, 0xcd, sizeof(imageCreateParams));
237 imageCreateParams.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
238 imageCreateParams.pNext = DE_NULL;
239 imageCreateParams.flags = 0;
240 imageCreateParams.imageType = imageParameters.imageType;
241 imageCreateParams.format = imageParameters.format;
242 imageCreateParams.extent = imageParameters.extent3D;
243 imageCreateParams.mipLevels = imageParameters.mipLevels;
244 imageCreateParams.arrayLayers = 1;
245 imageCreateParams.samples = imageParameters.samples;
246 imageCreateParams.tiling = imageParameters.tiling;
247 imageCreateParams.usage = imageParameters.usage;
248 imageCreateParams.sharingMode = imageParameters.sharingMode;
249 imageCreateParams.queueFamilyIndexCount = imageParameters.queueFamilyCount;
250 imageCreateParams.pQueueFamilyIndices = imageParameters.queueFamilyNdxList;
251 imageCreateParams.initialLayout = imageParameters.initialLayout;
252
253 image.image = createImage(vkd, device, &imageCreateParams);
254 image.allocation = allocator.allocate(getImageMemoryRequirements(vkd, device, *image.image), visibility);
255
256 VK_CHECK(vkd.bindImageMemory(device, *image.image, image.allocation->getMemory(), image.allocation->getOffset()));
257
258 componentMap.r = VK_COMPONENT_SWIZZLE_R;
259 componentMap.g = VK_COMPONENT_SWIZZLE_G;
260 componentMap.b = VK_COMPONENT_SWIZZLE_B;
261 componentMap.a = VK_COMPONENT_SWIZZLE_A;
262
263 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
264 subresourceRange.baseMipLevel = 0;
265 subresourceRange.levelCount = imageParameters.mipLevels;
266 subresourceRange.baseArrayLayer = 0;
267 subresourceRange.layerCount = 1;
268
269 deMemset(&imageViewCreateInfo, 0xcd, sizeof(imageViewCreateInfo));
270 imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
271 imageViewCreateInfo.pNext = DE_NULL;
272 imageViewCreateInfo.flags = 0;
273 imageViewCreateInfo.image = image.image.get();
274 imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
275 imageViewCreateInfo.format = imageParameters.format;
276 imageViewCreateInfo.components = componentMap;
277 imageViewCreateInfo.subresourceRange = subresourceRange;
278
279 image.imageView = createImageView(vkd, device, &imageViewCreateInfo);
280
281 deMemset(&imageBarrier, 0xcd, sizeof(imageBarrier));
282 imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
283 imageBarrier.pNext = DE_NULL;
284 imageBarrier.srcAccessMask = 0;
285 imageBarrier.dstAccessMask = imageParameters.barrierInputMask;
286 imageBarrier.oldLayout = imageParameters.initialLayout;
287 imageBarrier.newLayout = imageParameters.finalLayout;
288 imageBarrier.srcQueueFamilyIndex = imageParameters.queueFamilyNdxList[0];
289 imageBarrier.dstQueueFamilyIndex = imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
290 imageBarrier.image = image.image.get();
291 imageBarrier.subresourceRange = subresourceRange;
292
293 image.imageMemoryBarrier.push_back(imageBarrier);
294 }
295
296 struct RenderPassParameters
297 {
298 VkFormat colorFormat;
299 VkSampleCountFlagBits colorSamples;
300 };
301
createColorOnlyRenderPass(const DeviceInterface & vkd,VkDevice device,const RenderPassParameters & renderPassParameters,vk::Move<VkRenderPass> & renderPass)302 void createColorOnlyRenderPass (const DeviceInterface& vkd, VkDevice device, const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
303 {
304 VkAttachmentDescription colorAttachmentDesc;
305 VkAttachmentReference colorAttachmentRef;
306 VkAttachmentReference stencilAttachmentRef;
307 VkSubpassDescription subpassDesc;
308 VkRenderPassCreateInfo renderPassParams;
309 VkRenderPass newRenderPass;
310
311 colorAttachmentDesc.flags = 0;
312 colorAttachmentDesc.format = renderPassParameters.colorFormat;
313 colorAttachmentDesc.samples = renderPassParameters.colorSamples;
314 colorAttachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
315 colorAttachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
316 colorAttachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
317 colorAttachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
318 colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
319 colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
320
321 colorAttachmentRef.attachment = 0;
322 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
323
324 stencilAttachmentRef.attachment = VK_ATTACHMENT_UNUSED;
325 stencilAttachmentRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
326
327 subpassDesc.flags = 0;
328 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
329 subpassDesc.inputAttachmentCount = 0;
330 subpassDesc.pInputAttachments = DE_NULL;
331 subpassDesc.colorAttachmentCount = 1;
332 subpassDesc.pColorAttachments = &colorAttachmentRef;
333 subpassDesc.pResolveAttachments = DE_NULL;
334 subpassDesc.pDepthStencilAttachment = &stencilAttachmentRef;
335 subpassDesc.preserveAttachmentCount = 0;
336 subpassDesc.pPreserveAttachments = DE_NULL;
337
338 deMemset(&renderPassParams, 0xcd, sizeof(renderPassParams));
339 renderPassParams.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
340 renderPassParams.pNext = DE_NULL;
341 renderPassParams.flags = 0;
342 renderPassParams.attachmentCount = 1;
343 renderPassParams.pAttachments = &colorAttachmentDesc;
344 renderPassParams.subpassCount = 1;
345 renderPassParams.pSubpasses = &subpassDesc;
346 renderPassParams.dependencyCount = 0;
347 renderPassParams.pDependencies = DE_NULL;
348
349 renderPass = createRenderPass(vkd, device, &renderPassParams);
350 }
351
352 struct ShaderDescParams
353 {
354 VkShaderModule shaderModule;
355 VkShaderStageFlagBits stage;
356 };
357
358 struct VertexDesc
359 {
360 deUint32 location;
361 VkFormat format;
362 deUint32 stride;
363 deUint32 offset;
364 };
365
createVertexInfo(const vector<VertexDesc> & vertexDesc,vector<VkVertexInputBindingDescription> & bindingList,vector<VkVertexInputAttributeDescription> & attrList,VkPipelineVertexInputStateCreateInfo & vertexInputState)366 void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
367 {
368 for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
369 {
370 deUint32 bindingId = 0;
371 VkVertexInputBindingDescription bindingDesc;
372 VkVertexInputAttributeDescription attrDesc;
373
374 bindingDesc.binding = bindingId;
375 bindingDesc.stride = vertDescIter->stride;
376 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
377 bindingList.push_back(bindingDesc);
378
379 attrDesc.location = vertDescIter->location;
380 attrDesc.binding = bindingId;
381 attrDesc.format = vertDescIter->format;
382 attrDesc.offset = vertDescIter->offset;
383 attrList.push_back(attrDesc);
384
385 bindingId++;
386 }
387
388 deMemset(&vertexInputState, 0xcd, sizeof(vertexInputState));
389 vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
390 vertexInputState.pNext = DE_NULL;
391 vertexInputState.flags = 0u;
392 vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
393 vertexInputState.pVertexBindingDescriptions = &bindingList[0];
394 vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
395 vertexInputState.pVertexAttributeDescriptions = &attrList[0];
396 }
397
createCommandBuffer(const DeviceInterface & deviceInterface,const VkDevice device,const deUint32 queueFamilyNdx,vk::Move<VkCommandBuffer> * commandBufferRef,vk::Move<VkCommandPool> * commandPoolRef)398 void createCommandBuffer (const DeviceInterface& deviceInterface, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef, vk::Move<VkCommandPool>* commandPoolRef)
399 {
400 vk::Move<VkCommandPool> commandPool;
401 VkCommandBufferAllocateInfo commandBufferInfo;
402 VkCommandBuffer commandBuffer;
403
404 commandPool = createCommandPool(deviceInterface, device, 0u, queueFamilyNdx);
405
406 deMemset(&commandBufferInfo, 0xcd, sizeof(commandBufferInfo));
407 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
408 commandBufferInfo.pNext = DE_NULL;
409 commandBufferInfo.commandPool = commandPool.get();
410 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
411 commandBufferInfo.commandBufferCount = 1;
412
413 VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
414 *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, commandPool.get()));
415 *commandPoolRef = commandPool;
416 }
417
createFences(const DeviceInterface & deviceInterface,VkDevice device,bool signaled,deUint32 numFences,VkFence * fence)418 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
419 {
420 VkFenceCreateInfo fenceState;
421 VkFenceCreateFlags signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
422
423 deMemset(&fenceState, 0xcd, sizeof(fenceState));
424 fenceState.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
425 fenceState.pNext = DE_NULL;
426 fenceState.flags = signalFlag;
427
428 for (deUint32 ndx = 0; ndx < numFences; ndx++)
429 VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
430 }
431
destroyFences(const DeviceInterface & deviceInterface,VkDevice device,deUint32 numFences,VkFence * fence)432 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
433 {
434 for (deUint32 ndx = 0; ndx < numFences; ndx++)
435 deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
436 }
437
438 struct RenderInfo
439 {
440 deInt32 width;
441 deInt32 height;
442 deUint32 vertexBufferSize;
443 VkBuffer vertexBuffer;
444 VkImage image;
445 VkCommandBuffer commandBuffer;
446 VkRenderPass renderPass;
447 VkFramebuffer framebuffer;
448 VkPipeline pipeline;
449 deUint32 mipLevels;
450 const deUint32* queueFamilyNdxList;
451 deUint32 queueFamilyNdxCount;
452 bool waitEvent;
453 VkEvent event;
454 vector<VkImageMemoryBarrier>* barriers;
455 };
456
recordRenderPass(const DeviceInterface & deviceInterface,const RenderInfo & renderInfo)457 void recordRenderPass (const DeviceInterface& deviceInterface, const RenderInfo& renderInfo)
458 {
459 const VkDeviceSize bindingOffset = 0;
460 VkImageMemoryBarrier renderBarrier;
461
462 if (renderInfo.waitEvent)
463 deviceInterface.cmdWaitEvents(renderInfo.commandBuffer, 1, &renderInfo.event, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
464
465 beginRenderPass(deviceInterface, renderInfo.commandBuffer, renderInfo.renderPass, renderInfo.framebuffer, makeRect2D(0, 0, renderInfo.width, renderInfo.height), tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f));
466 deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
467 deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
468 deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
469 endRenderPass(deviceInterface, renderInfo.commandBuffer);
470
471 deMemset(&renderBarrier, 0xcd, sizeof(renderBarrier));
472 renderBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
473 renderBarrier.pNext = DE_NULL;
474 renderBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
475 renderBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
476 renderBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
477 renderBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
478 renderBarrier.srcQueueFamilyIndex = renderInfo.queueFamilyNdxList[0];
479 renderBarrier.dstQueueFamilyIndex = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
480 renderBarrier.image = renderInfo.image;
481 renderBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
482 renderBarrier.subresourceRange.baseMipLevel = 0;
483 renderBarrier.subresourceRange.levelCount = renderInfo.mipLevels;
484 renderBarrier.subresourceRange.baseArrayLayer = 0;
485 renderBarrier.subresourceRange.layerCount = 1;
486 renderInfo.barriers->push_back(renderBarrier);
487 }
488
489 struct TransferInfo
490 {
491 VkCommandBuffer commandBuffer;
492 deUint32 width;
493 deUint32 height;
494 VkImage image;
495 VkBuffer buffer;
496 VkDeviceSize size;
497 deUint32 mipLevel;
498 VkOffset3D imageOffset;
499 vector<VkBufferMemoryBarrier>* barriers;
500 };
501
copyToCPU(const DeviceInterface & vkd,TransferInfo * transferInfo)502 void copyToCPU (const DeviceInterface& vkd, TransferInfo* transferInfo)
503 {
504 VkBufferImageCopy copyState;
505
506 copyState.bufferOffset = 0;
507 copyState.bufferRowLength = transferInfo->width;
508 copyState.bufferImageHeight = transferInfo->height;
509 copyState.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
510 copyState.imageSubresource.mipLevel = transferInfo->mipLevel;
511 copyState.imageSubresource.baseArrayLayer = 0;
512 copyState.imageSubresource.layerCount = 1;
513 copyState.imageOffset = transferInfo->imageOffset;
514 copyState.imageExtent.width = (deInt32)(transferInfo->width);
515 copyState.imageExtent.height = (deInt32)(transferInfo->height);
516 copyState.imageExtent.depth = 1;
517
518 vkd.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, ©State);
519
520 {
521 VkBufferMemoryBarrier bufferBarrier;
522 deMemset(&bufferBarrier, 0xcd, sizeof(bufferBarrier));
523 bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
524 bufferBarrier.pNext = DE_NULL;
525 bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
526 bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
527 bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
528 bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
529 bufferBarrier.buffer = transferInfo->buffer;
530 bufferBarrier.offset = 0;
531 bufferBarrier.size = transferInfo->size;
532 transferInfo->barriers->push_back(bufferBarrier);
533 }
534 }
535
536 struct TestContext
537 {
538 const DeviceInterface& vkd;
539 const VkDevice device;
540 const deUint32 queueFamilyIndex;
541 const BinaryCollection& binaryCollection;
542 Allocator& allocator;
543
544 const tcu::Vec4* vertices;
545 deUint32 numVertices;
546 tcu::IVec2 renderDimension;
547 VkFence fences[2];
548 VkDeviceSize renderSize;
549 MovePtr<Allocation> renderReadBuffer;
550 MovePtr<Allocation> vertexBufferAllocation;
551 vk::Move<VkBuffer> vertexBuffer;
552 vk::Move<VkBuffer> renderBuffer;
553 bool waitEvent;
554 VkEvent event;
555 vk::Move<VkImage> image;
556 vk::Move<VkImageView> imageView;
557 vk::Move<VkFramebuffer> framebuffer;
558 vk::Move<VkCommandPool> commandPool;
559 vk::Move<VkCommandBuffer> cmdBuffer;
560 vk::Move<VkRenderPass> renderPass;
561 vk::Move<VkPipelineCache> pipelineCache;
562 vk::Move<VkPipeline> pipeline;
563 MovePtr<Allocation> imageAllocation;
564
TestContextvkt::synchronization::__anona70ccf9a0111::TestContext565 TestContext (const DeviceInterface& vkd_,
566 const VkDevice device_,
567 deUint32 queueFamilyIndex_,
568 const BinaryCollection& binaryCollection_,
569 Allocator& allocator_)
570 : vkd (vkd_)
571 , device (device_)
572 , queueFamilyIndex (queueFamilyIndex_)
573 , binaryCollection (binaryCollection_)
574 , allocator (allocator_)
575 , numVertices (0)
576 , waitEvent (false)
577 {
578 createFences(vkd, device, false, DE_LENGTH_OF_ARRAY(fences), fences);
579 }
580
~TestContextvkt::synchronization::__anona70ccf9a0111::TestContext581 ~TestContext()
582 {
583 destroyFences(vkd, device, DE_LENGTH_OF_ARRAY(fences), fences);
584 }
585 };
586
generateWork(TestContext & testContext)587 void generateWork (TestContext& testContext)
588 {
589 const DeviceInterface& deviceInterface = testContext.vkd;
590 const deUint32 queueFamilyNdx = testContext.queueFamilyIndex;
591
592 // \note VkShaderModule is consumed by vkCreate*Pipelines() so it can be deleted
593 // as pipeline has been constructed.
594 const vk::Unique<VkShaderModule> vertShaderModule (createShaderModule(deviceInterface,
595 testContext.device,
596 testContext.binaryCollection.get("glslvert"),
597 (VkShaderModuleCreateFlags)0));
598
599 const vk::Unique<VkShaderModule> fragShaderModule (createShaderModule(deviceInterface,
600 testContext.device,
601 testContext.binaryCollection.get("glslfrag"),
602 (VkShaderModuleCreateFlags)0));
603 const VkPipelineShaderStageCreateInfo shaderStageParams[] =
604 {
605 {
606 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
607 DE_NULL,
608 (VkPipelineShaderStageCreateFlags)0,
609 VK_SHADER_STAGE_VERTEX_BIT,
610 *vertShaderModule,
611 "main",
612 (const VkSpecializationInfo*)DE_NULL,
613 },
614 {
615 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
616 DE_NULL,
617 (VkPipelineShaderStageCreateFlags)0,
618 VK_SHADER_STAGE_FRAGMENT_BIT,
619 *fragShaderModule,
620 "main",
621 (const VkSpecializationInfo*)DE_NULL,
622 }
623 };
624
625 vk::Move<VkPipelineLayout> layout;
626 vector<ShaderDescParams> shaderDescParams;
627 VertexDesc vertexDesc;
628 vector<VertexDesc> vertexDescList;
629 vector<VkVertexInputAttributeDescription> attrList;
630 vector<VkBufferMemoryBarrier> bufferMemoryBarrier;
631 deUint32 memoryBarrierNdx;
632 deUint32 bufferMemoryBarrierNdx;
633 deUint32 imageMemoryBarrierNdx;
634 vector<VkVertexInputBindingDescription> bindingList;
635 VkPipelineVertexInputStateCreateInfo vertexInputState;
636 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
637 VkPipelineDepthStencilStateCreateInfo depthStencilState;
638 VkPipelineColorBlendAttachmentState blendAttachment;
639 VkPipelineColorBlendStateCreateInfo blendState;
640 VkPipelineLayoutCreateInfo pipelineLayoutState;
641 VkGraphicsPipelineCreateInfo pipelineState;
642 VkPipelineCacheCreateInfo cacheState;
643 VkViewport viewport;
644 VkPipelineViewportStateCreateInfo viewportInfo;
645 VkRect2D scissor;
646 BufferParameters bufferParameters;
647 Buffer buffer;
648 RenderInfo renderInfo;
649 ImageParameters imageParameters;
650 Image image;
651 VkPipelineRasterizationStateCreateInfo rasterState;
652 VkPipelineMultisampleStateCreateInfo multisampleState;
653 VkFramebufferCreateInfo fbState;
654 VkCommandBufferBeginInfo commandBufRecordState;
655 VkCommandBufferInheritanceInfo inheritanceInfo;
656 RenderPassParameters renderPassParameters;
657 TransferInfo transferInfo;
658 vector<void*> barrierList;
659 VkExtent3D extent;
660 vector<VkMemoryBarrier> memoryBarriers;
661 vector<VkBufferMemoryBarrier> bufferBarriers;
662 vector<VkImageMemoryBarrier> imageBarriers;
663
664 memoryBarrierNdx = 0;
665 bufferMemoryBarrierNdx = 0;
666 imageMemoryBarrierNdx = 0;
667 buffer.memoryBarrier.resize(memoryBarrierNdx);
668 bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
669 image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
670
671 memoryBarriers.resize(0);
672 bufferBarriers.resize(0);
673 imageBarriers.resize(0);
674
675 bufferParameters.memory = testContext.vertices;
676 bufferParameters.size = testContext.numVertices * sizeof(tcu::Vec4);
677 bufferParameters.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
678 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
679 bufferParameters.queueFamilyCount = 1;
680 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
681 bufferParameters.inputBarrierFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
682 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
683 testContext.vertexBufferAllocation = buffer.allocation;
684 testContext.vertexBuffer = buffer.buffer;
685
686 bufferParameters.memory = DE_NULL;
687 bufferParameters.size = testContext.renderSize;
688 bufferParameters.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
689 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
690 bufferParameters.queueFamilyCount = 1;
691 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
692 bufferParameters.inputBarrierFlags = 0;
693 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
694 testContext.renderReadBuffer = buffer.allocation;
695 testContext.renderBuffer = buffer.buffer;
696
697 extent.width = testContext.renderDimension.x();
698 extent.height = testContext.renderDimension.y();
699 extent.depth = 1;
700
701 imageParameters.imageType = VK_IMAGE_TYPE_2D;
702 imageParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
703 imageParameters.extent3D = extent;
704 imageParameters.mipLevels = 1;
705 imageParameters.samples = VK_SAMPLE_COUNT_1_BIT;
706 imageParameters.tiling = VK_IMAGE_TILING_OPTIMAL;
707 imageParameters.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
708 imageParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
709 imageParameters.queueFamilyCount = 1;
710 imageParameters.queueFamilyNdxList = &queueFamilyNdx;
711 imageParameters.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
712 imageParameters.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
713 imageParameters.barrierInputMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
714 createVulkanImage(deviceInterface, testContext.device, testContext.allocator, imageParameters, image, MemoryRequirement::Any);
715 testContext.imageAllocation = image.allocation;
716 testContext.image = image.image;
717
718 for (size_t ndx = 0; ndx < image.imageMemoryBarrier.size(); ++ndx)
719 imageBarriers.push_back(image.imageMemoryBarrier[ndx]);
720
721 renderPassParameters.colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
722 renderPassParameters.colorSamples = VK_SAMPLE_COUNT_1_BIT;
723 createColorOnlyRenderPass(deviceInterface, testContext.device, renderPassParameters, testContext.renderPass);
724
725 vertexDesc.location = 0;
726 vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
727 vertexDesc.stride = sizeof(tcu::Vec4);
728 vertexDesc.offset = 0;
729 vertexDescList.push_back(vertexDesc);
730
731 createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
732
733 deMemset(&inputAssemblyState, 0xcd, sizeof(inputAssemblyState));
734 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
735 inputAssemblyState.pNext = DE_NULL;
736 inputAssemblyState.flags = 0u;
737 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
738 inputAssemblyState.primitiveRestartEnable = false;
739
740 viewport.x = 0;
741 viewport.y = 0;
742 viewport.width = (float)testContext.renderDimension.x();
743 viewport.height = (float)testContext.renderDimension.y();
744 viewport.minDepth = 0;
745 viewport.maxDepth = 1;
746
747 scissor.offset.x = 0;
748 scissor.offset.y = 0;
749 scissor.extent.width = testContext.renderDimension.x();
750 scissor.extent.height = testContext.renderDimension.y();
751
752 deMemset(&viewportInfo, 0xcd, sizeof(viewportInfo));
753 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
754 viewportInfo.pNext = DE_NULL;
755 viewportInfo.flags = 0;
756 viewportInfo.viewportCount = 1;
757 viewportInfo.pViewports = &viewport;
758 viewportInfo.scissorCount = 1;
759 viewportInfo.pScissors = &scissor;
760
761 deMemset(&rasterState, 0xcd, sizeof(rasterState));
762 rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
763 rasterState.pNext = DE_NULL;
764 rasterState.flags = 0;
765 rasterState.depthClampEnable = VK_FALSE;
766 rasterState.rasterizerDiscardEnable = VK_FALSE;
767 rasterState.polygonMode = VK_POLYGON_MODE_FILL;
768 rasterState.cullMode = VK_CULL_MODE_NONE;
769 rasterState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
770 rasterState.depthBiasEnable = VK_FALSE;
771 rasterState.lineWidth = 1;
772
773 deMemset(&multisampleState, 0xcd, sizeof(multisampleState));
774 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
775 multisampleState.pNext = DE_NULL;
776 multisampleState.flags = 0;
777 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
778 multisampleState.sampleShadingEnable = VK_FALSE;
779 multisampleState.pSampleMask = DE_NULL;
780 multisampleState.alphaToCoverageEnable = VK_FALSE;
781 multisampleState.alphaToOneEnable = VK_FALSE;
782
783 deMemset(&depthStencilState, 0xcd, sizeof(depthStencilState));
784 depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
785 depthStencilState.pNext = DE_NULL;
786 depthStencilState.flags = 0;
787 depthStencilState.depthTestEnable = VK_FALSE;
788 depthStencilState.depthWriteEnable = VK_FALSE;
789 depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS;
790 depthStencilState.depthBoundsTestEnable = VK_FALSE;
791 depthStencilState.stencilTestEnable = VK_FALSE;
792 depthStencilState.front.failOp = VK_STENCIL_OP_KEEP;
793 depthStencilState.front.passOp = VK_STENCIL_OP_KEEP;
794 depthStencilState.front.depthFailOp = VK_STENCIL_OP_KEEP;
795 depthStencilState.front.compareOp = VK_COMPARE_OP_ALWAYS;
796 depthStencilState.front.compareMask = 0u;
797 depthStencilState.front.writeMask = 0u;
798 depthStencilState.front.reference = 0u;
799 depthStencilState.back = depthStencilState.front;
800
801 deMemset(&blendAttachment, 0xcd, sizeof(blendAttachment));
802 blendAttachment.blendEnable = VK_FALSE;
803 blendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
804 blendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
805 blendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
806 blendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
807 blendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
808 blendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
809 blendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
810
811 deMemset(&blendState, 0xcd, sizeof(blendState));
812 blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
813 blendState.pNext = DE_NULL;
814 blendState.flags = 0;
815 blendState.logicOpEnable = VK_FALSE;
816 blendState.logicOp = VK_LOGIC_OP_COPY;
817 blendState.attachmentCount = 1;
818 blendState.pAttachments = &blendAttachment;
819
820 deMemset(&pipelineLayoutState, 0xcd, sizeof(pipelineLayoutState));
821 pipelineLayoutState.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
822 pipelineLayoutState.pNext = DE_NULL;
823 pipelineLayoutState.flags = 0;
824 pipelineLayoutState.setLayoutCount = 0;
825 pipelineLayoutState.pSetLayouts = DE_NULL;
826 pipelineLayoutState.pushConstantRangeCount = 0;
827 pipelineLayoutState.pPushConstantRanges = DE_NULL;
828 layout = createPipelineLayout(deviceInterface, testContext.device, &pipelineLayoutState, DE_NULL);
829
830 deMemset(&pipelineState, 0xcd, sizeof(pipelineState));
831 pipelineState.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
832 pipelineState.pNext = DE_NULL;
833 pipelineState.flags = 0;
834 pipelineState.stageCount = DE_LENGTH_OF_ARRAY(shaderStageParams);
835 pipelineState.pStages = &shaderStageParams[0];
836 pipelineState.pVertexInputState = &vertexInputState;
837 pipelineState.pInputAssemblyState = &inputAssemblyState;
838 pipelineState.pTessellationState = DE_NULL;
839 pipelineState.pViewportState = &viewportInfo;
840 pipelineState.pRasterizationState = &rasterState;
841 pipelineState.pMultisampleState = &multisampleState;
842 pipelineState.pDepthStencilState = &depthStencilState;
843 pipelineState.pColorBlendState = &blendState;
844 pipelineState.pDynamicState = (const VkPipelineDynamicStateCreateInfo*)DE_NULL;
845 pipelineState.layout = layout.get();
846 pipelineState.renderPass = testContext.renderPass.get();
847 pipelineState.subpass = 0;
848 pipelineState.basePipelineHandle = DE_NULL;
849 pipelineState.basePipelineIndex = 0;
850
851 deMemset(&cacheState, 0xcd, sizeof(cacheState));
852 cacheState.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
853 cacheState.pNext = DE_NULL;
854 cacheState.flags = 0;
855 cacheState.initialDataSize = 0;
856 cacheState.pInitialData = DE_NULL;
857
858 testContext.pipelineCache = createPipelineCache(deviceInterface, testContext.device, &cacheState);
859 testContext.pipeline = createGraphicsPipeline(deviceInterface, testContext.device, testContext.pipelineCache.get(), &pipelineState);
860
861 deMemset(&fbState, 0xcd, sizeof(fbState));
862 fbState.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
863 fbState.pNext = DE_NULL;
864 fbState.flags = 0;
865 fbState.renderPass = testContext.renderPass.get();
866 fbState.attachmentCount = 1;
867 fbState.pAttachments = &image.imageView.get();
868 fbState.width = (deUint32)testContext.renderDimension.x();
869 fbState.height = (deUint32)testContext.renderDimension.y();
870 fbState.layers = 1;
871
872 testContext.framebuffer = createFramebuffer(deviceInterface, testContext.device, &fbState);
873 testContext.imageView = image.imageView;
874
875 deMemset(&inheritanceInfo, 0xcd, sizeof(inheritanceInfo));
876 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
877 inheritanceInfo.pNext = DE_NULL;
878 inheritanceInfo.renderPass = testContext.renderPass.get();
879 inheritanceInfo.subpass = 0;
880 inheritanceInfo.framebuffer = *testContext.framebuffer;
881 inheritanceInfo.occlusionQueryEnable = VK_FALSE;
882 inheritanceInfo.queryFlags = 0u;
883 inheritanceInfo.pipelineStatistics = 0u;
884
885 deMemset(&commandBufRecordState, 0xcd, sizeof(commandBufRecordState));
886 commandBufRecordState.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
887 commandBufRecordState.pNext = DE_NULL;
888 commandBufRecordState.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
889 commandBufRecordState.pInheritanceInfo = &inheritanceInfo;
890 VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
891
892 deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
893 VK_PIPELINE_STAGE_HOST_BIT,
894 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
895 false,
896 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
897 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
898 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
899
900 memoryBarriers.resize(0);
901 bufferBarriers.resize(0);
902 imageBarriers.resize(0);
903
904 renderInfo.width = testContext.renderDimension.x();
905 renderInfo.height = testContext.renderDimension.y();
906 renderInfo.vertexBufferSize = testContext.numVertices;
907 renderInfo.vertexBuffer = testContext.vertexBuffer.get();
908 renderInfo.image = testContext.image.get();
909 renderInfo.commandBuffer = testContext.cmdBuffer.get();
910 renderInfo.renderPass = testContext.renderPass.get();
911 renderInfo.framebuffer = *testContext.framebuffer;
912 renderInfo.pipeline = *testContext.pipeline;
913 renderInfo.mipLevels = 1;
914 renderInfo.queueFamilyNdxList = &queueFamilyNdx;
915 renderInfo.queueFamilyNdxCount = 1;
916 renderInfo.waitEvent = testContext.waitEvent;
917 renderInfo.event = testContext.event;
918 renderInfo.barriers = &imageBarriers;
919 recordRenderPass(deviceInterface, renderInfo);
920
921 deviceInterface.cmdPipelineBarrier( renderInfo.commandBuffer,
922 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
923 VK_PIPELINE_STAGE_TRANSFER_BIT,
924 false,
925 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
926 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
927 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
928
929 memoryBarriers.resize(0);
930 bufferBarriers.resize(0);
931 imageBarriers.resize(0);
932
933 transferInfo.commandBuffer = renderInfo.commandBuffer;
934 transferInfo.width = testContext.renderDimension.x();
935 transferInfo.height = testContext.renderDimension.y();
936 transferInfo.image = renderInfo.image;
937 transferInfo.buffer = testContext.renderBuffer.get();
938 transferInfo.size = testContext.renderSize;
939 transferInfo.mipLevel = 0;
940 transferInfo.imageOffset.x = 0;
941 transferInfo.imageOffset.y = 0;
942 transferInfo.imageOffset.z = 0;
943 transferInfo.barriers = &bufferBarriers;
944 copyToCPU(deviceInterface, &transferInfo);
945
946 deviceInterface.cmdPipelineBarrier( transferInfo.commandBuffer,
947 VK_PIPELINE_STAGE_TRANSFER_BIT,
948 VK_PIPELINE_STAGE_HOST_BIT,
949 false,
950 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
951 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
952 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
953
954 memoryBarriers.resize(0);
955 bufferBarriers.resize(0);
956 imageBarriers.resize(0);
957
958 endCommandBuffer(deviceInterface, transferInfo.commandBuffer);
959 }
960
initSubmitInfo(VkSubmitInfo * submitInfo,deUint32 submitInfoCount)961 static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount)
962 {
963 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
964 {
965 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
966 submitInfo[ndx].pNext = DE_NULL;
967 submitInfo[ndx].waitSemaphoreCount = 0;
968 submitInfo[ndx].pWaitSemaphores = DE_NULL;
969 submitInfo[ndx].pWaitDstStageMask = DE_NULL;
970 submitInfo[ndx].commandBufferCount = 1;
971 submitInfo[ndx].signalSemaphoreCount = 0;
972 submitInfo[ndx].pSignalSemaphores = DE_NULL;
973 }
974 }
975
initTimelineSemaphoreSubmitInfo(VkTimelineSemaphoreSubmitInfo * submitInfo,deUint32 submitInfoCount)976 static void initTimelineSemaphoreSubmitInfo (VkTimelineSemaphoreSubmitInfo* submitInfo, deUint32 submitInfoCount)
977 {
978 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
979 {
980 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO;
981 submitInfo[ndx].pNext = DE_NULL;
982 submitInfo[ndx].waitSemaphoreValueCount = 0;
983 submitInfo[ndx].pWaitSemaphoreValues = DE_NULL;
984 submitInfo[ndx].signalSemaphoreValueCount = 0;
985 submitInfo[ndx].pSignalSemaphoreValues = DE_NULL;
986 }
987 }
988
testFences(Context & context)989 tcu::TestStatus testFences (Context& context)
990 {
991 TestLog& log = context.getTestContext().getLog();
992 const DeviceInterface& deviceInterface = context.getDeviceInterface();
993 const VkQueue queue = context.getUniversalQueue();
994 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
995 VkDevice device = context.getDevice();
996 VkResult waitStatus;
997 VkResult fenceStatus;
998 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), context.getDefaultAllocator());
999 VkSubmitInfo submitInfo;
1000 void* resultImage;
1001
1002 const tcu::Vec4 vertices[] =
1003 {
1004 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1005 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1006 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1007 };
1008
1009 testContext.vertices = vertices;
1010 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
1011 testContext.renderDimension = tcu::IVec2(256, 256);
1012 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1013
1014 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
1015 generateWork(testContext);
1016
1017 initSubmitInfo(&submitInfo, 1);
1018 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
1019
1020 // Default status is unsignaled
1021 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1022 if (fenceStatus != VK_NOT_READY)
1023 {
1024 log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1025 return tcu::TestStatus::fail("Fence in incorrect state");
1026 }
1027 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]);
1028 if (fenceStatus != VK_NOT_READY)
1029 {
1030 log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1031 return tcu::TestStatus::fail("Fence in incorrect state");
1032 }
1033
1034 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1035
1036 // Wait with timeout = 0
1037 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 0u);
1038 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1039 {
1040 // Will most likely end with VK_TIMEOUT
1041 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1042 return tcu::TestStatus::fail("Failed to wait for a single fence");
1043 }
1044
1045 // Wait with a reasonable timeout
1046 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, DEFAULT_TIMEOUT);
1047 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1048 {
1049 // \note Wait can end with a timeout if DEFAULT_TIMEOUT is not sufficient
1050 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1051 return tcu::TestStatus::fail("Failed to wait for a single fence");
1052 }
1053
1054 // Wait for work on fences[0] to actually complete
1055 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, std::numeric_limits<deUint64>::max());
1056 if (waitStatus != VK_SUCCESS)
1057 {
1058 log << TestLog::Message << "testSynchPrimitives failed to wait for a fence" << TestLog::EndMessage;
1059 return tcu::TestStatus::fail("failed to wait for a fence");
1060 }
1061
1062 // Wait until timeout on a fence that has not been submitted
1063 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[1], true, 1);
1064 if (waitStatus != VK_TIMEOUT)
1065 {
1066 log << TestLog::Message << "testSyncPrimitives failed to timeout on wait for single fence" << TestLog::EndMessage;
1067 return tcu::TestStatus::fail("failed to timeout on wait for single fence");
1068 }
1069
1070 // Check that the fence is signaled after the wait
1071 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1072 if (fenceStatus != VK_SUCCESS)
1073 {
1074 log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1075 return tcu::TestStatus::fail("Fence in incorrect state");
1076 }
1077
1078 invalidateAlloc(deviceInterface, device, *testContext.renderReadBuffer);
1079 resultImage = testContext.renderReadBuffer->getHostPtr();
1080
1081 log << TestLog::Image( "result",
1082 "result",
1083 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1084 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1085 testContext.renderDimension.x(),
1086 testContext.renderDimension.y(),
1087 1,
1088 resultImage));
1089
1090 return TestStatus::pass("synchronization-fences passed");
1091 }
1092
testSemaphores(Context & context,VkSemaphoreType semaphoreType)1093 tcu::TestStatus testSemaphores (Context& context, VkSemaphoreType semaphoreType)
1094 {
1095 if (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE_KHR && !context.getTimelineSemaphoreFeatures().timelineSemaphore)
1096 TCU_THROW(NotSupportedError, "Timeline semaphore not supported");
1097
1098 TestLog& log = context.getTestContext().getLog();
1099 const PlatformInterface& platformInterface = context.getPlatformInterface();
1100 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1101 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1102 deUint32 queueFamilyIdx;
1103 vk::Move<VkDevice> device = createTestDevice(platformInterface, context.getInstance(), instanceInterface, physicalDevice, context.getTestContext().getCommandLine().isValidationEnabled(), &queueFamilyIdx);
1104 const DeviceDriver deviceInterface (platformInterface, context.getInstance(), *device);
1105 SimpleAllocator allocator (deviceInterface,
1106 *device,
1107 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice));
1108 const VkQueue queue[2] =
1109 {
1110 getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 0),
1111 getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 1)
1112 };
1113 VkResult testStatus;
1114 TestContext testContext1 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1115 TestContext testContext2 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1116 Unique<VkSemaphore> semaphore (createSemaphoreType(deviceInterface, *device, semaphoreType));
1117 VkSubmitInfo submitInfo[2];
1118 VkTimelineSemaphoreSubmitInfo timelineSubmitInfo[2];
1119 const deUint64 timelineValue = 1u;
1120
1121 void* resultImage;
1122 const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1123
1124 const tcu::Vec4 vertices1[] =
1125 {
1126 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1127 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1128 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1129 };
1130
1131 const tcu::Vec4 vertices2[] =
1132 {
1133 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1134 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1135 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1136 };
1137
1138 testContext1.vertices = vertices1;
1139 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1140 testContext1.renderDimension = tcu::IVec2(256, 256);
1141 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1142
1143 testContext2.vertices = vertices2;
1144 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
1145 testContext2.renderDimension = tcu::IVec2(256, 256);
1146 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1147
1148 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext1.cmdBuffer, &testContext1.commandPool);
1149 generateWork(testContext1);
1150
1151 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext2.cmdBuffer, &testContext2.commandPool);
1152 generateWork(testContext2);
1153
1154 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
1155 initTimelineSemaphoreSubmitInfo(timelineSubmitInfo, DE_LENGTH_OF_ARRAY(timelineSubmitInfo));
1156
1157 // The difference between the two submit infos is that each will use a unique cmd buffer,
1158 // and one will signal a semaphore but not wait on a semaphore, the other will wait on the
1159 // semaphore but not signal a semaphore
1160 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
1161 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
1162
1163 submitInfo[0].signalSemaphoreCount = 1;
1164 submitInfo[0].pSignalSemaphores = &semaphore.get();
1165 timelineSubmitInfo[0].pSignalSemaphoreValues = &timelineValue;
1166 timelineSubmitInfo[0].signalSemaphoreValueCount = 1;
1167 submitInfo[0].pNext = (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE ? &timelineSubmitInfo[0] : DE_NULL);
1168 submitInfo[1].waitSemaphoreCount = 1;
1169 submitInfo[1].pWaitSemaphores = &semaphore.get();
1170 timelineSubmitInfo[1].pWaitSemaphoreValues = &timelineValue;
1171 timelineSubmitInfo[1].waitSemaphoreValueCount = 1;
1172 submitInfo[1].pNext = (semaphoreType == VK_SEMAPHORE_TYPE_TIMELINE ? &timelineSubmitInfo[1] : DE_NULL);
1173 submitInfo[1].pWaitDstStageMask = &waitDstStageMask;
1174
1175 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
1176
1177 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], true, std::numeric_limits<deUint64>::max());
1178 if (testStatus != VK_SUCCESS)
1179 {
1180 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1181 return tcu::TestStatus::fail("failed to wait for a set fence");
1182 }
1183
1184 invalidateAlloc(deviceInterface, device.get(), *testContext1.renderReadBuffer);
1185 resultImage = testContext1.renderReadBuffer->getHostPtr();
1186
1187 log << TestLog::Image( "result",
1188 "result",
1189 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1190 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1191 testContext1.renderDimension.x(),
1192 testContext1.renderDimension.y(),
1193 1,
1194 resultImage));
1195
1196 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
1197
1198 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], true, std::numeric_limits<deUint64>::max());
1199 if (testStatus != VK_SUCCESS)
1200 {
1201 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1202 return tcu::TestStatus::fail("failed to wait for a set fence");
1203 }
1204
1205 invalidateAlloc(deviceInterface, device.get(), *testContext2.renderReadBuffer);
1206 resultImage = testContext2.renderReadBuffer->getHostPtr();
1207
1208 log << TestLog::Image( "result",
1209 "result",
1210 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1211 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1212 testContext2.renderDimension.x(),
1213 testContext2.renderDimension.y(),
1214 1,
1215 resultImage));
1216
1217 return tcu::TestStatus::pass("synchronization-semaphores passed");
1218 }
1219
testBinarySemaphores(Context & context)1220 tcu::TestStatus testBinarySemaphores (Context& context)
1221 {
1222 return testSemaphores(context, VK_SEMAPHORE_TYPE_BINARY_KHR);
1223 }
1224
testTimelineSemaphores(Context & context)1225 tcu::TestStatus testTimelineSemaphores (Context& context)
1226 {
1227 return testSemaphores(context, VK_SEMAPHORE_TYPE_TIMELINE_KHR);
1228 }
1229
1230 } // anonymous
1231
createSmokeTests(tcu::TestContext & textCtx)1232 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& textCtx)
1233 {
1234 de::MovePtr<tcu::TestCaseGroup> synchTests (new tcu::TestCaseGroup(textCtx, "smoke", "Synchronization smoke tests"));
1235
1236 addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
1237 addFunctionCaseWithPrograms(synchTests.get(), "binary_semaphores", "", buildShaders, testBinarySemaphores);
1238 addFunctionCaseWithPrograms(synchTests.get(), "timeline_semaphores", "", buildShaders, testTimelineSemaphores);
1239
1240 return synchTests.release();
1241 }
1242
1243 } // synchronization
1244 } // vkt
1245