1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group 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 Synchronization tests utilities
22 *//*--------------------------------------------------------------------*/
24 #include "vktSynchronizationUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include "vkCmdUtil.hpp"
27 #include "deStringUtil.hpp"
32 namespace synchronization
36 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
38 const VkCommandBufferAllocateInfo info =
40 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
41 DE_NULL, // const void* pNext;
42 commandPool, // VkCommandPool commandPool;
43 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
44 1u, // deUint32 commandBufferCount;
46 return allocateCommandBuffer(vk, device, &info);
49 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
50 const VkDevice device,
51 const VkPipelineLayout pipelineLayout,
52 const VkShaderModule shaderModule,
53 const VkSpecializationInfo* specInfo,
54 PipelineCacheData& pipelineCacheData)
56 const VkPipelineShaderStageCreateInfo shaderStageInfo =
58 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
59 DE_NULL, // const void* pNext;
60 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
61 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
62 shaderModule, // VkShaderModule module;
63 "main", // const char* pName;
64 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
66 const VkComputePipelineCreateInfo pipelineInfo =
68 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
69 DE_NULL, // const void* pNext;
70 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
71 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
72 pipelineLayout, // VkPipelineLayout layout;
73 DE_NULL, // VkPipeline basePipelineHandle;
74 0, // deInt32 basePipelineIndex;
78 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
79 vk::Move<vk::VkPipeline> pipeline (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
81 // Refresh data from cache
82 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
88 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
90 const VkImageCreateInfo imageInfo =
92 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
93 DE_NULL, // const void* pNext;
94 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
95 imageType, // VkImageType imageType;
96 format, // VkFormat format;
97 extent, // VkExtent3D extent;
98 1u, // uint32_t mipLevels;
99 1u, // uint32_t arrayLayers;
100 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
101 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
102 usage, // VkImageUsageFlags usage;
103 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
104 0u, // uint32_t queueFamilyIndexCount;
105 DE_NULL, // const uint32_t* pQueueFamilyIndices;
106 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
111 void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk,
112 const VkCommandBuffer commandBuffer,
113 const VkRenderPass renderPass,
114 const VkFramebuffer framebuffer)
116 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
118 beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
121 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
122 const VkDevice device,
123 const VkShaderStageFlagBits stage,
124 const ProgramBinary& binary,
125 const VkSpecializationInfo* specInfo)
127 VkShaderModule module;
130 case (VK_SHADER_STAGE_VERTEX_BIT):
131 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
132 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
133 module = *m_vertexShaderModule;
136 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
137 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
138 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
139 module = *m_tessControlShaderModule;
142 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
143 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
144 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
145 module = *m_tessEvaluationShaderModule;
148 case (VK_SHADER_STAGE_GEOMETRY_BIT):
149 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
150 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
151 module = *m_geometryShaderModule;
154 case (VK_SHADER_STAGE_FRAGMENT_BIT):
155 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
156 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
157 module = *m_fragmentShaderModule;
161 DE_FATAL("Invalid shader stage");
165 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
167 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
168 DE_NULL, // const void* pNext;
169 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
170 stage, // VkShaderStageFlagBits stage;
171 module, // VkShaderModule module;
172 "main", // const char* pName;
173 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
176 m_shaderStageFlags |= stage;
177 m_shaderStages.push_back(pipelineShaderStageInfo);
182 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
184 const VkVertexInputBindingDescription bindingDesc =
186 0u, // uint32_t binding;
187 stride, // uint32_t stride;
188 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
190 const VkVertexInputAttributeDescription attributeDesc =
192 0u, // uint32_t location;
193 0u, // uint32_t binding;
194 vertexFormat, // VkFormat format;
195 0u, // uint32_t offset;
198 m_vertexInputBindings.clear();
199 m_vertexInputBindings.push_back(bindingDesc);
201 m_vertexInputAttributes.clear();
202 m_vertexInputAttributes.push_back(attributeDesc);
208 inline const T* dataPointer (const std::vector<T>& vec)
210 return (vec.size() != 0 ? &vec[0] : DE_NULL);
213 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
214 const VkDevice device,
215 const VkPipelineLayout pipelineLayout,
216 const VkRenderPass renderPass,
217 PipelineCacheData& pipelineCacheData)
219 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
221 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
222 DE_NULL, // const void* pNext;
223 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
224 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount;
225 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
226 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount;
227 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
230 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
231 : m_primitiveTopology;
232 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
234 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
235 DE_NULL, // const void* pNext;
236 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
237 topology, // VkPrimitiveTopology topology;
238 VK_FALSE, // VkBool32 primitiveRestartEnable;
241 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
243 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
244 DE_NULL, // const void* pNext;
245 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
246 m_patchControlPoints, // uint32_t patchControlPoints;
249 const VkViewport viewport = makeViewport(m_renderSize);
250 const VkRect2D scissor = makeRect2D(m_renderSize);
252 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
254 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
255 DE_NULL, // const void* pNext;
256 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
257 1u, // uint32_t viewportCount;
258 &viewport, // const VkViewport* pViewports;
259 1u, // uint32_t scissorCount;
260 &scissor, // const VkRect2D* pScissors;
263 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
264 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
266 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
267 DE_NULL, // const void* pNext;
268 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
269 VK_FALSE, // VkBool32 depthClampEnable;
270 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable;
271 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
272 m_cullModeFlags, // VkCullModeFlags cullMode;
273 m_frontFace, // VkFrontFace frontFace;
274 VK_FALSE, // VkBool32 depthBiasEnable;
275 0.0f, // float depthBiasConstantFactor;
276 0.0f, // float depthBiasClamp;
277 0.0f, // float depthBiasSlopeFactor;
278 1.0f, // float lineWidth;
281 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
283 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
284 DE_NULL, // const void* pNext;
285 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
286 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
287 VK_FALSE, // VkBool32 sampleShadingEnable;
288 0.0f, // float minSampleShading;
289 DE_NULL, // const VkSampleMask* pSampleMask;
290 VK_FALSE, // VkBool32 alphaToCoverageEnable;
291 VK_FALSE // VkBool32 alphaToOneEnable;
294 const VkStencilOpState stencilOpState = makeStencilOpState(
295 VK_STENCIL_OP_KEEP, // stencil fail
296 VK_STENCIL_OP_KEEP, // depth & stencil pass
297 VK_STENCIL_OP_KEEP, // depth only fail
298 VK_COMPARE_OP_NEVER, // compare op
303 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
305 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
306 DE_NULL, // const void* pNext;
307 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
308 VK_FALSE, // VkBool32 depthTestEnable;
309 VK_FALSE, // VkBool32 depthWriteEnable;
310 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
311 VK_FALSE, // VkBool32 depthBoundsTestEnable;
312 VK_FALSE, // VkBool32 stencilTestEnable;
313 stencilOpState, // VkStencilOpState front;
314 stencilOpState, // VkStencilOpState back;
315 0.0f, // float minDepthBounds;
316 1.0f, // float maxDepthBounds;
319 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
320 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
322 m_blendEnable, // VkBool32 blendEnable;
323 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
324 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
325 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
326 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
327 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
328 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
329 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
332 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
334 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
335 DE_NULL, // const void* pNext;
336 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
337 VK_FALSE, // VkBool32 logicOpEnable;
338 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
339 1u, // deUint32 attachmentCount;
340 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
341 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
344 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
346 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
347 DE_NULL, // const void* pNext;
348 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
349 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
350 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
351 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
352 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
353 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
354 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState;
355 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
356 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
357 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
358 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
359 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
360 pipelineLayout, // VkPipelineLayout layout;
361 renderPass, // VkRenderPass renderPass;
362 0u, // deUint32 subpass;
363 DE_NULL, // VkPipeline basePipelineHandle;
364 0, // deInt32 basePipelineIndex;
368 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
369 vk::Move<vk::VkPipeline> pipeline (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
371 // Refresh data from cache
372 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
378 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
380 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
382 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
383 throw tcu::NotSupportedError("Tessellation shader not supported");
385 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
386 throw tcu::NotSupportedError("Geometry shader not supported");
388 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
389 throw tcu::NotSupportedError("Double-precision floats not supported");
391 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
392 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
394 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
395 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
397 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
398 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
401 void requireStorageImageSupport(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat fmt)
403 const VkFormatProperties p = getPhysicalDeviceFormatProperties(vki, physDevice, fmt);
404 if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
405 throw tcu::NotSupportedError("Storage image format not supported");
408 std::string getResourceName (const ResourceDescription& resource)
410 std::ostringstream str;
412 if (resource.type == RESOURCE_TYPE_BUFFER)
413 str << "buffer_" << resource.size.x();
414 else if (resource.type == RESOURCE_TYPE_IMAGE)
416 str << "image_" << resource.size.x()
417 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
418 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
419 << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
421 else if (isIndirectBuffer(resource.type))
422 str << "indirect_buffer";
429 bool isIndirectBuffer (const ResourceType type)
433 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
434 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
435 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
443 PipelineCacheData::PipelineCacheData (void)
447 PipelineCacheData::~PipelineCacheData (void)
451 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
453 const de::ScopedLock dataLock (m_lock);
454 const struct vk::VkPipelineCacheCreateInfo params =
456 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
458 (vk::VkPipelineCacheCreateFlags)0,
459 (deUintptr)m_data.size(),
460 (m_data.empty() ? DE_NULL : &m_data[0])
463 return vk::createPipelineCache(vk, device, ¶ms);
466 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
468 const de::ScopedLock dataLock (m_lock);
469 deUintptr dataSize = 0;
471 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
473 m_data.resize(dataSize);
476 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));