Set each dyanmic state to proper stage on a pipeline with
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / framework / vulkan / vkPipelineConstructionUtil.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2021 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 Wrapper that can construct monolithic pipeline or use
22           VK_EXT_graphics_pipeline_library for pipeline construction
23  *//*--------------------------------------------------------------------*/
24
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"
33
34 #include <memory>
35 #include <set>
36
37 namespace vk
38 {
39
40 namespace
41 {
42
43 enum PipelineSetupState
44 {
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,
50 };
51
52 using TessellationDomainOriginStatePtr = std::unique_ptr<VkPipelineTessellationDomainOriginStateCreateInfo>;
53
54 } // anonymous namespace
55
56 static const VkVertexInputBindingDescription defaultVertexInputBindingDescription
57 {
58         0u,                                                                                                                             // deUint32                                                                             binding
59         sizeof(tcu::Vec4),                                                                                              // deUint32                                                                             stride
60         VK_VERTEX_INPUT_RATE_VERTEX,                                                                    // VkVertexInputRate                                                    inputRate
61 };
62
63 static const VkVertexInputAttributeDescription defaultVertexInputAttributeDescription
64 {
65         0u,                                                                                                                             // deUint32                                                                             location
66         0u,                                                                                                                             // deUint32                                                                             binding
67         VK_FORMAT_R32G32B32A32_SFLOAT,                                                                  // VkFormat                                                                             format
68         0u                                                                                                                              // deUint32                                                                             offset
69 };
70
71 static const VkPipelineVertexInputStateCreateInfo defaultVertexInputState
72 {
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
80 };
81
82 static const VkStencilOpState defaultStencilOpState
83 {
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
91 };
92
93 static const VkPipelineDepthStencilStateCreateInfo defaultDepthStencilState
94 {
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
107 };
108
109 static const VkPipelineMultisampleStateCreateInfo defaultMultisampleState
110 {
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
120 };
121
122 static const VkPipelineColorBlendAttachmentState defaultColorBlendAttachmentState
123 {
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
132 };
133
134 static const VkPipelineColorBlendStateCreateInfo defaultColorBlendState
135 {
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]
144 };
145
146 namespace
147 {
148 #ifndef CTS_USES_VULKANSC
149 VkGraphicsPipelineLibraryCreateInfoEXT makeGraphicsPipelineLibraryCreateInfo(const VkGraphicsPipelineLibraryFlagsEXT flags)
150 {
151         return
152         {
153                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,    // VkStructureType                                              sType;
154                 DE_NULL,                                                                                                                // void*                                                                pNext;
155                 flags,                                                                                                                  // VkGraphicsPipelineLibraryFlagsEXT    flags;
156         };
157 }
158 #endif // CTS_USES_VULKANSC
159
160 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&                           vk,
161                                                                            VkDevice                                                             device,
162                                                                            VkPipelineCache                                              pipelineCache,
163                                                                            const VkGraphicsPipelineCreateInfo*  pCreateInfo,
164                                                                            const VkAllocationCallbacks*                 pAllocator = nullptr)
165 {
166         VkPipeline      object                                  = 0;
167         const auto      retcode                                 = vk.createGraphicsPipelines(device, pipelineCache, 1u, pCreateInfo, pAllocator, &object);
168
169 #ifndef CTS_USES_VULKANSC
170         const bool      allowCompileRequired    = ((pCreateInfo->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0u);
171
172         if (allowCompileRequired && retcode == VK_PIPELINE_COMPILE_REQUIRED)
173                 throw PipelineCompileRequiredError("createGraphicsPipelines returned VK_PIPELINE_COMPILE_REQUIRED");
174 #endif // CTS_USES_VULKANSC
175
176         VK_CHECK(retcode);
177         return Move<VkPipeline>(check<VkPipeline>(object), Deleter<VkPipeline>(vk, device, pAllocator));
178 }
179
180 } // anonymous
181
182 void checkPipelineLibraryRequirements (const InstanceInterface&         vki,
183                                                                            VkPhysicalDevice                             physicalDevice,
184                                                                            PipelineConstructionType             pipelineConstructionType)
185 {
186         if (pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
187                 return;
188
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");
192 }
193
194 void addToChain(void** structThatStartsChain, void* structToAddAtTheEnd)
195 {
196         DE_ASSERT(structThatStartsChain);
197
198         if (structToAddAtTheEnd == DE_NULL)
199                 return;
200
201         // Cast to the base out structure which has a non-const pNext pointer.
202         auto* structToAddAtTheEndCasted = reinterpret_cast<VkBaseOutStructure*>(structToAddAtTheEnd);
203
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;
208
209         deUint32        safetyCouter    = 10u;
210         void**          structInChain   = structThatStartsChain;
211
212         do
213         {
214                 // check if this is free spot
215                 if (*structInChain == DE_NULL)
216                 {
217                         // attach new structure at the end
218                         *structInChain = structToAddAtTheEndCasted;
219                         return;
220                 }
221
222                 // Cast to the base out structure which has a non-const pNext pointer.
223                 auto* gpl = reinterpret_cast<VkBaseOutStructure*>(*structInChain);
224
225                 // move structure pointer one position down the pNext chain
226                 structInChain = reinterpret_cast<void**>(&gpl->pNext);
227         }
228         while (--safetyCouter);
229
230         // probably safetyCouter is to small
231         DE_ASSERT(false);
232 }
233
234 namespace {
235         using PipelineShaderStageModuleIdPtr = std::unique_ptr<PipelineShaderStageModuleIdentifierCreateInfoWrapper>;
236 }
237
238 // Structure storing *CreateInfo structures that do not need to exist in memory after pipeline was constructed.
239 struct GraphicsPipelineWrapper::InternalData
240 {
241         const DeviceInterface&                                                          vk;
242         VkDevice                                                                                        device;
243         const PipelineConstructionType                                          pipelineConstructionType;
244         const VkPipelineCreateFlags                                                     pipelineFlags;
245
246         // attribute used for making sure pipeline is configured in correct order
247         int                                                                                                     setupState;
248
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;
259
260         TessellationDomainOriginStatePtr                                        pTessellationDomainOrigin;
261         deBool                                                                                          useViewportState;
262         deBool                                                                                          useDefaultRasterizationState;
263         deBool                                                                                          useDefaultDepthStencilState;
264         deBool                                                                                          useDefaultColorBlendState;
265         deBool                                                                                          useDefaultMultisampleState;
266         bool                                                                                            failOnCompileWhenLinking;
267
268         VkGraphicsPipelineCreateInfo                                            monolithicPipelineCreateInfo;
269
270         // initialize with most common values
271         InternalData(const DeviceInterface& vkd, VkDevice vkDevice, const PipelineConstructionType constructionType, const VkPipelineCreateFlags pipelineCreateFlags)
272                 : vk                                            (vkd)
273                 , device                                        (vkDevice)
274                 , pipelineConstructionType      (constructionType)
275                 , pipelineFlags                         (pipelineCreateFlags)
276                 , setupState                            (PSS_NONE)
277                 , inputAssemblyState
278                 {
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
284                 }
285                 , defaultRasterizationState
286                 {
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
300                 }
301                 , viewportState
302                 {
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
310                 }
311                 , tessellationState
312                 {
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
317                 }
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)
328         {
329                 monolithicPipelineCreateInfo = initVulkanStructure();
330         }
331 };
332
333 GraphicsPipelineWrapper::GraphicsPipelineWrapper(const DeviceInterface&                         vk,
334                                                                                                  VkDevice                                                       device,
335                                                                                                  const PipelineConstructionType         pipelineConstructionType,
336                                                                                                  const VkPipelineCreateFlags            flags)
337         : m_internalData        (new InternalData(vk, device, pipelineConstructionType, flags))
338 {
339 }
340
341 GraphicsPipelineWrapper::GraphicsPipelineWrapper(GraphicsPipelineWrapper&& pw) noexcept
342         : m_pipelineFinal       (pw.m_pipelineFinal)
343         , m_internalData        (pw.m_internalData)
344 {
345         std::move(pw.m_pipelineParts, pw.m_pipelineParts + de::arrayLength(pw.m_pipelineParts), m_pipelineParts);
346 }
347
348 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setMonolithicPipelineLayout(const VkPipelineLayout layout)
349 {
350         // make sure pipeline was not already built
351         DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
352
353         m_internalData->monolithicPipelineCreateInfo.layout = layout;
354
355         return *this;
356 }
357
358 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDynamicState(const VkPipelineDynamicStateCreateInfo* dynamicState)
359 {
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);
362
363         m_internalData->pDynamicState                                                           = dynamicState;
364         m_internalData->monolithicPipelineCreateInfo.pDynamicState      = dynamicState;
365
366         return *this;
367 }
368
369 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setRepresentativeFragmentTestState(PipelineRepresentativeFragmentTestCreateInfoWrapper representativeFragmentTestState)
370 {
371         // Representative fragment test state is needed by the fragment shader state.
372         DE_ASSERT(m_internalData && (m_internalData->setupState < PSS_FRAGMENT_SHADER));
373
374         m_internalData->pRepresentativeFragmentTestState = representativeFragmentTestState;
375         return *this;
376 }
377
378 std::vector<VkDynamicState> getDynamicStates(const VkPipelineDynamicStateCreateInfo* dynamicStateInfo, uint32_t setupState)
379 {
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,
385         };
386
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,
401
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,
422 #endif
423         };
424
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,
451
452 #endif
453         };
454
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,
479 #endif
480         };
481
482         const std::set<VkDynamicState> dynamicStates (dynamicStateInfo->pDynamicStates,
483                                                                                                   dynamicStateInfo->pDynamicStates + dynamicStateInfo->dynamicStateCount);
484
485         std::set<VkDynamicState> intersectedStates;
486
487         if (setupState & PSS_VERTEX_INPUT_INTERFACE)
488                 std::set_intersection(vertexInputStates.begin(), vertexInputStates.end(), dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
489
490         if (setupState & PSS_PRE_RASTERIZATION_SHADERS)
491                 std::set_intersection(preRastStates.begin(),     preRastStates.end(),     dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
492
493         if (setupState & PSS_FRAGMENT_SHADER)
494                 std::set_intersection(fragShaderStates.begin(),  fragShaderStates.end(),  dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
495
496         if (setupState & PSS_FRAGMENT_OUTPUT_INTERFACE)
497                 std::set_intersection(fragOutputStates.begin(),  fragOutputStates.end(),  dynamicStates.begin(), dynamicStates.end(), std::inserter(intersectedStates, intersectedStates.end()));
498
499         const std::vector<VkDynamicState> returnedStates (begin(intersectedStates), end(intersectedStates));
500
501         return returnedStates;
502 }
503
504 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultTopology(const VkPrimitiveTopology topology)
505 {
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));
508
509         m_internalData->inputAssemblyState.topology = topology;
510
511         return *this;
512 }
513
514 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultPatchControlPoints(const deUint32 patchControlPoints)
515 {
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));
518
519         m_internalData->tessellationState.patchControlPoints = patchControlPoints;
520
521         return *this;
522 }
523
524 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultTessellationDomainOrigin (const VkTessellationDomainOrigin domainOrigin, bool forceExtStruct)
525 {
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));
528
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)
534         {
535                 if (!m_internalData->pTessellationDomainOrigin)
536                 {
537                         m_internalData->pTessellationDomainOrigin.reset(new VkPipelineTessellationDomainOriginStateCreateInfo(initVulkanStructure()));
538                         m_internalData->tessellationState.pNext = m_internalData->pTessellationDomainOrigin.get();
539                 }
540                 m_internalData->pTessellationDomainOrigin->domainOrigin = domainOrigin;
541         }
542
543         return *this;
544 }
545
546 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultRasterizerDiscardEnable(const deBool rasterizerDiscardEnable)
547 {
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));
550
551         m_internalData->defaultRasterizationState.rasterizerDiscardEnable = rasterizerDiscardEnable;
552
553         return *this;
554 }
555
556
557 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultRasterizationState()
558 {
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));
561
562         m_internalData->useDefaultRasterizationState = DE_TRUE;
563
564         return *this;
565 }
566
567 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultDepthStencilState()
568 {
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));
571
572         m_internalData->useDefaultDepthStencilState = DE_TRUE;
573
574         return *this;
575 }
576
577 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultColorBlendState()
578 {
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));
581
582         m_internalData->useDefaultColorBlendState = DE_TRUE;
583
584         return *this;
585 }
586
587 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultMultisampleState()
588 {
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));
591
592         m_internalData->useDefaultMultisampleState = DE_TRUE;
593
594         return *this;
595 }
596
597 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultViewportsCount(deUint32 viewportCount)
598 {
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));
601
602         m_internalData->viewportState.viewportCount = viewportCount;
603
604         return *this;
605 }
606
607 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setDefaultScissorsCount(deUint32 scissorCount)
608 {
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));
611
612         m_internalData->viewportState.scissorCount = scissorCount;
613
614         return *this;
615 }
616
617 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setViewportStatePnext(const void* pNext)
618 {
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));
621
622         m_internalData->viewportState.pNext = pNext;
623
624         return *this;
625 }
626
627 #ifndef CTS_USES_VULKANSC
628 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setRenderingColorAttachmentsInfo(PipelineRenderingCreateInfoWrapper pipelineRenderingCreateInfo)
629 {
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.
633          */
634         if (!m_internalData->pRenderingState.ptr || m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
635                 return *this;
636
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));
640
641         m_internalData->pRenderingState.ptr = pipelineRenderingCreateInfo.ptr;
642
643         return *this;
644 }
645 #endif
646
647 GraphicsPipelineWrapper& GraphicsPipelineWrapper::disableViewportState()
648 {
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));
651
652         m_internalData->useViewportState = DE_FALSE;
653
654         return *this;
655 }
656
657 GraphicsPipelineWrapper& GraphicsPipelineWrapper::setupVertexInputState(const VkPipelineVertexInputStateCreateInfo*             vertexInputState,
658                                                                                                                                                 const VkPipelineInputAssemblyStateCreateInfo*   inputAssemblyState,
659                                                                                                                                                 const VkPipelineCache                                                   partPipelineCache,
660                                                                                                                                                 PipelineCreationFeedbackCreateInfoWrapper               partCreationFeedback)
661 {
662         // make sure pipeline was not already build
663         DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
664
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));
667
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);
671
672         m_internalData->setupState = PSS_VERTEX_INPUT_INTERFACE;
673
674         const auto pVertexInputState = vertexInputState ? vertexInputState : &defaultVertexInputState;
675         const auto pInputAssemblyState = inputAssemblyState ? inputAssemblyState : &m_internalData->inputAssemblyState;
676
677         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
678         {
679                 m_internalData->monolithicPipelineCreateInfo.pVertexInputState = pVertexInputState;
680                 m_internalData->monolithicPipelineCreateInfo.pInputAssemblyState = pInputAssemblyState;
681         }
682
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)
687         {
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);
691
692                 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
693                 std::vector<VkDynamicState> states;
694
695                 if(m_internalData->pDynamicState)
696                 {
697                         states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
698
699                         pickedDynamicStateInfo.pDynamicStates = states.data();
700                         pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
701                 }
702
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;
709
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;
712
713                 m_pipelineParts[0] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
714         }
715 #endif // CTS_USES_VULKANSC
716
717         return *this;
718 }
719
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)
735 {
736         return setupPreRasterizationShaderState2(viewports,
737                                                                                          scissors,
738                                                                                          layout,
739                                                                                          renderPass,
740                                                                                          subpass,
741                                                                                          vertexShaderModule,
742                                                                                          rasterizationState,
743                                                                                          tessellationControlShaderModule,
744                                                                                          tessellationEvalShaderModule,
745                                                                                          geometryShaderModule,
746                                                                                          // Reuse the same specialization info for all stages.
747                                                                                          specializationInfo,
748                                                                                          specializationInfo,
749                                                                                          specializationInfo,
750                                                                                          specializationInfo,
751                                                                                          fragmentShadingRateState,
752                                                                                          rendering,
753                                                                                          partPipelineCache,
754                                                                                          partCreationFeedback);
755 }
756
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)
775 {
776         return setupPreRasterizationShaderState3(viewports,
777                                                                                          scissors,
778                                                                                          layout,
779                                                                                          renderPass,
780                                                                                          subpass,
781                                                                                          vertexShaderModule,
782                                                                                          PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
783                                                                                          rasterizationState,
784                                                                                          tessellationControlShaderModule,
785                                                                                          PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
786                                                                                          tessellationEvalShaderModule,
787                                                                                          PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
788                                                                                          geometryShaderModule,
789                                                                                          PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
790                                                                                          vertSpecializationInfo,
791                                                                                          tescSpecializationInfo,
792                                                                                          teseSpecializationInfo,
793                                                                                          geomSpecializationInfo,
794                                                                                          fragmentShadingRateState,
795                                                                                          rendering,
796                                                                                          partPipelineCache,
797                                                                                          partCreationFeedback);
798 }
799
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)
822 {
823         // make sure pipeline was not already build
824         DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
825
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));
828
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);
836
837         m_internalData->setupState |= PSS_PRE_RASTERIZATION_SHADERS;
838         m_internalData->pFragmentShadingRateState = fragmentShadingRateState;
839         m_internalData->pRenderingState.ptr = rendering.ptr;
840
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);
844
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;
849
850         VkPipelineCreateFlags shaderModuleIdFlags = 0u;
851
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,
854         {
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
862         });
863
864 #ifndef CTS_USES_VULKANSC
865         if (vertShaderModuleId.ptr)
866         {
867                 m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(vertShaderModuleId.ptr));
868                 m_internalData->pipelineShaderStages[0].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
869
870                 if (vertexShaderModule == DE_NULL)
871                         shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
872         }
873 #endif // CTS_USES_VULKANSC
874
875         std::vector<VkPipelineShaderStageCreateInfo>::iterator currStage = m_internalData->pipelineShaderStages.begin() + 1;
876
877         if (hasTesc)
878         {
879                 currStage->stage                                = VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
880                 currStage->module                               = tessellationControlShaderModule;
881                 currStage->pSpecializationInfo  = tescSpecializationInfo;
882
883 #ifndef CTS_USES_VULKANSC
884                 if (tescShaderModuleId.ptr)
885                 {
886                         m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(tescShaderModuleId.ptr));
887                         currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
888
889                         if (tessellationControlShaderModule == DE_NULL)
890                                 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
891                 }
892 #endif // CTS_USES_VULKANSC
893
894                 ++currStage;
895         }
896
897         if (hasTese)
898         {
899                 currStage->stage                                = VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
900                 currStage->module                               = tessellationEvalShaderModule;
901                 currStage->pSpecializationInfo  = teseSpecializationInfo;
902
903 #ifndef CTS_USES_VULKANSC
904                 if (teseShaderModuleId.ptr)
905                 {
906                         m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(teseShaderModuleId.ptr));
907                         currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
908
909                         if (tessellationEvalShaderModule == DE_NULL)
910                                 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
911                 }
912 #endif // CTS_USES_VULKANSC
913
914                 ++currStage;
915         }
916
917         if (hasGeom)
918         {
919                 currStage->stage                                = VK_SHADER_STAGE_GEOMETRY_BIT;
920                 currStage->module                               = geometryShaderModule;
921                 currStage->pSpecializationInfo  = geomSpecializationInfo;
922
923 #ifndef CTS_USES_VULKANSC
924                 if (geomShaderModuleId.ptr)
925                 {
926                         m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(geomShaderModuleId.ptr));
927                         currStage->pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
928
929                         if (geometryShaderModule == DE_NULL)
930                                 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
931                 }
932 #endif // CTS_USES_VULKANSC
933         }
934
935         if (pViewportState)
936         {
937                 if (!viewports.empty())
938                 {
939                         pViewportState->viewportCount   = (deUint32)viewports.size();
940                         pViewportState->pViewports              = &viewports[0];
941                 }
942                 if (!scissors.empty())
943                 {
944                         pViewportState->scissorCount    = (deUint32)scissors.size();
945                         pViewportState->pScissors               = &scissors[0];
946                 }
947         }
948
949         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
950         {
951                 // make sure we dont overwrite layout specified with setupMonolithicPipelineLayout
952                 if (m_internalData->monolithicPipelineCreateInfo.layout == 0)
953                         m_internalData->monolithicPipelineCreateInfo.layout = layout;
954
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;
963         }
964
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)
969         {
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);
975
976                 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
977                 std::vector<VkDynamicState> states;
978
979                 if(m_internalData->pDynamicState)
980                 {
981                         states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
982
983                         pickedDynamicStateInfo.pDynamicStates = states.data();
984                         pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
985                 }
986
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;
999
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;
1002
1003                 if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
1004                         m_internalData->failOnCompileWhenLinking = true;
1005
1006                 m_pipelineParts[1] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1007         }
1008 #endif // CTS_USES_VULKANSC
1009
1010         return *this;
1011 }
1012
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)
1028 {
1029         // Make sure pipeline was not already built.
1030         DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1031
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));
1034
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;
1039
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
1046                                                                                 : nullptr);
1047         const auto pTessellationState   = nullptr;
1048         const auto pViewportState               = m_internalData->useViewportState ? &m_internalData->viewportState : DE_NULL;
1049
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,
1052         {
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
1060         });
1061
1062         // Mesh shader.
1063         auto currStage = m_internalData->pipelineShaderStages.begin();
1064         {
1065                 auto& stageInfo = *currStage;
1066
1067                 stageInfo.stage                                 = VK_SHADER_STAGE_MESH_BIT_EXT;
1068                 stageInfo.module                                = meshShaderModule;
1069                 stageInfo.pSpecializationInfo   = meshSpecializationInfo;
1070
1071                 ++currStage;
1072         }
1073
1074         if (hasTask)
1075         {
1076                 auto& stageInfo = *currStage;
1077
1078                 stageInfo.stage                                 = VK_SHADER_STAGE_TASK_BIT_EXT;
1079                 stageInfo.module                                = taskShaderModule;
1080                 stageInfo.pSpecializationInfo   = taskSpecializationInfo;
1081
1082                 ++currStage;
1083         }
1084
1085         if (pViewportState)
1086         {
1087                 if (!viewports.empty())
1088                 {
1089                         pViewportState->viewportCount   = (deUint32)viewports.size();
1090                         pViewportState->pViewports              = &viewports[0];
1091                 }
1092                 if (!scissors.empty())
1093                 {
1094                         pViewportState->scissorCount    = (deUint32)scissors.size();
1095                         pViewportState->pScissors               = &scissors[0];
1096                 }
1097         }
1098
1099         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1100         {
1101                 // make sure we dont overwrite layout specified with setupMonolithicPipelineLayout
1102                 if (m_internalData->monolithicPipelineCreateInfo.layout == 0)
1103                         m_internalData->monolithicPipelineCreateInfo.layout = layout;
1104
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;
1112         }
1113         else
1114         {
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);
1120
1121                 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
1122                 std::vector<VkDynamicState> states;
1123
1124                 if(m_internalData->pDynamicState)
1125                 {
1126                         states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
1127
1128                         pickedDynamicStateInfo.pDynamicStates = states.data();
1129                         pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
1130                 }
1131
1132
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;
1145
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;
1148
1149                 m_pipelineParts[1] = createGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1150         }
1151
1152         return *this;
1153 }
1154 #endif // CTS_USES_VULKANSC
1155
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)
1165 {
1166         return setupFragmentShaderState2(layout,
1167                                                                          renderPass,
1168                                                                          subpass,
1169                                                                          fragmentShaderModule,
1170                                                                          PipelineShaderStageModuleIdentifierCreateInfoWrapper(),
1171                                                                          depthStencilState,
1172                                                                          multisampleState,
1173                                                                          specializationInfo,
1174                                                                          partPipelineCache,
1175                                                                          partCreationFeedback);
1176 }
1177
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)
1188 {
1189         // make sure pipeline was not already build
1190         DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1191
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)));
1194
1195         // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
1196         DE_UNREF(layout);
1197         DE_UNREF(renderPass);
1198         DE_UNREF(subpass);
1199         DE_UNREF(partPipelineCache);
1200         DE_UNREF(partCreationFeedback);
1201         DE_UNREF(fragmentShaderModuleId);
1202
1203         m_internalData->setupState |= PSS_FRAGMENT_SHADER;
1204
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);
1210
1211         VkPipelineCreateFlags shaderModuleIdFlags = 0u;
1212
1213         deUint32 stageIndex = 1;
1214         if (hasFrag)
1215         {
1216                 // find free space for fragment shader
1217                 for (; stageIndex < 5; ++stageIndex)
1218                 {
1219                         if (m_internalData->pipelineShaderStages[stageIndex].stage == VK_SHADER_STAGE_VERTEX_BIT)
1220                         {
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)
1226                                 {
1227                                         m_internalData->pipelineShaderIdentifiers.emplace_back(new PipelineShaderStageModuleIdentifierCreateInfoWrapper(fragmentShaderModuleId.ptr));
1228                                         m_internalData->pipelineShaderStages[stageIndex].pNext = m_internalData->pipelineShaderIdentifiers.back().get()->ptr;
1229
1230                                         if (fragmentShaderModule == DE_NULL)
1231                                                 shaderModuleIdFlags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
1232                                 }
1233 #endif // CTS_USES_VULKANSC
1234                                 break;
1235                         }
1236                 }
1237         }
1238
1239         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1240         {
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;
1245         }
1246
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)
1251         {
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);
1258
1259                 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
1260                 std::vector<VkDynamicState> states;
1261
1262                 if(m_internalData->pDynamicState)
1263                 {
1264                         states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
1265
1266                         pickedDynamicStateInfo.pDynamicStates = states.data();
1267                         pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
1268                 }
1269
1270
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;
1282
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;
1285
1286                 if ((shaderModuleIdFlags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT) != 0)
1287                         m_internalData->failOnCompileWhenLinking = true;
1288
1289                 m_pipelineParts[2] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1290         }
1291 #endif // CTS_USES_VULKANSC
1292
1293         return *this;
1294 }
1295
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)
1302 {
1303         // make sure pipeline was not already build
1304         DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1305
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;
1309
1310         // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
1311         DE_UNREF(renderPass);
1312         DE_UNREF(subpass);
1313         DE_UNREF(partPipelineCache);
1314         DE_UNREF(partCreationFeedback);
1315
1316         void* firstStructInChain = DE_NULL;
1317         addToChain(&firstStructInChain, m_internalData->pFragmentShadingRateState);
1318
1319 #ifndef CTS_USES_VULKANSC
1320         addToChain(&firstStructInChain, m_internalData->pRenderingState.ptr);
1321 #endif // CTS_USES_VULKANSC
1322
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);
1327
1328         if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1329         {
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;
1334         }
1335
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)
1340         {
1341                 auto libraryCreateInfo = makeGraphicsPipelineLibraryCreateInfo(VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT);
1342                 addToChain(&firstStructInChain, &libraryCreateInfo);
1343                 addToChain(&firstStructInChain, partCreationFeedback.ptr);
1344
1345
1346                 VkPipelineDynamicStateCreateInfo pickedDynamicStateInfo = initVulkanStructure();
1347                 std::vector<VkDynamicState> states;
1348
1349                 if(m_internalData->pDynamicState)
1350                 {
1351                         states = getDynamicStates(m_internalData->pDynamicState, m_internalData->setupState);
1352
1353                         pickedDynamicStateInfo.pDynamicStates = states.data();
1354                         pickedDynamicStateInfo.dynamicStateCount = static_cast<uint32_t>(states.size());
1355                 }
1356
1357
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;
1366
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;
1369
1370                 m_pipelineParts[3] = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, partPipelineCache, &pipelinePartCreateInfo);
1371         }
1372 #endif // CTS_USES_VULKANSC
1373
1374         return *this;
1375 }
1376
1377 void GraphicsPipelineWrapper::buildPipeline(const VkPipelineCache                                               pipelineCache,
1378                                                                                         const VkPipeline                                                        basePipelineHandle,
1379                                                                                         const deInt32                                                           basePipelineIndex,
1380                                                                                         PipelineCreationFeedbackCreateInfoWrapper       creationFeedback)
1381 {
1382         // make sure we are not trying to build pipeline second time
1383         DE_ASSERT(m_pipelineFinal.get() == DE_NULL);
1384
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)));
1388
1389         // Unreference variables that are not used in Vulkan SC. No need to put this in ifdef.
1390         DE_UNREF(creationFeedback);
1391
1392         VkGraphicsPipelineCreateInfo*   pointerToCreateInfo     = &m_internalData->monolithicPipelineCreateInfo;
1393
1394 #ifndef CTS_USES_VULKANSC
1395         VkGraphicsPipelineCreateInfo    linkedCreateInfo        = initVulkanStructure();
1396         std::vector<VkPipeline>                 rawPipelines;
1397         VkPipelineLibraryCreateInfoKHR  linkingInfo
1398         {
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;
1403         };
1404
1405         if (m_internalData->pipelineConstructionType != PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1406         {
1407                 for (const auto& pipelinePtr : m_pipelineParts)
1408                 {
1409                         const auto& pipeline = pipelinePtr.get();
1410                         if (pipeline != DE_NULL)
1411                                 rawPipelines.push_back(pipeline);
1412                 }
1413
1414                 linkingInfo.libraryCount        = static_cast<uint32_t>(rawPipelines.size());
1415                 linkingInfo.pLibraries          = de::dataOrNull(rawPipelines);
1416
1417                 linkedCreateInfo.flags          = m_internalData->pipelineFlags;
1418                 linkedCreateInfo.layout         = m_internalData->monolithicPipelineCreateInfo.layout;
1419                 linkedCreateInfo.pNext          = &linkingInfo;
1420
1421                 pointerToCreateInfo                     = &linkedCreateInfo;
1422
1423                 if (m_internalData->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_LINK_TIME_OPTIMIZED_LIBRARY)
1424                         linkedCreateInfo.flags |= VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
1425
1426                 if (m_internalData->failOnCompileWhenLinking)
1427                         linkedCreateInfo.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
1428         }
1429         else
1430         {
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);
1435         }
1436 #endif // CTS_USES_VULKANSC
1437
1438         pointerToCreateInfo->basePipelineHandle = basePipelineHandle;
1439         pointerToCreateInfo->basePipelineIndex  = basePipelineIndex;
1440
1441         m_pipelineFinal = makeGraphicsPipeline(m_internalData->vk, m_internalData->device, pipelineCache, pointerToCreateInfo);
1442
1443         // pipeline was created - we can free CreateInfo structures
1444         m_internalData.clear();
1445 }
1446
1447 deBool GraphicsPipelineWrapper::wasBuild() const
1448 {
1449         return !!m_pipelineFinal.get();
1450 }
1451
1452 VkPipeline GraphicsPipelineWrapper::getPipeline() const
1453 {
1454         DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
1455         return m_pipelineFinal.get();
1456 }
1457
1458 void GraphicsPipelineWrapper::destroyPipeline(void)
1459 {
1460         DE_ASSERT(m_pipelineFinal.get() != DE_NULL);
1461
1462         m_pipelineFinal = Move<VkPipeline>();
1463 }
1464
1465 } // vk