1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2021 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 Wrapper that can construct monolithic pipeline or use
22 VK_EXT_graphics_pipeline_library for pipeline construction
23 *//*--------------------------------------------------------------------*/
25 #include "vkRefUtil.hpp"
26 #include "vkQueryUtil.hpp"
27 #include "deSharedPtr.hpp"
28 #include "deSTLUtil.hpp"
29 #include "tcuVector.hpp"
30 #include "tcuVectorType.hpp"
31 #include "tcuMaybe.hpp"
32 #include "vkPipelineConstructionUtil.hpp"
43 enum PipelineSetupState
45 PSS_NONE = 0x00000000,
46 PSS_VERTEX_INPUT_INTERFACE = 0x00000001,
47 PSS_PRE_RASTERIZATION_SHADERS = 0x00000002,
48 PSS_FRAGMENT_SHADER = 0x00000004,
49 PSS_FRAGMENT_OUTPUT_INTERFACE = 0x00000008,
52 using TessellationDomainOriginStatePtr = std::unique_ptr<VkPipelineTessellationDomainOriginStateCreateInfo>;
54 } // anonymous namespace
56 static const VkVertexInputBindingDescription defaultVertexInputBindingDescription
58 0u, // deUint32 binding
59 sizeof(tcu::Vec4), // deUint32 stride
60 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate
63 static const VkVertexInputAttributeDescription defaultVertexInputAttributeDescription
65 0u, // deUint32 location
66 0u, // deUint32 binding
67 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
71 static const VkPipelineVertexInputStateCreateInfo defaultVertexInputState
73 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
74 DE_NULL, // const void* pNext
75 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags
76 1u, // deUint32 vertexBindingDescriptionCount
77 &defaultVertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
78 1u, // deUint32 vertexAttributeDescriptionCount
79 &defaultVertexInputAttributeDescription // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
82 static const VkStencilOpState defaultStencilOpState
84 VK_STENCIL_OP_KEEP, // VkStencilOp failOp
85 VK_STENCIL_OP_KEEP, // VkStencilOp passOp
86 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp
87 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp
88 0u, // deUint32 compareMask
89 0u, // deUint32 writeMask
90 0u // deUint32 reference
93 static const VkPipelineDepthStencilStateCreateInfo defaultDepthStencilState
95 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
96 DE_NULL, // const void* pNext
97 0u, // VkPipelineDepthStencilStateCreateFlags flags
98 VK_FALSE, // VkBool32 depthTestEnable
99 VK_FALSE, // VkBool32 depthWriteEnable
100 VK_COMPARE_OP_LESS_OR_EQUAL, // VkCompareOp depthCompareOp
101 VK_FALSE, // VkBool32 depthBoundsTestEnable
102 VK_FALSE, // VkBool32 stencilTestEnable
103 defaultStencilOpState, // VkStencilOpState front
104 defaultStencilOpState, // VkStencilOpState back
105 0.0f, // float minDepthBounds
106 1.0f, // float maxDepthBounds
109 static const VkPipelineMultisampleStateCreateInfo defaultMultisampleState
111 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
112 DE_NULL, // const void* pNext
113 0u, // VkPipelineMultisampleStateCreateFlags flags
114 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
115 VK_FALSE, // VkBool32 sampleShadingEnable
116 1.0f, // float minSampleShading
117 DE_NULL, // const VkSampleMask* pSampleMask
118 VK_FALSE, // VkBool32 alphaToCoverageEnable
119 VK_FALSE // VkBool32 alphaToOneEnable
122 static const VkPipelineColorBlendAttachmentState defaultColorBlendAttachmentState
124 VK_FALSE, // VkBool32 blendEnable
125 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor
126 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor
127 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
128 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
129 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
130 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
131 0xf // VkColorComponentFlags colorWriteMask
134 static const VkPipelineColorBlendStateCreateInfo defaultColorBlendState
136 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
137 DE_NULL, // const void* pNext
138 0u, // VkPipelineColorBlendStateCreateFlags flags
139 VK_FALSE, // VkBool32 logicOpEnable
140 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
141 1u, // deUint32 attachmentCount
142 &defaultColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
143 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]
148 #ifndef CTS_USES_VULKANSC
149 VkGraphicsPipelineLibraryCreateInfoEXT makeGraphicsPipelineLibraryCreateInfo(const VkGraphicsPipelineLibraryFlagsEXT flags)
153 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT, // VkStructureType sType;
154 DE_NULL, // void* pNext;
155 flags, // VkGraphicsPipelineLibraryFlagsEXT flags;
158 #endif // CTS_USES_VULKANSC
160 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface& vk,
162 VkPipelineCache pipelineCache,
163 const VkGraphicsPipelineCreateInfo* pCreateInfo,
164 const VkAllocationCallbacks* pAllocator = nullptr)
166 VkPipeline object = 0;
167 const auto retcode = vk.createGraphicsPipelines(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object);
169 #ifndef CTS_USES_VULKANSC
170 const bool allowCompileRequired = ((pCreateInfo->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0u);
172 if (allowCompileRequired && retcode == VK_PIPELINE_COMPILE_REQUIRED)
173 throw PipelineCompileRequiredError("createGraphicsPipelines returned VK_PIPELINE_COMPILE_REQUIRED");
174 #endif // CTS_USES_VULKANSC
177 return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
182 void checkPipelineLibraryRequirements (const InstanceInterface& vki,
183 VkPhysicalDevice physicalDevice,
184 PipelineConstructionType pipelineConstructionType)
186 if (pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
189 const auto supportedExtensions = enumerateDeviceExtensionProperties(vki, physicalDevice, DE_NULL);
190 if (!isExtensionStructSupported(supportedExtensions, RequiredExtension("VK_EXT_graphics_pipeline_library")))
191 TCU_THROW(NotSupportedError, "VK_EXT_graphics_pipeline_library not supported");
194 void addToChain(void** structThatStartsChain, void* structToAddAtTheEnd)
196 DE_ASSERT(structThatStartsChain);
198 if (structToAddAtTheEnd == DE_NULL)
201 // Cast to the base out structure which has a non-const pNext pointer.
202 auto* structToAddAtTheEndCasted = reinterpret_cast<VkBaseOutStructure*>(structToAddAtTheEnd);
204 // make sure that pNext pointer of structure that is added to chain is empty;
205 // we are construting chains on our own and there are cases that use same
206 // structure for multiple instances of GraphicsPipelineWrapper
207 structToAddAtTheEndCasted->pNext = DE_NULL;
209 deUint32 safetyCouter = 10u;
210 void** structInChain = structThatStartsChain;
214 // check if this is free spot
215 if (*structInChain == DE_NULL)
217 // attach new structure at the end
218 *structInChain = structToAddAtTheEndCasted;
222 // Cast to the base out structure which has a non-const pNext pointer.
223 auto* gpl = reinterpret_cast<VkBaseOutStructure*>(*structInChain);
225 // move structure pointer one position down the pNext chain
226 structInChain = reinterpret_cast<void**>(&gpl->pNext);
228 while (--safetyCouter);
230 // probably safetyCouter is to small
235 using PipelineShaderStageModuleIdPtr = std::unique_ptr<PipelineShaderStageModuleIdentifierCreateInfoWrapper>;
238 // Structure storing *CreateInfo structures that do not need to exist in memory after pipeline was constructed.
239 struct GraphicsPipelineWrapper::InternalData
241 const DeviceInterface& vk;
243 const PipelineConstructionType pipelineConstructionType;
244 const VkPipelineCreateFlags pipelineFlags;
246 // attribute used for making sure pipeline is configured in correct order
249 std::vector<PipelineShaderStageModuleIdPtr> pipelineShaderIdentifiers;
250 std::vector<VkPipelineShaderStageCreateInfo> pipelineShaderStages;
251 VkPipelineInputAssemblyStateCreateInfo inputAssemblyState;
252 VkPipelineRasterizationStateCreateInfo defaultRasterizationState;
253 VkPipelineViewportStateCreateInfo viewportState;
254 VkPipelineTessellationStateCreateInfo tessellationState;
255 VkPipelineFragmentShadingRateStateCreateInfoKHR* pFragmentShadingRateState;
256 PipelineRenderingCreateInfoWrapper pRenderingState;
257 const VkPipelineDynamicStateCreateInfo* pDynamicState;
258 PipelineRepresentativeFragmentTestCreateInfoWrapper pRepresentativeFragmentTestState;
260 TessellationDomainOriginStatePtr pTessellationDomainOrigin;
261 deBool useViewportState;
262 deBool useDefaultRasterizationState;
263 deBool useDefaultDepthStencilState;
264 deBool useDefaultColorBlendState;
265 deBool useDefaultMultisampleState;
266 bool failOnCompileWhenLinking;
268 VkGraphicsPipelineCreateInfo monolithicPipelineCreateInfo;
270 // initialize with most common values
271 InternalData(const DeviceInterface& vkd, VkDevice vkDevice, const PipelineConstructionType constructionType, const VkPipelineCreateFlags pipelineCreateFlags)
274 , pipelineConstructionType (constructionType)
275 , pipelineFlags (pipelineCreateFlags)
276 , setupState (PSS_NONE)
279 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType
280 DE_NULL, // const void* pNext
281 0u, // VkPipelineInputAssemblyStateCreateFlags flags
282 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology
283 VK_FALSE // VkBool32 primitiveRestartEnable
285 , defaultRasterizationState
287 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType
288 DE_NULL, // const void* pNext
289 0u, // VkPipelineRasterizationStateCreateFlags flags
290 VK_FALSE, // VkBool32 depthClampEnable
291 VK_FALSE, // VkBool32 rasterizerDiscardEnable
292 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode
293 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode
294 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace
295 VK_FALSE, // VkBool32 depthBiasEnable
296 0.0f, // float depthBiasConstantFactor
297 0.0f, // float depthBiasClamp
298 0.0f, // float depthBiasSlopeFactor
299 1.0f // float lineWidth
303 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType
304 DE_NULL, // const void* pNext
305 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags
306 1u, // deUint32 viewportCount
307 DE_NULL, // const VkViewport* pViewports
308 1u, // deUint32 scissorCount
309 DE_NULL // const VkRect2D* pScissors
313 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType
314 DE_NULL, // const void* pNext
315 0u, // VkPipelineTessellationStateCreateFlags flags
316 3u // deUint32 patchControlPoints
318 , pFragmentShadingRateState (nullptr)
319 , pDynamicState (DE_NULL)
320 , pRepresentativeFragmentTestState(nullptr)
321 , pTessellationDomainOrigin ()
322 , useViewportState (DE_TRUE)
323 , useDefaultRasterizationState (DE_FALSE)
324 , useDefaultDepthStencilState (DE_FALSE)
325 , useDefaultColorBlendState (DE_FALSE)
326 , useDefaultMultisampleState (DE_FALSE)
327 , failOnCompileWhenLinking (false)
329 monolithicPipelineCreateInfo = initVulkanStructure();
333 GraphicsPipelineWrapper::GraphicsPipelineWrapper(const DeviceInterface& vk,
335 const PipelineConstructionType pipelineConstructionType,
336 const VkPipelineCreateFlags flags)
337 : m_internalData (new InternalData(vk, device, pipelineConstructionType, flags))
341 GraphicsPipelineWrapper::GraphicsPipelineWrapper(GraphicsPipelineWrapper&& pw) noexcept
342 : m_pipelineFinal (pw.m_pipelineFinal)
343 , m_internalData (pw.m_internalData)
345 std::move(pw.m_pipelineParts, pw.m_pipelineParts + de::arrayLength(pw.m_pipelineParts), m_pipelineParts);
348 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setMonolithicPipelineLayout(const VkPipelineLayout layout)
350 // make sure pipeline was not already built
351 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
353 m_internalData->monolithicPipelineCreateInfo.layout = layout;
358 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDynamicState(const VkPipelineDynamicStateCreateInfo* dynamicState)
360 // make sure states are not yet setup - all pipeline states must know about dynamic state
361 DE_ASSERT(m_internalData && m_internalData->setupState == PSS_NONE);
363 m_internalData->pDynamicState = dynamicState;
364 m_internalData->monolithicPipelineCreateInfo.pDynamicState = dynamicState;
369 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setRepresentativeFragmentTestState(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)
371 // Representative fragment test state is needed by the fragment shader state.
372 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
374 m_internalData->pRepresentativeFragmentTestState = representativeFragmentTestState;
378 std::vector<VkDynamicState> getDynamicStates(const VkPipelineDynamicStateCreateInfo* dynamicStateInfo, uint32_t setupState)
380 static const std::set<VkDynamicState> vertexInputStates {
381 VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT,
382 VK_DYNAMIC_STATE_VERTEX_INPUT_EXT,
383 VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT,
384 VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT,
387 static const std::set<VkDynamicState> preRastStates {
388 VK_DYNAMIC_STATE_VIEWPORT,
389 VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT,
390 VK_DYNAMIC_STATE_SCISSOR,
391 VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT,
392 VK_DYNAMIC_STATE_LINE_WIDTH,
393 VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
394 VK_DYNAMIC_STATE_CULL_MODE_EXT,
395 VK_DYNAMIC_STATE_FRONT_FACE_EXT,
396 VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT,
397 VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT,
398 VK_DYNAMIC_STATE_DISCARD_RECTANGLE_EXT,
399 VK_DYNAMIC_STATE_DEPTH_BIAS,
400 VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE_EXT,
402 #ifndef CTS_USES_VULKANSC
403 VK_DYNAMIC_STATE_TESSELLATION_DOMAIN_ORIGIN_EXT,
404 VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT,
405 VK_DYNAMIC_STATE_POLYGON_MODE_EXT,
406 VK_DYNAMIC_STATE_RASTERIZATION_STREAM_EXT,
407 VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT,
408 VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT,
409 VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT,
410 VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT,
411 VK_DYNAMIC_STATE_LINE_STIPPLE_EXT,
412 VK_DYNAMIC_STATE_CONSERVATIVE_RASTERIZATION_MODE_EXT,
413 VK_DYNAMIC_STATE_EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT,
414 VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT,
415 VK_DYNAMIC_STATE_VIEWPORT_SWIZZLE_NV,
416 VK_DYNAMIC_STATE_SHADING_RATE_IMAGE_ENABLE_NV,
417 VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_ENABLE_NV,
418 VK_DYNAMIC_STATE_VIEWPORT_W_SCALING_NV,
419 VK_DYNAMIC_STATE_VIEWPORT_SHADING_RATE_PALETTE_NV,
420 VK_DYNAMIC_STATE_VIEWPORT_COARSE_SAMPLE_ORDER_NV,
421 VK_DYNAMIC_STATE_EXCLUSIVE_SCISSOR_NV,
425 static const std::set<VkDynamicState> fragShaderStates {
426 VK_DYNAMIC_STATE_DEPTH_BOUNDS,
427 VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT,
428 VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT,
429 VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT,
430 VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT,
431 VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK,
432 VK_DYNAMIC_STATE_STENCIL_WRITE_MASK,
433 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
434 VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT,
435 VK_DYNAMIC_STATE_STENCIL_OP_EXT,
436 // Needs MSAA info here as well as fragment output state
437 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
438 #ifndef CTS_USES_VULKANSC
439 VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
440 VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
441 VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
442 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
443 VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
444 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
445 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
446 VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
447 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
448 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
449 VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
450 VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
455 static const std::set<VkDynamicState> fragOutputStates {
456 VK_DYNAMIC_STATE_LOGIC_OP_EXT,
457 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
458 VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT,
459 VK_DYNAMIC_STATE_FRAGMENT_SHADING_RATE_KHR,
460 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT,
461 #ifndef CTS_USES_VULKANSC
462 VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT,
463 VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT,
464 VK_DYNAMIC_STATE_COLOR_BLEND_ADVANCED_EXT,
465 VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT,
466 VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT,
467 VK_DYNAMIC_STATE_SAMPLE_MASK_EXT,
468 VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT,
469 VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT,
470 VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_ENABLE_EXT,
471 VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT,
472 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_ENABLE_NV,
473 VK_DYNAMIC_STATE_COVERAGE_TO_COLOR_LOCATION_NV,
474 VK_DYNAMIC_STATE_COVERAGE_MODULATION_MODE_NV,
475 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_ENABLE_NV,
476 VK_DYNAMIC_STATE_COVERAGE_MODULATION_TABLE_NV,
477 VK_DYNAMIC_STATE_COVERAGE_REDUCTION_MODE_NV,
478 VK_DYNAMIC_STATE_REPRESENTATIVE_FRAGMENT_TEST_ENABLE_NV,
482 const std::set<VkDynamicState> dynamicStates (dynamicStateInfo->pDynamicStates,
483 dynamicStateInfo->pDynamicStates + dynamicStateInfo->dynamicStateCount);
485 std::set<VkDynamicState> intersectedStates;
487 if (setupState & PSS_VERTEX_INPUT_INTERFACE)
488 std::set_intersection(vertexInputStates.begin(), vertexInputStates.end(), dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
490 if (setupState & PSS_PRE_RASTERIZATION_SHADERS)
491 std::set_intersection(preRastStates.begin(), preRastStates.end(), dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
493 if (setupState & PSS_FRAGMENT_SHADER)
494 std::set_intersection(fragShaderStates.begin(), fragShaderStates.end(), dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
496 if (setupState & PSS_FRAGMENT_OUTPUT_INTERFACE)
497 std::set_intersection(fragOutputStates.begin(), fragOutputStates.end(), dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
499 const std::vector<VkDynamicState> returnedStates (begin(intersectedStates), end(intersectedStates));
501 return returnedStates;
504 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultTopology(const VkPrimitiveTopology topology)
506 // topology is needed by vertex input state, make sure vertex input state was not setup yet
507 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
509 m_internalData->inputAssemblyState.topology = topology;
514 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultPatchControlPoints(const deUint32 patchControlPoints)
516 // patchControlPoints are needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
517 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
519 m_internalData->tessellationState.patchControlPoints = patchControlPoints;
524 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultTessellationDomainOrigin (const VkTessellationDomainOrigin domainOrigin, bool forceExtStruct)
526 // Tessellation domain origin is needed by pre-rasterization shader state, make sure pre-rasterization state was not setup yet
527 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
529 // We need the extension structure when:
530 // - We want to force it.
531 // - The domain origin is not the default value.
532 // - We have already hooked the extension structure.
533 if (forceExtStruct || domainOrigin != VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT || m_internalData->pTessellationDomainOrigin)
535 if (!m_internalData->pTessellationDomainOrigin)
537 m_internalData->pTessellationDomainOrigin.reset(new VkPipelineTessellationDomainOriginStateCreateInfo(initVulkanStructure()));
538 m_internalData->tessellationState.pNext = m_internalData->pTessellationDomainOrigin.get();
540 m_internalData->pTessellationDomainOrigin->domainOrigin = domainOrigin;
546 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultRasterizerDiscardEnable(const deBool rasterizerDiscardEnable)
548 // rasterizerDiscardEnable is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
549 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
551 m_internalData->defaultRasterizationState.rasterizerDiscardEnable = rasterizerDiscardEnable;
557 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultRasterizationState()
559 // RasterizationState is used in pre-rasterization shader state, make sure this state was not setup yet
560 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
562 m_internalData->useDefaultRasterizationState = DE_TRUE;
567 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultDepthStencilState()
569 // DepthStencilState is used in fragment shader state, make sure fragment shader state was not setup yet
570 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
572 m_internalData->useDefaultDepthStencilState = DE_TRUE;
577 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultColorBlendState()
579 // ColorBlendState is used in fragment shader state, make sure fragment shader state was not setup yet
580 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
582 m_internalData->useDefaultColorBlendState = DE_TRUE;
587 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultMultisampleState()
589 // MultisampleState is used in fragment shader state, make sure fragment shader state was not setup yet
590 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
592 m_internalData->useDefaultMultisampleState = DE_TRUE;
597 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultViewportsCount(deUint32 viewportCount)
599 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
600 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
602 m_internalData->viewportState.viewportCount = viewportCount;
607 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultScissorsCount(deUint32 scissorCount)
609 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
610 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
612 m_internalData->viewportState.scissorCount = scissorCount;
617 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setViewportStatePnext(const void* pNext)
619 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
620 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
622 m_internalData->viewportState.pNext = pNext;
627 #ifndef CTS_USES_VULKANSC
628 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setRenderingColorAttachmentsInfo(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)
630 /* When both graphics pipeline library and dynamic rendering enabled, we just need only viewMask of VkPipelineRenderingCreateInfo
631 * on non-fragment stages. But we need the rest info for setting up fragment output states.
632 * This method provides a way to verify this condition.
634 if (!m_internalData->pRenderingState.ptr || m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
637 DE_ASSERT(m_internalData && (m_internalData->setupState > PSS_VERTEX_INPUT_INTERFACE) &&
638 (m_internalData->setupState < PSS_FRAGMENT_OUTPUT_INTERFACE) &&
639 (m_internalData->pRenderingState.ptr->viewMask == pipelineRenderingCreateInfo.ptr->viewMask));
641 m_internalData->pRenderingState.ptr = pipelineRenderingCreateInfo.ptr;
647 GraphicsPipelineWrapper& GraphicsPipelineWrapper::disableViewportState()
649 // ViewportState is used in pre-rasterization shader state, make sure pre-rasterization state was not setup yet
650 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
652 m_internalData->useViewportState = DE_FALSE;
657 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupVertexInputState(const VkPipelineVertexInputStateCreateInfo* vertexInputState,
658 const VkPipelineInputAssemblyStateCreateInfo* inputAssemblyState,
659 const VkPipelineCache partPipelineCache,
660 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
662 // make sure pipeline was not already build
663 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
665 // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set first
666 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_NONE));
668 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
669 DE_UNREF(partPipelineCache);
670 DE_UNREF(partCreationFeedback);
672 m_internalData->setupState = PSS_VERTEX_INPUT_INTERFACE;
674 const auto pVertexInputState = vertexInputState ? vertexInputState : &defaultVertexInputState;
675 const auto pInputAssemblyState = inputAssemblyState ? inputAssemblyState : &m_internalData->inputAssemblyState;
677 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
679 m_internalData->monolithicPipelineCreateInfo.pVertexInputState = pVertexInputState;
680 m_internalData->monolithicPipelineCreateInfo.pInputAssemblyState = pInputAssemblyState;
683 #ifndef CTS_USES_VULKANSC
684 // note we could just use else to if statement above but sinc
685 // this section is cut out for Vulkan SC its cleaner with separate if
686 if (m_internalData->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
688 auto libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT);
689 void* firstStructInChain = reinterpret_cast<void*>(&libraryCreateInfo);
690 addToChain(&firstStructInChain, partCreationFeedback.ptr);
692 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
693 std::vector<VkDynamicState> states;
695 if(m_internalData->pDynamicState)
697 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
699 pickedDynamicStateInfo.pDynamicStates = states.data();
700 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
703 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
704 pipelinePartCreateInfo.pNext = firstStructInChain;
705 pipelinePartCreateInfo.flags = (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
706 pipelinePartCreateInfo.pVertexInputState = pVertexInputState;
707 pipelinePartCreateInfo.pInputAssemblyState = pInputAssemblyState;
708 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
710 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
711 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
713 m_pipelineParts[0] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
715 #endif // CTS_USES_VULKANSC
720 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationShaderState(const std::vector<VkViewport>& viewports,
721 const std::vector<VkRect2D>& scissors,
722 const VkPipelineLayout layout,
723 const VkRenderPass renderPass,
724 const deUint32 subpass,
725 const VkShaderModule vertexShaderModule,
726 const VkPipelineRasterizationStateCreateInfo* rasterizationState,
727 const VkShaderModule tessellationControlShaderModule,
728 const VkShaderModule tessellationEvalShaderModule,
729 const VkShaderModule geometryShaderModule,
730 const VkSpecializationInfo *specializationInfo,
731 VkPipelineFragmentShadingRateStateCreateInfoKHR* fragmentShadingRateState,
732 PipelineRenderingCreateInfoWrapper rendering,
733 const VkPipelineCache partPipelineCache,
734 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
736 return setupPreRasterizationShaderState2(viewports,
743 tessellationControlShaderModule,
744 tessellationEvalShaderModule,
745 geometryShaderModule,
746 // Reuse the same specialization info for all stages.
751 fragmentShadingRateState,
754 partCreationFeedback);
757 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationShaderState2(const std::vector<VkViewport>& viewports,
758 const std::vector<VkRect2D>& scissors,
759 const VkPipelineLayout layout,
760 const VkRenderPass renderPass,
761 const deUint32 subpass,
762 const VkShaderModule vertexShaderModule,
763 const VkPipelineRasterizationStateCreateInfo* rasterizationState,
764 const VkShaderModule tessellationControlShaderModule,
765 const VkShaderModule tessellationEvalShaderModule,
766 const VkShaderModule geometryShaderModule,
767 const VkSpecializationInfo* vertSpecializationInfo,
768 const VkSpecializationInfo* tescSpecializationInfo,
769 const VkSpecializationInfo* teseSpecializationInfo,
770 const VkSpecializationInfo* geomSpecializationInfo,
771 VkPipelineFragmentShadingRateStateCreateInfoKHR*fragmentShadingRateState,
772 PipelineRenderingCreateInfoWrapper rendering,
773 const VkPipelineCache partPipelineCache,
774 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
776 return setupPreRasterizationShaderState3(viewports,
782 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
784 tessellationControlShaderModule,
785 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
786 tessellationEvalShaderModule,
787 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
788 geometryShaderModule,
789 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
790 vertSpecializationInfo,
791 tescSpecializationInfo,
792 teseSpecializationInfo,
793 geomSpecializationInfo,
794 fragmentShadingRateState,
797 partCreationFeedback);
800 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationShaderState3(const std::vector<VkViewport>& viewports,
801 const std::vector<VkRect2D>& scissors,
802 const VkPipelineLayout layout,
803 const VkRenderPass renderPass,
804 const deUint32 subpass,
805 const VkShaderModule vertexShaderModule,
806 PipelineShaderStageModuleIdentifierCreateInfoWrapper vertShaderModuleId,
807 const VkPipelineRasterizationStateCreateInfo* rasterizationState,
808 const VkShaderModule tessellationControlShaderModule,
809 PipelineShaderStageModuleIdentifierCreateInfoWrapper tescShaderModuleId,
810 const VkShaderModule tessellationEvalShaderModule,
811 PipelineShaderStageModuleIdentifierCreateInfoWrapper teseShaderModuleId,
812 const VkShaderModule geometryShaderModule,
813 PipelineShaderStageModuleIdentifierCreateInfoWrapper geomShaderModuleId,
814 const VkSpecializationInfo* vertSpecializationInfo,
815 const VkSpecializationInfo* tescSpecializationInfo,
816 const VkSpecializationInfo* teseSpecializationInfo,
817 const VkSpecializationInfo* geomSpecializationInfo,
818 VkPipelineFragmentShadingRateStateCreateInfoKHR* fragmentShadingRateState,
819 PipelineRenderingCreateInfoWrapper rendering,
820 const VkPipelineCache partPipelineCache,
821 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
823 // make sure pipeline was not already build
824 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
826 // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set second
827 DE_ASSERT(m_internalData && (m_internalData->setupState == PSS_VERTEX_INPUT_INTERFACE));
829 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
830 DE_UNREF(partPipelineCache);
831 DE_UNREF(partCreationFeedback);
832 DE_UNREF(vertShaderModuleId);
833 DE_UNREF(tescShaderModuleId);
834 DE_UNREF(teseShaderModuleId);
835 DE_UNREF(geomShaderModuleId);
837 m_internalData->setupState |= PSS_PRE_RASTERIZATION_SHADERS;
838 m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
839 m_internalData->pRenderingState.ptr = rendering.ptr;
841 const bool hasTesc = (tessellationControlShaderModule != DE_NULL || tescShaderModuleId.ptr);
842 const bool hasTese = (tessellationEvalShaderModule != DE_NULL || teseShaderModuleId.ptr);
843 const bool hasGeom = (geometryShaderModule != DE_NULL || geomShaderModuleId.ptr);
845 const auto pRasterizationState = rasterizationState ? rasterizationState
846 : (m_internalData->useDefaultRasterizationState ? &m_internalData->defaultRasterizationState : DE_NULL);
847 const auto pTessellationState = (hasTesc || hasTese) ? &m_internalData->tessellationState : DE_NULL;
848 const auto pViewportState = m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
850 VkPipelineCreateFlags shaderModuleIdFlags = 0u;
852 // reserve space for all stages including fragment - this is needed when we create monolithic pipeline
853 m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(2u + hasTesc + hasTese + hasGeom,
855 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
856 DE_NULL, // const void* pNext
857 0u, // VkPipelineShaderStageCreateFlags flags
858 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage
859 vertexShaderModule, // VkShaderModule module
860 "main", // const char* pName
861 vertSpecializationInfo // const VkSpecializationInfo* pSpecializationInfo
864 #ifndef CTS_USES_VULKANSC
865 if (vertShaderModuleId.ptr)
867 m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(vertShaderModuleId.ptr));
868 m_internalData->pipelineShaderStages[0].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
870 if (vertexShaderModule == DE_NULL)
871 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
873 #endif // CTS_USES_VULKANSC
875 std::vector<VkPipelineShaderStageCreateInfo>::iterator currStage = m_internalData->pipelineShaderStages.begin() + 1;
879 currStage->stage = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
880 currStage->module = tessellationControlShaderModule;
881 currStage->pSpecializationInfo = tescSpecializationInfo;
883 #ifndef CTS_USES_VULKANSC
884 if (tescShaderModuleId.ptr)
886 m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(tescShaderModuleId.ptr));
887 currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
889 if (tessellationControlShaderModule == DE_NULL)
890 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
892 #endif // CTS_USES_VULKANSC
899 currStage->stage = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
900 currStage->module = tessellationEvalShaderModule;
901 currStage->pSpecializationInfo = teseSpecializationInfo;
903 #ifndef CTS_USES_VULKANSC
904 if (teseShaderModuleId.ptr)
906 m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(teseShaderModuleId.ptr));
907 currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
909 if (tessellationEvalShaderModule == DE_NULL)
910 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
912 #endif // CTS_USES_VULKANSC
919 currStage->stage = VK_SHADER_STAGE_GEOMETRY_BIT;
920 currStage->module = geometryShaderModule;
921 currStage->pSpecializationInfo = geomSpecializationInfo;
923 #ifndef CTS_USES_VULKANSC
924 if (geomShaderModuleId.ptr)
926 m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(geomShaderModuleId.ptr));
927 currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
929 if (geometryShaderModule == DE_NULL)
930 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
932 #endif // CTS_USES_VULKANSC
937 if (!viewports.empty())
939 pViewportState->viewportCount = (deUint32)viewports.size();
940 pViewportState->pViewports = &viewports[0];
942 if (!scissors.empty())
944 pViewportState->scissorCount = (deUint32)scissors.size();
945 pViewportState->pScissors = &scissors[0];
949 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
951 // make sure we dont overwrite layout specified with setupMonolithicPipelineLayout
952 if (m_internalData->monolithicPipelineCreateInfo.layout == 0)
953 m_internalData->monolithicPipelineCreateInfo.layout = layout;
955 m_internalData->monolithicPipelineCreateInfo.renderPass = renderPass;
956 m_internalData->monolithicPipelineCreateInfo.subpass = subpass;
957 m_internalData->monolithicPipelineCreateInfo.pRasterizationState = pRasterizationState;
958 m_internalData->monolithicPipelineCreateInfo.pViewportState = pViewportState;
959 m_internalData->monolithicPipelineCreateInfo.stageCount = 1u + hasTesc + hasTese + hasGeom;
960 m_internalData->monolithicPipelineCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
961 m_internalData->monolithicPipelineCreateInfo.pTessellationState = pTessellationState;
962 m_internalData->monolithicPipelineCreateInfo.flags |= shaderModuleIdFlags;
965 #ifndef CTS_USES_VULKANSC
966 // note we could just use else to if statement above but sinc
967 // this section is cut out for Vulkan SC its cleaner with separate if
968 if (m_internalData->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
970 auto libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
971 void* firstStructInChain = reinterpret_cast<void*>(&libraryCreateInfo);
972 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
973 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
974 addToChain(&firstStructInChain, partCreationFeedback.ptr);
976 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
977 std::vector<VkDynamicState> states;
979 if(m_internalData->pDynamicState)
981 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
983 pickedDynamicStateInfo.pDynamicStates = states.data();
984 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
987 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
988 pipelinePartCreateInfo.pNext = firstStructInChain;
989 pipelinePartCreateInfo.flags = (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
990 pipelinePartCreateInfo.layout = layout;
991 pipelinePartCreateInfo.renderPass = renderPass;
992 pipelinePartCreateInfo.subpass = subpass;
993 pipelinePartCreateInfo.pRasterizationState = pRasterizationState;
994 pipelinePartCreateInfo.pViewportState = pViewportState;
995 pipelinePartCreateInfo.stageCount = 1u + hasTesc + hasTese + hasGeom;
996 pipelinePartCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
997 pipelinePartCreateInfo.pTessellationState = pTessellationState;
998 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
1000 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
1001 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
1003 if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
1004 m_internalData->failOnCompileWhenLinking = true;
1006 m_pipelineParts[1] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1008 #endif // CTS_USES_VULKANSC
1013 #ifndef CTS_USES_VULKANSC
1014 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupPreRasterizationMeshShaderState(const std::vector<VkViewport>& viewports,
1015 const std::vector<VkRect2D>& scissors,
1016 const VkPipelineLayout layout,
1017 const VkRenderPass renderPass,
1018 const deUint32 subpass,
1019 const VkShaderModule taskShaderModule,
1020 const VkShaderModule meshShaderModule,
1021 const VkPipelineRasterizationStateCreateInfo* rasterizationState,
1022 const VkSpecializationInfo *taskSpecializationInfo,
1023 const VkSpecializationInfo *meshSpecializationInfo,
1024 VkPipelineFragmentShadingRateStateCreateInfoKHR* fragmentShadingRateState,
1025 PipelineRenderingCreateInfoWrapper rendering,
1026 const VkPipelineCache partPipelineCache,
1027 VkPipelineCreationFeedbackCreateInfoEXT *partCreationFeedback)
1029 // Make sure pipeline was not already built.
1030 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1032 // Make sure states are set in order - this state needs to be set first or second.
1033 DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_PRE_RASTERIZATION_SHADERS));
1035 // The vertex input interface is not needed for mesh shading pipelines, so we're going to mark it as ready here.
1036 m_internalData->setupState |= (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS);
1037 m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
1038 m_internalData->pRenderingState = rendering;
1040 const bool hasTask = (taskShaderModule != DE_NULL);
1041 const auto taskShaderCount = static_cast<uint32_t>(hasTask);
1042 const auto pRasterizationState = rasterizationState
1043 ? rasterizationState
1044 : (m_internalData->useDefaultRasterizationState
1045 ? &m_internalData->defaultRasterizationState
1047 const auto pTessellationState = nullptr;
1048 const auto pViewportState = m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
1050 // Reserve space for all stages including fragment. This is needed when we create monolithic pipeline.
1051 m_internalData->pipelineShaderStages = std::vector<VkPipelineShaderStageCreateInfo>(2u + taskShaderCount,
1053 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType
1054 nullptr, // const void* pNext
1055 0u, // VkPipelineShaderStageCreateFlags flags
1056 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage
1057 DE_NULL, // VkShaderModule module
1058 "main", // const char* pName
1059 nullptr, // const VkSpecializationInfo* pSpecializationInfo
1063 auto currStage = m_internalData->pipelineShaderStages.begin();
1065 auto& stageInfo = *currStage;
1067 stageInfo.stage = VK_SHADER_STAGE_MESH_BIT_EXT;
1068 stageInfo.module = meshShaderModule;
1069 stageInfo.pSpecializationInfo = meshSpecializationInfo;
1076 auto& stageInfo = *currStage;
1078 stageInfo.stage = VK_SHADER_STAGE_TASK_BIT_EXT;
1079 stageInfo.module = taskShaderModule;
1080 stageInfo.pSpecializationInfo = taskSpecializationInfo;
1087 if (!viewports.empty())
1089 pViewportState->viewportCount = (deUint32)viewports.size();
1090 pViewportState->pViewports = &viewports[0];
1092 if (!scissors.empty())
1094 pViewportState->scissorCount = (deUint32)scissors.size();
1095 pViewportState->pScissors = &scissors[0];
1099 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1101 // make sure we dont overwrite layout specified with setupMonolithicPipelineLayout
1102 if (m_internalData->monolithicPipelineCreateInfo.layout == 0)
1103 m_internalData->monolithicPipelineCreateInfo.layout = layout;
1105 m_internalData->monolithicPipelineCreateInfo.renderPass = renderPass;
1106 m_internalData->monolithicPipelineCreateInfo.subpass = subpass;
1107 m_internalData->monolithicPipelineCreateInfo.pRasterizationState = pRasterizationState;
1108 m_internalData->monolithicPipelineCreateInfo.pViewportState = pViewportState;
1109 m_internalData->monolithicPipelineCreateInfo.stageCount = 1u + taskShaderCount;
1110 m_internalData->monolithicPipelineCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
1111 m_internalData->monolithicPipelineCreateInfo.pTessellationState = pTessellationState;
1115 auto libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT);
1116 void* firstStructInChain = reinterpret_cast<void*>(&libraryCreateInfo);
1117 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
1118 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
1119 addToChain(&firstStructInChain, partCreationFeedback);
1121 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
1122 std::vector<VkDynamicState> states;
1124 if(m_internalData->pDynamicState)
1126 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
1128 pickedDynamicStateInfo.pDynamicStates = states.data();
1129 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
1133 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
1134 pipelinePartCreateInfo.pNext = firstStructInChain;
1135 pipelinePartCreateInfo.flags = m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
1136 pipelinePartCreateInfo.layout = layout;
1137 pipelinePartCreateInfo.renderPass = renderPass;
1138 pipelinePartCreateInfo.subpass = subpass;
1139 pipelinePartCreateInfo.pRasterizationState = pRasterizationState;
1140 pipelinePartCreateInfo.pViewportState = pViewportState;
1141 pipelinePartCreateInfo.stageCount = 1u + taskShaderCount;
1142 pipelinePartCreateInfo.pStages = m_internalData->pipelineShaderStages.data();
1143 pipelinePartCreateInfo.pTessellationState = pTessellationState;
1144 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
1146 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
1147 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
1149 m_pipelineParts[1] = createGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1154 #endif // CTS_USES_VULKANSC
1156 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupFragmentShaderState(const VkPipelineLayout layout,
1157 const VkRenderPass renderPass,
1158 const deUint32 subpass,
1159 const VkShaderModule fragmentShaderModule,
1160 const VkPipelineDepthStencilStateCreateInfo* depthStencilState,
1161 const VkPipelineMultisampleStateCreateInfo* multisampleState,
1162 const VkSpecializationInfo* specializationInfo,
1163 const VkPipelineCache partPipelineCache,
1164 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
1166 return setupFragmentShaderState2(layout,
1169 fragmentShaderModule,
1170 PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
1175 partCreationFeedback);
1178 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupFragmentShaderState2(const VkPipelineLayout layout,
1179 const VkRenderPass renderPass,
1180 const deUint32 subpass,
1181 const VkShaderModule fragmentShaderModule,
1182 PipelineShaderStageModuleIdentifierCreateInfoWrapper fragmentShaderModuleId,
1183 const VkPipelineDepthStencilStateCreateInfo* depthStencilState,
1184 const VkPipelineMultisampleStateCreateInfo* multisampleState,
1185 const VkSpecializationInfo* specializationInfo,
1186 const VkPipelineCache partPipelineCache,
1187 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
1189 // make sure pipeline was not already build
1190 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1192 // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set third
1193 DE_ASSERT(m_internalData && (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS)));
1195 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
1197 DE_UNREF(renderPass);
1199 DE_UNREF(partPipelineCache);
1200 DE_UNREF(partCreationFeedback);
1201 DE_UNREF(fragmentShaderModuleId);
1203 m_internalData->setupState |= PSS_FRAGMENT_SHADER;
1205 const auto pDepthStencilState = depthStencilState ? depthStencilState
1206 : (m_internalData->useDefaultDepthStencilState ? &defaultDepthStencilState : DE_NULL);
1207 const auto pMultisampleState = multisampleState ? multisampleState
1208 : (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
1209 const bool hasFrag = (fragmentShaderModule != DE_NULL || fragmentShaderModuleId.ptr);
1211 VkPipelineCreateFlags shaderModuleIdFlags = 0u;
1213 deUint32 stageIndex = 1;
1216 // find free space for fragment shader
1217 for (; stageIndex < 5; ++stageIndex)
1219 if (m_internalData->pipelineShaderStages[stageIndex].stage == VK_SHADER_STAGE_VERTEX_BIT)
1221 m_internalData->pipelineShaderStages[stageIndex].stage = VK_SHADER_STAGE_FRAGMENT_BIT;
1222 m_internalData->pipelineShaderStages[stageIndex].module = fragmentShaderModule;
1223 m_internalData->pipelineShaderStages[stageIndex].pSpecializationInfo = specializationInfo;
1224 #ifndef CTS_USES_VULKANSC
1225 if (fragmentShaderModuleId.ptr)
1227 m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(fragmentShaderModuleId.ptr));
1228 m_internalData->pipelineShaderStages[stageIndex].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
1230 if (fragmentShaderModule == DE_NULL)
1231 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
1233 #endif // CTS_USES_VULKANSC
1239 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1241 m_internalData->monolithicPipelineCreateInfo.pDepthStencilState = pDepthStencilState;
1242 m_internalData->monolithicPipelineCreateInfo.pMultisampleState = pMultisampleState;
1243 m_internalData->monolithicPipelineCreateInfo.stageCount += (hasFrag ? 1u : 0u);
1244 m_internalData->monolithicPipelineCreateInfo.flags |= shaderModuleIdFlags;
1247 #ifndef CTS_USES_VULKANSC
1248 // note we could just use else to if statement above but sinc
1249 // this section is cut out for Vulkan SC its cleaner with separate if
1250 if (m_internalData->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1252 auto libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT);
1253 void* firstStructInChain = reinterpret_cast<void*>(&libraryCreateInfo);
1254 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
1255 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
1256 addToChain(&firstStructInChain, partCreationFeedback.ptr);
1257 addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
1259 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
1260 std::vector<VkDynamicState> states;
1262 if(m_internalData->pDynamicState)
1264 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
1266 pickedDynamicStateInfo.pDynamicStates = states.data();
1267 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
1271 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
1272 pipelinePartCreateInfo.pNext = firstStructInChain;
1273 pipelinePartCreateInfo.flags = (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | shaderModuleIdFlags) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
1274 pipelinePartCreateInfo.layout = layout;
1275 pipelinePartCreateInfo.renderPass = renderPass;
1276 pipelinePartCreateInfo.subpass = subpass;
1277 pipelinePartCreateInfo.pDepthStencilState = pDepthStencilState;
1278 pipelinePartCreateInfo.pMultisampleState = pMultisampleState;
1279 pipelinePartCreateInfo.stageCount = hasFrag;
1280 pipelinePartCreateInfo.pStages = hasFrag ? &m_internalData->pipelineShaderStages[stageIndex] : DE_NULL;
1281 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
1283 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
1284 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
1286 if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
1287 m_internalData->failOnCompileWhenLinking = true;
1289 m_pipelineParts[2] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1291 #endif // CTS_USES_VULKANSC
1296 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupFragmentOutputState(const VkRenderPass renderPass,
1297 const deUint32 subpass,
1298 const VkPipelineColorBlendStateCreateInfo* colorBlendState,
1299 const VkPipelineMultisampleStateCreateInfo* multisampleState,
1300 const VkPipelineCache partPipelineCache,
1301 PipelineCreationFeedbackCreateInfoWrapper partCreationFeedback)
1303 // make sure pipeline was not already build
1304 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1306 // make sure states are set in order - no need to complicate logic to support out of order specification - this state needs to be set last
1307 DE_ASSERT(m_internalData && (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS | PSS_FRAGMENT_SHADER)));
1308 m_internalData->setupState |= PSS_FRAGMENT_OUTPUT_INTERFACE;
1310 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
1311 DE_UNREF(renderPass);
1313 DE_UNREF(partPipelineCache);
1314 DE_UNREF(partCreationFeedback);
1316 void* firstStructInChain = DE_NULL;
1317 addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
1319 #ifndef CTS_USES_VULKANSC
1320 addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
1321 #endif // CTS_USES_VULKANSC
1323 const auto pColorBlendState = colorBlendState ? colorBlendState
1324 : (m_internalData->useDefaultColorBlendState ? &defaultColorBlendState : DE_NULL);
1325 const auto pMultisampleState = multisampleState ? multisampleState
1326 : (m_internalData->useDefaultMultisampleState ? &defaultMultisampleState : DE_NULL);
1328 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1330 m_internalData->monolithicPipelineCreateInfo.pNext = firstStructInChain;
1331 m_internalData->monolithicPipelineCreateInfo.flags |= m_internalData->pipelineFlags;
1332 m_internalData->monolithicPipelineCreateInfo.pColorBlendState = pColorBlendState;
1333 m_internalData->monolithicPipelineCreateInfo.pMultisampleState = pMultisampleState;
1336 #ifndef CTS_USES_VULKANSC
1337 // note we could just use else to if statement above but sinc
1338 // this section is cut out for Vulkan SC its cleaner with separate if
1339 if (m_internalData->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1341 auto libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
1342 addToChain(&firstStructInChain, &libraryCreateInfo);
1343 addToChain(&firstStructInChain, partCreationFeedback.ptr);
1346 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
1347 std::vector<VkDynamicState> states;
1349 if(m_internalData->pDynamicState)
1351 states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
1353 pickedDynamicStateInfo.pDynamicStates = states.data();
1354 pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
1358 VkGraphicsPipelineCreateInfo pipelinePartCreateInfo = initVulkanStructure();
1359 pipelinePartCreateInfo.pNext = firstStructInChain;
1360 pipelinePartCreateInfo.flags = (m_internalData->pipelineFlags | VK_PIPELINE_CREATE_LIBRARY_BIT_KHR) & ~VK_PIPELINE_CREATE_DERIVATIVE_BIT;
1361 pipelinePartCreateInfo.renderPass = renderPass;
1362 pipelinePartCreateInfo.subpass = subpass;
1363 pipelinePartCreateInfo.pColorBlendState = pColorBlendState;
1364 pipelinePartCreateInfo.pMultisampleState = pMultisampleState;
1365 pipelinePartCreateInfo.pDynamicState = &pickedDynamicStateInfo;
1367 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
1368 pipelinePartCreateInfo.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
1370 m_pipelineParts[3] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1372 #endif // CTS_USES_VULKANSC
1377 void GraphicsPipelineWrapper::buildPipeline(const VkPipelineCache pipelineCache,
1378 const VkPipeline basePipelineHandle,
1379 const deInt32 basePipelineIndex,
1380 PipelineCreationFeedbackCreateInfoWrapper creationFeedback)
1382 // make sure we are not trying to build pipeline second time
1383 DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1385 // make sure all states were set
1386 DE_ASSERT(m_internalData && (m_internalData->setupState == (PSS_VERTEX_INPUT_INTERFACE | PSS_PRE_RASTERIZATION_SHADERS |
1387 PSS_FRAGMENT_SHADER | PSS_FRAGMENT_OUTPUT_INTERFACE)));
1389 // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
1390 DE_UNREF(creationFeedback);
1392 VkGraphicsPipelineCreateInfo* pointerToCreateInfo = &m_internalData->monolithicPipelineCreateInfo;
1394 #ifndef CTS_USES_VULKANSC
1395 VkGraphicsPipelineCreateInfo linkedCreateInfo = initVulkanStructure();
1396 std::vector<VkPipeline> rawPipelines;
1397 VkPipelineLibraryCreateInfoKHR linkingInfo
1399 VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR, // VkStructureType sType;
1400 creationFeedback.ptr, // const void* pNext;
1401 0u, // deUint32 libraryCount;
1402 nullptr, // const VkPipeline* pLibraries;
1405 if (m_internalData->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1407 for (const auto& pipelinePtr : m_pipelineParts)
1409 const auto& pipeline = pipelinePtr.get();
1410 if (pipeline != DE_NULL)
1411 rawPipelines.push_back(pipeline);
1414 linkingInfo.libraryCount = static_cast<uint32_t>(rawPipelines.size());
1415 linkingInfo.pLibraries = de::dataOrNull(rawPipelines);
1417 linkedCreateInfo.flags = m_internalData->pipelineFlags;
1418 linkedCreateInfo.layout = m_internalData->monolithicPipelineCreateInfo.layout;
1419 linkedCreateInfo.pNext = &linkingInfo;
1421 pointerToCreateInfo = &linkedCreateInfo;
1423 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
1424 linkedCreateInfo.flags |= VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
1426 if (m_internalData->failOnCompileWhenLinking)
1427 linkedCreateInfo.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
1431 // note: there might be other structures in the chain already
1432 void* firstStructInChain = static_cast<void*>(pointerToCreateInfo);
1433 addToChain(&firstStructInChain, creationFeedback.ptr);
1434 addToChain(&firstStructInChain, m_internalData->pRepresentativeFragmentTestState.ptr);
1436 #endif // CTS_USES_VULKANSC
1438 pointerToCreateInfo->basePipelineHandle = basePipelineHandle;
1439 pointerToCreateInfo->basePipelineIndex = basePipelineIndex;
1441 m_pipelineFinal = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, pipelineCache, pointerToCreateInfo);
1443 // pipeline was created - we can free CreateInfo structures
1444 m_internalData.clear();
1447 deBool GraphicsPipelineWrapper::wasBuild() const
1449 return !!m_pipelineFinal.get();
1452 VkPipeline GraphicsPipelineWrapper::getPipeline() const
1454 DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
1455 return m_pipelineFinal.get();
1458 void GraphicsPipelineWrapper::destroyPipeline(void)
1460 DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
1462 m_pipelineFinal = Move<VkPipeline>();