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