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 "vktSynchronization.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"
59 static const deUint64 DEFAULT_TIMEOUT = 2ull*1000*1000*1000; //!< 2 seconds in nanoseconds
61 void buildShaders (SourceCollections& shaderCollection)
63 shaderCollection.glslSources.add("glslvert") <<
66 "precision mediump float;\n"
67 "layout (location = 0) in vec4 vertexPosition;\n"
70 " gl_Position = vertexPosition;\n"
73 shaderCollection.glslSources.add("glslfrag") <<
76 "precision mediump float;\n"
77 "layout (location = 0) out vec4 outputColor;\n"
80 " outputColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
84 Move<VkDevice> createTestDevice (const InstanceInterface& vki, VkPhysicalDevice physicalDevice, deUint32 *outQueueFamilyIndex)
86 VkDeviceQueueCreateInfo queueInfo;
87 VkDeviceCreateInfo deviceInfo;
89 const float queuePriority = 1.0f;
90 const deUint32 queueCount = 2u;
92 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
93 const VkPhysicalDeviceFeatures physicalDeviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice);
95 for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
97 if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT && (queueProps[queueNdx].queueCount >= queueCount))
101 if (queueNdx >= queueProps.size())
103 // No queue family index found
104 std::ostringstream msg;
105 msg << "Cannot create device with " << queueCount << " graphics queues";
107 throw tcu::NotSupportedError(msg.str());
110 deMemset(&queueInfo, 0, sizeof(queueInfo));
111 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
113 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
114 queueInfo.pNext = DE_NULL;
115 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
116 queueInfo.queueFamilyIndex = (deUint32)queueNdx;
117 queueInfo.queueCount = queueCount;
118 queueInfo.pQueuePriorities = &queuePriority;
120 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
121 deviceInfo.pNext = DE_NULL;
122 deviceInfo.queueCreateInfoCount = 1u;
123 deviceInfo.pQueueCreateInfos = &queueInfo;
124 deviceInfo.enabledExtensionCount = 0u;
125 deviceInfo.ppEnabledExtensionNames = DE_NULL;
126 deviceInfo.enabledLayerCount = 0u;
127 deviceInfo.ppEnabledLayerNames = DE_NULL;
128 deviceInfo.pEnabledFeatures = &physicalDeviceFeatures;
130 *outQueueFamilyIndex = queueInfo.queueFamilyIndex;
132 return createDevice(vki, physicalDevice, &deviceInfo);
135 struct BufferParameters
141 VkBufferUsageFlags usage;
142 VkSharingMode sharingMode;
143 deUint32 queueFamilyCount;
144 const deUint32* queueFamilyIndex;
145 VkAccessFlags inputBarrierFlags;
150 MovePtr<Allocation> allocation;
151 vector<VkMemoryBarrier> memoryBarrier;
152 vk::Move<VkBuffer> buffer;
155 void createVulkanBuffer (const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
157 TestLog& log = bufferParameters.context->getTestContext().getLog();
158 const VkDevice device = bufferParameters.device;
159 const VkPhysicalDevice physDevice = bufferParameters.context->getPhysicalDevice();
160 const DeviceInterface& deviceInterface = bufferParameters.context->getDeviceInterface();
161 const InstanceInterface& instanceInterface = bufferParameters.context->getInstanceInterface();
162 VkResult vkApiStatus;
163 VkPhysicalDeviceMemoryProperties memProps;
164 VkMemoryRequirements memReq;
165 VkBufferCreateInfo bufferCreateParams;
168 bufferCreateParams.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
169 bufferCreateParams.pNext = DE_NULL;
170 bufferCreateParams.flags = 0;
171 bufferCreateParams.size = bufferParameters.size;
172 bufferCreateParams.usage = bufferParameters.usage;
173 bufferCreateParams.sharingMode = bufferParameters.sharingMode;
174 bufferCreateParams.queueFamilyIndexCount = bufferParameters.queueFamilyCount;
175 bufferCreateParams.pQueueFamilyIndices = bufferParameters.queueFamilyIndex;
177 vkApiStatus = deviceInterface.createBuffer(device, &bufferCreateParams, DE_NULL, &newBuffer);
178 if (vkApiStatus != VK_SUCCESS)
180 log << TestLog::Message << "Vulkan createBuffer with (size,usage,sharingMode) = ("
181 << bufferParameters.size << "," << bufferParameters.usage << "," << bufferParameters.sharingMode <<") failed with status "
182 << vkApiStatus << TestLog::EndMessage;
183 VK_CHECK(vkApiStatus);
186 buffer.buffer = vk::Move<VkBuffer>(vk::check<VkBuffer>(newBuffer), Deleter<VkBuffer>(deviceInterface, device, DE_NULL));
188 instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
189 deviceInterface.getBufferMemoryRequirements(device, buffer.buffer.get(), &memReq);
192 Allocator& allocator = bufferParameters.context->getDefaultAllocator();
193 MovePtr<Allocation> newMemory (allocator.allocate(memReq, visibility));
195 vkApiStatus = deviceInterface.bindBufferMemory(device, buffer.buffer.get(), newMemory->getMemory(), newMemory->getOffset());
196 if (vkApiStatus != VK_SUCCESS)
198 log << TestLog::Message << "bindBufferMemory on device " << device
199 << "failed with status " << vkApiStatus << TestLog::EndMessage;
200 VK_CHECK(vkApiStatus);
203 // If caller provides a host memory buffer for the allocation, then go
204 // ahead and copy the provided data into the allocation and update the
205 // barrier list with the associated access
206 if (bufferParameters.memory != DE_NULL)
208 VkMemoryBarrier barrier;
209 VkMappedMemoryRange range;
211 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
212 range.pNext = DE_NULL;
213 range.memory = newMemory->getMemory();
214 range.offset = newMemory->getOffset();
215 range.size = bufferParameters.size;
217 deMemcpy(newMemory->getHostPtr(), bufferParameters.memory, (size_t)bufferParameters.size);
218 VK_CHECK(deviceInterface.flushMappedMemoryRanges(device, 1, &range));
220 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
221 barrier.pNext = DE_NULL;
222 barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
223 barrier.dstAccessMask = bufferParameters.inputBarrierFlags;
225 buffer.memoryBarrier.push_back(barrier);
227 buffer.allocation = newMemory;
231 struct ImageParameters
235 VkImageType imageType;
239 VkSampleCountFlagBits samples;
240 VkImageTiling tiling;
241 VkBufferUsageFlags usage;
242 VkSharingMode sharingMode;
243 deUint32 queueFamilyCount;
244 const deUint32* queueFamilyNdxList;
245 VkImageLayout initialLayout;
246 VkImageLayout finalLayout;
247 VkAccessFlags barrierInputMask;
252 vk::Move<VkImage> image;
253 vk::Move<VkImageView> imageView;
254 MovePtr<Allocation> allocation;
255 vector<VkImageMemoryBarrier> imageMemoryBarrier;
258 void createVulkanImage (const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
260 TestLog& log = imageParameters.context->getTestContext().getLog();
261 const DeviceInterface& deviceInterface = imageParameters.context->getDeviceInterface();
262 const InstanceInterface& instanceInterface = imageParameters.context->getInstanceInterface();
263 const VkPhysicalDevice physDevice = imageParameters.context->getPhysicalDevice();
264 const VkDevice device = imageParameters.device;
266 VkPhysicalDeviceMemoryProperties memProps;
267 VkMemoryRequirements memReq;
268 VkComponentMapping componentMap;
269 VkImageSubresourceRange subresourceRange;
270 VkImageViewCreateInfo imageViewCreateInfo;
271 VkImageCreateInfo imageCreateParams;
272 VkImageMemoryBarrier imageBarrier;
274 VkImageView newImageView;
276 imageCreateParams.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
277 imageCreateParams.pNext = DE_NULL;
278 imageCreateParams.flags = 0;
279 imageCreateParams.imageType = imageParameters.imageType;
280 imageCreateParams.format = imageParameters.format;
281 imageCreateParams.extent = imageParameters.extent3D;
282 imageCreateParams.mipLevels = imageParameters.mipLevels;
283 imageCreateParams.arrayLayers = 1;
284 imageCreateParams.samples = imageParameters.samples;
285 imageCreateParams.tiling = imageParameters.tiling;
286 imageCreateParams.usage = imageParameters.usage;
287 imageCreateParams.sharingMode = imageParameters.sharingMode;
288 imageCreateParams.queueFamilyIndexCount = imageParameters.queueFamilyCount;
289 imageCreateParams.pQueueFamilyIndices = imageParameters.queueFamilyNdxList;
290 imageCreateParams.initialLayout = imageParameters.initialLayout;
292 result = deviceInterface.createImage(device, &imageCreateParams, DE_NULL, &newImage);
293 if (result != VK_SUCCESS)
295 log << TestLog::Message << "createImage failed with status " << result << TestLog::EndMessage;
299 image.image = vk::Move<VkImage>(vk::check<VkImage>(newImage), Deleter<VkImage>(deviceInterface, device, DE_NULL));
301 instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
302 deviceInterface.getImageMemoryRequirements(device, image.image.get(), &memReq);
305 Allocator& allocator = imageParameters.context->getDefaultAllocator();
306 MovePtr<Allocation> newMemory (allocator.allocate(memReq, visibility));
307 result = deviceInterface.bindImageMemory(device, image.image.get(), newMemory->getMemory(), newMemory->getOffset());
308 if (result != VK_SUCCESS)
310 log << TestLog::Message << "bindImageMemory failed with status " << result << TestLog::EndMessage;
314 componentMap.r = VK_COMPONENT_SWIZZLE_R;
315 componentMap.g = VK_COMPONENT_SWIZZLE_G;
316 componentMap.b = VK_COMPONENT_SWIZZLE_B;
317 componentMap.a = VK_COMPONENT_SWIZZLE_A;
319 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
320 subresourceRange.baseMipLevel = 0;
321 subresourceRange.levelCount = imageParameters.mipLevels;
322 subresourceRange.baseArrayLayer = 0;
323 subresourceRange.layerCount = 1;
325 imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
326 imageViewCreateInfo.pNext = DE_NULL;
327 imageViewCreateInfo.flags = 0;
328 imageViewCreateInfo.image = image.image.get();
329 imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
330 imageViewCreateInfo.format = imageParameters.format;
331 imageViewCreateInfo.components = componentMap;
332 imageViewCreateInfo.subresourceRange = subresourceRange;
334 result = deviceInterface.createImageView(device, &imageViewCreateInfo, DE_NULL, &newImageView);
335 if (result != VK_SUCCESS)
337 log << TestLog::Message << "createImageView failed with status " << result << TestLog::EndMessage;
341 image.imageView = vk::Move<VkImageView>(vk::check<VkImageView>(newImageView), Deleter<VkImageView>(deviceInterface, device, DE_NULL));
342 image.allocation = newMemory;
344 imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
345 imageBarrier.pNext = DE_NULL;
346 imageBarrier.srcAccessMask = 0;
347 imageBarrier.dstAccessMask = imageParameters.barrierInputMask;
348 imageBarrier.oldLayout = imageParameters.initialLayout;
349 imageBarrier.newLayout = imageParameters.finalLayout;
350 imageBarrier.srcQueueFamilyIndex = imageParameters.queueFamilyNdxList[0];
351 imageBarrier.dstQueueFamilyIndex = imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
352 imageBarrier.image = image.image.get();
353 imageBarrier.subresourceRange = subresourceRange;
355 image.imageMemoryBarrier.push_back(imageBarrier);
359 struct RenderPassParameters
363 VkFormat colorFormat;
364 VkSampleCountFlagBits colorSamples;
367 void createColorOnlyRenderPass (const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
369 const DeviceInterface& deviceInterface = renderPassParameters.context->getDeviceInterface();
370 const VkDevice device = renderPassParameters.device;
371 VkAttachmentDescription colorAttachmentDesc;
372 VkAttachmentReference colorAttachmentRef;
373 VkAttachmentReference stencilAttachmentRef;
374 VkSubpassDescription subpassDesc;
375 VkRenderPassCreateInfo renderPassParams;
376 VkRenderPass newRenderPass;
378 colorAttachmentDesc.flags = 0;
379 colorAttachmentDesc.format = renderPassParameters.colorFormat;
380 colorAttachmentDesc.samples = renderPassParameters.colorSamples;
381 colorAttachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
382 colorAttachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
383 colorAttachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
384 colorAttachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
385 colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
386 colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
388 colorAttachmentRef.attachment = 0;
389 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
391 stencilAttachmentRef.attachment = VK_NO_ATTACHMENT;
392 stencilAttachmentRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
394 subpassDesc.flags = 0;
395 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
396 subpassDesc.inputAttachmentCount = 0;
397 subpassDesc.pInputAttachments = DE_NULL;
398 subpassDesc.colorAttachmentCount = 1;
399 subpassDesc.pColorAttachments = &colorAttachmentRef;
400 subpassDesc.pResolveAttachments = DE_NULL;
401 subpassDesc.pDepthStencilAttachment = &stencilAttachmentRef;
402 subpassDesc.preserveAttachmentCount = 0;
403 subpassDesc.pPreserveAttachments = DE_NULL;
405 renderPassParams.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
406 renderPassParams.pNext = DE_NULL;
407 renderPassParams.flags = 0;
408 renderPassParams.attachmentCount = 1;
409 renderPassParams.pAttachments = &colorAttachmentDesc;
410 renderPassParams.subpassCount = 1;
411 renderPassParams.pSubpasses = &subpassDesc;
412 renderPassParams.dependencyCount = 0;
413 renderPassParams.pDependencies = DE_NULL;
415 VK_CHECK(deviceInterface.createRenderPass(device, &renderPassParams, DE_NULL, &newRenderPass));
416 renderPass = vk::Move<VkRenderPass>(vk::check<VkRenderPass>(newRenderPass), Deleter<VkRenderPass>(deviceInterface, device, DE_NULL));
419 struct ShaderDescParams
422 VkShaderStageFlagBits stage;
425 void createGraphicsShaderStages (Context& context, const VkDevice device, vector<ShaderDescParams> shaderDesc, vector<VkPipelineShaderStageCreateInfo>& shaderCreateParams)
427 const DeviceInterface& deviceInterface = context.getDeviceInterface();
429 for (vector<ShaderDescParams>::iterator shaderDescIter = shaderDesc.begin(); shaderDescIter != shaderDesc.end(); shaderDescIter++)
431 VkPipelineShaderStageCreateInfo shaderStageInfo;
432 VkShaderModule shaderModule;
433 VkShaderModuleCreateInfo shaderModuleInfo;
435 shaderModuleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
436 shaderModuleInfo.pNext = DE_NULL;
437 shaderModuleInfo.flags = 0;
438 shaderModuleInfo.codeSize = context.getBinaryCollection().get(shaderDescIter->name).getSize();
439 shaderModuleInfo.pCode = (const deUint32*)context.getBinaryCollection().get(shaderDescIter->name).getBinary();
440 VK_CHECK(deviceInterface.createShaderModule(device, &shaderModuleInfo, DE_NULL, &shaderModule));
442 shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
443 shaderStageInfo.pNext = DE_NULL;
444 shaderStageInfo.flags = 0;
445 shaderStageInfo.stage = shaderDescIter->stage;
446 shaderStageInfo.module = shaderModule;
447 shaderStageInfo.pName = "main";
448 shaderStageInfo.pSpecializationInfo = DE_NULL;
449 shaderCreateParams.push_back(shaderStageInfo);
461 void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
463 for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
465 deUint32 bindingId = 0;
466 VkVertexInputBindingDescription bindingDesc;
467 VkVertexInputAttributeDescription attrDesc;
469 bindingDesc.binding = bindingId;
470 bindingDesc.stride = vertDescIter->stride;
471 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
472 bindingList.push_back(bindingDesc);
474 attrDesc.location = vertDescIter->location;
475 attrDesc.binding = bindingId;
476 attrDesc.format = vertDescIter->format;
477 attrDesc.offset = vertDescIter->offset;
478 attrList.push_back(attrDesc);
483 vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
484 vertexInputState.pNext = DE_NULL,
485 vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
486 vertexInputState.pVertexBindingDescriptions = &bindingList[0];
487 vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
488 vertexInputState.pVertexAttributeDescriptions = &attrList[0];
491 void createCommandBuffer (Context& context, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef)
493 const DeviceInterface& deviceInterface = context.getDeviceInterface();
494 VkCommandPool commandPool;
495 VkCommandPoolCreateInfo commandPoolInfo;
496 VkCommandBufferAllocateInfo commandBufferInfo;
497 VkCommandBuffer commandBuffer;
499 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
500 commandPoolInfo.pNext = DE_NULL;
501 commandPoolInfo.flags = 0;
502 commandPoolInfo.queueFamilyIndex = queueFamilyNdx;
504 VK_CHECK(deviceInterface.createCommandPool(device, &commandPoolInfo, DE_NULL, &commandPool));
506 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
507 commandBufferInfo.pNext = DE_NULL;
508 commandBufferInfo.commandPool = commandPool;
509 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
510 commandBufferInfo.commandBufferCount = 1;
512 VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
513 *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, commandPool));
516 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
518 VkFenceCreateInfo fenceState;
519 VkFenceCreateFlags signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
521 fenceState.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
522 fenceState.pNext = DE_NULL;
523 fenceState.flags = signalFlag;
525 for (deUint32 ndx = 0; ndx < numFences; ndx++)
526 VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
529 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
531 for (deUint32 ndx = 0; ndx < numFences; ndx++)
532 deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
540 deUint32 vertexBufferSize;
541 VkBuffer vertexBuffer;
543 VkCommandBuffer commandBuffer;
544 VkRenderPass renderPass;
545 VkFramebuffer framebuffer;
548 const deUint32* queueFamilyNdxList;
549 deUint32 queueFamilyNdxCount;
553 vector<VkImageMemoryBarrier>* barriers;
556 void recordRenderPass (const RenderInfo& renderInfo)
558 const DeviceInterface& deviceInterface = renderInfo.context->getDeviceInterface();
559 const VkDeviceSize bindingOffset = 0;
560 const VkClearValue clearValue = makeClearValueColorF32(0.0, 0.0, 1.0, 1.0);
561 VkRenderPassBeginInfo renderPassBeginState;
562 VkImageMemoryBarrier renderBarrier;
564 renderPassBeginState.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
565 renderPassBeginState.pNext = DE_NULL;
566 renderPassBeginState.renderPass = renderInfo.renderPass;
567 renderPassBeginState.framebuffer = renderInfo.framebuffer;
568 renderPassBeginState.renderArea.offset.x = 0;
569 renderPassBeginState.renderArea.offset.y = 0;
570 renderPassBeginState.renderArea.extent.width = renderInfo.width;
571 renderPassBeginState.renderArea.extent.height = renderInfo.height;
572 renderPassBeginState.clearValueCount = 1;
573 renderPassBeginState.pClearValues = &clearValue;
575 deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE);
576 if (renderInfo.waitEvent)
577 deviceInterface.cmdWaitEvents(renderInfo.commandBuffer, 1, &renderInfo.event, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 0, DE_NULL, 0, DE_NULL, 0, DE_NULL);
578 deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
579 deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
580 deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
581 if (renderInfo.setEvent)
582 deviceInterface.cmdSetEvent(renderInfo.commandBuffer, renderInfo.event, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
583 deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer);
585 renderBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
586 renderBarrier.pNext = DE_NULL;
587 renderBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
588 renderBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
589 renderBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
590 renderBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
591 renderBarrier.srcQueueFamilyIndex = renderInfo.queueFamilyNdxList[0];
592 renderBarrier.dstQueueFamilyIndex = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
593 renderBarrier.image = renderInfo.image;
594 renderBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
595 renderBarrier.subresourceRange.baseMipLevel = 0;
596 renderBarrier.subresourceRange.levelCount = renderInfo.mipLevels;
597 renderBarrier.subresourceRange.baseArrayLayer = 0;
598 renderBarrier.subresourceRange.layerCount = 1;
599 renderInfo.barriers->push_back(renderBarrier);
605 VkCommandBuffer commandBuffer;
612 VkOffset3D imageOffset;
613 vector<VkBufferMemoryBarrier>* barriers;
616 void copyToCPU (TransferInfo* transferInfo)
618 const DeviceInterface& deviceInterface = transferInfo->context->getDeviceInterface();
619 VkBufferImageCopy copyState;
621 copyState.bufferOffset = 0;
622 copyState.bufferRowLength = transferInfo->width;
623 copyState.bufferImageHeight = transferInfo->height;
624 copyState.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
625 copyState.imageSubresource.mipLevel = transferInfo->mipLevel;
626 copyState.imageSubresource.baseArrayLayer = 0;
627 copyState.imageSubresource.layerCount = 1;
628 copyState.imageOffset = transferInfo->imageOffset;
629 copyState.imageExtent.width = (deInt32)(transferInfo->width);
630 copyState.imageExtent.height = (deInt32)(transferInfo->height);
631 copyState.imageExtent.depth = 1;
633 deviceInterface.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, ©State);
636 VkBufferMemoryBarrier bufferBarrier;
637 bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
638 bufferBarrier.pNext = DE_NULL;
639 bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
640 bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
641 bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
642 bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
643 bufferBarrier.buffer = transferInfo->buffer;
644 bufferBarrier.offset = 0;
645 bufferBarrier.size = transferInfo->size;
646 transferInfo->barriers->push_back(bufferBarrier);
653 const VkDevice& device;
654 const tcu::Vec4* vertices;
655 deUint32 numVertices;
656 tcu::IVec2 renderDimension;
658 VkDeviceSize renderSize;
659 MovePtr<Allocation> renderReadBuffer;
660 MovePtr<Allocation> vertexBufferAllocation;
661 vk::Move<VkBuffer> vertexBuffer;
662 vk::Move<VkBuffer> renderBuffer;
666 vk::Move<VkImage> image;
667 vk::Move<VkImageView> imageView;
668 vk::Move<VkCommandBuffer> cmdBuffer;
669 MovePtr<Allocation> imageAllocation;
671 TestContext(Context& context_, const VkDevice& device_)
675 , setEvent (DE_FALSE)
676 , waitEvent (DE_FALSE)
678 createFences(context.getDeviceInterface(), device, false, DE_LENGTH_OF_ARRAY(fences), fences);
683 destroyFences(context.getDeviceInterface(), device, DE_LENGTH_OF_ARRAY(fences), fences);
687 void generateWork (TestContext& testContext)
689 const DeviceInterface& deviceInterface = testContext.context.getDeviceInterface();
690 const deUint32 queueFamilyNdx = testContext.context.getUniversalQueueFamilyIndex();
691 vk::Move<VkRenderPass> renderPass;
692 VkPipelineCache cache;
693 VkPipelineLayout layout;
695 VkFramebuffer framebuffer;
696 vector<ShaderDescParams> shaderDescParams;
697 vector<VkPipelineShaderStageCreateInfo> shaderStageCreateParams;
698 VertexDesc vertexDesc;
699 vector<VertexDesc> vertexDescList;
700 vector<VkVertexInputAttributeDescription> attrList;
701 vector<VkBufferMemoryBarrier> bufferMemoryBarrier;
702 deUint32 memoryBarrierNdx;
703 deUint32 bufferMemoryBarrierNdx;
704 deUint32 imageMemoryBarrierNdx;
705 vector<VkVertexInputBindingDescription> bindingList;
706 VkPipelineVertexInputStateCreateInfo vertexInputState;
707 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
708 VkPipelineDepthStencilStateCreateInfo depthStencilState;
709 VkPipelineColorBlendAttachmentState blendAttachment;
710 VkPipelineColorBlendStateCreateInfo blendState;
711 VkPipelineLayoutCreateInfo pipelineLayoutState;
712 VkGraphicsPipelineCreateInfo pipelineState;
713 VkPipelineCacheCreateInfo cacheState;
715 VkPipelineViewportStateCreateInfo viewportInfo;
717 BufferParameters bufferParameters;
719 RenderInfo renderInfo;
720 ImageParameters imageParameters;
722 VkPipelineRasterizationStateCreateInfo rasterState;
723 VkPipelineMultisampleStateCreateInfo multisampleState;
724 VkFramebufferCreateInfo fbState;
725 VkCommandBufferBeginInfo commandBufRecordState;
726 VkCommandBufferInheritanceInfo inheritanceInfo;
727 RenderPassParameters renderPassParameters;
728 TransferInfo transferInfo;
729 vector<void*> barrierList;
731 vector<VkMemoryBarrier> memoryBarriers;
732 vector<VkBufferMemoryBarrier> bufferBarriers;
733 vector<VkImageMemoryBarrier> imageBarriers;
735 memoryBarrierNdx = 0;
736 bufferMemoryBarrierNdx = 0;
737 imageMemoryBarrierNdx = 0;
738 buffer.memoryBarrier.resize(memoryBarrierNdx);
739 bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
740 image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
742 memoryBarriers.resize(0);
743 bufferBarriers.resize(0);
744 imageBarriers.resize(0);
746 bufferParameters.context = &testContext.context;
747 bufferParameters.device = testContext.device;
748 bufferParameters.memory = testContext.vertices;
749 bufferParameters.size = testContext.numVertices * sizeof(tcu::Vec4);
750 bufferParameters.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
751 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
752 bufferParameters.queueFamilyCount = 1;
753 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
754 bufferParameters.inputBarrierFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
755 createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
756 testContext.vertexBufferAllocation = buffer.allocation;
757 testContext.vertexBuffer = buffer.buffer;
759 bufferParameters.context = &testContext.context;
760 bufferParameters.device = testContext.device;
761 bufferParameters.memory = DE_NULL;
762 bufferParameters.size = testContext.renderSize;
763 bufferParameters.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
764 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
765 bufferParameters.queueFamilyCount = 1;
766 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
767 bufferParameters.inputBarrierFlags = 0;
768 createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
769 testContext.renderReadBuffer = buffer.allocation;
770 testContext.renderBuffer = buffer.buffer;
772 extent.width = testContext.renderDimension.x();
773 extent.height = testContext.renderDimension.y();
776 imageParameters.context = &testContext.context;
777 imageParameters.device = testContext.device;
778 imageParameters.imageType = VK_IMAGE_TYPE_2D;
779 imageParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
780 imageParameters.extent3D = extent;
781 imageParameters.mipLevels = 1;
782 imageParameters.samples = VK_SAMPLE_COUNT_1_BIT;
783 imageParameters.tiling = VK_IMAGE_TILING_OPTIMAL;
784 imageParameters.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
785 imageParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
786 imageParameters.queueFamilyCount = 1;
787 imageParameters.queueFamilyNdxList = &queueFamilyNdx;
788 imageParameters.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
789 imageParameters.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
790 imageParameters.barrierInputMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
791 createVulkanImage(imageParameters, image, MemoryRequirement::Any);
792 testContext.imageAllocation = image.allocation;
793 testContext.image = image.image;
795 renderPassParameters.context = &testContext.context;
796 renderPassParameters.device = testContext.device;
797 renderPassParameters.colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
798 renderPassParameters.colorSamples = VK_SAMPLE_COUNT_1_BIT;
799 createColorOnlyRenderPass(renderPassParameters, renderPass);
801 ShaderDescParams param;
802 param.name = "glslvert";
803 param.stage = VK_SHADER_STAGE_VERTEX_BIT;
804 shaderDescParams.push_back(param);
806 param.name = "glslfrag";
807 param.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
808 shaderDescParams.push_back(param);
809 createGraphicsShaderStages(testContext.context, testContext.device, shaderDescParams, shaderStageCreateParams);
811 vertexDesc.location = 0;
812 vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
813 vertexDesc.stride = sizeof(tcu::Vec4);
814 vertexDesc.offset = 0;
815 vertexDescList.push_back(vertexDesc);
817 createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
819 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
820 inputAssemblyState.pNext = DE_NULL;
821 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
822 inputAssemblyState.primitiveRestartEnable = DE_FALSE;
826 viewport.width = (float)testContext.renderDimension.x();
827 viewport.height = (float)testContext.renderDimension.y();
828 viewport.minDepth = 0;
829 viewport.maxDepth = 1;
831 scissor.offset.x = 0;
832 scissor.offset.y = 0;
833 scissor.extent.width = testContext.renderDimension.x();
834 scissor.extent.height = testContext.renderDimension.y();
836 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
837 viewportInfo.pNext = DE_NULL;
838 viewportInfo.flags = 0;
839 viewportInfo.viewportCount = 1;
840 viewportInfo.pViewports = &viewport;
841 viewportInfo.scissorCount = 1;
842 viewportInfo.pScissors = &scissor;
844 rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
845 rasterState.pNext = DE_NULL;
846 rasterState.flags = 0;
847 rasterState.depthClampEnable = VK_TRUE;
848 rasterState.rasterizerDiscardEnable = VK_FALSE;
849 rasterState.polygonMode = VK_POLYGON_MODE_FILL;
850 rasterState.cullMode = VK_CULL_MODE_NONE;
851 rasterState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
852 rasterState.depthBiasEnable = VK_FALSE;
853 rasterState.lineWidth = 1;
855 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
856 multisampleState.pNext = DE_NULL;
857 multisampleState.flags = 0;
858 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
859 multisampleState.sampleShadingEnable = VK_FALSE;
860 multisampleState.pSampleMask = DE_NULL;
861 multisampleState.alphaToCoverageEnable = VK_FALSE;
862 multisampleState.alphaToOneEnable = VK_FALSE;
864 depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
865 depthStencilState.pNext = DE_NULL;
866 depthStencilState.flags = 0;
867 depthStencilState.depthTestEnable = VK_FALSE;
868 depthStencilState.depthWriteEnable = VK_FALSE;
869 depthStencilState.depthBoundsTestEnable = VK_FALSE;
870 depthStencilState.stencilTestEnable = VK_FALSE;
872 blendAttachment.blendEnable = VK_FALSE;
874 blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
875 blendState.pNext = DE_NULL;
876 blendState.flags = 0;
877 blendState.logicOpEnable = VK_FALSE;
878 blendState.attachmentCount = 1;
879 blendState.pAttachments = &blendAttachment;
881 pipelineLayoutState.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
882 pipelineLayoutState.pNext = DE_NULL;
883 pipelineLayoutState.flags = 0;
884 pipelineLayoutState.setLayoutCount = 0;
885 pipelineLayoutState.pSetLayouts = DE_NULL;
886 pipelineLayoutState.pushConstantRangeCount = 0;
887 pipelineLayoutState.pPushConstantRanges = DE_NULL;
888 VK_CHECK(deviceInterface.createPipelineLayout(testContext.device, &pipelineLayoutState, DE_NULL, &layout));
890 pipelineState.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
891 pipelineState.pNext = DE_NULL;
892 pipelineState.flags = 0;
893 pipelineState.stageCount = (deUint32)shaderStageCreateParams.size();
894 pipelineState.pStages = &shaderStageCreateParams[0];
895 pipelineState.pVertexInputState = &vertexInputState;
896 pipelineState.pInputAssemblyState = &inputAssemblyState;
897 pipelineState.pTessellationState = DE_NULL;
898 pipelineState.pViewportState = &viewportInfo;
899 pipelineState.pRasterizationState = &rasterState;
900 pipelineState.pMultisampleState = &multisampleState;
901 pipelineState.pDepthStencilState = &depthStencilState;
902 pipelineState.pColorBlendState = &blendState;
903 pipelineState.pDynamicState = (const VkPipelineDynamicStateCreateInfo*)DE_NULL;
904 pipelineState.layout = layout;
905 pipelineState.renderPass = renderPass.get();
906 pipelineState.subpass = 0;
907 pipelineState.basePipelineHandle = DE_NULL;
908 pipelineState.basePipelineIndex = 0;
910 cacheState.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
911 cacheState.pNext = DE_NULL;
912 cacheState.flags = 0;
913 cacheState.initialDataSize = 0;
914 cacheState.pInitialData = DE_NULL;
916 VK_CHECK(deviceInterface.createPipelineCache(testContext.device, &cacheState, DE_NULL, &cache));
917 VK_CHECK(deviceInterface.createGraphicsPipelines(testContext.device, cache, 1, &pipelineState, DE_NULL, &pipeline));
919 fbState.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
920 fbState.pNext = DE_NULL;
922 fbState.renderPass = renderPass.get();
923 fbState.attachmentCount = 1;
924 fbState.pAttachments = &image.imageView.get();
925 fbState.width = (deUint32)testContext.renderDimension.x();
926 fbState.height = (deUint32)testContext.renderDimension.y();
928 VK_CHECK(deviceInterface.createFramebuffer(testContext.device, &fbState, DE_NULL, &framebuffer));
929 testContext.imageView = image.imageView;
931 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
932 inheritanceInfo.pNext = DE_NULL;
933 inheritanceInfo.renderPass = renderPass.get();
934 inheritanceInfo.subpass = 0;
935 inheritanceInfo.framebuffer = framebuffer;
936 inheritanceInfo.occlusionQueryEnable = VK_FALSE;
938 commandBufRecordState.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
939 commandBufRecordState.pNext = DE_NULL;
940 commandBufRecordState.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
941 commandBufRecordState.pInheritanceInfo = &inheritanceInfo;
942 VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
944 deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
945 VK_PIPELINE_STAGE_HOST_BIT,
946 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
948 (deUint32)memoryBarriers.size(), &memoryBarriers[0],
949 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
950 (deUint32)imageBarriers.size(), &imageBarriers[0]);
952 memoryBarriers.resize(0);
953 bufferBarriers.resize(0);
954 imageBarriers.resize(0);
956 renderInfo.context = &testContext.context;
957 renderInfo.width = testContext.renderDimension.x();
958 renderInfo.height = testContext.renderDimension.y();
959 renderInfo.vertexBufferSize = testContext.numVertices;
960 renderInfo.vertexBuffer = testContext.vertexBuffer.get();
961 renderInfo.image = testContext.image.get();
962 renderInfo.commandBuffer = testContext.cmdBuffer.get();
963 renderInfo.renderPass = renderPass.get();
964 renderInfo.framebuffer = framebuffer;
965 renderInfo.pipeline = pipeline;
966 renderInfo.mipLevels = 1;
967 renderInfo.queueFamilyNdxList = &queueFamilyNdx;
968 renderInfo.queueFamilyNdxCount = 1;
969 renderInfo.setEvent = testContext.setEvent;
970 renderInfo.waitEvent = testContext.waitEvent;
971 renderInfo.event = testContext.event;
972 renderInfo.barriers = &imageBarriers;
973 recordRenderPass(renderInfo);
975 deviceInterface.cmdPipelineBarrier( renderInfo.commandBuffer,
976 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
977 VK_PIPELINE_STAGE_TRANSFER_BIT,
979 (deUint32)memoryBarriers.size(), &memoryBarriers[0],
980 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
981 (deUint32)imageBarriers.size(), &imageBarriers[0]);
983 memoryBarriers.resize(0);
984 bufferBarriers.resize(0);
985 imageBarriers.resize(0);
987 transferInfo.context = &testContext.context;
988 transferInfo.commandBuffer = renderInfo.commandBuffer;
989 transferInfo.width = testContext.renderDimension.x();
990 transferInfo.height = testContext.renderDimension.y();
991 transferInfo.image = renderInfo.image;
992 transferInfo.buffer = testContext.renderBuffer.get();
993 transferInfo.size = testContext.renderSize;
994 transferInfo.mipLevel = 0;
995 transferInfo.imageOffset.x = 0;
996 transferInfo.imageOffset.y = 0;
997 transferInfo.imageOffset.z = 0;
998 transferInfo.barriers = &bufferBarriers;
999 copyToCPU(&transferInfo);
1001 deviceInterface.cmdPipelineBarrier( transferInfo.commandBuffer,
1002 VK_PIPELINE_STAGE_TRANSFER_BIT,
1003 VK_PIPELINE_STAGE_HOST_BIT,
1005 (deUint32)memoryBarriers.size(), &memoryBarriers[0],
1006 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
1007 (deUint32)imageBarriers.size(), &imageBarriers[0]);
1009 memoryBarriers.resize(0);
1010 bufferBarriers.resize(0);
1011 imageBarriers.resize(0);
1013 VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer));
1016 static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount)
1018 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
1020 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1021 submitInfo[ndx].pNext = DE_NULL;
1022 submitInfo[ndx].waitSemaphoreCount = 0;
1023 submitInfo[ndx].pWaitSemaphores = DE_NULL;
1024 submitInfo[ndx].pWaitDstStageMask = DE_NULL;
1025 submitInfo[ndx].commandBufferCount = 1;
1026 submitInfo[ndx].signalSemaphoreCount = 0;
1027 submitInfo[ndx].pSignalSemaphores = DE_NULL;
1031 tcu::TestStatus testFences (Context& context)
1033 TestLog& log = context.getTestContext().getLog();
1034 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1035 const VkQueue queue = context.getUniversalQueue();
1036 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
1037 VkDevice device = context.getDevice();
1038 VkResult testStatus;
1039 VkResult fenceStatus;
1040 TestContext testContext(context, device);
1041 VkSubmitInfo submitInfo;
1042 VkMappedMemoryRange range;
1045 const tcu::Vec4 vertices[] =
1047 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1048 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1049 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1052 testContext.vertices = vertices;
1053 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
1054 testContext.renderDimension = tcu::IVec2(256, 256);
1055 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1057 createCommandBuffer(testContext.context, device, queueFamilyIdx, &testContext.cmdBuffer);
1058 generateWork(testContext);
1060 initSubmitInfo(&submitInfo, 1);
1061 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
1063 // Default status is unsignaled
1064 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1065 if (fenceStatus != VK_NOT_READY)
1067 log << TestLog::Message << "testSynchronizationPrimitives fence 0 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1068 return tcu::TestStatus::fail("Fence in incorrect state");
1070 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[1]);
1071 if (fenceStatus != VK_NOT_READY)
1073 log << TestLog::Message << "testSynchronizationPrimitives fence 1 should be reset but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1074 return tcu::TestStatus::fail("Fence in incorrect state");
1077 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1079 // Wait for both fences
1080 testStatus = deviceInterface.waitForFences(device, 2, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1081 if (testStatus != VK_TIMEOUT)
1083 log << TestLog::Message << "testSynchPrimitives failed to wait for all fences" << TestLog::EndMessage;
1084 return tcu::TestStatus::fail("Failed to wait for mulitple fences");
1087 // Wait until timeout (no work has been submited to testContext.fences[1])
1088 testStatus = deviceInterface.waitForFences(device,
1090 &testContext.fences[1],
1094 if (testStatus != VK_TIMEOUT)
1096 log << TestLog::Message << "testSyncPrimitives failed to wait for single fence" << TestLog::EndMessage;
1097 return tcu::TestStatus::fail("failed to wait for single fence");
1100 // Wait for testContext.fences[0], assuming that the work can be completed
1101 // in the default time + the time given so far since the queueSubmit
1102 testStatus = deviceInterface.waitForFences(device, 1, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1103 if (testStatus != VK_SUCCESS)
1105 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1106 return tcu::TestStatus::fail("failed to wait for a set fence");
1109 // Check that the fence is signaled after the wait
1110 fenceStatus = deviceInterface.getFenceStatus(device, testContext.fences[0]);
1111 if (fenceStatus != VK_SUCCESS)
1113 log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << getResultName(fenceStatus) << TestLog::EndMessage;
1114 return tcu::TestStatus::fail("Fence in incorrect state");
1117 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1118 range.pNext = DE_NULL;
1119 range.memory = testContext.renderReadBuffer->getMemory();
1121 range.size = testContext.renderSize;
1122 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device, 1, &range));
1123 resultImage = testContext.renderReadBuffer->getHostPtr();
1125 log << TestLog::Image( "result",
1127 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1128 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1129 testContext.renderDimension.x(),
1130 testContext.renderDimension.y(),
1134 return TestStatus::pass("synchronization-fences passed");
1137 vk::refdetails::Checked<VkSemaphore> createSemaphore (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
1139 VkSemaphoreCreateInfo semaCreateInfo;
1140 VkSemaphore semaphore;
1142 semaCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1143 semaCreateInfo.pNext = DE_NULL;
1144 semaCreateInfo.flags = 0;
1145 VK_CHECK(deviceInterface.createSemaphore(device, &semaCreateInfo, allocationCallbacks, &semaphore));
1147 return vk::check<VkSemaphore>(semaphore);
1150 tcu::TestStatus testSemaphores (Context& context)
1152 TestLog& log = context.getTestContext().getLog();
1153 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1154 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1155 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1156 deUint32 queueFamilyIdx;
1157 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice, &queueFamilyIdx);
1159 VkResult testStatus;
1160 TestContext testContext1(context, device.get());
1161 TestContext testContext2(context, device.get());
1162 Unique<VkSemaphore> semaphore(createSemaphore(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkSemaphore>(deviceInterface, device.get(), DE_NULL));
1163 VkSubmitInfo submitInfo[2];
1164 VkMappedMemoryRange range;
1167 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
1168 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
1170 const tcu::Vec4 vertices1[] =
1172 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1173 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1174 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1177 const tcu::Vec4 vertices2[] =
1179 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1180 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1181 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1184 testContext1.vertices = vertices1;
1185 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1186 testContext1.renderDimension = tcu::IVec2(256, 256);
1187 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1189 testContext2.vertices = vertices2;
1190 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
1191 testContext2.renderDimension = tcu::IVec2(256, 256);
1192 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1194 createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
1195 generateWork(testContext1);
1197 createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
1198 generateWork(testContext2);
1200 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
1202 // The difference between the two submit infos is that each will use a unique cmd buffer,
1203 // and one will signal a semaphore but not wait on a semaphore, the other will wait on the
1204 // semaphore but not signal a semaphore
1205 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
1206 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
1208 submitInfo[0].signalSemaphoreCount = 1;
1209 submitInfo[0].pSignalSemaphores = &semaphore.get();
1210 submitInfo[1].waitSemaphoreCount = 1;
1211 submitInfo[1].pWaitSemaphores = &semaphore.get();
1213 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
1215 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1216 if (testStatus != VK_SUCCESS)
1218 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1219 return tcu::TestStatus::fail("failed to wait for a set fence");
1222 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1223 range.pNext = DE_NULL;
1224 range.memory = testContext1.renderReadBuffer->getMemory();
1226 range.size = testContext1.renderSize;
1227 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1228 resultImage = testContext1.renderReadBuffer->getHostPtr();
1230 log << TestLog::Image( "result",
1232 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1233 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1234 testContext1.renderDimension.x(),
1235 testContext1.renderDimension.y(),
1239 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
1241 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1242 if (testStatus != VK_SUCCESS)
1244 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1245 return tcu::TestStatus::fail("failed to wait for a set fence");
1248 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1249 range.pNext = DE_NULL;
1250 range.memory = testContext2.renderReadBuffer->getMemory();
1252 range.size = testContext2.renderSize;
1253 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1254 resultImage = testContext2.renderReadBuffer->getHostPtr();
1256 log << TestLog::Image( "result",
1258 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1259 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1260 testContext2.renderDimension.x(),
1261 testContext2.renderDimension.y(),
1265 return tcu::TestStatus::pass("synchronization-semaphores passed");
1268 vk::refdetails::Checked<VkEvent> createEvent (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
1270 VkEventCreateInfo eventCreateInfo;
1273 eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1274 eventCreateInfo.pNext = DE_NULL;
1275 eventCreateInfo.flags = 0;
1276 VK_CHECK(deviceInterface.createEvent(device, &eventCreateInfo, allocationCallbacks, &event));
1278 return vk::check<VkEvent>(event);
1281 tcu::TestStatus testEvents (Context& context)
1283 TestLog& log = context.getTestContext().getLog();
1284 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1285 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1286 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1287 deUint32 queueFamilyIdx;
1288 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice, &queueFamilyIdx);
1290 VkResult testStatus;
1291 VkResult eventStatus;
1292 TestContext testContext1(context, device.get());
1293 TestContext testContext2(context, device.get());
1294 Unique<VkEvent> event(createEvent(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkEvent>(deviceInterface, device.get(), DE_NULL));
1295 VkSubmitInfo submitInfo[2];
1296 VkMappedMemoryRange range;
1299 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
1300 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
1302 const tcu::Vec4 vertices1[] =
1304 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1305 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1306 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1309 const tcu::Vec4 vertices2[] =
1311 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1312 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1313 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1316 testContext1.vertices = vertices1;
1317 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1318 testContext1.renderDimension = tcu::IVec2(256, 256);
1319 testContext1.setEvent = DE_TRUE;
1320 testContext1.event = event.get();
1321 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1323 testContext2.vertices = vertices2;
1324 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
1325 testContext2.renderDimension = tcu::IVec2(256, 256);
1326 testContext2.waitEvent = DE_TRUE;
1327 testContext2.event = event.get();
1328 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1330 createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
1331 generateWork(testContext1);
1333 createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
1334 generateWork(testContext2);
1336 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
1337 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
1338 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
1340 eventStatus = deviceInterface.getEventStatus(device.get(), event.get());
1341 if (eventStatus != VK_EVENT_RESET)
1343 log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << getResultName(eventStatus) << TestLog::EndMessage;
1344 return tcu::TestStatus::fail("Event in incorrect status");
1347 // Now the two contexts are submitted normally, so, context1 and set the event and context2 can wait for the event
1348 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
1349 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
1351 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1352 if (testStatus != VK_SUCCESS)
1354 log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set fence" << TestLog::EndMessage;
1355 return tcu::TestStatus::fail("failed to wait for set fence");
1358 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1359 range.pNext = DE_NULL;
1360 range.memory = testContext1.renderReadBuffer->getMemory();
1362 range.size = testContext1.renderSize;
1363 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1364 resultImage = testContext1.renderReadBuffer->getHostPtr();
1366 log << TestLog::Image( "result",
1368 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1369 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1370 testContext1.renderDimension.x(),
1371 testContext1.renderDimension.y(),
1375 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1376 if (testStatus != VK_SUCCESS)
1378 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1379 return tcu::TestStatus::fail("failed to wait for a set fence");
1382 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1383 range.pNext = DE_NULL;
1384 range.memory = testContext2.renderReadBuffer->getMemory();
1386 range.size = testContext2.renderSize;
1387 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1388 resultImage = testContext2.renderReadBuffer->getHostPtr();
1390 log << TestLog::Image( "result",
1392 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1393 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1394 testContext2.renderDimension.x(),
1395 testContext2.renderDimension.y(),
1399 return tcu::TestStatus::pass("synchronization-events passed");
1404 tcu::TestCaseGroup* createSynchronizationTests (tcu::TestContext& textCtx)
1406 de::MovePtr<tcu::TestCaseGroup> synchTests (new tcu::TestCaseGroup(textCtx, "synchronization", "Vulkan Synchronization Tests"));
1408 addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
1409 addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores);
1410 addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents);
1412 return synchTests.release();