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)
86 VkDeviceQueueCreateInfo queueInfo;
87 VkDeviceCreateInfo deviceInfo;
89 const float queuePriority = 1.0f;
91 const vector<VkQueueFamilyProperties> queueProps = getPhysicalDeviceQueueFamilyProperties(vki, physicalDevice);
92 const VkPhysicalDeviceFeatures physicalDeviceFeatures = getPhysicalDeviceFeatures(vki, physicalDevice);
94 for (queueNdx = 0; queueNdx < queueProps.size(); queueNdx++)
96 if ((queueProps[queueNdx].queueFlags & VK_QUEUE_GRAPHICS_BIT) == VK_QUEUE_GRAPHICS_BIT)
100 deMemset(&queueInfo, 0, sizeof(queueInfo));
101 deMemset(&deviceInfo, 0, sizeof(deviceInfo));
103 queueInfo.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
104 queueInfo.pNext = DE_NULL;
105 queueInfo.flags = (VkDeviceQueueCreateFlags)0u;
106 queueInfo.queueFamilyIndex = (deUint32)queueNdx;
107 queueInfo.queueCount = 2u;
108 queueInfo.pQueuePriorities = &queuePriority;
110 deviceInfo.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
111 deviceInfo.pNext = DE_NULL;
112 deviceInfo.queueCreateInfoCount = 1u;
113 deviceInfo.pQueueCreateInfos = &queueInfo;
114 deviceInfo.enabledExtensionCount = 0u;
115 deviceInfo.ppEnabledExtensionNames = DE_NULL;
116 deviceInfo.enabledLayerCount = 0u;
117 deviceInfo.ppEnabledLayerNames = DE_NULL;
118 deviceInfo.pEnabledFeatures = &physicalDeviceFeatures;
120 return createDevice(vki, physicalDevice, &deviceInfo);
123 struct BufferParameters
129 VkBufferUsageFlags usage;
130 VkSharingMode sharingMode;
131 deUint32 queueFamilyCount;
132 const deUint32* queueFamilyIndex;
133 VkAccessFlags inputBarrierFlags;
138 MovePtr<Allocation> allocation;
139 vector<VkMemoryBarrier> memoryBarrier;
140 vk::Move<VkBuffer> buffer;
143 void createVulkanBuffer (const BufferParameters& bufferParameters, Buffer& buffer, MemoryRequirement visibility)
145 TestLog& log = bufferParameters.context->getTestContext().getLog();
146 const VkDevice device = bufferParameters.device;
147 const VkPhysicalDevice physDevice = bufferParameters.context->getPhysicalDevice();
148 const DeviceInterface& deviceInterface = bufferParameters.context->getDeviceInterface();
149 const InstanceInterface& instanceInterface = bufferParameters.context->getInstanceInterface();
150 VkResult vkApiStatus;
151 VkPhysicalDeviceMemoryProperties memProps;
152 VkMemoryRequirements memReq;
153 VkBufferCreateInfo bufferCreateParams;
156 bufferCreateParams.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
157 bufferCreateParams.pNext = DE_NULL;
158 bufferCreateParams.flags = 0;
159 bufferCreateParams.size = bufferParameters.size;
160 bufferCreateParams.usage = bufferParameters.usage;
161 bufferCreateParams.sharingMode = bufferParameters.sharingMode;
162 bufferCreateParams.queueFamilyIndexCount = bufferParameters.queueFamilyCount;
163 bufferCreateParams.pQueueFamilyIndices = bufferParameters.queueFamilyIndex;
165 vkApiStatus = deviceInterface.createBuffer(device, &bufferCreateParams, DE_NULL, &newBuffer);
166 if (vkApiStatus != VK_SUCCESS)
168 log << TestLog::Message << "Vulkan createBuffer with (size,usage,sharingMode) = ("
169 << bufferParameters.size << "," << bufferParameters.usage << "," << bufferParameters.sharingMode <<") failed with status "
170 << vkApiStatus << TestLog::EndMessage;
171 VK_CHECK(vkApiStatus);
174 buffer.buffer = vk::Move<VkBuffer>(vk::check<VkBuffer>(newBuffer), Deleter<VkBuffer>(deviceInterface, device, DE_NULL));
176 instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
177 deviceInterface.getBufferMemoryRequirements(device, buffer.buffer.get(), &memReq);
180 Allocator& allocator = bufferParameters.context->getDefaultAllocator();
181 MovePtr<Allocation> newMemory (allocator.allocate(memReq, visibility));
183 vkApiStatus = deviceInterface.bindBufferMemory(device, buffer.buffer.get(), newMemory->getMemory(), newMemory->getOffset());
184 if (vkApiStatus != VK_SUCCESS)
186 log << TestLog::Message << "bindBufferMemory on device " << device
187 << "failed with status " << vkApiStatus << TestLog::EndMessage;
188 VK_CHECK(vkApiStatus);
191 // If caller provides a host memory buffer for the allocation, then go
192 // ahead and copy the provided data into the allocation and update the
193 // barrier list with the associated access
194 if (bufferParameters.memory != DE_NULL)
196 VkMemoryBarrier barrier;
197 VkMappedMemoryRange range;
199 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
200 range.pNext = DE_NULL;
201 range.memory = newMemory->getMemory();
202 range.offset = newMemory->getOffset();
203 range.size = bufferParameters.size;
205 deMemcpy(newMemory->getHostPtr(), bufferParameters.memory, (size_t)bufferParameters.size);
206 VK_CHECK(deviceInterface.flushMappedMemoryRanges(device, 1, &range));
208 barrier.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER;
209 barrier.pNext = DE_NULL;
210 barrier.srcAccessMask = VK_ACCESS_HOST_WRITE_BIT;
211 barrier.dstAccessMask = bufferParameters.inputBarrierFlags;
213 buffer.memoryBarrier.push_back(barrier);
215 buffer.allocation = newMemory;
219 struct ImageParameters
223 VkImageType imageType;
227 VkSampleCountFlagBits samples;
228 VkImageTiling tiling;
229 VkBufferUsageFlags usage;
230 VkSharingMode sharingMode;
231 deUint32 queueFamilyCount;
232 const deUint32* queueFamilyNdxList;
233 VkImageLayout initialLayout;
234 VkImageLayout finalLayout;
235 VkAccessFlags barrierInputMask;
240 vk::Move<VkImage> image;
241 vk::Move<VkImageView> imageView;
242 MovePtr<Allocation> allocation;
243 vector<VkImageMemoryBarrier> imageMemoryBarrier;
246 void createVulkanImage (const ImageParameters& imageParameters, Image& image, MemoryRequirement visibility)
248 TestLog& log = imageParameters.context->getTestContext().getLog();
249 const DeviceInterface& deviceInterface = imageParameters.context->getDeviceInterface();
250 const InstanceInterface& instanceInterface = imageParameters.context->getInstanceInterface();
251 const VkPhysicalDevice physDevice = imageParameters.context->getPhysicalDevice();
252 const VkDevice device = imageParameters.device;
254 VkPhysicalDeviceMemoryProperties memProps;
255 VkMemoryRequirements memReq;
256 VkComponentMapping componentMap;
257 VkImageSubresourceRange subresourceRange;
258 VkImageViewCreateInfo imageViewCreateInfo;
259 VkImageCreateInfo imageCreateParams;
260 VkImageMemoryBarrier imageBarrier;
262 VkImageView newImageView;
264 imageCreateParams.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
265 imageCreateParams.pNext = DE_NULL;
266 imageCreateParams.flags = 0;
267 imageCreateParams.imageType = imageParameters.imageType;
268 imageCreateParams.format = imageParameters.format;
269 imageCreateParams.extent = imageParameters.extent3D;
270 imageCreateParams.mipLevels = imageParameters.mipLevels;
271 imageCreateParams.arrayLayers = 1;
272 imageCreateParams.samples = imageParameters.samples;
273 imageCreateParams.tiling = imageParameters.tiling;
274 imageCreateParams.usage = imageParameters.usage;
275 imageCreateParams.sharingMode = imageParameters.sharingMode;
276 imageCreateParams.queueFamilyIndexCount = imageParameters.queueFamilyCount;
277 imageCreateParams.pQueueFamilyIndices = imageParameters.queueFamilyNdxList;
278 imageCreateParams.initialLayout = imageParameters.initialLayout;
280 result = deviceInterface.createImage(device, &imageCreateParams, DE_NULL, &newImage);
281 if (result != VK_SUCCESS)
283 log << TestLog::Message << "createImage failed with status " << result << TestLog::EndMessage;
287 image.image = vk::Move<VkImage>(vk::check<VkImage>(newImage), Deleter<VkImage>(deviceInterface, device, DE_NULL));
289 instanceInterface.getPhysicalDeviceMemoryProperties(physDevice, &memProps);
290 deviceInterface.getImageMemoryRequirements(device, image.image.get(), &memReq);
293 Allocator& allocator = imageParameters.context->getDefaultAllocator();
294 MovePtr<Allocation> newMemory (allocator.allocate(memReq, visibility));
295 result = deviceInterface.bindImageMemory(device, image.image.get(), newMemory->getMemory(), newMemory->getOffset());
296 if (result != VK_SUCCESS)
298 log << TestLog::Message << "bindImageMemory failed with status " << result << TestLog::EndMessage;
302 componentMap.r = VK_COMPONENT_SWIZZLE_R;
303 componentMap.g = VK_COMPONENT_SWIZZLE_G;
304 componentMap.b = VK_COMPONENT_SWIZZLE_B;
305 componentMap.a = VK_COMPONENT_SWIZZLE_A;
307 subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
308 subresourceRange.baseMipLevel = 0;
309 subresourceRange.levelCount = imageParameters.mipLevels;
310 subresourceRange.baseArrayLayer = 0;
311 subresourceRange.layerCount = 1;
313 imageViewCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
314 imageViewCreateInfo.pNext = DE_NULL;
315 imageViewCreateInfo.flags = 0;
316 imageViewCreateInfo.image = image.image.get();
317 imageViewCreateInfo.viewType = VK_IMAGE_VIEW_TYPE_3D;
318 imageViewCreateInfo.format = imageParameters.format;
319 imageViewCreateInfo.components = componentMap;
320 imageViewCreateInfo.subresourceRange = subresourceRange;
322 result = deviceInterface.createImageView(device, &imageViewCreateInfo, DE_NULL, &newImageView);
323 if (result != VK_SUCCESS)
325 log << TestLog::Message << "createImageView failed with status " << result << TestLog::EndMessage;
329 image.imageView = vk::Move<VkImageView>(vk::check<VkImageView>(newImageView), Deleter<VkImageView>(deviceInterface, device, DE_NULL));
330 image.allocation = newMemory;
332 imageBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
333 imageBarrier.pNext = DE_NULL;
334 imageBarrier.srcAccessMask = 0;
335 imageBarrier.dstAccessMask = imageParameters.barrierInputMask;
336 imageBarrier.oldLayout = imageParameters.initialLayout;
337 imageBarrier.newLayout = imageParameters.finalLayout;
338 imageBarrier.srcQueueFamilyIndex = imageParameters.queueFamilyNdxList[0];
339 imageBarrier.dstQueueFamilyIndex = imageParameters.queueFamilyNdxList[imageParameters.queueFamilyCount-1];
340 imageBarrier.image = image.image.get();
341 imageBarrier.subresourceRange = subresourceRange;
343 image.imageMemoryBarrier.push_back(imageBarrier);
347 struct RenderPassParameters
351 VkFormat colorFormat;
352 VkSampleCountFlagBits colorSamples;
355 void createColorOnlyRenderPass (const RenderPassParameters& renderPassParameters, vk::Move<VkRenderPass>& renderPass)
357 const DeviceInterface& deviceInterface = renderPassParameters.context->getDeviceInterface();
358 const VkDevice device = renderPassParameters.device;
359 VkAttachmentDescription colorAttachmentDesc;
360 VkAttachmentReference colorAttachmentRef;
361 VkAttachmentReference stencilAttachmentRef;
362 VkSubpassDescription subpassDesc;
363 VkRenderPassCreateInfo renderPassParams;
364 VkRenderPass newRenderPass;
366 colorAttachmentDesc.flags = 0;
367 colorAttachmentDesc.format = renderPassParameters.colorFormat;
368 colorAttachmentDesc.samples = renderPassParameters.colorSamples;
369 colorAttachmentDesc.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
370 colorAttachmentDesc.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
371 colorAttachmentDesc.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
372 colorAttachmentDesc.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
373 colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
374 colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
376 colorAttachmentRef.attachment = 0;
377 colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
379 stencilAttachmentRef.attachment = VK_NO_ATTACHMENT;
380 stencilAttachmentRef.layout = VK_IMAGE_LAYOUT_UNDEFINED;
382 subpassDesc.flags = 0;
383 subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
384 subpassDesc.inputAttachmentCount = 0;
385 subpassDesc.pInputAttachments = DE_NULL;
386 subpassDesc.colorAttachmentCount = 1;
387 subpassDesc.pColorAttachments = &colorAttachmentRef;
388 subpassDesc.pResolveAttachments = DE_NULL;
389 subpassDesc.pDepthStencilAttachment = &stencilAttachmentRef;
390 subpassDesc.preserveAttachmentCount = 0;
391 subpassDesc.pPreserveAttachments = DE_NULL;
393 renderPassParams.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
394 renderPassParams.pNext = DE_NULL;
395 renderPassParams.flags = 0;
396 renderPassParams.attachmentCount = 1;
397 renderPassParams.pAttachments = &colorAttachmentDesc;
398 renderPassParams.subpassCount = 1;
399 renderPassParams.pSubpasses = &subpassDesc;
400 renderPassParams.dependencyCount = 0;
401 renderPassParams.pDependencies = DE_NULL;
403 VK_CHECK(deviceInterface.createRenderPass(device, &renderPassParams, DE_NULL, &newRenderPass));
404 renderPass = vk::Move<VkRenderPass>(vk::check<VkRenderPass>(newRenderPass), Deleter<VkRenderPass>(deviceInterface, device, DE_NULL));
407 struct ShaderDescParams
410 VkShaderStageFlagBits stage;
413 void createGraphicsShaderStages (Context& context, const VkDevice device, vector<ShaderDescParams> shaderDesc, vector<VkPipelineShaderStageCreateInfo>& shaderCreateParams)
415 const DeviceInterface& deviceInterface = context.getDeviceInterface();
417 for (vector<ShaderDescParams>::iterator shaderDescIter = shaderDesc.begin(); shaderDescIter != shaderDesc.end(); shaderDescIter++)
419 VkPipelineShaderStageCreateInfo shaderStageInfo;
420 VkShaderModule shaderModule;
421 VkShaderModuleCreateInfo shaderModuleInfo;
423 shaderModuleInfo.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
424 shaderModuleInfo.pNext = DE_NULL;
425 shaderModuleInfo.flags = 0;
426 shaderModuleInfo.codeSize = context.getBinaryCollection().get(shaderDescIter->name).getSize();
427 shaderModuleInfo.pCode = (const deUint32*)context.getBinaryCollection().get(shaderDescIter->name).getBinary();
428 VK_CHECK(deviceInterface.createShaderModule(device, &shaderModuleInfo, DE_NULL, &shaderModule));
430 shaderStageInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
431 shaderStageInfo.pNext = DE_NULL;
432 shaderStageInfo.flags = 0;
433 shaderStageInfo.stage = shaderDescIter->stage;
434 shaderStageInfo.module = shaderModule;
435 shaderStageInfo.pName = "main";
436 shaderStageInfo.pSpecializationInfo = DE_NULL;
437 shaderCreateParams.push_back(shaderStageInfo);
449 void createVertexInfo (const vector<VertexDesc>& vertexDesc, vector<VkVertexInputBindingDescription>& bindingList, vector<VkVertexInputAttributeDescription>& attrList, VkPipelineVertexInputStateCreateInfo& vertexInputState)
451 for (vector<VertexDesc>::const_iterator vertDescIter = vertexDesc.begin(); vertDescIter != vertexDesc.end(); vertDescIter++)
453 deUint32 bindingId = 0;
454 VkVertexInputBindingDescription bindingDesc;
455 VkVertexInputAttributeDescription attrDesc;
457 bindingDesc.binding = bindingId;
458 bindingDesc.stride = vertDescIter->stride;
459 bindingDesc.inputRate = VK_VERTEX_INPUT_RATE_VERTEX;
460 bindingList.push_back(bindingDesc);
462 attrDesc.location = vertDescIter->location;
463 attrDesc.binding = bindingId;
464 attrDesc.format = vertDescIter->format;
465 attrDesc.offset = vertDescIter->offset;
466 attrList.push_back(attrDesc);
471 vertexInputState.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
472 vertexInputState.pNext = DE_NULL,
473 vertexInputState.vertexBindingDescriptionCount = (deUint32)bindingList.size();
474 vertexInputState.pVertexBindingDescriptions = &bindingList[0];
475 vertexInputState.vertexAttributeDescriptionCount = (deUint32)attrList.size();
476 vertexInputState.pVertexAttributeDescriptions = &attrList[0];
479 void createCommandBuffer (Context& context, const VkDevice device, const deUint32 queueFamilyNdx, vk::Move<VkCommandBuffer>* commandBufferRef)
481 const DeviceInterface& deviceInterface = context.getDeviceInterface();
482 VkCommandPool commandPool;
483 VkCommandPoolCreateInfo commandPoolInfo;
484 VkCommandBufferAllocateInfo commandBufferInfo;
485 VkCommandBuffer commandBuffer;
487 commandPoolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
488 commandPoolInfo.pNext = DE_NULL;
489 commandPoolInfo.flags = 0;
490 commandPoolInfo.queueFamilyIndex = queueFamilyNdx;
492 VK_CHECK(deviceInterface.createCommandPool(device, &commandPoolInfo, DE_NULL, &commandPool));
494 commandBufferInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
495 commandBufferInfo.pNext = DE_NULL;
496 commandBufferInfo.commandPool = commandPool;
497 commandBufferInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
498 commandBufferInfo.commandBufferCount = 1;
500 VK_CHECK(deviceInterface.allocateCommandBuffers(device, &commandBufferInfo, &commandBuffer));
501 *commandBufferRef = vk::Move<VkCommandBuffer>(vk::check<VkCommandBuffer>(commandBuffer), Deleter<VkCommandBuffer>(deviceInterface, device, DE_NULL));
504 void createFences (const DeviceInterface& deviceInterface, VkDevice device, bool signaled, deUint32 numFences, VkFence* fence)
506 VkFenceCreateInfo fenceState;
507 VkFenceCreateFlags signalFlag = signaled ? VK_FENCE_CREATE_SIGNALED_BIT : 0;
509 fenceState.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
510 fenceState.pNext = DE_NULL;
511 fenceState.flags = signalFlag;
513 for (deUint32 ndx = 0; ndx < numFences; ndx++)
514 VK_CHECK(deviceInterface.createFence(device, &fenceState, DE_NULL, &fence[ndx]));
517 void destroyFences (const DeviceInterface& deviceInterface, VkDevice device, deUint32 numFences, VkFence* fence)
519 for (deUint32 ndx = 0; ndx < numFences; ndx++)
520 deviceInterface.destroyFence(device, fence[ndx], DE_NULL);
528 deUint32 vertexBufferSize;
529 VkBuffer vertexBuffer;
531 VkCommandBuffer commandBuffer;
532 VkRenderPass renderPass;
533 VkFramebuffer framebuffer;
536 const deUint32* queueFamilyNdxList;
537 deUint32 queueFamilyNdxCount;
541 vector<VkImageMemoryBarrier>* barriers;
544 void recordRenderPass (const RenderInfo& renderInfo)
546 const DeviceInterface& deviceInterface = renderInfo.context->getDeviceInterface();
547 const VkDeviceSize bindingOffset = 0;
548 const VkClearValue clearValue = makeClearValueColorF32(0.0, 0.0, 1.0, 1.0);
549 VkRenderPassBeginInfo renderPassBeginState;
550 VkImageMemoryBarrier renderBarrier;
552 renderPassBeginState.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
553 renderPassBeginState.pNext = DE_NULL;
554 renderPassBeginState.renderPass = renderInfo.renderPass;
555 renderPassBeginState.framebuffer = renderInfo.framebuffer;
556 renderPassBeginState.renderArea.offset.x = 0;
557 renderPassBeginState.renderArea.offset.y = 0;
558 renderPassBeginState.renderArea.extent.width = renderInfo.width;
559 renderPassBeginState.renderArea.extent.height = renderInfo.height;
560 renderPassBeginState.clearValueCount = 1;
561 renderPassBeginState.pClearValues = &clearValue;
563 deviceInterface.cmdBeginRenderPass(renderInfo.commandBuffer, &renderPassBeginState, VK_SUBPASS_CONTENTS_INLINE);
564 if (renderInfo.waitEvent)
565 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);
566 deviceInterface.cmdBindPipeline(renderInfo.commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, renderInfo.pipeline);
567 deviceInterface.cmdBindVertexBuffers(renderInfo.commandBuffer, 0u, 1u, &renderInfo.vertexBuffer, &bindingOffset);
568 deviceInterface.cmdDraw(renderInfo.commandBuffer, renderInfo.vertexBufferSize, 1, 0, 0);
569 if (renderInfo.setEvent)
570 deviceInterface.cmdSetEvent(renderInfo.commandBuffer, renderInfo.event, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT);
571 deviceInterface.cmdEndRenderPass(renderInfo.commandBuffer);
573 renderBarrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
574 renderBarrier.pNext = DE_NULL;
575 renderBarrier.srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
576 renderBarrier.dstAccessMask = VK_ACCESS_TRANSFER_READ_BIT;
577 renderBarrier.oldLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
578 renderBarrier.newLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
579 renderBarrier.srcQueueFamilyIndex = renderInfo.queueFamilyNdxList[0];
580 renderBarrier.dstQueueFamilyIndex = renderInfo.queueFamilyNdxList[renderInfo.queueFamilyNdxCount-1];
581 renderBarrier.image = renderInfo.image;
582 renderBarrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
583 renderBarrier.subresourceRange.baseMipLevel = 0;
584 renderBarrier.subresourceRange.levelCount = renderInfo.mipLevels;
585 renderBarrier.subresourceRange.baseArrayLayer = 0;
586 renderBarrier.subresourceRange.layerCount = 1;
587 renderInfo.barriers->push_back(renderBarrier);
593 VkCommandBuffer commandBuffer;
600 VkOffset3D imageOffset;
601 vector<VkBufferMemoryBarrier>* barriers;
604 void copyToCPU (TransferInfo* transferInfo)
606 const DeviceInterface& deviceInterface = transferInfo->context->getDeviceInterface();
607 VkBufferImageCopy copyState;
609 copyState.bufferOffset = 0;
610 copyState.bufferRowLength = transferInfo->width;
611 copyState.bufferImageHeight = transferInfo->height;
612 copyState.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
613 copyState.imageSubresource.mipLevel = transferInfo->mipLevel;
614 copyState.imageSubresource.baseArrayLayer = 0;
615 copyState.imageSubresource.layerCount = 1;
616 copyState.imageOffset = transferInfo->imageOffset;
617 copyState.imageExtent.width = (deInt32)(transferInfo->width);
618 copyState.imageExtent.height = (deInt32)(transferInfo->height);
619 copyState.imageExtent.depth = 1;
621 deviceInterface.cmdCopyImageToBuffer(transferInfo->commandBuffer, transferInfo->image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, transferInfo->buffer, 1, ©State);
624 VkBufferMemoryBarrier bufferBarrier;
625 bufferBarrier.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER;
626 bufferBarrier.pNext = DE_NULL;
627 bufferBarrier.srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT;
628 bufferBarrier.dstAccessMask = VK_ACCESS_HOST_READ_BIT;
629 bufferBarrier.srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
630 bufferBarrier.dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED;
631 bufferBarrier.buffer = transferInfo->buffer;
632 bufferBarrier.offset = 0;
633 bufferBarrier.size = transferInfo->size;
634 transferInfo->barriers->push_back(bufferBarrier);
641 const VkDevice& device;
642 const tcu::Vec4* vertices;
643 deUint32 numVertices;
644 tcu::IVec2 renderDimension;
646 VkDeviceSize renderSize;
647 MovePtr<Allocation> renderReadBuffer;
648 MovePtr<Allocation> vertexBufferAllocation;
649 vk::Move<VkBuffer> vertexBuffer;
650 vk::Move<VkBuffer> renderBuffer;
654 vk::Move<VkImage> image;
655 vk::Move<VkImageView> imageView;
656 vk::Move<VkCommandBuffer> cmdBuffer;
657 MovePtr<Allocation> imageAllocation;
659 TestContext(Context& context_, const VkDevice& device_)
663 , setEvent (DE_FALSE)
664 , waitEvent (DE_FALSE)
666 createFences(context.getDeviceInterface(), device, DE_NULL, DE_LENGTH_OF_ARRAY(fences), fences);
671 destroyFences(context.getDeviceInterface(), device, DE_LENGTH_OF_ARRAY(fences), fences);
675 void generateWork (TestContext& testContext)
677 const DeviceInterface& deviceInterface = testContext.context.getDeviceInterface();
678 const deUint32 queueFamilyNdx = testContext.context.getUniversalQueueFamilyIndex();
679 vk::Move<VkRenderPass> renderPass;
680 VkPipelineCache cache;
681 VkPipelineLayout layout;
683 VkFramebuffer framebuffer;
684 vector<ShaderDescParams> shaderDescParams;
685 vector<VkPipelineShaderStageCreateInfo> shaderStageCreateParams;
686 VertexDesc vertexDesc;
687 vector<VertexDesc> vertexDescList;
688 vector<VkVertexInputAttributeDescription> attrList;
689 vector<VkBufferMemoryBarrier> bufferMemoryBarrier;
690 deUint32 memoryBarrierNdx;
691 deUint32 bufferMemoryBarrierNdx;
692 deUint32 imageMemoryBarrierNdx;
693 vector<VkVertexInputBindingDescription> bindingList;
694 VkPipelineVertexInputStateCreateInfo vertexInputState;
695 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
696 VkPipelineDepthStencilStateCreateInfo depthStencilState;
697 VkPipelineColorBlendAttachmentState blendAttachment;
698 VkPipelineColorBlendStateCreateInfo blendState;
699 VkPipelineLayoutCreateInfo pipelineLayoutState;
700 VkGraphicsPipelineCreateInfo pipelineState;
701 VkPipelineCacheCreateInfo cacheState;
703 VkPipelineViewportStateCreateInfo viewportInfo;
705 BufferParameters bufferParameters;
707 RenderInfo renderInfo;
708 ImageParameters imageParameters;
710 VkPipelineRasterizationStateCreateInfo rasterState;
711 VkPipelineMultisampleStateCreateInfo multisampleState;
712 VkFramebufferCreateInfo fbState;
713 VkCommandBufferBeginInfo commandBufRecordState;
714 VkCommandBufferInheritanceInfo inheritanceInfo;
715 RenderPassParameters renderPassParameters;
716 TransferInfo transferInfo;
717 vector<void*> barrierList;
719 vector<VkMemoryBarrier> memoryBarriers;
720 vector<VkBufferMemoryBarrier> bufferBarriers;
721 vector<VkImageMemoryBarrier> imageBarriers;
723 memoryBarrierNdx = 0;
724 bufferMemoryBarrierNdx = 0;
725 imageMemoryBarrierNdx = 0;
726 buffer.memoryBarrier.resize(memoryBarrierNdx);
727 bufferMemoryBarrier.resize(bufferMemoryBarrierNdx);
728 image.imageMemoryBarrier.resize(imageMemoryBarrierNdx);
730 memoryBarriers.resize(0);
731 bufferBarriers.resize(0);
732 imageBarriers.resize(0);
734 bufferParameters.context = &testContext.context;
735 bufferParameters.device = testContext.device;
736 bufferParameters.memory = testContext.vertices;
737 bufferParameters.size = testContext.numVertices * sizeof(tcu::Vec4);
738 bufferParameters.usage = VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
739 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
740 bufferParameters.queueFamilyCount = 1;
741 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
742 bufferParameters.inputBarrierFlags = VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT;
743 createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
744 testContext.vertexBufferAllocation = buffer.allocation;
745 testContext.vertexBuffer = buffer.buffer;
747 bufferParameters.context = &testContext.context;
748 bufferParameters.device = testContext.device;
749 bufferParameters.memory = DE_NULL;
750 bufferParameters.size = testContext.renderSize;
751 bufferParameters.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT;
752 bufferParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
753 bufferParameters.queueFamilyCount = 1;
754 bufferParameters.queueFamilyIndex = &queueFamilyNdx;
755 bufferParameters.inputBarrierFlags = 0;
756 createVulkanBuffer(bufferParameters, buffer, MemoryRequirement::HostVisible);
757 testContext.renderReadBuffer = buffer.allocation;
758 testContext.renderBuffer = buffer.buffer;
760 extent.width = testContext.renderDimension.x();
761 extent.height = testContext.renderDimension.y();
764 imageParameters.context = &testContext.context;
765 imageParameters.device = testContext.device;
766 imageParameters.imageType = VK_IMAGE_TYPE_2D;
767 imageParameters.format = VK_FORMAT_R8G8B8A8_UNORM;
768 imageParameters.extent3D = extent;
769 imageParameters.mipLevels = 1;
770 imageParameters.samples = VK_SAMPLE_COUNT_1_BIT;
771 imageParameters.tiling = VK_IMAGE_TILING_OPTIMAL;
772 imageParameters.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT|VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
773 imageParameters.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
774 imageParameters.queueFamilyCount = 1;
775 imageParameters.queueFamilyNdxList = &queueFamilyNdx;
776 imageParameters.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
777 imageParameters.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
778 imageParameters.barrierInputMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
779 createVulkanImage(imageParameters, image, MemoryRequirement::Any);
780 testContext.imageAllocation = image.allocation;
781 testContext.image = image.image;
783 renderPassParameters.context = &testContext.context;
784 renderPassParameters.device = testContext.device;
785 renderPassParameters.colorFormat = VK_FORMAT_R8G8B8A8_UNORM;
786 renderPassParameters.colorSamples = VK_SAMPLE_COUNT_1_BIT;
787 createColorOnlyRenderPass(renderPassParameters, renderPass);
789 ShaderDescParams param;
790 param.name = "glslvert";
791 param.stage = VK_SHADER_STAGE_VERTEX_BIT;
792 shaderDescParams.push_back(param);
794 param.name = "glslfrag";
795 param.stage = VK_SHADER_STAGE_FRAGMENT_BIT;
796 shaderDescParams.push_back(param);
797 createGraphicsShaderStages(testContext.context, testContext.device, shaderDescParams, shaderStageCreateParams);
799 vertexDesc.location = 0;
800 vertexDesc.format = VK_FORMAT_R32G32B32A32_SFLOAT;
801 vertexDesc.stride = sizeof(tcu::Vec4);
802 vertexDesc.offset = 0;
803 vertexDescList.push_back(vertexDesc);
805 createVertexInfo(vertexDescList, bindingList, attrList, vertexInputState);
807 inputAssemblyState.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
808 inputAssemblyState.pNext = DE_NULL;
809 inputAssemblyState.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
810 inputAssemblyState.primitiveRestartEnable = DE_FALSE;
814 viewport.width = (float)testContext.renderDimension.x();
815 viewport.height = (float)testContext.renderDimension.y();
816 viewport.minDepth = 0;
817 viewport.maxDepth = 1;
819 scissor.offset.x = 0;
820 scissor.offset.y = 0;
821 scissor.extent.width = testContext.renderDimension.x();
822 scissor.extent.height = testContext.renderDimension.y();
824 viewportInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
825 viewportInfo.pNext = DE_NULL;
826 viewportInfo.flags = 0;
827 viewportInfo.viewportCount = 1;
828 viewportInfo.pViewports = &viewport;
829 viewportInfo.scissorCount = 1;
830 viewportInfo.pScissors = &scissor;
832 rasterState.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
833 rasterState.pNext = DE_NULL;
834 rasterState.flags = 0;
835 rasterState.depthClampEnable = VK_TRUE;
836 rasterState.rasterizerDiscardEnable = VK_FALSE;
837 rasterState.polygonMode = VK_POLYGON_MODE_FILL;
838 rasterState.cullMode = VK_CULL_MODE_NONE;
839 rasterState.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE;
840 rasterState.depthBiasEnable = VK_FALSE;
841 rasterState.lineWidth = 1;
843 multisampleState.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
844 multisampleState.pNext = DE_NULL;
845 multisampleState.flags = 0;
846 multisampleState.rasterizationSamples = VK_SAMPLE_COUNT_1_BIT;
847 multisampleState.sampleShadingEnable = VK_FALSE;
848 multisampleState.pSampleMask = DE_NULL;
849 multisampleState.alphaToCoverageEnable = VK_FALSE;
850 multisampleState.alphaToOneEnable = VK_FALSE;
852 depthStencilState.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
853 depthStencilState.pNext = DE_NULL;
854 depthStencilState.flags = 0;
855 depthStencilState.depthTestEnable = VK_FALSE;
856 depthStencilState.depthWriteEnable = VK_FALSE;
857 depthStencilState.depthBoundsTestEnable = VK_FALSE;
858 depthStencilState.stencilTestEnable = VK_FALSE;
860 blendAttachment.blendEnable = VK_FALSE;
862 blendState.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
863 blendState.pNext = DE_NULL;
864 blendState.flags = 0;
865 blendState.logicOpEnable = VK_FALSE;
866 blendState.attachmentCount = 1;
867 blendState.pAttachments = &blendAttachment;
869 pipelineLayoutState.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
870 pipelineLayoutState.pNext = DE_NULL;
871 pipelineLayoutState.flags = 0;
872 pipelineLayoutState.setLayoutCount = 0;
873 pipelineLayoutState.pSetLayouts = DE_NULL;
874 pipelineLayoutState.pushConstantRangeCount = 0;
875 pipelineLayoutState.pPushConstantRanges = DE_NULL;
876 VK_CHECK(deviceInterface.createPipelineLayout(testContext.device, &pipelineLayoutState, DE_NULL, &layout));
878 pipelineState.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
879 pipelineState.pNext = DE_NULL;
880 pipelineState.flags = 0;
881 pipelineState.stageCount = (deUint32)shaderStageCreateParams.size();
882 pipelineState.pStages = &shaderStageCreateParams[0];
883 pipelineState.pVertexInputState = &vertexInputState;
884 pipelineState.pInputAssemblyState = &inputAssemblyState;
885 pipelineState.pTessellationState = DE_NULL;
886 pipelineState.pViewportState = &viewportInfo;
887 pipelineState.pRasterizationState = &rasterState;
888 pipelineState.pMultisampleState = &multisampleState;
889 pipelineState.pDepthStencilState = &depthStencilState;
890 pipelineState.pColorBlendState = &blendState;
891 pipelineState.pDynamicState = (const VkPipelineDynamicStateCreateInfo*)DE_NULL;
892 pipelineState.layout = layout;
893 pipelineState.renderPass = renderPass.get();
894 pipelineState.subpass = 0;
895 pipelineState.basePipelineHandle = DE_NULL;
896 pipelineState.basePipelineIndex = 0;
898 cacheState.sType = VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO;
899 cacheState.pNext = DE_NULL;
900 cacheState.flags = 0;
901 cacheState.initialDataSize = 0;
902 cacheState.pInitialData = DE_NULL;
904 VK_CHECK(deviceInterface.createPipelineCache(testContext.device, &cacheState, DE_NULL, &cache));
905 VK_CHECK(deviceInterface.createGraphicsPipelines(testContext.device, cache, 1, &pipelineState, DE_NULL, &pipeline));
907 fbState.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
908 fbState.pNext = DE_NULL;
910 fbState.renderPass = renderPass.get();
911 fbState.attachmentCount = 1;
912 fbState.pAttachments = &image.imageView.get();
913 fbState.width = (deUint32)testContext.renderDimension.x();
914 fbState.height = (deUint32)testContext.renderDimension.y();
916 VK_CHECK(deviceInterface.createFramebuffer(testContext.device, &fbState, DE_NULL, &framebuffer));
917 testContext.imageView = image.imageView;
919 inheritanceInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO;
920 inheritanceInfo.pNext = DE_NULL;
921 inheritanceInfo.renderPass = renderPass.get();
922 inheritanceInfo.subpass = 0;
923 inheritanceInfo.framebuffer = framebuffer;
924 inheritanceInfo.occlusionQueryEnable = VK_FALSE;
926 commandBufRecordState.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
927 commandBufRecordState.pNext = DE_NULL;
928 commandBufRecordState.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
929 commandBufRecordState.pInheritanceInfo = &inheritanceInfo;
930 VK_CHECK(deviceInterface.beginCommandBuffer(testContext.cmdBuffer.get(), &commandBufRecordState));
932 deviceInterface.cmdPipelineBarrier( testContext.cmdBuffer.get(),
933 VK_PIPELINE_STAGE_HOST_BIT,
934 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
936 (deUint32)memoryBarriers.size(), &memoryBarriers[0],
937 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
938 (deUint32)imageBarriers.size(), &imageBarriers[0]);
940 memoryBarriers.resize(0);
941 bufferBarriers.resize(0);
942 imageBarriers.resize(0);
944 renderInfo.context = &testContext.context;
945 renderInfo.width = testContext.renderDimension.x();
946 renderInfo.height = testContext.renderDimension.y();
947 renderInfo.vertexBufferSize = testContext.numVertices;
948 renderInfo.vertexBuffer = testContext.vertexBuffer.get();
949 renderInfo.image = testContext.image.get();
950 renderInfo.commandBuffer = testContext.cmdBuffer.get();
951 renderInfo.renderPass = renderPass.get();
952 renderInfo.framebuffer = framebuffer;
953 renderInfo.pipeline = pipeline;
954 renderInfo.mipLevels = 1;
955 renderInfo.queueFamilyNdxList = &queueFamilyNdx;
956 renderInfo.queueFamilyNdxCount = 1;
957 renderInfo.setEvent = testContext.setEvent;
958 renderInfo.waitEvent = testContext.waitEvent;
959 renderInfo.event = testContext.event;
960 renderInfo.barriers = &imageBarriers;
961 recordRenderPass(renderInfo);
963 deviceInterface.cmdPipelineBarrier( renderInfo.commandBuffer,
964 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
965 VK_PIPELINE_STAGE_TRANSFER_BIT,
967 (deUint32)memoryBarriers.size(), &memoryBarriers[0],
968 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
969 (deUint32)imageBarriers.size(), &imageBarriers[0]);
971 memoryBarriers.resize(0);
972 bufferBarriers.resize(0);
973 imageBarriers.resize(0);
975 transferInfo.context = &testContext.context;
976 transferInfo.commandBuffer = renderInfo.commandBuffer;
977 transferInfo.width = testContext.renderDimension.x();
978 transferInfo.height = testContext.renderDimension.y();
979 transferInfo.image = renderInfo.image;
980 transferInfo.buffer = testContext.renderBuffer.get();
981 transferInfo.size = testContext.renderSize;
982 transferInfo.mipLevel = 0;
983 transferInfo.imageOffset.x = 0;
984 transferInfo.imageOffset.y = 0;
985 transferInfo.imageOffset.z = 0;
986 transferInfo.barriers = &bufferBarriers;
987 copyToCPU(&transferInfo);
989 deviceInterface.cmdPipelineBarrier( transferInfo.commandBuffer,
990 VK_PIPELINE_STAGE_TRANSFER_BIT,
991 VK_PIPELINE_STAGE_HOST_BIT,
993 (deUint32)memoryBarriers.size(), &memoryBarriers[0],
994 (deUint32)bufferBarriers.size(), &bufferBarriers[0],
995 (deUint32)imageBarriers.size(), &imageBarriers[0]);
997 memoryBarriers.resize(0);
998 bufferBarriers.resize(0);
999 imageBarriers.resize(0);
1001 VK_CHECK(deviceInterface.endCommandBuffer(transferInfo.commandBuffer));
1004 static void initSubmitInfo (VkSubmitInfo* submitInfo, deUint32 submitInfoCount)
1006 for (deUint32 ndx = 0; ndx < submitInfoCount; ndx++)
1008 submitInfo[ndx].sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
1009 submitInfo[ndx].pNext = DE_NULL;
1010 submitInfo[ndx].waitSemaphoreCount = 0;
1011 submitInfo[ndx].pWaitSemaphores = DE_NULL;
1012 submitInfo[ndx].pWaitDstStageMask = DE_NULL;
1013 submitInfo[ndx].commandBufferCount = 1;
1014 submitInfo[ndx].signalSemaphoreCount = 0;
1015 submitInfo[ndx].pSignalSemaphores = DE_NULL;
1019 tcu::TestStatus testFences (Context& context)
1021 TestLog& log = context.getTestContext().getLog();
1022 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1023 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1024 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1025 const VkQueue queue = context.getUniversalQueue();
1026 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
1027 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice);
1028 VkResult testStatus;
1029 VkResult fenceStatus;
1030 TestContext testContext(context, device.get());
1031 VkSubmitInfo submitInfo;
1032 VkMappedMemoryRange range;
1035 const tcu::Vec4 vertices[] =
1037 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1038 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1039 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1042 testContext.vertices = vertices;
1043 testContext.numVertices = DE_LENGTH_OF_ARRAY(vertices);
1044 testContext.renderDimension = tcu::IVec2(256, 256);
1045 testContext.renderSize = sizeof(deUint32) * testContext.renderDimension.x() * testContext.renderDimension.y();
1047 createCommandBuffer(testContext.context, device.get(), queueFamilyIdx, &testContext.cmdBuffer);
1048 generateWork(testContext);
1050 initSubmitInfo(&submitInfo, 1);
1051 submitInfo.pCommandBuffers = &testContext.cmdBuffer.get();
1053 VK_CHECK(deviceInterface.queueSubmit(queue, 1, &submitInfo, testContext.fences[0]));
1055 fenceStatus = deviceInterface.getFenceStatus(device.get(), testContext.fences[0]);
1056 if (fenceStatus != VK_NOT_READY)
1058 log << TestLog::Message << "testSynchronizationPrimitives fence should be reset but status is " << fenceStatus << TestLog::EndMessage;
1059 return tcu::TestStatus::fail("Fence in incorrect state");
1062 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1063 if (testStatus != VK_TIMEOUT)
1065 log << TestLog::Message << "testSynchPrimitives failed to wait for all fences" << TestLog::EndMessage;
1066 return tcu::TestStatus::fail("Failed to wait for mulitple fences");
1069 testStatus = deviceInterface.waitForFences(device.get(),
1071 &testContext.fences[1],
1075 if (testStatus != VK_TIMEOUT)
1077 log << TestLog::Message << "testSyncPrimitives failed to wait for single fence" << TestLog::EndMessage;
1078 return tcu::TestStatus::fail("failed to wait for single fence");
1081 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1082 if (testStatus != VK_SUCCESS)
1084 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1085 return tcu::TestStatus::fail("failed to wait for a set fence");
1088 fenceStatus = deviceInterface.getFenceStatus(device.get(), testContext.fences[0]);
1089 if (fenceStatus != VK_SUCCESS)
1091 log << TestLog::Message << "testSynchronizationPrimitives fence should be signaled but status is " << fenceStatus << TestLog::EndMessage;
1092 return tcu::TestStatus::fail("Fence in incorrect state");
1095 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1096 range.pNext = DE_NULL;
1097 range.memory = testContext.renderReadBuffer->getMemory();
1099 range.size = testContext.renderSize;
1100 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1101 resultImage = testContext.renderReadBuffer->getHostPtr();
1103 log << TestLog::Image( "result",
1105 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1106 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1107 testContext.renderDimension.x(),
1108 testContext.renderDimension.y(),
1112 return TestStatus::pass("synchornization-fences passed");
1115 vk::refdetails::Checked<VkSemaphore> createSemaphore (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
1117 VkSemaphoreCreateInfo semaCreateInfo;
1118 VkSemaphore semaphore;
1120 semaCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
1121 semaCreateInfo.pNext = DE_NULL;
1122 semaCreateInfo.flags = 0;
1123 VK_CHECK(deviceInterface.createSemaphore(device, &semaCreateInfo, allocationCallbacks, &semaphore));
1125 return vk::check<VkSemaphore>(semaphore);
1128 tcu::TestStatus testSemaphores (Context& context)
1130 TestLog& log = context.getTestContext().getLog();
1131 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1132 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1133 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1134 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice);
1136 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
1137 VkResult testStatus;
1138 TestContext testContext1(context, device.get());
1139 TestContext testContext2(context, device.get());
1140 Unique<VkSemaphore> semaphore(createSemaphore(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkSemaphore>(deviceInterface, device.get(), DE_NULL));
1141 VkSubmitInfo submitInfo[2];
1142 VkMappedMemoryRange range;
1145 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
1146 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
1148 const tcu::Vec4 vertices1[] =
1150 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1151 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1152 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1155 const tcu::Vec4 vertices2[] =
1157 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1158 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1159 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1162 testContext1.vertices = vertices1;
1163 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1164 testContext1.renderDimension = tcu::IVec2(256, 256);
1165 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1167 testContext2.vertices = vertices2;
1168 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
1169 testContext2.renderDimension = tcu::IVec2(256, 256);
1170 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1172 createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
1173 generateWork(testContext1);
1175 createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
1176 generateWork(testContext2);
1178 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
1180 // The difference between the two submit infos is that each will use a unique cmd buffer,
1181 // and one will signal a semaphore but not wait on a semaphore, the other will wait on the
1182 // semaphore but not signal a semaphore
1183 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
1184 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
1186 submitInfo[0].signalSemaphoreCount = 1;
1187 submitInfo[0].pSignalSemaphores = &semaphore.get();
1188 submitInfo[1].waitSemaphoreCount = 1;
1189 submitInfo[1].pWaitSemaphores = &semaphore.get();
1191 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
1193 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1194 if (testStatus != VK_SUCCESS)
1196 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1197 return tcu::TestStatus::fail("failed to wait for a set fence");
1200 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1201 range.pNext = DE_NULL;
1202 range.memory = testContext1.renderReadBuffer->getMemory();
1204 range.size = testContext1.renderSize;
1205 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1206 resultImage = testContext1.renderReadBuffer->getHostPtr();
1208 log << TestLog::Image( "result",
1210 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1211 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1212 testContext1.renderDimension.x(),
1213 testContext1.renderDimension.y(),
1217 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
1219 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1220 if (testStatus != VK_SUCCESS)
1222 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1223 return tcu::TestStatus::fail("failed to wait for a set fence");
1226 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1227 range.pNext = DE_NULL;
1228 range.memory = testContext2.renderReadBuffer->getMemory();
1230 range.size = testContext2.renderSize;
1231 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1232 resultImage = testContext2.renderReadBuffer->getHostPtr();
1234 log << TestLog::Image( "result",
1236 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1237 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1238 testContext2.renderDimension.x(),
1239 testContext2.renderDimension.y(),
1243 return tcu::TestStatus::pass("synchronization-semaphores passed");
1246 vk::refdetails::Checked<VkEvent> createEvent (const DeviceInterface& deviceInterface, const VkDevice& device, const VkAllocationCallbacks* allocationCallbacks)
1248 VkEventCreateInfo eventCreateInfo;
1251 eventCreateInfo.sType = VK_STRUCTURE_TYPE_EVENT_CREATE_INFO;
1252 eventCreateInfo.pNext = DE_NULL;
1253 eventCreateInfo.flags = 0;
1254 VK_CHECK(deviceInterface.createEvent(device, &eventCreateInfo, allocationCallbacks, &event));
1256 return vk::check<VkEvent>(event);
1259 tcu::TestStatus testEvents (Context& context)
1261 TestLog& log = context.getTestContext().getLog();
1262 const DeviceInterface& deviceInterface = context.getDeviceInterface();
1263 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1264 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
1265 vk::Move<VkDevice> device = createTestDevice(instanceInterface, physicalDevice);
1267 const deUint32 queueFamilyIdx = context.getUniversalQueueFamilyIndex();
1268 VkResult testStatus;
1269 VkResult eventStatus;
1270 TestContext testContext1(context, device.get());
1271 TestContext testContext2(context, device.get());
1272 Unique<VkEvent> event(createEvent(deviceInterface, device.get(), (VkAllocationCallbacks*)DE_NULL), Deleter<VkEvent>(deviceInterface, device.get(), DE_NULL));
1273 VkSubmitInfo submitInfo[2];
1274 VkMappedMemoryRange range;
1277 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 0, &queue[0]);
1278 deviceInterface.getDeviceQueue(device.get(), queueFamilyIdx, 1, &queue[1]);
1280 const tcu::Vec4 vertices1[] =
1282 tcu::Vec4( 0.5f, 0.5f, 0.0f, 1.0f),
1283 tcu::Vec4(-0.5f, 0.5f, 0.0f, 1.0f),
1284 tcu::Vec4( 0.0f, -0.5f, 0.0f, 1.0f)
1287 const tcu::Vec4 vertices2[] =
1289 tcu::Vec4(-0.5f, -0.5f, 0.0f, 1.0f),
1290 tcu::Vec4(+0.5f, -0.5f, 0.0f, 1.0f),
1291 tcu::Vec4( 0.0f, +0.5f, 0.0f, 1.0f)
1294 testContext1.vertices = vertices1;
1295 testContext1.numVertices = DE_LENGTH_OF_ARRAY(vertices1);
1296 testContext1.renderDimension = tcu::IVec2(256, 256);
1297 testContext1.setEvent = DE_TRUE;
1298 testContext1.event = event.get();
1299 testContext1.renderSize = sizeof(deUint32) * testContext1.renderDimension.x() * testContext1.renderDimension.y();
1301 testContext2.vertices = vertices2;
1302 testContext2.numVertices = DE_LENGTH_OF_ARRAY(vertices2);
1303 testContext2.renderDimension = tcu::IVec2(256, 256);
1304 testContext2.waitEvent = DE_TRUE;
1305 testContext2.event = event.get();
1306 testContext2.renderSize = sizeof(deUint32) * testContext2.renderDimension.x() * testContext2.renderDimension.y();
1308 createCommandBuffer(testContext1.context, device.get(), queueFamilyIdx, &testContext1.cmdBuffer);
1309 generateWork(testContext1);
1311 createCommandBuffer(testContext2.context, device.get(), queueFamilyIdx, &testContext2.cmdBuffer);
1312 generateWork(testContext2);
1314 initSubmitInfo(submitInfo, DE_LENGTH_OF_ARRAY(submitInfo));
1315 submitInfo[0].pCommandBuffers = &testContext1.cmdBuffer.get();
1316 submitInfo[1].pCommandBuffers = &testContext2.cmdBuffer.get();
1318 eventStatus = deviceInterface.getEventStatus(device.get(), event.get());
1319 if (eventStatus != VK_EVENT_RESET)
1321 log << TestLog::Message << "testSynchronizationPrimitives event should be reset but status is " << eventStatus << TestLog::EndMessage;
1322 return tcu::TestStatus::fail("Event in incorrect status");
1325 // Now the two contexts are submitted normally, so, context1 and set the event and context2 can wait for the event
1326 VK_CHECK(deviceInterface.queueSubmit(queue[0], 1, &submitInfo[0], testContext1.fences[0]));
1327 VK_CHECK(deviceInterface.queueSubmit(queue[1], 1, &submitInfo[1], testContext2.fences[0]));
1329 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext1.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1330 if (testStatus != VK_SUCCESS)
1332 log << TestLog::Message << "testSynchronizationPrimitives failed to wait for set fence" << TestLog::EndMessage;
1333 return tcu::TestStatus::fail("failed to wait for set fence");
1336 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1337 range.pNext = DE_NULL;
1338 range.memory = testContext1.renderReadBuffer->getMemory();
1340 range.size = testContext1.renderSize;
1341 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1342 resultImage = testContext1.renderReadBuffer->getHostPtr();
1344 log << TestLog::Image( "result",
1346 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1347 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1348 testContext1.renderDimension.x(),
1349 testContext1.renderDimension.y(),
1353 testStatus = deviceInterface.waitForFences(device.get(), 1, &testContext2.fences[0], DE_TRUE, DEFAULT_TIMEOUT);
1354 if (testStatus != VK_SUCCESS)
1356 log << TestLog::Message << "testSynchPrimitives failed to wait for a set fence" << TestLog::EndMessage;
1357 return tcu::TestStatus::fail("failed to wait for a set fence");
1360 range.sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE;
1361 range.pNext = DE_NULL;
1362 range.memory = testContext2.renderReadBuffer->getMemory();
1364 range.size = testContext2.renderSize;
1365 VK_CHECK(deviceInterface.invalidateMappedMemoryRanges(device.get(), 1, &range));
1366 resultImage = testContext2.renderReadBuffer->getHostPtr();
1368 log << TestLog::Image( "result",
1370 tcu::ConstPixelBufferAccess(tcu::TextureFormat(
1371 tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8),
1372 testContext2.renderDimension.x(),
1373 testContext2.renderDimension.y(),
1377 return tcu::TestStatus::pass("synchronization-events passed");
1382 tcu::TestCaseGroup* createSynchronizationTests (tcu::TestContext& textCtx)
1384 de::MovePtr<tcu::TestCaseGroup> synchTests (new tcu::TestCaseGroup(textCtx, "synchronization", "Vulkan Synchronization Tests"));
1386 addFunctionCaseWithPrograms(synchTests.get(), "fences", "", buildShaders, testFences);
1387 addFunctionCaseWithPrograms(synchTests.get(), "semaphores", "", buildShaders, testSemaphores);
1388 addFunctionCaseWithPrograms(synchTests.get(), "events", "", buildShaders, testEvents);
1390 return synchTests.release();