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