zink: don't use ds3 blend states without color attachments
[platform/upstream/mesa.git] / src / gallium / drivers / zink / zink_pipeline.c
1 /*
2  * Copyright 2018 Collabora Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * on the rights to use, copy, modify, merge, publish, distribute, sub
8  * license, and/or sell copies of the Software, and to permit persons to whom
9  * the Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21  * USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23
24 #include "compiler/spirv/spirv.h"
25
26 #include "zink_pipeline.h"
27
28 #include "zink_compiler.h"
29 #include "zink_context.h"
30 #include "zink_program.h"
31 #include "zink_render_pass.h"
32 #include "zink_screen.h"
33 #include "zink_state.h"
34
35 #include "util/u_debug.h"
36 #include "util/u_prim.h"
37
38 VkPipeline
39 zink_create_gfx_pipeline(struct zink_screen *screen,
40                          struct zink_gfx_program *prog,
41                          struct zink_gfx_pipeline_state *state,
42                          const uint8_t *binding_map,
43                          VkPrimitiveTopology primitive_topology,
44                          bool optimize)
45 {
46    struct zink_rasterizer_hw_state *hw_rast_state = (void*)&state->dyn_state3;
47    VkPipelineVertexInputStateCreateInfo vertex_input_state;
48    if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride) {
49       memset(&vertex_input_state, 0, sizeof(vertex_input_state));
50       vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
51       vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
52       vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
53       vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
54       vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
55       if (!screen->info.have_EXT_extended_dynamic_state || !state->uses_dynamic_stride) {
56          for (int i = 0; i < state->element_state->num_bindings; ++i) {
57             const unsigned buffer_id = binding_map[i];
58             VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
59             binding->stride = state->vertex_strides[buffer_id];
60          }
61       }
62    }
63
64    VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
65    if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
66        memset(&vdiv_state, 0, sizeof(vdiv_state));
67        vertex_input_state.pNext = &vdiv_state;
68        vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
69        vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
70        vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
71    }
72
73    VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
74    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
75    primitive_state.topology = primitive_topology;
76    if (!screen->info.have_EXT_extended_dynamic_state2) {
77       switch (primitive_topology) {
78       case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
79       case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
80       case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
81       case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
82       case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
83          if (screen->info.have_EXT_primitive_topology_list_restart) {
84             primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
85             break;
86          }
87          FALLTHROUGH;
88       case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
89          if (state->dyn_state2.primitive_restart)
90             mesa_loge("zink: restart_index set with unsupported primitive topology %u\n", primitive_topology);
91          primitive_state.primitiveRestartEnable = VK_FALSE;
92          break;
93       default:
94          primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
95       }
96    }
97
98    VkPipelineColorBlendStateCreateInfo blend_state = {0};
99    blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
100    if (state->blend_state) {
101       unsigned num_attachments = state->render_pass ?
102                                  state->render_pass->state.num_rts :
103                                  state->rendering_info.colorAttachmentCount;
104       if (state->render_pass && state->render_pass->state.have_zsbuf)
105          num_attachments--;
106       blend_state.pAttachments = state->blend_state->attachments;
107       blend_state.attachmentCount = num_attachments;
108       blend_state.logicOpEnable = state->blend_state->logicop_enable;
109       blend_state.logicOp = state->blend_state->logicop_func;
110    }
111    if (state->rast_attachment_order)
112       blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
113
114    VkPipelineMultisampleStateCreateInfo ms_state = {0};
115    ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
116    ms_state.rasterizationSamples = state->rast_samples + 1;
117    if (state->blend_state) {
118       ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
119       if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
120          static bool warned = false;
121          warn_missing_feature(warned, "alphaToOne");
122       }
123       ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
124    }
125    /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
126     * - Chapter 27. Rasterization
127     * 
128     * thus it never makes sense to leave this as NULL since gallium will provide correct
129     * data here as long as sample_mask is initialized on context creation
130     */
131    ms_state.pSampleMask = &state->sample_mask;
132    if (state->force_persample_interp) {
133       ms_state.sampleShadingEnable = VK_TRUE;
134       ms_state.minSampleShading = 1.0;
135    } else if (state->min_samples > 0) {
136       ms_state.sampleShadingEnable = VK_TRUE;
137       ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
138    }
139
140    VkPipelineViewportStateCreateInfo viewport_state = {0};
141    VkPipelineViewportDepthClipControlCreateInfoEXT clip = {
142       VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
143       NULL,
144       VK_TRUE
145    };
146    viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
147    viewport_state.viewportCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
148    viewport_state.pViewports = NULL;
149    viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
150    viewport_state.pScissors = NULL;
151    if (!screen->driver_workarounds.depth_clip_control_missing && !hw_rast_state->clip_halfz)
152       viewport_state.pNext = &clip;
153
154    VkPipelineRasterizationStateCreateInfo rast_state = {0};
155    rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
156
157    rast_state.depthClampEnable = hw_rast_state->depth_clamp;
158    rast_state.rasterizerDiscardEnable = state->dyn_state2.rasterizer_discard;
159    rast_state.polygonMode = hw_rast_state->polygon_mode;
160    rast_state.cullMode = state->dyn_state1.cull_mode;
161    rast_state.frontFace = state->dyn_state1.front_face;
162
163    rast_state.depthBiasEnable = VK_TRUE;
164    rast_state.depthBiasConstantFactor = 0.0;
165    rast_state.depthBiasClamp = 0.0;
166    rast_state.depthBiasSlopeFactor = 0.0;
167    rast_state.lineWidth = 1.0f;
168
169    VkPipelineRasterizationDepthClipStateCreateInfoEXT depth_clip_state = {0};
170    depth_clip_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT;
171    depth_clip_state.depthClipEnable = hw_rast_state->depth_clip;
172    if (screen->info.have_EXT_depth_clip_enable) {
173       depth_clip_state.pNext = rast_state.pNext;
174       rast_state.pNext = &depth_clip_state;
175    } else {
176       static bool warned = false;
177       warn_missing_feature(warned, "VK_EXT_depth_clip_enable");
178    }
179
180    VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state;
181    pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
182    pv_state.provokingVertexMode = hw_rast_state->pv_last ?
183                                   VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
184                                   VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
185    if (screen->info.have_EXT_provoking_vertex && hw_rast_state->pv_last) {
186       pv_state.pNext = rast_state.pNext;
187       rast_state.pNext = &pv_state;
188    }
189
190    VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
191    depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
192    depth_stencil_state.depthTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_test;
193    depth_stencil_state.depthCompareOp = state->dyn_state1.depth_stencil_alpha_state->depth_compare_op;
194    depth_stencil_state.depthBoundsTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_bounds_test;
195    depth_stencil_state.minDepthBounds = state->dyn_state1.depth_stencil_alpha_state->min_depth_bounds;
196    depth_stencil_state.maxDepthBounds = state->dyn_state1.depth_stencil_alpha_state->max_depth_bounds;
197    depth_stencil_state.stencilTestEnable = state->dyn_state1.depth_stencil_alpha_state->stencil_test;
198    depth_stencil_state.front = state->dyn_state1.depth_stencil_alpha_state->stencil_front;
199    depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back;
200    depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write;
201
202    VkDynamicState dynamicStateEnables[80] = {
203       VK_DYNAMIC_STATE_LINE_WIDTH,
204       VK_DYNAMIC_STATE_DEPTH_BIAS,
205       VK_DYNAMIC_STATE_BLEND_CONSTANTS,
206       VK_DYNAMIC_STATE_STENCIL_REFERENCE,
207    };
208    unsigned state_count = 4;
209    if (screen->info.have_EXT_extended_dynamic_state) {
210       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
211       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
212       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
213       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
214       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
215       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
216       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
217       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
218       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
219       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
220       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
221       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
222       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
223       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
224       if (state->sample_locations_enabled)
225          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
226    } else {
227       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT;
228       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR;
229    }
230    if (screen->info.have_EXT_vertex_input_dynamic_state)
231       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
232    else if (screen->info.have_EXT_extended_dynamic_state && state->uses_dynamic_stride && state->element_state->num_attribs)
233       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE;
234    if (screen->info.have_EXT_extended_dynamic_state2) {
235       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
236       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
237       if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
238          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
239    }
240    if (screen->info.have_EXT_extended_dynamic_state3) {
241       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
242       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
243       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
244       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
245       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
246       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
247       if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
248          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
249       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
250       if (screen->have_full_ds3) {
251          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
252          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
253          if (state->blend_state) {
254             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
255             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
256             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
257             if (screen->info.feats.features.alphaToOne)
258                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
259             if (state->rendering_info.colorAttachmentCount) {
260                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
261                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
262                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
263             }
264          }
265       }
266    }
267    if (screen->info.have_EXT_color_write_enable)
268       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
269
270    assert(state->rast_prim != PIPE_PRIM_MAX);
271
272    VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
273    if (screen->info.have_EXT_line_rasterization) {
274       rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
275       rast_line_state.pNext = rast_state.pNext;
276       rast_line_state.stippledLineEnable = VK_FALSE;
277       rast_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
278
279       if (state->rast_prim == PIPE_PRIM_LINES) {
280          const char *features[4][2] = {
281             [VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT] = {"",""},
282             [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT] = {"rectangularLines", "stippledRectangularLines"},
283             [VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT] = {"bresenhamLines", "stippledBresenhamLines"},
284             [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT] = {"smoothLines", "stippledSmoothLines"},
285          };
286          static bool warned[6] = {0};
287          const VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats = &screen->info.line_rast_feats;
288          /* line features can be represented as an array VkBool32[6],
289           * with the 3 base features preceding the 3 (matching) stippled features
290           */
291          const VkBool32 *feat = &line_feats->rectangularLines;
292          unsigned mode_idx = hw_rast_state->line_mode - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
293          /* add base mode index, add 3 if stippling is enabled */
294          mode_idx += hw_rast_state->line_stipple_enable * 3;
295          if (*(feat + mode_idx))
296             rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
297          else
298             warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]);
299       }
300
301       if (hw_rast_state->line_stipple_enable) {
302          if (!screen->info.have_EXT_extended_dynamic_state3)
303             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
304          rast_line_state.stippledLineEnable = VK_TRUE;
305       }
306
307       rast_state.pNext = &rast_line_state;
308    }
309    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
310
311    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
312    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
313    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
314    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
315
316    VkGraphicsPipelineCreateInfo pci = {0};
317    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
318    static bool feedback_warn = false;
319    if (!optimize)
320       pci.flags |= VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
321    if (state->feedback_loop) {
322       if (screen->info.have_EXT_attachment_feedback_loop_layout)
323          pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
324       else
325          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
326    }
327    if (state->feedback_loop_zs) {
328       if (screen->info.have_EXT_attachment_feedback_loop_layout)
329          pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
330       else
331          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
332    }
333    pci.layout = prog->base.layout;
334    if (state->render_pass)
335       pci.renderPass = state->render_pass->render_pass;
336    else
337       pci.pNext = &state->rendering_info;
338    if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride)
339       pci.pVertexInputState = &vertex_input_state;
340    pci.pInputAssemblyState = &primitive_state;
341    pci.pRasterizationState = &rast_state;
342    pci.pColorBlendState = &blend_state;
343    pci.pMultisampleState = &ms_state;
344    pci.pViewportState = &viewport_state;
345    pci.pDepthStencilState = &depth_stencil_state;
346    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
347
348    VkPipelineTessellationStateCreateInfo tci = {0};
349    VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
350    if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
351       tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
352       tci.patchControlPoints = state->dyn_state2.vertices_per_patch;
353       pci.pTessellationState = &tci;
354       tci.pNext = &tdci;
355       tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
356       tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
357    }
358
359    VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
360    uint32_t num_stages = 0;
361    for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
362       if (!prog->modules[i])
363          continue;
364
365       VkPipelineShaderStageCreateInfo stage = {0};
366       stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
367       stage.stage = mesa_to_vk_shader_stage(i);
368       stage.module = prog->modules[i];
369       stage.pName = "main";
370       shader_stages[num_stages++] = stage;
371    }
372    assert(num_stages > 0);
373
374    pci.pStages = shader_stages;
375    pci.stageCount = num_stages;
376
377    VkPipeline pipeline;
378    VkResult result = VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache,
379                                                     1, &pci, NULL, &pipeline);
380    if (result != VK_SUCCESS) {
381       mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
382       return VK_NULL_HANDLE;
383    }
384
385    return pipeline;
386 }
387
388 VkPipeline
389 zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
390 {
391    VkComputePipelineCreateInfo pci = {0};
392    pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
393    pci.layout = comp->base.layout;
394
395    VkPipelineShaderStageCreateInfo stage = {0};
396    stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
397    stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
398    stage.module = comp->curr->shader;
399    stage.pName = "main";
400
401    VkSpecializationInfo sinfo = {0};
402    VkSpecializationMapEntry me[3];
403    if (comp->use_local_size) {
404       stage.pSpecializationInfo = &sinfo;
405       sinfo.mapEntryCount = 3;
406       sinfo.pMapEntries = &me[0];
407       sinfo.dataSize = sizeof(state->local_size);
408       sinfo.pData = &state->local_size[0];
409       uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
410       for (int i = 0; i < 3; i++) {
411          me[i].size = sizeof(uint32_t);
412          me[i].constantID = ids[i];
413          me[i].offset = i * sizeof(uint32_t);
414       }
415    }
416
417    pci.stage = stage;
418
419    VkPipeline pipeline;
420    VkResult result = VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache,
421                                                    1, &pci, NULL, &pipeline);
422    if (result != VK_SUCCESS) {
423       mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result));
424       return VK_NULL_HANDLE;
425    }
426
427    return pipeline;
428 }
429
430 VkPipeline
431 zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipeline_state *state)
432 {
433    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
434       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
435       &state->rendering_info,
436       VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT,
437    };
438
439    VkPipelineColorBlendStateCreateInfo blend_state = {0};
440    blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
441    if (state->rast_attachment_order)
442       blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
443    blend_state.attachmentCount = state->rendering_info.colorAttachmentCount;
444    if (state->blend_state)
445       blend_state.logicOp = state->blend_state->logicop_func;
446
447    VkPipelineMultisampleStateCreateInfo ms_state = {0};
448    ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
449    if (state->force_persample_interp) {
450       ms_state.sampleShadingEnable = VK_TRUE;
451       ms_state.minSampleShading = 1.0;
452    } else if (state->min_samples > 0) {
453       ms_state.sampleShadingEnable = VK_TRUE;
454       ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
455    }
456
457    VkDynamicState dynamicStateEnables[30] = {
458       VK_DYNAMIC_STATE_BLEND_CONSTANTS,
459    };
460    unsigned state_count = 1;
461    if (screen->info.have_EXT_extended_dynamic_state) {
462       if (state->sample_locations_enabled)
463          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
464    }
465    if (screen->info.have_EXT_color_write_enable)
466       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
467
468    if (screen->have_full_ds3) {
469       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
470       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
471       if (state->blend_state) {
472          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
473          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
474          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
475          if (screen->info.feats.features.alphaToOne)
476             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
477          if (state->rendering_info.colorAttachmentCount) {
478             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
479             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
480             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
481          }
482       }
483    } else {
484       if (state->blend_state) {
485          unsigned num_attachments = state->render_pass ?
486                                     state->render_pass->state.num_rts :
487                                     state->rendering_info.colorAttachmentCount;
488          if (state->render_pass && state->render_pass->state.have_zsbuf)
489             num_attachments--;
490          blend_state.pAttachments = state->blend_state->attachments;
491          blend_state.attachmentCount = num_attachments;
492          blend_state.logicOpEnable = state->blend_state->logicop_enable;
493          blend_state.logicOp = state->blend_state->logicop_func;
494
495          ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
496          if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
497             static bool warned = false;
498             warn_missing_feature(warned, "alphaToOne");
499          }
500          ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
501       }
502       ms_state.rasterizationSamples = state->rast_samples + 1;
503       /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
504        * - Chapter 27. Rasterization
505        * 
506        * thus it never makes sense to leave this as NULL since gallium will provide correct
507        * data here as long as sample_mask is initialized on context creation
508        */
509       ms_state.pSampleMask = &state->sample_mask;
510    }
511    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
512
513    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
514    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
515    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
516    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
517
518    VkGraphicsPipelineCreateInfo pci = {0};
519    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
520    pci.pNext = &gplci;
521    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
522    static bool feedback_warn = false;
523    if (state->feedback_loop) {
524       if (screen->info.have_EXT_attachment_feedback_loop_layout)
525          pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
526       else
527          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
528    }
529    if (state->feedback_loop_zs) {
530       if (screen->info.have_EXT_attachment_feedback_loop_layout)
531          pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
532       else
533          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
534    }
535    pci.pColorBlendState = &blend_state;
536    pci.pMultisampleState = &ms_state;
537    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
538
539    VkPipeline pipeline;
540    if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
541                                       NULL, &pipeline) != VK_SUCCESS) {
542       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
543       return VK_NULL_HANDLE;
544    }
545
546    return pipeline;
547 }
548
549 VkPipeline
550 zink_create_gfx_pipeline_input(struct zink_screen *screen,
551                                struct zink_gfx_pipeline_state *state,
552                                const uint8_t *binding_map,
553                                VkPrimitiveTopology primitive_topology)
554 {
555    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
556       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
557       NULL,
558       VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT
559    };
560
561    VkPipelineVertexInputStateCreateInfo vertex_input_state;
562    memset(&vertex_input_state, 0, sizeof(vertex_input_state));
563    vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
564    if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->uses_dynamic_stride) {
565       vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
566       vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
567       vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
568       vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
569       if (!state->uses_dynamic_stride) {
570          for (int i = 0; i < state->element_state->num_bindings; ++i) {
571             const unsigned buffer_id = binding_map[i];
572             VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
573             binding->stride = state->vertex_strides[buffer_id];
574          }
575       }
576    }
577
578    VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
579    if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
580        memset(&vdiv_state, 0, sizeof(vdiv_state));
581        vertex_input_state.pNext = &vdiv_state;
582        vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
583        vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
584        vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
585    }
586
587    VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
588    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
589    primitive_state.topology = primitive_topology;
590    assert(screen->info.have_EXT_extended_dynamic_state2);
591
592    VkDynamicState dynamicStateEnables[30];
593    unsigned state_count = 0;
594    if (screen->info.have_EXT_vertex_input_dynamic_state)
595       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
596    else if (state->uses_dynamic_stride && state->element_state->num_attribs)
597       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
598    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
599    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
600    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
601
602    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
603    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
604    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
605    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
606
607    VkGraphicsPipelineCreateInfo pci = {0};
608    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
609    pci.pNext = &gplci;
610    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
611    pci.pVertexInputState = &vertex_input_state;
612    pci.pInputAssemblyState = &primitive_state;
613    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
614
615    VkPipeline pipeline;
616    if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
617                                       NULL, &pipeline) != VK_SUCCESS) {
618       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
619       return VK_NULL_HANDLE;
620    }
621
622    return pipeline;
623 }
624
625 VkPipeline
626 zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_program *prog)
627 {
628    assert(screen->info.have_EXT_extended_dynamic_state && screen->info.have_EXT_extended_dynamic_state2);
629    VkPipelineRenderingCreateInfo rendering_info;
630    rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
631    rendering_info.pNext = NULL;
632    rendering_info.viewMask = 0;
633    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
634       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
635       &rendering_info,
636       VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT
637    };
638
639    VkPipelineViewportStateCreateInfo viewport_state = {0};
640    viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
641    viewport_state.viewportCount = 0;
642    viewport_state.pViewports = NULL;
643    viewport_state.scissorCount = 0;
644    viewport_state.pScissors = NULL;
645
646    VkPipelineRasterizationStateCreateInfo rast_state = {0};
647    rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
648    rast_state.depthBiasEnable = VK_TRUE;
649
650    VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
651    depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
652
653    VkDynamicState dynamicStateEnables[64] = {
654       VK_DYNAMIC_STATE_LINE_WIDTH,
655       VK_DYNAMIC_STATE_DEPTH_BIAS,
656       VK_DYNAMIC_STATE_STENCIL_REFERENCE,
657    };
658    unsigned state_count = 3;
659    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
660    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
661    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
662    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
663    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
664    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
665    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
666    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
667    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
668    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
669    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
670    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
671    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
672    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
673    if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
674       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
675
676    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
677    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
678    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
679    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
680    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
681    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
682    if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
683       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
684    if (screen->info.have_EXT_line_rasterization)
685       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
686    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
687
688    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
689    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
690    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
691    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
692
693    VkGraphicsPipelineCreateInfo pci = {0};
694    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
695    pci.pNext = &gplci;
696    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
697    pci.layout = prog->base.layout;
698    pci.pRasterizationState = &rast_state;
699    pci.pViewportState = &viewport_state;
700    pci.pDepthStencilState = &depth_stencil_state;
701    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
702
703    VkPipelineTessellationStateCreateInfo tci = {0};
704    VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
705    if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
706       tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
707       //this is a wild guess; pray for extendedDynamicState2PatchControlPoints
708       if (!screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) {
709          static bool warned = false;
710          warn_missing_feature(warned, "extendedDynamicState2PatchControlPoints");
711       }
712       tci.patchControlPoints = 32;
713       pci.pTessellationState = &tci;
714       tci.pNext = &tdci;
715       tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
716       tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
717    }
718
719    VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
720    uint32_t num_stages = 0;
721    for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
722       if (!prog->modules[i])
723          continue;
724
725       VkPipelineShaderStageCreateInfo stage = {0};
726       stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
727       stage.stage = mesa_to_vk_shader_stage(i);
728       stage.module = prog->modules[i];
729       stage.pName = "main";
730       shader_stages[num_stages++] = stage;
731    }
732    assert(num_stages > 0);
733
734    pci.pStages = shader_stages;
735    pci.stageCount = num_stages;
736
737    VkPipeline pipeline;
738    if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
739                                       NULL, &pipeline) != VK_SUCCESS) {
740       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
741       return VK_NULL_HANDLE;
742    }
743
744    return pipeline;
745 }
746
747 VkPipeline
748 zink_create_gfx_pipeline_combined(struct zink_screen *screen, struct zink_gfx_program *prog, VkPipeline input, VkPipeline library, VkPipeline output, bool optimized)
749 {
750    VkPipeline libraries[] = {input, library, output};
751    VkPipelineLibraryCreateInfoKHR libstate = {0};
752    libstate.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
753    libstate.libraryCount = 3;
754    libstate.pLibraries = libraries;
755
756    VkGraphicsPipelineCreateInfo pci = {0};
757    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
758    if (optimized)
759       pci.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
760    else
761       pci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
762    pci.pNext = &libstate;
763
764    VkPipeline pipeline;
765    if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
766                                       NULL, &pipeline) != VK_SUCCESS) {
767       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
768       return VK_NULL_HANDLE;
769    }
770
771    return pipeline;
772 }