68e27f1e690f9b463cf93eb29f4c0bf28d8fd69e
[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             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
260             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
261             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
262          }
263       }
264    }
265    if (screen->info.have_EXT_color_write_enable)
266       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
267
268    assert(state->rast_prim != PIPE_PRIM_MAX);
269
270    VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
271    if (screen->info.have_EXT_line_rasterization) {
272       rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
273       rast_line_state.pNext = rast_state.pNext;
274       rast_line_state.stippledLineEnable = VK_FALSE;
275       rast_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
276
277       if (state->rast_prim == PIPE_PRIM_LINES) {
278          const char *features[4][2] = {
279             [VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT] = {"",""},
280             [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT] = {"rectangularLines", "stippledRectangularLines"},
281             [VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT] = {"bresenhamLines", "stippledBresenhamLines"},
282             [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT] = {"smoothLines", "stippledSmoothLines"},
283          };
284          static bool warned[6] = {0};
285          const VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats = &screen->info.line_rast_feats;
286          /* line features can be represented as an array VkBool32[6],
287           * with the 3 base features preceding the 3 (matching) stippled features
288           */
289          const VkBool32 *feat = &line_feats->rectangularLines;
290          unsigned mode_idx = hw_rast_state->line_mode - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
291          /* add base mode index, add 3 if stippling is enabled */
292          mode_idx += hw_rast_state->line_stipple_enable * 3;
293          if (*(feat + mode_idx))
294             rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
295          else
296             warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]);
297       }
298
299       if (hw_rast_state->line_stipple_enable) {
300          if (!screen->info.have_EXT_extended_dynamic_state3)
301             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
302          rast_line_state.stippledLineEnable = VK_TRUE;
303       }
304
305       rast_state.pNext = &rast_line_state;
306    }
307    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
308
309    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
310    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
311    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
312    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
313
314    VkGraphicsPipelineCreateInfo pci = {0};
315    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
316    static bool feedback_warn = false;
317    if (!optimize)
318       pci.flags |= VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
319    if (state->feedback_loop) {
320       if (screen->info.have_EXT_attachment_feedback_loop_layout)
321          pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
322       else
323          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
324    }
325    if (state->feedback_loop_zs) {
326       if (screen->info.have_EXT_attachment_feedback_loop_layout)
327          pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
328       else
329          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
330    }
331    pci.layout = prog->base.layout;
332    if (state->render_pass)
333       pci.renderPass = state->render_pass->render_pass;
334    else
335       pci.pNext = &state->rendering_info;
336    if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride)
337       pci.pVertexInputState = &vertex_input_state;
338    pci.pInputAssemblyState = &primitive_state;
339    pci.pRasterizationState = &rast_state;
340    pci.pColorBlendState = &blend_state;
341    pci.pMultisampleState = &ms_state;
342    pci.pViewportState = &viewport_state;
343    pci.pDepthStencilState = &depth_stencil_state;
344    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
345
346    VkPipelineTessellationStateCreateInfo tci = {0};
347    VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
348    if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
349       tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
350       tci.patchControlPoints = state->dyn_state2.vertices_per_patch;
351       pci.pTessellationState = &tci;
352       tci.pNext = &tdci;
353       tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
354       tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
355    }
356
357    VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
358    uint32_t num_stages = 0;
359    for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
360       if (!prog->modules[i])
361          continue;
362
363       VkPipelineShaderStageCreateInfo stage = {0};
364       stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
365       stage.stage = mesa_to_vk_shader_stage(i);
366       stage.module = prog->modules[i];
367       stage.pName = "main";
368       shader_stages[num_stages++] = stage;
369    }
370    assert(num_stages > 0);
371
372    pci.pStages = shader_stages;
373    pci.stageCount = num_stages;
374
375    VkPipeline pipeline;
376    VkResult result = VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache,
377                                                     1, &pci, NULL, &pipeline);
378    if (result != VK_SUCCESS) {
379       mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
380       return VK_NULL_HANDLE;
381    }
382
383    return pipeline;
384 }
385
386 VkPipeline
387 zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
388 {
389    VkComputePipelineCreateInfo pci = {0};
390    pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
391    pci.layout = comp->base.layout;
392
393    VkPipelineShaderStageCreateInfo stage = {0};
394    stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
395    stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
396    stage.module = comp->curr->shader;
397    stage.pName = "main";
398
399    VkSpecializationInfo sinfo = {0};
400    VkSpecializationMapEntry me[3];
401    if (comp->use_local_size) {
402       stage.pSpecializationInfo = &sinfo;
403       sinfo.mapEntryCount = 3;
404       sinfo.pMapEntries = &me[0];
405       sinfo.dataSize = sizeof(state->local_size);
406       sinfo.pData = &state->local_size[0];
407       uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
408       for (int i = 0; i < 3; i++) {
409          me[i].size = sizeof(uint32_t);
410          me[i].constantID = ids[i];
411          me[i].offset = i * sizeof(uint32_t);
412       }
413    }
414
415    pci.stage = stage;
416
417    VkPipeline pipeline;
418    VkResult result = VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache,
419                                                    1, &pci, NULL, &pipeline);
420    if (result != VK_SUCCESS) {
421       mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result));
422       return VK_NULL_HANDLE;
423    }
424
425    return pipeline;
426 }
427
428 VkPipeline
429 zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipeline_state *state)
430 {
431    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
432       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
433       &state->rendering_info,
434       VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT,
435    };
436
437    VkPipelineColorBlendStateCreateInfo blend_state = {0};
438    blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
439    if (state->rast_attachment_order)
440       blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
441    blend_state.attachmentCount = state->rendering_info.colorAttachmentCount;
442    if (state->blend_state)
443       blend_state.logicOp = state->blend_state->logicop_func;
444
445    VkPipelineMultisampleStateCreateInfo ms_state = {0};
446    ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
447    if (state->force_persample_interp) {
448       ms_state.sampleShadingEnable = VK_TRUE;
449       ms_state.minSampleShading = 1.0;
450    } else if (state->min_samples > 0) {
451       ms_state.sampleShadingEnable = VK_TRUE;
452       ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
453    }
454
455    VkDynamicState dynamicStateEnables[30] = {
456       VK_DYNAMIC_STATE_BLEND_CONSTANTS,
457    };
458    unsigned state_count = 1;
459    if (screen->info.have_EXT_extended_dynamic_state) {
460       if (state->sample_locations_enabled)
461          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
462    }
463    if (screen->info.have_EXT_color_write_enable)
464       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
465
466    if (screen->have_full_ds3) {
467       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
468       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
469       if (state->blend_state) {
470          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
471          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
472          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
473          if (screen->info.feats.features.alphaToOne)
474             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
475          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
476          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
477          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
478       }
479    } else {
480       if (state->blend_state) {
481          unsigned num_attachments = state->render_pass ?
482                                     state->render_pass->state.num_rts :
483                                     state->rendering_info.colorAttachmentCount;
484          if (state->render_pass && state->render_pass->state.have_zsbuf)
485             num_attachments--;
486          blend_state.pAttachments = state->blend_state->attachments;
487          blend_state.attachmentCount = num_attachments;
488          blend_state.logicOpEnable = state->blend_state->logicop_enable;
489          blend_state.logicOp = state->blend_state->logicop_func;
490
491          ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
492          if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
493             static bool warned = false;
494             warn_missing_feature(warned, "alphaToOne");
495          }
496          ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
497       }
498       ms_state.rasterizationSamples = state->rast_samples + 1;
499       /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
500        * - Chapter 27. Rasterization
501        * 
502        * thus it never makes sense to leave this as NULL since gallium will provide correct
503        * data here as long as sample_mask is initialized on context creation
504        */
505       ms_state.pSampleMask = &state->sample_mask;
506    }
507    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
508
509    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
510    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
511    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
512    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
513
514    VkGraphicsPipelineCreateInfo pci = {0};
515    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
516    pci.pNext = &gplci;
517    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
518    static bool feedback_warn = false;
519    if (state->feedback_loop) {
520       if (screen->info.have_EXT_attachment_feedback_loop_layout)
521          pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
522       else
523          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
524    }
525    if (state->feedback_loop_zs) {
526       if (screen->info.have_EXT_attachment_feedback_loop_layout)
527          pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
528       else
529          warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
530    }
531    pci.pColorBlendState = &blend_state;
532    pci.pMultisampleState = &ms_state;
533    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
534
535    VkPipeline pipeline;
536    if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
537                                       NULL, &pipeline) != VK_SUCCESS) {
538       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
539       return VK_NULL_HANDLE;
540    }
541
542    return pipeline;
543 }
544
545 VkPipeline
546 zink_create_gfx_pipeline_input(struct zink_screen *screen,
547                                struct zink_gfx_pipeline_state *state,
548                                const uint8_t *binding_map,
549                                VkPrimitiveTopology primitive_topology)
550 {
551    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
552       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
553       NULL,
554       VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT
555    };
556
557    VkPipelineVertexInputStateCreateInfo vertex_input_state;
558    memset(&vertex_input_state, 0, sizeof(vertex_input_state));
559    vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
560    if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->uses_dynamic_stride) {
561       vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
562       vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
563       vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
564       vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
565       if (!state->uses_dynamic_stride) {
566          for (int i = 0; i < state->element_state->num_bindings; ++i) {
567             const unsigned buffer_id = binding_map[i];
568             VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
569             binding->stride = state->vertex_strides[buffer_id];
570          }
571       }
572    }
573
574    VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
575    if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
576        memset(&vdiv_state, 0, sizeof(vdiv_state));
577        vertex_input_state.pNext = &vdiv_state;
578        vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
579        vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
580        vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
581    }
582
583    VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
584    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
585    primitive_state.topology = primitive_topology;
586    assert(screen->info.have_EXT_extended_dynamic_state2);
587
588    VkDynamicState dynamicStateEnables[30];
589    unsigned state_count = 0;
590    if (screen->info.have_EXT_vertex_input_dynamic_state)
591       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
592    else if (state->uses_dynamic_stride && state->element_state->num_attribs)
593       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
594    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
595    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
596    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
597
598    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
599    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
600    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
601    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
602
603    VkGraphicsPipelineCreateInfo pci = {0};
604    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
605    pci.pNext = &gplci;
606    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
607    pci.pVertexInputState = &vertex_input_state;
608    pci.pInputAssemblyState = &primitive_state;
609    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
610
611    VkPipeline pipeline;
612    if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
613                                       NULL, &pipeline) != VK_SUCCESS) {
614       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
615       return VK_NULL_HANDLE;
616    }
617
618    return pipeline;
619 }
620
621 VkPipeline
622 zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_program *prog)
623 {
624    assert(screen->info.have_EXT_extended_dynamic_state && screen->info.have_EXT_extended_dynamic_state2);
625    VkPipelineRenderingCreateInfo rendering_info;
626    rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
627    rendering_info.pNext = NULL;
628    rendering_info.viewMask = 0;
629    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
630       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
631       &rendering_info,
632       VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT
633    };
634
635    VkPipelineViewportStateCreateInfo viewport_state = {0};
636    viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
637    viewport_state.viewportCount = 0;
638    viewport_state.pViewports = NULL;
639    viewport_state.scissorCount = 0;
640    viewport_state.pScissors = NULL;
641
642    VkPipelineRasterizationStateCreateInfo rast_state = {0};
643    rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
644    rast_state.depthBiasEnable = VK_TRUE;
645
646    VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
647    depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
648
649    VkDynamicState dynamicStateEnables[64] = {
650       VK_DYNAMIC_STATE_LINE_WIDTH,
651       VK_DYNAMIC_STATE_DEPTH_BIAS,
652       VK_DYNAMIC_STATE_STENCIL_REFERENCE,
653    };
654    unsigned state_count = 3;
655    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
656    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
657    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
658    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
659    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
660    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
661    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
662    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
663    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
664    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
665    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
666    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
667    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
668    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
669    if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
670       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
671
672    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
673    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
674    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
675    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
676    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
677    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
678    if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
679       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
680    if (screen->info.have_EXT_line_rasterization)
681       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
682    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
683
684    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
685    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
686    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
687    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
688
689    VkGraphicsPipelineCreateInfo pci = {0};
690    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
691    pci.pNext = &gplci;
692    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
693    pci.layout = prog->base.layout;
694    pci.pRasterizationState = &rast_state;
695    pci.pViewportState = &viewport_state;
696    pci.pDepthStencilState = &depth_stencil_state;
697    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
698
699    VkPipelineTessellationStateCreateInfo tci = {0};
700    VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
701    if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
702       tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
703       //this is a wild guess; pray for extendedDynamicState2PatchControlPoints
704       if (!screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) {
705          static bool warned = false;
706          warn_missing_feature(warned, "extendedDynamicState2PatchControlPoints");
707       }
708       tci.patchControlPoints = 32;
709       pci.pTessellationState = &tci;
710       tci.pNext = &tdci;
711       tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
712       tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
713    }
714
715    VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
716    uint32_t num_stages = 0;
717    for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
718       if (!prog->modules[i])
719          continue;
720
721       VkPipelineShaderStageCreateInfo stage = {0};
722       stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
723       stage.stage = mesa_to_vk_shader_stage(i);
724       stage.module = prog->modules[i];
725       stage.pName = "main";
726       shader_stages[num_stages++] = stage;
727    }
728    assert(num_stages > 0);
729
730    pci.pStages = shader_stages;
731    pci.stageCount = num_stages;
732
733    VkPipeline pipeline;
734    if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
735                                       NULL, &pipeline) != VK_SUCCESS) {
736       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
737       return VK_NULL_HANDLE;
738    }
739
740    return pipeline;
741 }
742
743 VkPipeline
744 zink_create_gfx_pipeline_combined(struct zink_screen *screen, struct zink_gfx_program *prog, VkPipeline input, VkPipeline library, VkPipeline output, bool optimized)
745 {
746    VkPipeline libraries[] = {input, library, output};
747    VkPipelineLibraryCreateInfoKHR libstate = {0};
748    libstate.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
749    libstate.libraryCount = 3;
750    libstate.pLibraries = libraries;
751
752    VkGraphicsPipelineCreateInfo pci = {0};
753    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
754    if (optimized)
755       pci.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
756    else
757       pci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
758    pci.pNext = &libstate;
759
760    VkPipeline pipeline;
761    if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
762                                       NULL, &pipeline) != VK_SUCCESS) {
763       mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
764       return VK_NULL_HANDLE;
765    }
766
767    return pipeline;
768 }