1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group 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 Pipeline specialization constants test utilities 22 *//*--------------------------------------------------------------------*/ 23 24#include "vktPipelineSpecConstantUtil.hpp" 25#include "vkTypeUtil.hpp" 26#include <vector> 27 28namespace vkt 29{ 30namespace pipeline 31{ 32using namespace vk; 33 34GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk, 35 const VkDevice device, 36 const VkShaderStageFlagBits stage, 37 const ProgramBinary& binary, 38 const VkSpecializationInfo* specInfo) 39{ 40 VkShaderModule module; 41 switch (stage) 42 { 43 case (VK_SHADER_STAGE_VERTEX_BIT): 44 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL); 45 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 46 module = *m_vertexShaderModule; 47 break; 48 49 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT): 50 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL); 51 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 52 module = *m_tessControlShaderModule; 53 break; 54 55 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT): 56 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL); 57 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 58 module = *m_tessEvaluationShaderModule; 59 break; 60 61 case (VK_SHADER_STAGE_GEOMETRY_BIT): 62 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL); 63 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 64 module = *m_geometryShaderModule; 65 break; 66 67 case (VK_SHADER_STAGE_FRAGMENT_BIT): 68 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL); 69 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0); 70 module = *m_fragmentShaderModule; 71 break; 72 73 default: 74 DE_FATAL("Invalid shader stage"); 75 return *this; 76 } 77 78 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo = 79 { 80 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 81 DE_NULL, // const void* pNext; 82 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 83 stage, // VkShaderStageFlagBits stage; 84 module, // VkShaderModule module; 85 "main", // const char* pName; 86 specInfo, // const VkSpecializationInfo* pSpecializationInfo; 87 }; 88 89 m_shaderStageFlags |= stage; 90 m_shaderStages.push_back(pipelineShaderStageInfo); 91 92 return *this; 93} 94 95Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk, 96 const VkDevice device, 97 const VkPipelineLayout pipelineLayout, 98 const VkRenderPass renderPass) 99{ 100 const VkVertexInputBindingDescription vertexInputBindingDescription = 101 { 102 0u, // uint32_t binding; 103 sizeof(tcu::Vec4), // uint32_t stride; // Vertex is a 4-element vector XYZW, position only 104 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate; 105 }; 106 107 const VkVertexInputAttributeDescription vertexInputAttributeDescription = 108 { 109 0u, // uint32_t location; 110 0u, // uint32_t binding; 111 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format; 112 0u, // uint32_t offset; 113 }; 114 115 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo = 116 { 117 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType; 118 DE_NULL, // const void* pNext; 119 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags; 120 1u, // uint32_t vertexBindingDescriptionCount; 121 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions; 122 1u, // uint32_t vertexAttributeDescriptionCount; 123 &vertexInputAttributeDescription, // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions; 124 }; 125 126 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; 127 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo = 128 { 129 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType; 130 DE_NULL, // const void* pNext; 131 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags; 132 topology, // VkPrimitiveTopology topology; 133 VK_FALSE, // VkBool32 primitiveRestartEnable; 134 }; 135 136 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo = 137 { 138 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType; 139 DE_NULL, // const void* pNext; 140 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags; 141 3u, // uint32_t patchControlPoints; 142 }; 143 144 const VkViewport viewport = makeViewport( 145 0.0f, 0.0f, 146 static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()), 147 0.0f, 1.0f); 148 149 const VkRect2D scissor = { 150 makeOffset2D(0, 0), 151 makeExtent2D(m_renderSize.x(), m_renderSize.y()), 152 }; 153 154 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo = 155 { 156 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType; 157 DE_NULL, // const void* pNext; 158 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags; 159 1u, // uint32_t viewportCount; 160 &viewport, // const VkViewport* pViewports; 161 1u, // uint32_t scissorCount; 162 &scissor, // const VkRect2D* pScissors; 163 }; 164 165 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo = 166 { 167 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType; 168 DE_NULL, // const void* pNext; 169 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags; 170 VK_FALSE, // VkBool32 depthClampEnable; 171 VK_FALSE, // VkBool32 rasterizerDiscardEnable; 172 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode; 173 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode; 174 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace; 175 VK_FALSE, // VkBool32 depthBiasEnable; 176 0.0f, // float depthBiasConstantFactor; 177 0.0f, // float depthBiasClamp; 178 0.0f, // float depthBiasSlopeFactor; 179 1.0f, // float lineWidth; 180 }; 181 182 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo = 183 { 184 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType; 185 DE_NULL, // const void* pNext; 186 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags; 187 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples; 188 VK_FALSE, // VkBool32 sampleShadingEnable; 189 0.0f, // float minSampleShading; 190 DE_NULL, // const VkSampleMask* pSampleMask; 191 VK_FALSE, // VkBool32 alphaToCoverageEnable; 192 VK_FALSE // VkBool32 alphaToOneEnable; 193 }; 194 195 const VkStencilOpState stencilOpStateBasic = makeStencilOpState( 196 VK_STENCIL_OP_KEEP, // stencil fail 197 VK_STENCIL_OP_KEEP, // depth & stencil pass 198 VK_STENCIL_OP_KEEP, // depth only fail 199 VK_COMPARE_OP_NEVER, // compare op 200 0u, // compare mask 201 0u, // write mask 202 0u); // reference 203 204 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo = 205 { 206 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType; 207 DE_NULL, // const void* pNext; 208 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags; 209 VK_FALSE, // VkBool32 depthTestEnable; 210 VK_FALSE, // VkBool32 depthWriteEnable; 211 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp; 212 VK_FALSE, // VkBool32 depthBoundsTestEnable; 213 VK_FALSE, // VkBool32 stencilTestEnable; 214 stencilOpStateBasic, // VkStencilOpState front; 215 stencilOpStateBasic, // VkStencilOpState back; 216 0.0f, // float minDepthBounds; 217 1.0f, // float maxDepthBounds; 218 }; 219 220 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT; 221 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState = 222 { 223 VK_FALSE, // VkBool32 blendEnable; 224 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 225 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor; 226 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 227 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 228 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor; 229 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 230 colorComponentsAll, // VkColorComponentFlags colorWriteMask; 231 }; 232 233 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo = 234 { 235 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType; 236 DE_NULL, // const void* pNext; 237 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags; 238 VK_FALSE, // VkBool32 logicOpEnable; 239 VK_LOGIC_OP_COPY, // VkLogicOp logicOp; 240 1u, // deUint32 attachmentCount; 241 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments; 242 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4]; 243 }; 244 245 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo = 246 { 247 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType; 248 DE_NULL, // const void* pNext; 249 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 250 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount; 251 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages; 252 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState; 253 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState; 254 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState; 255 &pipelineViewportStateInfo, // const VkPipelineViewportStateCreateInfo* pViewportState; 256 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState; 257 &pipelineMultisampleStateInfo, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState; 258 &pipelineDepthStencilStateInfo, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState; 259 &pipelineColorBlendStateInfo, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState; 260 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState; 261 pipelineLayout, // VkPipelineLayout layout; 262 renderPass, // VkRenderPass renderPass; 263 0u, // deUint32 subpass; 264 DE_NULL, // VkPipeline basePipelineHandle; 265 0, // deInt32 basePipelineIndex; 266 }; 267 268 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo); 269} 270 271Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk, 272 const VkDevice device, 273 const VkFormat colorFormat) 274{ 275 const VkAttachmentDescription colorAttachmentDescription = 276 { 277 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags; 278 colorFormat, // VkFormat format; 279 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 280 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 281 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 282 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; 283 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; 284 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout; 285 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; 286 }; 287 288 const VkAttachmentReference colorAttachmentReference = 289 { 290 0u, // deUint32 attachment; 291 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout; 292 }; 293 294 const VkAttachmentReference depthAttachmentReference = 295 { 296 VK_ATTACHMENT_UNUSED, // deUint32 attachment; 297 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout; 298 }; 299 300 const VkSubpassDescription subpassDescription = 301 { 302 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; 303 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; 304 0u, // deUint32 inputAttachmentCount; 305 DE_NULL, // const VkAttachmentReference* pInputAttachments; 306 1u, // deUint32 colorAttachmentCount; 307 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments; 308 DE_NULL, // const VkAttachmentReference* pResolveAttachments; 309 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment; 310 0u, // deUint32 preserveAttachmentCount; 311 DE_NULL // const deUint32* pPreserveAttachments; 312 }; 313 314 const VkRenderPassCreateInfo renderPassInfo = 315 { 316 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType; 317 DE_NULL, // const void* pNext; 318 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags; 319 1u, // deUint32 attachmentCount; 320 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments; 321 1u, // deUint32 subpassCount; 322 &subpassDescription, // const VkSubpassDescription* pSubpasses; 323 0u, // deUint32 dependencyCount; 324 DE_NULL // const VkSubpassDependency* pDependencies; 325 }; 326 327 return createRenderPass(vk, device, &renderPassInfo); 328} 329 330void beginRenderPass (const DeviceInterface& vk, 331 const VkCommandBuffer commandBuffer, 332 const VkRenderPass renderPass, 333 const VkFramebuffer framebuffer, 334 const VkRect2D& renderArea, 335 const tcu::Vec4& clearColor) 336{ 337 const VkClearValue clearValue = makeClearValueColor(clearColor); 338 339 const VkRenderPassBeginInfo renderPassBeginInfo = { 340 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType; 341 DE_NULL, // const void* pNext; 342 renderPass, // VkRenderPass renderPass; 343 framebuffer, // VkFramebuffer framebuffer; 344 renderArea, // VkRect2D renderArea; 345 1u, // uint32_t clearValueCount; 346 &clearValue, // const VkClearValue* pClearValues; 347 }; 348 349 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); 350} 351 352VkImageCreateInfo makeImageCreateInfo (const tcu::IVec2& size, const VkFormat format, const VkImageUsageFlags usage) 353{ 354 const VkImageCreateInfo imageInfo = 355 { 356 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType; 357 DE_NULL, // const void* pNext; 358 (VkImageCreateFlags)0, // VkImageCreateFlags flags; 359 VK_IMAGE_TYPE_2D, // VkImageType imageType; 360 format, // VkFormat format; 361 makeExtent3D(size.x(), size.y(), 1), // VkExtent3D extent; 362 1u, // uint32_t mipLevels; 363 1u, // uint32_t arrayLayers; 364 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; 365 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling; 366 usage, // VkImageUsageFlags usage; 367 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 368 0u, // uint32_t queueFamilyIndexCount; 369 DE_NULL, // const uint32_t* pQueueFamilyIndices; 370 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; 371 }; 372 return imageInfo; 373} 374 375void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags) 376{ 377 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice); 378 379 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader) 380 throw tcu::NotSupportedError("Tessellation shader not supported"); 381 382 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader) 383 throw tcu::NotSupportedError("Geometry shader not supported"); 384 385 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64) 386 throw tcu::NotSupportedError("Double-precision floats not supported"); 387 388 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics) 389 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline"); 390 391 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics) 392 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader"); 393} 394 395} // pipeline 396} // vkt 397