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"
31 namespace synchronization
35 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
37 const VkCommandBufferAllocateInfo info =
39 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
40 DE_NULL, // const void* pNext;
41 commandPool, // VkCommandPool commandPool;
42 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
43 1u, // deUint32 commandBufferCount;
45 return allocateCommandBuffer(vk, device, &info);
48 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
49 const VkDevice device,
50 const VkPipelineLayout pipelineLayout,
51 const VkShaderModule shaderModule,
52 const VkSpecializationInfo* specInfo,
53 PipelineCacheData& pipelineCacheData)
55 const VkPipelineShaderStageCreateInfo shaderStageInfo =
57 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
58 DE_NULL, // const void* pNext;
59 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
60 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
61 shaderModule, // VkShaderModule module;
62 "main", // const char* pName;
63 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
65 const VkComputePipelineCreateInfo pipelineInfo =
67 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
68 DE_NULL, // const void* pNext;
69 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
70 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
71 pipelineLayout, // VkPipelineLayout layout;
72 DE_NULL, // VkPipeline basePipelineHandle;
73 0, // deInt32 basePipelineIndex;
77 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
78 vk::Move<vk::VkPipeline> pipeline (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
80 // Refresh data from cache
81 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
87 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
89 const VkImageCreateInfo imageInfo =
91 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
92 DE_NULL, // const void* pNext;
93 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
94 imageType, // VkImageType imageType;
95 format, // VkFormat format;
96 extent, // VkExtent3D extent;
97 1u, // uint32_t mipLevels;
98 1u, // uint32_t arrayLayers;
99 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
100 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
101 usage, // VkImageUsageFlags usage;
102 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
103 0u, // uint32_t queueFamilyIndexCount;
104 DE_NULL, // const uint32_t* pQueueFamilyIndices;
105 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
110 void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk,
111 const VkCommandBuffer commandBuffer,
112 const VkRenderPass renderPass,
113 const VkFramebuffer framebuffer)
115 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
117 beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
120 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
121 const VkDevice device,
122 const VkShaderStageFlagBits stage,
123 const ProgramBinary& binary,
124 const VkSpecializationInfo* specInfo)
126 VkShaderModule module;
129 case (VK_SHADER_STAGE_VERTEX_BIT):
130 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
131 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
132 module = *m_vertexShaderModule;
135 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
136 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
137 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
138 module = *m_tessControlShaderModule;
141 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
142 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
143 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
144 module = *m_tessEvaluationShaderModule;
147 case (VK_SHADER_STAGE_GEOMETRY_BIT):
148 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
149 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
150 module = *m_geometryShaderModule;
153 case (VK_SHADER_STAGE_FRAGMENT_BIT):
154 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
155 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
156 module = *m_fragmentShaderModule;
160 DE_FATAL("Invalid shader stage");
164 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
166 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
167 DE_NULL, // const void* pNext;
168 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
169 stage, // VkShaderStageFlagBits stage;
170 module, // VkShaderModule module;
171 "main", // const char* pName;
172 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
175 m_shaderStageFlags |= stage;
176 m_shaderStages.push_back(pipelineShaderStageInfo);
181 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
183 const VkVertexInputBindingDescription bindingDesc =
185 0u, // uint32_t binding;
186 stride, // uint32_t stride;
187 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
189 const VkVertexInputAttributeDescription attributeDesc =
191 0u, // uint32_t location;
192 0u, // uint32_t binding;
193 vertexFormat, // VkFormat format;
194 0u, // uint32_t offset;
197 m_vertexInputBindings.clear();
198 m_vertexInputBindings.push_back(bindingDesc);
200 m_vertexInputAttributes.clear();
201 m_vertexInputAttributes.push_back(attributeDesc);
207 inline const T* dataPointer (const std::vector<T>& vec)
209 return (vec.size() != 0 ? &vec[0] : DE_NULL);
212 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
213 const VkDevice device,
214 const VkPipelineLayout pipelineLayout,
215 const VkRenderPass renderPass,
216 PipelineCacheData& pipelineCacheData)
218 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
220 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
221 DE_NULL, // const void* pNext;
222 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
223 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount;
224 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
225 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount;
226 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
229 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
230 : m_primitiveTopology;
231 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
233 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
234 DE_NULL, // const void* pNext;
235 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
236 topology, // VkPrimitiveTopology topology;
237 VK_FALSE, // VkBool32 primitiveRestartEnable;
240 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
242 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
243 DE_NULL, // const void* pNext;
244 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
245 m_patchControlPoints, // uint32_t patchControlPoints;
248 const VkViewport viewport = makeViewport(m_renderSize);
249 const VkRect2D scissor = makeRect2D(m_renderSize);
251 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
253 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
254 DE_NULL, // const void* pNext;
255 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
256 1u, // uint32_t viewportCount;
257 &viewport, // const VkViewport* pViewports;
258 1u, // uint32_t scissorCount;
259 &scissor, // const VkRect2D* pScissors;
262 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
263 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
265 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
266 DE_NULL, // const void* pNext;
267 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
268 VK_FALSE, // VkBool32 depthClampEnable;
269 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable;
270 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
271 m_cullModeFlags, // VkCullModeFlags cullMode;
272 m_frontFace, // VkFrontFace frontFace;
273 VK_FALSE, // VkBool32 depthBiasEnable;
274 0.0f, // float depthBiasConstantFactor;
275 0.0f, // float depthBiasClamp;
276 0.0f, // float depthBiasSlopeFactor;
277 1.0f, // float lineWidth;
280 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
282 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
283 DE_NULL, // const void* pNext;
284 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
285 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
286 VK_FALSE, // VkBool32 sampleShadingEnable;
287 0.0f, // float minSampleShading;
288 DE_NULL, // const VkSampleMask* pSampleMask;
289 VK_FALSE, // VkBool32 alphaToCoverageEnable;
290 VK_FALSE // VkBool32 alphaToOneEnable;
293 const VkStencilOpState stencilOpState = makeStencilOpState(
294 VK_STENCIL_OP_KEEP, // stencil fail
295 VK_STENCIL_OP_KEEP, // depth & stencil pass
296 VK_STENCIL_OP_KEEP, // depth only fail
297 VK_COMPARE_OP_NEVER, // compare op
302 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
304 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
305 DE_NULL, // const void* pNext;
306 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
307 VK_FALSE, // VkBool32 depthTestEnable;
308 VK_FALSE, // VkBool32 depthWriteEnable;
309 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
310 VK_FALSE, // VkBool32 depthBoundsTestEnable;
311 VK_FALSE, // VkBool32 stencilTestEnable;
312 stencilOpState, // VkStencilOpState front;
313 stencilOpState, // VkStencilOpState back;
314 0.0f, // float minDepthBounds;
315 1.0f, // float maxDepthBounds;
318 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
319 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
321 m_blendEnable, // VkBool32 blendEnable;
322 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
323 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
324 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
325 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
326 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
327 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
328 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
331 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
333 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
334 DE_NULL, // const void* pNext;
335 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
336 VK_FALSE, // VkBool32 logicOpEnable;
337 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
338 1u, // deUint32 attachmentCount;
339 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
340 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
343 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
345 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
346 DE_NULL, // const void* pNext;
347 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
348 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
349 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
350 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
351 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
352 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
353 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState;
354 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
355 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
356 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
357 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
358 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
359 pipelineLayout, // VkPipelineLayout layout;
360 renderPass, // VkRenderPass renderPass;
361 0u, // deUint32 subpass;
362 DE_NULL, // VkPipeline basePipelineHandle;
363 0, // deInt32 basePipelineIndex;
367 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
368 vk::Move<vk::VkPipeline> pipeline (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
370 // Refresh data from cache
371 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
377 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
379 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
381 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
382 throw tcu::NotSupportedError("Tessellation shader not supported");
384 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
385 throw tcu::NotSupportedError("Geometry shader not supported");
387 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
388 throw tcu::NotSupportedError("Double-precision floats not supported");
390 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
391 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
393 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
394 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
396 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
397 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
400 void requireStorageImageSupport(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat fmt)
402 const VkFormatProperties p = getPhysicalDeviceFormatProperties(vki, physDevice, fmt);
403 if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
404 throw tcu::NotSupportedError("Storage image format not supported");
407 std::string getResourceName (const ResourceDescription& resource)
409 std::ostringstream str;
411 if (resource.type == RESOURCE_TYPE_BUFFER)
412 str << "buffer_" << resource.size.x();
413 else if (resource.type == RESOURCE_TYPE_IMAGE)
415 str << "image_" << resource.size.x()
416 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
417 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
418 << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
420 else if (isIndirectBuffer(resource.type))
421 str << "indirect_buffer";
428 bool isIndirectBuffer (const ResourceType type)
432 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
433 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
434 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
442 PipelineCacheData::PipelineCacheData (void)
446 PipelineCacheData::~PipelineCacheData (void)
450 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
452 const de::ScopedLock dataLock (m_lock);
453 const struct vk::VkPipelineCacheCreateInfo params =
455 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
457 (vk::VkPipelineCacheCreateFlags)0,
458 (deUintptr)m_data.size(),
459 (m_data.empty() ? DE_NULL : &m_data[0])
462 return vk::createPipelineCache(vk, device, ¶ms);
465 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
467 const de::ScopedLock dataLock (m_lock);
468 deUintptr dataSize = 0;
470 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
472 m_data.resize(dataSize);
475 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));