1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 Google Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Platform Synchronization tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktSynchronizationSmokeTests.hpp"
26 #include "vktTestCaseUtil.hpp"
28 #include "vkPlatform.hpp"
29 #include "vkStrUtil.hpp"
31 #include "vkRefUtil.hpp"
32 #include "vkDeviceUtil.hpp"
34 #include "tcuTestLog.hpp"
35 #include "tcuFormatUtil.hpp"
37 #include "deUniquePtr.hpp"
38 #include "deThread.hpp"
39 #include "vkMemUtil.hpp"
40 #include "vkQueryUtil.hpp"
41 #include "vkPrograms.hpp"
42 #include "vkTypeUtil.hpp"
48 namespace synchronization
63 static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds
65 void buildShaders (SourceCollections& shaderCollection)
67 shaderCollection.glslSources.add("glslvert") <<
70 "precision mediump float;\n"
71 "layout (location = 0) in vec4 vertexPosition;\n"
74 " gl_Position = vertexPosition;\n"
77 shaderCollection.glslSources.add("glslfrag") <<
80 "precision mediump float;\n"
81 "layout (location = 0) out vec4 outputColor;\n"
84 " outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
88 Move<VkDevice> createTestDevice (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 *outQueueFamilyIndex)
90 VkDeviceQueueCreateInfo queueInfo;
91 VkDeviceCreateInfo deviceInfo;
93 const deUint32 queueCount = 2u;
94 const float queuePriority[queueCount] = { 1.0f, 1.0f };
96 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
97 const VkPhysicalDeviceFeatures physicalDeviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice);
99 for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
101 if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && (queueProps[queueNdx].queueCount >= queueCount))
105 if (queueNdx >= queueProps.size())
107 // No queue family index found
108 std::ostringstream msg;
109 msg << "Cannot create device with " << queueCount << " graphics queues";
111 throw tcu::NotSupportedError(msg.str());
114 deMemset(&queueInfo, 0, sizeof(queueInfo));
115 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
117 deMemset(&queueInfo, 0xcd, sizeof(queueInfo));
118 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
119 queueInfo.pNext = DE_NULL;
120 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
121 queueInfo.queueFamilyIndex = (deUint32)queueNdx;
122 queueInfo.queueCount = queueCount;
123 queueInfo.pQueuePriorities = queuePriority;
125 deMemset(&deviceInfo, 0xcd, sizeof(deviceInfo));
126 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
127 deviceInfo.pNext = DE_NULL;
128 deviceInfo.flags = (VkDeviceCreateFlags)0u;
129 deviceInfo.queueCreateInfoCount = 1u;
130 deviceInfo.pQueueCreateInfos = &queueInfo;
131 deviceInfo.enabledExtensionCount = 0u;
132 deviceInfo.ppEnabledExtensionNames = DE_NULL;
133 deviceInfo.enabledLayerCount = 0u;
134 deviceInfo.ppEnabledLayerNames = DE_NULL;
135 deviceInfo.pEnabledFeatures = &physicalDeviceFeatures;
137 *outQueueFamilyIndex = queueInfo.queueFamilyIndex;
139 return createDevice(vki, physicalDevice, &deviceInfo);
142 struct BufferParameters
146 VkBufferUsageFlags usage;
147 VkSharingMode sharingMode;
148 deUint32 queueFamilyCount;
149 const deUint32* queueFamilyIndex;
150 VkAccessFlags inputBarrierFlags;
155 MovePtr<Allocation> allocation;
156 vector<VkMemoryBarrier> memoryBarrier;
157 vk::Move<VkBuffer> buffer;
160 void createVulkanBuffer (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
162 VkBufferCreateInfo bufferCreateParams;
164 deMemset(&bufferCreateParams, 0xcd, sizeof(bufferCreateParams));
165 bufferCreateParams.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
166 bufferCreateParams.pNext = DE_NULL;
167 bufferCreateParams.flags = 0;
168 bufferCreateParams.size = bufferParameters.size;
169 bufferCreateParams.usage = bufferParameters.usage;
170 bufferCreateParams.sharingMode = bufferParameters.sharingMode;
171 bufferCreateParams.queueFamilyIndexCount = bufferParameters.queueFamilyCount;
172 bufferCreateParams.pQueueFamilyIndices = bufferParameters.queueFamilyIndex;
174 buffer.buffer = createBuffer(vkd, device, &bufferCreateParams);
175 buffer.allocation = allocator.allocate(getBufferMemoryRequirements(vkd, device, *buffer.buffer), visibility);
177 VK_CHECK(vkd.bindBufferMemory(device, *buffer.buffer, buffer.allocation->getMemory(), buffer.allocation->getOffset()));
179 // If caller provides a host memory buffer for the allocation, then go
180 // ahead and copy the provided data into the allocation and update the
181 // barrier list with the associated access
182 if (bufferParameters.memory != DE_NULL)
184 VkMemoryBarrier barrier;
185 VkMappedMemoryRange range;
187 deMemset(&range, 0xcd, sizeof(range));
188 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
189 range.pNext = DE_NULL;
190 range.memory = buffer.allocation->getMemory();
191 range.offset = buffer.allocation->getOffset();
192 range.size = bufferParameters.size;
194 deMemcpy(buffer.allocation->getHostPtr(), bufferParameters.memory, (size_t)bufferParameters.size);
195 VK_CHECK(vkd.flushMappedMemoryRanges(device, 1, &range));
197 deMemset(&barrier, 0xcd, sizeof(barrier));
198 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
199 barrier.pNext = DE_NULL;
200 barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
201 barrier.dstAccessMask = bufferParameters.inputBarrierFlags;
203 buffer.memoryBarrier.push_back(barrier);
207 struct ImageParameters
209 VkImageType imageType;
213 VkSampleCountFlagBits samples;
214 VkImageTiling tiling;
215 VkBufferUsageFlags usage;
216 VkSharingMode sharingMode;
217 deUint32 queueFamilyCount;
218 const deUint32* queueFamilyNdxList;
219 VkImageLayout initialLayout;
220 VkImageLayout finalLayout;
221 VkAccessFlags barrierInputMask;
226 vk::Move<VkImage> image;
227 vk::Move<VkImageView> imageView;
228 MovePtr<Allocation> allocation;
229 vector<VkImageMemoryBarrier> imageMemoryBarrier;
232 void createVulkanImage (const DeviceInterface& vkd, VkDevice device, Allocator& allocator, const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
234 VkComponentMapping componentMap;
235 VkImageSubresourceRange subresourceRange;
236 VkImageViewCreateInfo imageViewCreateInfo;
237 VkImageCreateInfo imageCreateParams;
238 VkImageMemoryBarrier imageBarrier;
240 deMemset(&imageCreateParams, 0xcd, sizeof(imageCreateParams));
241 imageCreateParams.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
242 imageCreateParams.pNext = DE_NULL;
243 imageCreateParams.flags = 0;
244 imageCreateParams.imageType = imageParameters.imageType;
245 imageCreateParams.format = imageParameters.format;
246 imageCreateParams.extent = imageParameters.extent3D;
247 imageCreateParams.mipLevels = imageParameters.mipLevels;
248 imageCreateParams.arrayLayers = 1;
249 imageCreateParams.samples = imageParameters.samples;
250 imageCreateParams.tiling = imageParameters.tiling;
251 imageCreateParams.usage = imageParameters.usage;
252 imageCreateParams.sharingMode = imageParameters.sharingMode;
253 imageCreateParams.queueFamilyIndexCount = imageParameters.queueFamilyCount;
254 imageCreateParams.pQueueFamilyIndices = imageParameters.queueFamilyNdxList;
255 imageCreateParams.initialLayout = imageParameters.initialLayout;
257 image.image = createImage(vkd, device, &imageCreateParams);
258 image.allocation = allocator.allocate(getImageMemoryRequirements(vkd, device, *image.image), visibility);
260 VK_CHECK(vkd.bindImageMemory(device, *image.image, image.allocation->getMemory(), image.allocation->getOffset()));
262 componentMap.r = VK_COMPONENT_SWIZZLE_R;
263 componentMap.g = VK_COMPONENT_SWIZZLE_G;
264 componentMap.b = VK_COMPONENT_SWIZZLE_B;
265 componentMap.a = VK_COMPONENT_SWIZZLE_A;
267 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
268 subresourceRange.baseMipLevel = 0;
269 subresourceRange.levelCount = imageParameters.mipLevels;
270 subresourceRange.baseArrayLayer = 0;
271 subresourceRange.layerCount = 1;
273 deMemset(&imageViewCreateInfo, 0xcd, sizeof(imageViewCreateInfo));
274 imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
275 imageViewCreateInfo.pNext = DE_NULL;
276 imageViewCreateInfo.flags = 0;
277 imageViewCreateInfo.image = image.image.get();
278 imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
279 imageViewCreateInfo.format = imageParameters.format;
280 imageViewCreateInfo.components = componentMap;
281 imageViewCreateInfo.subresourceRange = subresourceRange;
283 image.imageView = createImageView(vkd, device, &imageViewCreateInfo);
285 deMemset(&imageBarrier, 0xcd, sizeof(imageBarrier));
286 imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
287 imageBarrier.pNext = DE_NULL;
288 imageBarrier.srcAccessMask = 0;
289 imageBarrier.dstAccessMask = imageParameters.barrierInputMask;
290 imageBarrier.oldLayout = imageParameters.initialLayout;
291 imageBarrier.newLayout = imageParameters.finalLayout;
292 imageBarrier.srcQueueFamilyIndex = imageParameters.queueFamilyNdxList[0];
293 imageBarrier.dstQueueFamilyIndex = imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
294 imageBarrier.image = image.image.get();
295 imageBarrier.subresourceRange = subresourceRange;
297 image.imageMemoryBarrier.push_back(imageBarrier);
300 struct RenderPassParameters
302 VkFormat colorFormat;
303 VkSampleCountFlagBits colorSamples;
306 void createColorOnlyRenderPass (const DeviceInterface& vkd, VkDevice device, const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
308 VkAttachmentDescription colorAttachmentDesc;
309 VkAttachmentReference colorAttachmentRef;
310 VkAttachmentReference stencilAttachmentRef;
311 VkSubpassDescription subpassDesc;
312 VkRenderPassCreateInfo renderPassParams;
313 VkRenderPass newRenderPass;
315 colorAttachmentDesc.flags = 0;
316 colorAttachmentDesc.format = renderPassParameters.colorFormat;
317 colorAttachmentDesc.samples = renderPassParameters.colorSamples;
318 colorAttachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
319 colorAttachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
320 colorAttachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
321 colorAttachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
322 colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
323 colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
325 colorAttachmentRef.attachment = 0;
326 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
328 stencilAttachmentRef.attachment = VK_ATTACHMENT_UNUSED;
329 stencilAttachmentRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
331 subpassDesc.flags = 0;
332 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
333 subpassDesc.inputAttachmentCount = 0;
334 subpassDesc.pInputAttachments = DE_NULL;
335 subpassDesc.colorAttachmentCount = 1;
336 subpassDesc.pColorAttachments = &colorAttachmentRef;
337 subpassDesc.pResolveAttachments = DE_NULL;
338 subpassDesc.pDepthStencilAttachment = &stencilAttachmentRef;
339 subpassDesc.preserveAttachmentCount = 0;
340 subpassDesc.pPreserveAttachments = DE_NULL;
342 deMemset(&renderPassParams, 0xcd, sizeof(renderPassParams));
343 renderPassParams.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
344 renderPassParams.pNext = DE_NULL;
345 renderPassParams.flags = 0;
346 renderPassParams.attachmentCount = 1;
347 renderPassParams.pAttachments = &colorAttachmentDesc;
348 renderPassParams.subpassCount = 1;
349 renderPassParams.pSubpasses = &subpassDesc;
350 renderPassParams.dependencyCount = 0;
351 renderPassParams.pDependencies = DE_NULL;
353 renderPass = createRenderPass(vkd, device, &renderPassParams);
356 struct ShaderDescParams
358 VkShaderModule shaderModule;
359 VkShaderStageFlagBits stage;
370 void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
372 for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
374 deUint32 bindingId = 0;
375 VkVertexInputBindingDescription bindingDesc;
376 VkVertexInputAttributeDescription attrDesc;
378 bindingDesc.binding = bindingId;
379 bindingDesc.stride = vertDescIter->stride;
380 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
381 bindingList.push_back(bindingDesc);
383 attrDesc.location = vertDescIter->location;
384 attrDesc.binding = bindingId;
385 attrDesc.format = vertDescIter->format;
386 attrDesc.offset = vertDescIter->offset;
387 attrList.push_back(attrDesc);
392 deMemset(&vertexInputState, 0xcd, sizeof(vertexInputState));
393 vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
394 vertexInputState.pNext = DE_NULL;
395 vertexInputState.flags = 0u;
396 vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
397 vertexInputState.pVertexBindingDescriptions = &bindingList[0];
398 vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
399 vertexInputState.pVertexAttributeDescriptions = &attrList[0];
402 void createCommandBuffer (const DeviceInterface& deviceInterface, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef, vk::Move<VkCommandPool>* commandPoolRef)
404 vk::Move<VkCommandPool> commandPool;
405 VkCommandBufferAllocateInfo commandBufferInfo;
406 VkCommandBuffer commandBuffer;
408 commandPool = createCommandPool(deviceInterface, device, 0u, queueFamilyNdx);
410 deMemset(&commandBufferInfo, 0xcd, sizeof(commandBufferInfo));
411 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
412 commandBufferInfo.pNext = DE_NULL;
413 commandBufferInfo.commandPool = commandPool.get();
414 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
415 commandBufferInfo.commandBufferCount = 1;
417 VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
418 *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, commandPool.get()));
419 *commandPoolRef = commandPool;
422 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
424 VkFenceCreateInfo fenceState;
425 VkFenceCreateFlags signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
427 deMemset(&fenceState, 0xcd, sizeof(fenceState));
428 fenceState.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
429 fenceState.pNext = DE_NULL;
430 fenceState.flags = signalFlag;
432 for (deUint32 ndx = 0; ndx < numFences; ndx++)
433 VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
436 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
438 for (deUint32 ndx = 0; ndx < numFences; ndx++)
439 deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
446 deUint32 vertexBufferSize;
447 VkBuffer vertexBuffer;
449 VkCommandBuffer commandBuffer;
450 VkRenderPass renderPass;
451 VkFramebuffer framebuffer;
454 const deUint32* queueFamilyNdxList;
455 deUint32 queueFamilyNdxCount;
458 vector<VkImageMemoryBarrier>* barriers;
461 void recordRenderPass (const DeviceInterface& deviceInterface, const RenderInfo& renderInfo)
463 const VkDeviceSize bindingOffset = 0;
464 const VkClearValue clearValue = makeClearValueColorF32(0.0, 0.0, 1.0, 1.0);
465 VkRenderPassBeginInfo renderPassBeginState;
466 VkImageMemoryBarrier renderBarrier;
468 deMemset(&renderPassBeginState, 0xcd, sizeof(renderPassBeginState));
469 renderPassBeginState.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
470 renderPassBeginState.pNext = DE_NULL;
471 renderPassBeginState.renderPass = renderInfo.renderPass;
472 renderPassBeginState.framebuffer = renderInfo.framebuffer;
473 renderPassBeginState.renderArea.offset.x = 0;
474 renderPassBeginState.renderArea.offset.y = 0;
475 renderPassBeginState.renderArea.extent.width = renderInfo.width;
476 renderPassBeginState.renderArea.extent.height = renderInfo.height;
477 renderPassBeginState.clearValueCount = 1;
478 renderPassBeginState.pClearValues = &clearValue;
480 deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE);
481 if (renderInfo.waitEvent)
482 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);
483 deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
484 deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
485 deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
486 deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer);
488 deMemset(&renderBarrier, 0xcd, sizeof(renderBarrier));
489 renderBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
490 renderBarrier.pNext = DE_NULL;
491 renderBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
492 renderBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
493 renderBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
494 renderBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
495 renderBarrier.srcQueueFamilyIndex = renderInfo.queueFamilyNdxList[0];
496 renderBarrier.dstQueueFamilyIndex = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
497 renderBarrier.image = renderInfo.image;
498 renderBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
499 renderBarrier.subresourceRange.baseMipLevel = 0;
500 renderBarrier.subresourceRange.levelCount = renderInfo.mipLevels;
501 renderBarrier.subresourceRange.baseArrayLayer = 0;
502 renderBarrier.subresourceRange.layerCount = 1;
503 renderInfo.barriers->push_back(renderBarrier);
508 VkCommandBuffer commandBuffer;
515 VkOffset3D imageOffset;
516 vector<VkBufferMemoryBarrier>* barriers;
519 void copyToCPU (const DeviceInterface& vkd, TransferInfo* transferInfo)
521 VkBufferImageCopy copyState;
523 copyState.bufferOffset = 0;
524 copyState.bufferRowLength = transferInfo->width;
525 copyState.bufferImageHeight = transferInfo->height;
526 copyState.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
527 copyState.imageSubresource.mipLevel = transferInfo->mipLevel;
528 copyState.imageSubresource.baseArrayLayer = 0;
529 copyState.imageSubresource.layerCount = 1;
530 copyState.imageOffset = transferInfo->imageOffset;
531 copyState.imageExtent.width = (deInt32)(transferInfo->width);
532 copyState.imageExtent.height = (deInt32)(transferInfo->height);
533 copyState.imageExtent.depth = 1;
535 vkd.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, ©State);
538 VkBufferMemoryBarrier bufferBarrier;
539 deMemset(&bufferBarrier, 0xcd, sizeof(bufferBarrier));
540 bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
541 bufferBarrier.pNext = DE_NULL;
542 bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
543 bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
544 bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
545 bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
546 bufferBarrier.buffer = transferInfo->buffer;
547 bufferBarrier.offset = 0;
548 bufferBarrier.size = transferInfo->size;
549 transferInfo->barriers->push_back(bufferBarrier);
555 const DeviceInterface& vkd;
556 const VkDevice device;
557 const deUint32 queueFamilyIndex;
558 const BinaryCollection& binaryCollection;
559 Allocator& allocator;
561 const tcu::Vec4* vertices;
562 deUint32 numVertices;
563 tcu::IVec2 renderDimension;
565 VkDeviceSize renderSize;
566 MovePtr<Allocation> renderReadBuffer;
567 MovePtr<Allocation> vertexBufferAllocation;
568 vk::Move<VkBuffer> vertexBuffer;
569 vk::Move<VkBuffer> renderBuffer;
572 vk::Move<VkImage> image;
573 vk::Move<VkImageView> imageView;
574 vk::Move<VkFramebuffer> framebuffer;
575 vk::Move<VkCommandPool> commandPool;
576 vk::Move<VkCommandBuffer> cmdBuffer;
577 vk::Move<VkRenderPass> renderPass;
578 vk::Move<VkPipelineCache> pipelineCache;
579 vk::Move<VkPipeline> pipeline;
580 MovePtr<Allocation> imageAllocation;
582 TestContext (const DeviceInterface& vkd_,
583 const VkDevice device_,
584 deUint32 queueFamilyIndex_,
585 const BinaryCollection& binaryCollection_,
586 Allocator& allocator_)
589 , queueFamilyIndex (queueFamilyIndex_)
590 , binaryCollection (binaryCollection_)
591 , allocator (allocator_)
595 createFences(vkd, device, false, DE_LENGTH_OF_ARRAY(fences), fences);
600 destroyFences(vkd, device, DE_LENGTH_OF_ARRAY(fences), fences);
604 void generateWork (TestContext& testContext)
606 const DeviceInterface& deviceInterface = testContext.vkd;
607 const deUint32 queueFamilyNdx = testContext.queueFamilyIndex;
609 // \note VkShaderModule is consumed by vkCreate*Pipelines() so it can be deleted
610 // as pipeline has been constructed.
611 const vk::Unique<VkShaderModule> vertShaderModule (createShaderModule(deviceInterface,
613 testContext.binaryCollection.get("glslvert"),
614 (VkShaderModuleCreateFlags)0));
616 const vk::Unique<VkShaderModule> fragShaderModule (createShaderModule(deviceInterface,
618 testContext.binaryCollection.get("glslfrag"),
619 (VkShaderModuleCreateFlags)0));
620 const VkPipelineShaderStageCreateInfo shaderStageParams[] =
623 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
625 (VkPipelineShaderStageCreateFlags)0,
626 VK_SHADER_STAGE_VERTEX_BIT,
629 (const VkSpecializationInfo*)DE_NULL,
632 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
634 (VkPipelineShaderStageCreateFlags)0,
635 VK_SHADER_STAGE_FRAGMENT_BIT,
638 (const VkSpecializationInfo*)DE_NULL,
642 vk::Move<VkPipelineLayout> layout;
643 vector<ShaderDescParams> shaderDescParams;
644 VertexDesc vertexDesc;
645 vector<VertexDesc> vertexDescList;
646 vector<VkVertexInputAttributeDescription> attrList;
647 vector<VkBufferMemoryBarrier> bufferMemoryBarrier;
648 deUint32 memoryBarrierNdx;
649 deUint32 bufferMemoryBarrierNdx;
650 deUint32 imageMemoryBarrierNdx;
651 vector<VkVertexInputBindingDescription> bindingList;
652 VkPipelineVertexInputStateCreateInfo vertexInputState;
653 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
654 VkPipelineDepthStencilStateCreateInfo depthStencilState;
655 VkPipelineColorBlendAttachmentState blendAttachment;
656 VkPipelineColorBlendStateCreateInfo blendState;
657 VkPipelineLayoutCreateInfo pipelineLayoutState;
658 VkGraphicsPipelineCreateInfo pipelineState;
659 VkPipelineCacheCreateInfo cacheState;
661 VkPipelineViewportStateCreateInfo viewportInfo;
663 BufferParameters bufferParameters;
665 RenderInfo renderInfo;
666 ImageParameters imageParameters;
668 VkPipelineRasterizationStateCreateInfo rasterState;
669 VkPipelineMultisampleStateCreateInfo multisampleState;
670 VkFramebufferCreateInfo fbState;
671 VkCommandBufferBeginInfo commandBufRecordState;
672 VkCommandBufferInheritanceInfo inheritanceInfo;
673 RenderPassParameters renderPassParameters;
674 TransferInfo transferInfo;
675 vector<void*> barrierList;
677 vector<VkMemoryBarrier> memoryBarriers;
678 vector<VkBufferMemoryBarrier> bufferBarriers;
679 vector<VkImageMemoryBarrier> imageBarriers;
681 memoryBarrierNdx = 0;
682 bufferMemoryBarrierNdx = 0;
683 imageMemoryBarrierNdx = 0;
684 buffer.memoryBarrier.resize(memoryBarrierNdx);
685 bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
686 image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
688 memoryBarriers.resize(0);
689 bufferBarriers.resize(0);
690 imageBarriers.resize(0);
692 bufferParameters.memory = testContext.vertices;
693 bufferParameters.size = testContext.numVertices * sizeof(tcu::Vec4);
694 bufferParameters.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
695 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
696 bufferParameters.queueFamilyCount = 1;
697 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
698 bufferParameters.inputBarrierFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
699 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
700 testContext.vertexBufferAllocation = buffer.allocation;
701 testContext.vertexBuffer = buffer.buffer;
703 bufferParameters.memory = DE_NULL;
704 bufferParameters.size = testContext.renderSize;
705 bufferParameters.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
706 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
707 bufferParameters.queueFamilyCount = 1;
708 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
709 bufferParameters.inputBarrierFlags = 0;
710 createVulkanBuffer(deviceInterface, testContext.device, testContext.allocator, bufferParameters, buffer, MemoryRequirement::HostVisible);
711 testContext.renderReadBuffer = buffer.allocation;
712 testContext.renderBuffer = buffer.buffer;
714 extent.width = testContext.renderDimension.x();
715 extent.height = testContext.renderDimension.y();
718 imageParameters.imageType = VK_IMAGE_TYPE_2D;
719 imageParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
720 imageParameters.extent3D = extent;
721 imageParameters.mipLevels = 1;
722 imageParameters.samples = VK_SAMPLE_COUNT_1_BIT;
723 imageParameters.tiling = VK_IMAGE_TILING_OPTIMAL;
724 imageParameters.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
725 imageParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
726 imageParameters.queueFamilyCount = 1;
727 imageParameters.queueFamilyNdxList = &queueFamilyNdx;
728 imageParameters.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
729 imageParameters.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
730 imageParameters.barrierInputMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
731 createVulkanImage(deviceInterface, testContext.device, testContext.allocator, imageParameters, image, MemoryRequirement::Any);
732 testContext.imageAllocation = image.allocation;
733 testContext.image = image.image;
735 for (size_t ndx = 0; ndx < image.imageMemoryBarrier.size(); ++ndx)
736 imageBarriers.push_back(image.imageMemoryBarrier[ndx]);
738 renderPassParameters.colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
739 renderPassParameters.colorSamples = VK_SAMPLE_COUNT_1_BIT;
740 createColorOnlyRenderPass(deviceInterface, testContext.device, renderPassParameters, testContext.renderPass);
742 vertexDesc.location = 0;
743 vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
744 vertexDesc.stride = sizeof(tcu::Vec4);
745 vertexDesc.offset = 0;
746 vertexDescList.push_back(vertexDesc);
748 createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
750 deMemset(&inputAssemblyState, 0xcd, sizeof(inputAssemblyState));
751 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
752 inputAssemblyState.pNext = DE_NULL;
753 inputAssemblyState.flags = 0u;
754 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
755 inputAssemblyState.primitiveRestartEnable = false;
759 viewport.width = (float)testContext.renderDimension.x();
760 viewport.height = (float)testContext.renderDimension.y();
761 viewport.minDepth = 0;
762 viewport.maxDepth = 1;
764 scissor.offset.x = 0;
765 scissor.offset.y = 0;
766 scissor.extent.width = testContext.renderDimension.x();
767 scissor.extent.height = testContext.renderDimension.y();
769 deMemset(&viewportInfo, 0xcd, sizeof(viewportInfo));
770 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
771 viewportInfo.pNext = DE_NULL;
772 viewportInfo.flags = 0;
773 viewportInfo.viewportCount = 1;
774 viewportInfo.pViewports = &viewport;
775 viewportInfo.scissorCount = 1;
776 viewportInfo.pScissors = &scissor;
778 deMemset(&rasterState, 0xcd, sizeof(rasterState));
779 rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
780 rasterState.pNext = DE_NULL;
781 rasterState.flags = 0;
782 rasterState.depthClampEnable = VK_TRUE;
783 rasterState.rasterizerDiscardEnable = VK_FALSE;
784 rasterState.polygonMode = VK_POLYGON_MODE_FILL;
785 rasterState.cullMode = VK_CULL_MODE_NONE;
786 rasterState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
787 rasterState.depthBiasEnable = VK_FALSE;
788 rasterState.lineWidth = 1;
790 deMemset(&multisampleState, 0xcd, sizeof(multisampleState));
791 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
792 multisampleState.pNext = DE_NULL;
793 multisampleState.flags = 0;
794 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
795 multisampleState.sampleShadingEnable = VK_FALSE;
796 multisampleState.pSampleMask = DE_NULL;
797 multisampleState.alphaToCoverageEnable = VK_FALSE;
798 multisampleState.alphaToOneEnable = VK_FALSE;
800 deMemset(&depthStencilState, 0xcd, sizeof(depthStencilState));
801 depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
802 depthStencilState.pNext = DE_NULL;
803 depthStencilState.flags = 0;
804 depthStencilState.depthTestEnable = VK_FALSE;
805 depthStencilState.depthWriteEnable = VK_FALSE;
806 depthStencilState.depthCompareOp = VK_COMPARE_OP_ALWAYS;
807 depthStencilState.depthBoundsTestEnable = VK_FALSE;
808 depthStencilState.stencilTestEnable = VK_FALSE;
809 depthStencilState.front.failOp = VK_STENCIL_OP_KEEP;
810 depthStencilState.front.passOp = VK_STENCIL_OP_KEEP;
811 depthStencilState.front.depthFailOp = VK_STENCIL_OP_KEEP;
812 depthStencilState.front.compareOp = VK_COMPARE_OP_ALWAYS;
813 depthStencilState.front.compareMask = 0u;
814 depthStencilState.front.writeMask = 0u;
815 depthStencilState.front.reference = 0u;
816 depthStencilState.back = depthStencilState.front;
818 deMemset(&blendAttachment, 0xcd, sizeof(blendAttachment));
819 blendAttachment.blendEnable = VK_FALSE;
820 blendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ZERO;
821 blendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
822 blendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO;
823 blendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
824 blendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
825 blendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
826 blendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
828 deMemset(&blendState, 0xcd, sizeof(blendState));
829 blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
830 blendState.pNext = DE_NULL;
831 blendState.flags = 0;
832 blendState.logicOpEnable = VK_FALSE;
833 blendState.logicOp = VK_LOGIC_OP_COPY;
834 blendState.attachmentCount = 1;
835 blendState.pAttachments = &blendAttachment;
837 deMemset(&pipelineLayoutState, 0xcd, sizeof(pipelineLayoutState));
838 pipelineLayoutState.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
839 pipelineLayoutState.pNext = DE_NULL;
840 pipelineLayoutState.flags = 0;
841 pipelineLayoutState.setLayoutCount = 0;
842 pipelineLayoutState.pSetLayouts = DE_NULL;
843 pipelineLayoutState.pushConstantRangeCount = 0;
844 pipelineLayoutState.pPushConstantRanges = DE_NULL;
845 layout = createPipelineLayout(deviceInterface, testContext.device, &pipelineLayoutState, DE_NULL);
847 deMemset(&pipelineState, 0xcd, sizeof(pipelineState));
848 pipelineState.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
849 pipelineState.pNext = DE_NULL;
850 pipelineState.flags = 0;
851 pipelineState.stageCount = DE_LENGTH_OF_ARRAY(shaderStageParams);
852 pipelineState.pStages = &shaderStageParams[0];
853 pipelineState.pVertexInputState = &vertexInputState;
854 pipelineState.pInputAssemblyState = &inputAssemblyState;
855 pipelineState.pTessellationState = DE_NULL;
856 pipelineState.pViewportState = &viewportInfo;
857 pipelineState.pRasterizationState = &rasterState;
858 pipelineState.pMultisampleState = &multisampleState;
859 pipelineState.pDepthStencilState = &depthStencilState;
860 pipelineState.pColorBlendState = &blendState;
861 pipelineState.pDynamicState = (const VkPipelineDynamicStateCreateInfo*)DE_NULL;
862 pipelineState.layout = layout.get();
863 pipelineState.renderPass = testContext.renderPass.get();
864 pipelineState.subpass = 0;
865 pipelineState.basePipelineHandle = DE_NULL;
866 pipelineState.basePipelineIndex = 0;
868 deMemset(&cacheState, 0xcd, sizeof(cacheState));
869 cacheState.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
870 cacheState.pNext = DE_NULL;
871 cacheState.flags = 0;
872 cacheState.initialDataSize = 0;
873 cacheState.pInitialData = DE_NULL;
875 testContext.pipelineCache = createPipelineCache(deviceInterface, testContext.device, &cacheState);
876 testContext.pipeline = createGraphicsPipeline(deviceInterface, testContext.device, testContext.pipelineCache.get(), &pipelineState);
878 deMemset(&fbState, 0xcd, sizeof(fbState));
879 fbState.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
880 fbState.pNext = DE_NULL;
882 fbState.renderPass = testContext.renderPass.get();
883 fbState.attachmentCount = 1;
884 fbState.pAttachments = &image.imageView.get();
885 fbState.width = (deUint32)testContext.renderDimension.x();
886 fbState.height = (deUint32)testContext.renderDimension.y();
889 testContext.framebuffer = createFramebuffer(deviceInterface, testContext.device, &fbState);
890 testContext.imageView = image.imageView;
892 deMemset(&inheritanceInfo, 0xcd, sizeof(inheritanceInfo));
893 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
894 inheritanceInfo.pNext = DE_NULL;
895 inheritanceInfo.renderPass = testContext.renderPass.get();
896 inheritanceInfo.subpass = 0;
897 inheritanceInfo.framebuffer = *testContext.framebuffer;
898 inheritanceInfo.occlusionQueryEnable = VK_FALSE;
899 inheritanceInfo.queryFlags = 0u;
900 inheritanceInfo.pipelineStatistics = 0u;
902 deMemset(&commandBufRecordState, 0xcd, sizeof(commandBufRecordState));
903 commandBufRecordState.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
904 commandBufRecordState.pNext = DE_NULL;
905 commandBufRecordState.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
906 commandBufRecordState.pInheritanceInfo = &inheritanceInfo;
907 VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
909 deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
910 VK_PIPELINE_STAGE_HOST_BIT,
911 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
913 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
914 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
915 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
917 memoryBarriers.resize(0);
918 bufferBarriers.resize(0);
919 imageBarriers.resize(0);
921 renderInfo.width = testContext.renderDimension.x();
922 renderInfo.height = testContext.renderDimension.y();
923 renderInfo.vertexBufferSize = testContext.numVertices;
924 renderInfo.vertexBuffer = testContext.vertexBuffer.get();
925 renderInfo.image = testContext.image.get();
926 renderInfo.commandBuffer = testContext.cmdBuffer.get();
927 renderInfo.renderPass = testContext.renderPass.get();
928 renderInfo.framebuffer = *testContext.framebuffer;
929 renderInfo.pipeline = *testContext.pipeline;
930 renderInfo.mipLevels = 1;
931 renderInfo.queueFamilyNdxList = &queueFamilyNdx;
932 renderInfo.queueFamilyNdxCount = 1;
933 renderInfo.waitEvent = testContext.waitEvent;
934 renderInfo.event = testContext.event;
935 renderInfo.barriers = &imageBarriers;
936 recordRenderPass(deviceInterface, renderInfo);
938 deviceInterface.cmdPipelineBarrier( renderInfo.commandBuffer,
939 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
940 VK_PIPELINE_STAGE_TRANSFER_BIT,
942 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
943 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
944 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
946 memoryBarriers.resize(0);
947 bufferBarriers.resize(0);
948 imageBarriers.resize(0);
950 transferInfo.commandBuffer = renderInfo.commandBuffer;
951 transferInfo.width = testContext.renderDimension.x();
952 transferInfo.height = testContext.renderDimension.y();
953 transferInfo.image = renderInfo.image;
954 transferInfo.buffer = testContext.renderBuffer.get();
955 transferInfo.size = testContext.renderSize;
956 transferInfo.mipLevel = 0;
957 transferInfo.imageOffset.x = 0;
958 transferInfo.imageOffset.y = 0;
959 transferInfo.imageOffset.z = 0;
960 transferInfo.barriers = &bufferBarriers;
961 copyToCPU(deviceInterface, &transferInfo);
963 deviceInterface.cmdPipelineBarrier( transferInfo.commandBuffer,
964 VK_PIPELINE_STAGE_TRANSFER_BIT,
965 VK_PIPELINE_STAGE_HOST_BIT,
967 (deUint32)memoryBarriers.size(), (memoryBarriers.empty() ? DE_NULL : &memoryBarriers[0]),
968 (deUint32)bufferBarriers.size(), (bufferBarriers.empty() ? DE_NULL : &bufferBarriers[0]),
969 (deUint32)imageBarriers.size(), (imageBarriers.empty() ? DE_NULL : &imageBarriers[0]));
971 memoryBarriers.resize(0);
972 bufferBarriers.resize(0);
973 imageBarriers.resize(0);
975 VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer));
978 static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount)
980 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
982 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
983 submitInfo[ndx].pNext = DE_NULL;
984 submitInfo[ndx].waitSemaphoreCount = 0;
985 submitInfo[ndx].pWaitSemaphores = DE_NULL;
986 submitInfo[ndx].pWaitDstStageMask = DE_NULL;
987 submitInfo[ndx].commandBufferCount = 1;
988 submitInfo[ndx].signalSemaphoreCount = 0;
989 submitInfo[ndx].pSignalSemaphores = DE_NULL;
993 tcu::TestStatus testFences (Context& context)
995 TestLog& log = context.getTestContext().getLog();
996 const DeviceInterface& deviceInterface = context.getDeviceInterface();
997 const VkQueue queue = context.getUniversalQueue();
998 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
999 VkDevice device = context.getDevice();
1000 VkResult waitStatus;
1001 VkResult fenceStatus;
1002 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), context.getDefaultAllocator());
1003 VkSubmitInfo submitInfo;
1004 VkMappedMemoryRange range;
1007 const tcu::Vec4 vertices[] =
1009 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1010 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1011 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1014 testContext.vertices = vertices;
1015 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
1016 testContext.renderDimension = tcu::IVec2(256, 256);
1017 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1019 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
1020 generateWork(testContext);
1022 initSubmitInfo(&submitInfo, 1);
1023 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
1025 // Default status is unsignaled
1026 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1027 if (fenceStatus != VK_NOT_READY)
1029 log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1030 return tcu::TestStatus::fail("Fence in incorrect state");
1032 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]);
1033 if (fenceStatus != VK_NOT_READY)
1035 log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1036 return tcu::TestStatus::fail("Fence in incorrect state");
1039 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1041 // Wait with timeout = 0
1042 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 0u);
1043 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1045 // Will most likely end with VK_TIMEOUT
1046 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1047 return tcu::TestStatus::fail("Failed to wait for a single fence");
1050 // Wait with a reasonable timeout
1051 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, DEFAULT_TIMEOUT);
1052 if (waitStatus != VK_SUCCESS && waitStatus != VK_TIMEOUT)
1054 // \note Wait can end with a timeout if DEFAULT_TIMEOUT is not sufficient
1055 log << TestLog::Message << "testSynchPrimitives failed to wait for a single fence" << TestLog::EndMessage;
1056 return tcu::TestStatus::fail("Failed to wait for a single fence");
1059 // Wait for work on fences[0] to actually complete
1060 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, std::numeric_limits<deUint64>::max());
1061 if (waitStatus != VK_SUCCESS)
1063 log << TestLog::Message << "testSynchPrimitives failed to wait for a fence" << TestLog::EndMessage;
1064 return tcu::TestStatus::fail("failed to wait for a fence");
1067 // Wait until timeout on a fence that has not been submitted
1068 waitStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[1], true, 1);
1069 if (waitStatus != VK_TIMEOUT)
1071 log << TestLog::Message << "testSyncPrimitives failed to timeout on wait for single fence" << TestLog::EndMessage;
1072 return tcu::TestStatus::fail("failed to timeout on wait for single fence");
1075 // Check that the fence is signaled after the wait
1076 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1077 if (fenceStatus != VK_SUCCESS)
1079 log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1080 return tcu::TestStatus::fail("Fence in incorrect state");
1083 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1084 range.pNext = DE_NULL;
1085 range.memory = testContext.renderReadBuffer->getMemory();
1087 range.size = testContext.renderSize;
1088 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range));
1089 resultImage = testContext.renderReadBuffer->getHostPtr();
1091 log << TestLog::Image( "result",
1093 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1094 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1095 testContext.renderDimension.x(),
1096 testContext.renderDimension.y(),
1100 return TestStatus::pass("synchronization-fences passed");
1103 tcu::TestStatus testSemaphores (Context& context)
1105 TestLog& log = context.getTestContext().getLog();
1106 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1107 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1108 deUint32 queueFamilyIdx;
1109 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice, &queueFamilyIdx);
1110 const DeviceDriver deviceInterface (instanceInterface, *device);
1111 SimpleAllocator allocator (deviceInterface,
1113 getPhysicalDeviceMemoryProperties(instanceInterface, physicalDevice));
1114 const VkQueue queue[2] =
1116 getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 0),
1117 getDeviceQueue(deviceInterface, *device, queueFamilyIdx, 1)
1119 VkResult testStatus;
1120 TestContext testContext1 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1121 TestContext testContext2 (deviceInterface, device.get(), queueFamilyIdx, context.getBinaryCollection(), allocator);
1122 Unique<VkSemaphore> semaphore (createSemaphore(deviceInterface, *device));
1123 VkSubmitInfo submitInfo[2];
1124 VkMappedMemoryRange range;
1126 const VkPipelineStageFlags waitDstStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
1128 const tcu::Vec4 vertices1[] =
1130 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1131 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1132 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1135 const tcu::Vec4 vertices2[] =
1137 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1138 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1139 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1142 testContext1.vertices = vertices1;
1143 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1144 testContext1.renderDimension = tcu::IVec2(256, 256);
1145 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1147 testContext2.vertices = vertices2;
1148 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
1149 testContext2.renderDimension = tcu::IVec2(256, 256);
1150 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1152 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext1.cmdBuffer, &testContext1.commandPool);
1153 generateWork(testContext1);
1155 createCommandBuffer(deviceInterface, device.get(), queueFamilyIdx, &testContext2.cmdBuffer, &testContext2.commandPool);
1156 generateWork(testContext2);
1158 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
1160 // The difference between the two submit infos is that each will use a unique cmd buffer,
1161 // and one will signal a semaphore but not wait on a semaphore, the other will wait on the
1162 // semaphore but not signal a semaphore
1163 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
1164 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
1166 submitInfo[0].signalSemaphoreCount = 1;
1167 submitInfo[0].pSignalSemaphores = &semaphore.get();
1168 submitInfo[1].waitSemaphoreCount = 1;
1169 submitInfo[1].pWaitSemaphores = &semaphore.get();
1170 submitInfo[1].pWaitDstStageMask = &waitDstStageMask;
1172 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
1174 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], true, std::numeric_limits<deUint64>::max());
1175 if (testStatus != VK_SUCCESS)
1177 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1178 return tcu::TestStatus::fail("failed to wait for a set fence");
1181 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1182 range.pNext = DE_NULL;
1183 range.memory = testContext1.renderReadBuffer->getMemory();
1185 range.size = testContext1.renderSize;
1186 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1187 resultImage = testContext1.renderReadBuffer->getHostPtr();
1189 log << TestLog::Image( "result",
1191 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1192 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1193 testContext1.renderDimension.x(),
1194 testContext1.renderDimension.y(),
1198 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
1200 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], true, std::numeric_limits<deUint64>::max());
1201 if (testStatus != VK_SUCCESS)
1203 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1204 return tcu::TestStatus::fail("failed to wait for a set fence");
1207 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1208 range.pNext = DE_NULL;
1209 range.memory = testContext2.renderReadBuffer->getMemory();
1211 range.size = testContext2.renderSize;
1212 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1213 resultImage = testContext2.renderReadBuffer->getHostPtr();
1215 log << TestLog::Image( "result",
1217 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1218 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1219 testContext2.renderDimension.x(),
1220 testContext2.renderDimension.y(),
1224 return tcu::TestStatus::pass("synchronization-semaphores passed");
1227 tcu::TestStatus testEvents (Context& context)
1229 TestLog& log = context.getTestContext().getLog();
1230 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1231 VkDevice device = context.getDevice();
1232 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
1233 Allocator& allocator = context.getDefaultAllocator();
1234 VkQueue queue = context.getUniversalQueue();
1235 VkResult testStatus;
1236 VkResult eventStatus;
1237 TestContext testContext (deviceInterface, device, queueFamilyIdx, context.getBinaryCollection(), allocator);
1238 Unique<VkEvent> event (createEvent(deviceInterface, device));
1239 VkSubmitInfo submitInfo;
1240 VkMappedMemoryRange range;
1243 const tcu::Vec4 vertices1[] =
1245 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1246 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1247 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1250 testContext.vertices = vertices1;
1251 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1252 testContext.renderDimension = tcu::IVec2(256, 256);
1253 testContext.waitEvent = true;
1254 testContext.event = event.get();
1255 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1257 createCommandBuffer(deviceInterface, device, queueFamilyIdx, &testContext.cmdBuffer, &testContext.commandPool);
1258 generateWork(testContext);
1260 initSubmitInfo(&submitInfo, 1);
1261 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
1263 // 6.3 An event is initially in the unsignaled state
1264 eventStatus = deviceInterface.getEventStatus(device, event.get());
1265 if (eventStatus != VK_EVENT_RESET)
1267 log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << getResultName(eventStatus) << TestLog::EndMessage;
1268 return tcu::TestStatus::fail("Event in incorrect status");
1271 // The recorded command buffer should wait at the top of the graphics pipe for an event signaled by the host and so should not
1272 // make forward progress as long as the event is not signaled
1273 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1275 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, 1);
1276 if (testStatus != VK_TIMEOUT)
1278 log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set event from host." << TestLog::EndMessage;
1279 return tcu::TestStatus::fail("failed to wait for event set from host");
1282 // Should allow the recorded command buffer to finally make progress
1283 VK_CHECK(deviceInterface.setEvent(device, event.get()));
1284 eventStatus = deviceInterface.getEventStatus(device, event.get());
1285 if (eventStatus != VK_EVENT_SET)
1287 log << TestLog::Message << "testEvents failed to transition event to signaled state via setEvent call from host" << TestLog::EndMessage;
1288 return tcu::TestStatus::fail("failed to signal event from host");
1291 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], true, ~(0ull));
1292 if (testStatus != VK_SUCCESS)
1294 log << TestLog::Message << "testSynchronizationPrimitives failed to proceed after set event from host." << TestLog::EndMessage;
1295 return tcu::TestStatus::fail("failed to proceed after event set from host");
1298 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1299 range.pNext = DE_NULL;
1300 range.memory = testContext.renderReadBuffer->getMemory();
1302 range.size = testContext.renderSize;
1303 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range));
1304 resultImage = testContext.renderReadBuffer->getHostPtr();
1306 log << TestLog::Image( "result",
1308 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1309 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1310 testContext.renderDimension.x(),
1311 testContext.renderDimension.y(),
1315 return tcu::TestStatus::pass("synchronization-events passed");
1320 tcu::TestCaseGroup* createSmokeTests (tcu::TestContext& textCtx)
1322 de::MovePtr<tcu::TestCaseGroup> synchTests (new tcu::TestCaseGroup(textCtx, "smoke", "Synchronization smoke tests"));
1324 addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
1325 addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores);
1326 addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents);
1328 return synchTests.release();
1331 } // synchronization