• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "nir_to_spirv/nir_to_spirv.h"
30 #include "zink_context.h"
31 #include "zink_program.h"
32 #include "zink_render_pass.h"
33 #include "zink_screen.h"
34 #include "zink_state.h"
35 
36 #include "util/u_debug.h"
37 #include "util/u_prim.h"
38 
39 VkPipeline
zink_create_gfx_pipeline(struct zink_screen * screen,struct zink_gfx_program * prog,struct zink_shader_object * objs,struct zink_gfx_pipeline_state * state,const uint8_t * binding_map,VkPrimitiveTopology primitive_topology,bool optimize,struct util_dynarray * dgc)40 zink_create_gfx_pipeline(struct zink_screen *screen,
41                          struct zink_gfx_program *prog,
42                          struct zink_shader_object *objs,
43                          struct zink_gfx_pipeline_state *state,
44                          const uint8_t *binding_map,
45                          VkPrimitiveTopology primitive_topology,
46                          bool optimize,
47                          struct util_dynarray *dgc)
48 {
49    struct zink_rasterizer_hw_state *hw_rast_state = (void*)&state->dyn_state3;
50    VkPipelineVertexInputStateCreateInfo vertex_input_state;
51    bool needs_vi = !screen->info.have_EXT_vertex_input_dynamic_state;
52    if (needs_vi) {
53       memset(&vertex_input_state, 0, sizeof(vertex_input_state));
54       vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
55       vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
56       vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
57       vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
58       vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
59       if (!screen->info.have_EXT_extended_dynamic_state || !state->uses_dynamic_stride) {
60          for (int i = 0; i < state->element_state->num_bindings; ++i) {
61             const unsigned buffer_id = binding_map[i];
62             VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
63             binding->stride = state->vertex_strides[buffer_id];
64          }
65       }
66    }
67 
68    VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
69    if (needs_vi && state->element_state->b.divisors_present) {
70        memset(&vdiv_state, 0, sizeof(vdiv_state));
71        vertex_input_state.pNext = &vdiv_state;
72        vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
73        vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
74        vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
75    }
76 
77    VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
78    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
79    primitive_state.topology = primitive_topology;
80    if (!screen->info.have_EXT_extended_dynamic_state2) {
81       switch (primitive_topology) {
82       case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
83       case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
84       case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
85       case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
86       case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
87          if (screen->info.have_EXT_primitive_topology_list_restart) {
88             primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
89             break;
90          }
91          FALLTHROUGH;
92       case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
93          if (state->dyn_state2.primitive_restart)
94             mesa_loge("zink: restart_index set with unsupported primitive topology %s\n", vk_PrimitiveTopology_to_str(primitive_topology));
95          primitive_state.primitiveRestartEnable = VK_FALSE;
96          break;
97       default:
98          primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
99       }
100    }
101 
102    VkPipelineColorBlendStateCreateInfo blend_state = {0};
103    blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
104    if (state->blend_state) {
105       unsigned num_attachments = state->render_pass ?
106                                  state->render_pass->state.num_rts :
107                                  state->rendering_info.colorAttachmentCount;
108       if (state->render_pass && state->render_pass->state.have_zsbuf)
109          num_attachments--;
110       blend_state.pAttachments = state->blend_state->attachments;
111       blend_state.attachmentCount = num_attachments;
112       blend_state.logicOpEnable = state->blend_state->logicop_enable;
113       blend_state.logicOp = state->blend_state->logicop_func;
114    }
115    if (state->rast_attachment_order)
116       blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
117 
118    VkPipelineMultisampleStateCreateInfo ms_state = {0};
119    ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
120    ms_state.rasterizationSamples = state->rast_samples + 1;
121    if (state->blend_state) {
122       ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
123       if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
124          static bool warned = false;
125          warn_missing_feature(warned, "alphaToOne");
126       }
127       ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
128    }
129    /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
130     * - Chapter 27. Rasterization
131     *
132     * thus it never makes sense to leave this as NULL since gallium will provide correct
133     * data here as long as sample_mask is initialized on context creation
134     */
135    ms_state.pSampleMask = &state->sample_mask;
136    if (state->force_persample_interp) {
137       ms_state.sampleShadingEnable = VK_TRUE;
138       ms_state.minSampleShading = 1.0;
139    } else if (state->min_samples > 0) {
140       ms_state.sampleShadingEnable = VK_TRUE;
141       ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
142    }
143 
144    VkPipelineViewportStateCreateInfo viewport_state = {0};
145    VkPipelineViewportDepthClipControlCreateInfoEXT clip = {
146       VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
147       NULL,
148       VK_TRUE
149    };
150    viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
151    viewport_state.viewportCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
152    viewport_state.pViewports = NULL;
153    viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
154    viewport_state.pScissors = NULL;
155    if (screen->info.have_EXT_depth_clip_control && !hw_rast_state->clip_halfz)
156       viewport_state.pNext = &clip;
157 
158    VkPipelineRasterizationStateCreateInfo rast_state = {0};
159    rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
160 
161    rast_state.depthClampEnable = hw_rast_state->depth_clamp;
162    rast_state.rasterizerDiscardEnable = state->dyn_state2.rasterizer_discard;
163    rast_state.polygonMode = hw_rast_state->polygon_mode;
164    rast_state.cullMode = state->dyn_state1.cull_mode;
165    rast_state.frontFace = state->dyn_state1.front_face;
166 
167    rast_state.depthBiasEnable = VK_TRUE;
168    rast_state.depthBiasConstantFactor = 0.0;
169    rast_state.depthBiasClamp = 0.0;
170    rast_state.depthBiasSlopeFactor = 0.0;
171    rast_state.lineWidth = 1.0f;
172 
173    VkPipelineRasterizationDepthClipStateCreateInfoEXT depth_clip_state = {0};
174    depth_clip_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT;
175    depth_clip_state.depthClipEnable = hw_rast_state->depth_clip;
176    if (screen->info.have_EXT_depth_clip_enable) {
177       depth_clip_state.pNext = rast_state.pNext;
178       rast_state.pNext = &depth_clip_state;
179    } else {
180       static bool warned = false;
181       warn_missing_feature(warned, "VK_EXT_depth_clip_enable");
182    }
183 
184    VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state;
185    pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
186    pv_state.provokingVertexMode = hw_rast_state->pv_last ?
187                                   VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
188                                   VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
189    if (screen->info.have_EXT_provoking_vertex && hw_rast_state->pv_last) {
190       pv_state.pNext = rast_state.pNext;
191       rast_state.pNext = &pv_state;
192    }
193 
194    VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
195    depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
196    depth_stencil_state.depthTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_test;
197    depth_stencil_state.depthCompareOp = state->dyn_state1.depth_stencil_alpha_state->depth_compare_op;
198    depth_stencil_state.depthBoundsTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_bounds_test;
199    depth_stencil_state.minDepthBounds = state->dyn_state1.depth_stencil_alpha_state->min_depth_bounds;
200    depth_stencil_state.maxDepthBounds = state->dyn_state1.depth_stencil_alpha_state->max_depth_bounds;
201    depth_stencil_state.stencilTestEnable = state->dyn_state1.depth_stencil_alpha_state->stencil_test;
202    depth_stencil_state.front = state->dyn_state1.depth_stencil_alpha_state->stencil_front;
203    depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back;
204    depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write;
205 
206    VkDynamicState dynamicStateEnables[80] = {
207       VK_DYNAMIC_STATE_LINE_WIDTH,
208       VK_DYNAMIC_STATE_DEPTH_BIAS,
209       VK_DYNAMIC_STATE_BLEND_CONSTANTS,
210       VK_DYNAMIC_STATE_STENCIL_REFERENCE,
211    };
212    unsigned state_count = 4;
213    if (screen->info.have_EXT_extended_dynamic_state) {
214       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
215       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
216       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
217       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
218       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
219       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
220       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
221       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
222       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
223       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
224       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
225       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
226       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
227       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
228       if (state->sample_locations_enabled)
229          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
230    } else {
231       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT;
232       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR;
233    }
234    if (screen->info.have_EXT_vertex_input_dynamic_state)
235       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
236    else if (screen->info.have_EXT_extended_dynamic_state && state->uses_dynamic_stride && state->element_state->num_attribs)
237       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE;
238    if (screen->info.have_EXT_extended_dynamic_state2) {
239       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
240       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
241       if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
242          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
243    }
244    if (screen->info.have_EXT_extended_dynamic_state3) {
245       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
246       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
247       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
248       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
249       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
250       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
251       if (!screen->driver_workarounds.no_linestipple) {
252          if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
253             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
254          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
255       }
256       if (screen->have_full_ds3) {
257          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
258          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
259          if (state->blend_state) {
260             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
261             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
262             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
263             if (screen->info.feats.features.alphaToOne)
264                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
265             if (state->rendering_info.colorAttachmentCount) {
266                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
267                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
268                dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
269             }
270          }
271       }
272    }
273    if (screen->info.have_EXT_color_write_enable)
274       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
275 
276    assert(state->rast_prim != MESA_PRIM_COUNT);
277 
278    VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
279    if (screen->info.have_EXT_line_rasterization &&
280        !state->shader_keys.key[MESA_SHADER_FRAGMENT].key.fs.lower_line_smooth) {
281       rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
282       rast_line_state.pNext = rast_state.pNext;
283       rast_line_state.stippledLineEnable = VK_FALSE;
284       rast_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
285 
286       if (state->rast_prim == MESA_PRIM_LINES) {
287          const char *features[4][2] = {
288             [VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT] = {"",""},
289             [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT] = {"rectangularLines", "stippledRectangularLines"},
290             [VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT] = {"bresenhamLines", "stippledBresenhamLines"},
291             [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT] = {"smoothLines", "stippledSmoothLines"},
292          };
293          static bool warned[6] = {0};
294          const VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats = &screen->info.line_rast_feats;
295          /* line features can be represented as an array VkBool32[6],
296           * with the 3 base features preceding the 3 (matching) stippled features
297           */
298          const VkBool32 *feat = &line_feats->rectangularLines;
299          unsigned mode_idx = hw_rast_state->line_mode - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
300          /* add base mode index, add 3 if stippling is enabled */
301          mode_idx += hw_rast_state->line_stipple_enable * 3;
302          if (*(feat + mode_idx))
303             rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
304          else if (hw_rast_state->line_stipple_enable &&
305                   screen->driver_workarounds.no_linestipple) {
306             /* drop line stipple, we can emulate it */
307             mode_idx -= hw_rast_state->line_stipple_enable * 3;
308             if (*(feat + mode_idx))
309                rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
310             /* non-strictLine default lines are either parallelogram or bresenham which while not in GL spec,
311              * in practice end up being within the two-pixel exception in the GL spec.
312              */
313             else if ((mode_idx != 1) || screen->info.props.limits.strictLines)
314                warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][0]);
315          } else if ((mode_idx != 1) || screen->info.props.limits.strictLines)
316             warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]);
317       }
318 
319       if (hw_rast_state->line_stipple_enable) {
320          if (!screen->info.have_EXT_extended_dynamic_state3)
321             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
322          rast_line_state.stippledLineEnable = VK_TRUE;
323       }
324 
325       rast_state.pNext = &rast_line_state;
326    }
327    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
328 
329    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
330    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
331    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
332 
333    VkGraphicsPipelineCreateInfo pci = {0};
334    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
335    if (!optimize)
336       pci.flags |= VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
337    if (screen->info.have_EXT_attachment_feedback_loop_dynamic_state) {
338       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT;
339    } else {
340       static bool feedback_warn = false;
341       if (state->feedback_loop) {
342          if (screen->info.have_EXT_attachment_feedback_loop_layout)
343             pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
344          else
345             warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
346       }
347       if (state->feedback_loop_zs) {
348          if (screen->info.have_EXT_attachment_feedback_loop_layout)
349             pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
350          else
351             warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
352       }
353    }
354    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
355       pci.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
356    pci.layout = prog->base.layout;
357    if (state->render_pass)
358       pci.renderPass = state->render_pass->render_pass;
359    else
360       pci.pNext = &state->rendering_info;
361    if (needs_vi)
362       pci.pVertexInputState = &vertex_input_state;
363    pci.pInputAssemblyState = &primitive_state;
364    pci.pRasterizationState = &rast_state;
365    pci.pColorBlendState = &blend_state;
366    pci.pMultisampleState = &ms_state;
367    pci.pViewportState = &viewport_state;
368    pci.pDepthStencilState = &depth_stencil_state;
369    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
370    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
371 
372    VkPipelineTessellationStateCreateInfo tci = {0};
373    VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
374    unsigned tess_bits = BITFIELD_BIT(MESA_SHADER_TESS_CTRL) | BITFIELD_BIT(MESA_SHADER_TESS_EVAL);
375    if ((prog->stages_present & tess_bits) == tess_bits) {
376       tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
377       tci.patchControlPoints = state->dyn_state2.vertices_per_patch;
378       pci.pTessellationState = &tci;
379       tci.pNext = &tdci;
380       tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
381       tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
382    }
383 
384    VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
385    VkShaderModuleCreateInfo smci[ZINK_GFX_SHADER_COUNT] = {0};
386    uint32_t num_stages = 0;
387    for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
388       if (!(prog->stages_present & BITFIELD_BIT(i)))
389          continue;
390 
391       VkPipelineShaderStageCreateInfo stage = {0};
392       stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
393       stage.stage = mesa_to_vk_shader_stage(i);
394       stage.pName = "main";
395       if (objs[i].mod) {
396          stage.module = objs[i].mod;
397       } else {
398          smci[i].sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
399          stage.pNext = &smci[i];
400          smci[i].codeSize = objs[i].spirv->num_words * sizeof(uint32_t);
401          smci[i].pCode = objs[i].spirv->words;
402       }
403       shader_stages[num_stages++] = stage;
404    }
405    assert(num_stages > 0);
406 
407    pci.pStages = shader_stages;
408    pci.stageCount = num_stages;
409 
410    VkGraphicsShaderGroupCreateInfoNV gci = {
411       VK_STRUCTURE_TYPE_GRAPHICS_SHADER_GROUP_CREATE_INFO_NV,
412       NULL,
413       pci.stageCount,
414       pci.pStages,
415       pci.pVertexInputState,
416       pci.pTessellationState
417    };
418    VkGraphicsPipelineShaderGroupsCreateInfoNV dgci = {
419       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_SHADER_GROUPS_CREATE_INFO_NV,
420       pci.pNext,
421       1,
422       &gci,
423       dgc ? util_dynarray_num_elements(dgc, VkPipeline) : 0,
424       dgc ? dgc->data : NULL
425    };
426    if (zink_debug & ZINK_DEBUG_DGC) {
427       pci.flags |= VK_PIPELINE_CREATE_INDIRECT_BINDABLE_BIT_NV;
428       pci.pNext = &dgci;
429    }
430 
431    VkPipeline pipeline;
432    u_rwlock_wrlock(&prog->base.pipeline_cache_lock);
433    VkResult result;
434    VRAM_ALLOC_LOOP(result,
435       VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci, NULL, &pipeline),
436       u_rwlock_wrunlock(&prog->base.pipeline_cache_lock);
437       if (result != VK_SUCCESS) {
438          mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
439          return VK_NULL_HANDLE;
440       }
441    );
442 
443    return pipeline;
444 }
445 
446 VkPipeline
zink_create_compute_pipeline(struct zink_screen * screen,struct zink_compute_program * comp,struct zink_compute_pipeline_state * state)447 zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
448 {
449    VkComputePipelineCreateInfo pci = {0};
450    pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
451    pci.layout = comp->base.layout;
452    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
453       pci.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
454 
455    VkPipelineShaderStageCreateInfo stage = {0};
456    stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
457    stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
458    stage.module = comp->curr->obj.mod;
459    stage.pName = "main";
460 
461    VkSpecializationInfo sinfo = {0};
462    VkSpecializationMapEntry me[4];
463    uint32_t data[4];
464    if (state)  {
465       int i = 0;
466 
467       if (comp->use_local_size) {
468          sinfo.mapEntryCount += 3;
469          sinfo.dataSize += sizeof(state->local_size);
470 
471          uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
472          for (int l = 0; l < 3; l++, i++) {
473             data[i] = state->local_size[l];
474             me[i].size = sizeof(uint32_t);
475             me[i].constantID = ids[l];
476             me[i].offset = i * sizeof(uint32_t);
477          }
478       }
479 
480       if (comp->has_variable_shared_mem) {
481          sinfo.mapEntryCount += 1;
482          sinfo.dataSize += sizeof(uint32_t);
483          data[i] = state->variable_shared_mem;
484          me[i].size = sizeof(uint32_t);
485          me[i].constantID = ZINK_VARIABLE_SHARED_MEM;
486          me[i].offset = i * sizeof(uint32_t);
487          i++;
488       }
489 
490       if (sinfo.dataSize) {
491          stage.pSpecializationInfo = &sinfo;
492          sinfo.pData = data;
493          sinfo.pMapEntries = me;
494       }
495 
496       assert(i <= ARRAY_SIZE(data));
497       STATIC_ASSERT(ARRAY_SIZE(data) == ARRAY_SIZE(me));
498    }
499 
500    pci.stage = stage;
501 
502    VkPipeline pipeline;
503    VkResult result;
504    u_rwlock_wrlock(&comp->base.pipeline_cache_lock);
505    VRAM_ALLOC_LOOP(result,
506       VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache, 1, &pci, NULL, &pipeline),
507       u_rwlock_wrunlock(&comp->base.pipeline_cache_lock);
508       if (result != VK_SUCCESS) {
509          mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result));
510          return VK_NULL_HANDLE;
511       }
512    );
513 
514    return pipeline;
515 }
516 
517 VkPipeline
zink_create_gfx_pipeline_output(struct zink_screen * screen,struct zink_gfx_pipeline_state * state)518 zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipeline_state *state)
519 {
520    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
521       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
522       &state->rendering_info,
523       VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT,
524    };
525 
526    VkPipelineColorBlendStateCreateInfo blend_state = {0};
527    blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
528    if (state->rast_attachment_order)
529       blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
530 
531    VkPipelineMultisampleStateCreateInfo ms_state = {0};
532    ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
533    if (state->force_persample_interp) {
534       ms_state.sampleShadingEnable = VK_TRUE;
535       ms_state.minSampleShading = 1.0;
536    } else if (state->min_samples > 0) {
537       ms_state.sampleShadingEnable = VK_TRUE;
538       ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
539    }
540 
541    VkDynamicState dynamicStateEnables[30] = {
542       VK_DYNAMIC_STATE_BLEND_CONSTANTS,
543    };
544    unsigned state_count = 1;
545    if (screen->info.have_EXT_extended_dynamic_state) {
546       if (state->sample_locations_enabled)
547          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
548    }
549    if (screen->info.have_EXT_color_write_enable)
550       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
551 
552    if (screen->have_full_ds3) {
553       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
554       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
555       if (state->blend_state) {
556          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
557          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
558          dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
559          if (screen->info.feats.features.alphaToOne)
560             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
561          if (state->rendering_info.colorAttachmentCount) {
562             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
563             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
564             dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
565          }
566       }
567    } else {
568       if (state->blend_state) {
569          blend_state.pAttachments = state->blend_state->attachments;
570          blend_state.attachmentCount = state->rendering_info.colorAttachmentCount;
571          blend_state.logicOpEnable = state->blend_state->logicop_enable;
572          blend_state.logicOp = state->blend_state->logicop_func;
573 
574          ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
575          if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
576             static bool warned = false;
577             warn_missing_feature(warned, "alphaToOne");
578          }
579          ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
580       }
581       ms_state.rasterizationSamples = state->rast_samples + 1;
582       /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
583        * - Chapter 27. Rasterization
584        *
585        * thus it never makes sense to leave this as NULL since gallium will provide correct
586        * data here as long as sample_mask is initialized on context creation
587        */
588       ms_state.pSampleMask = &state->sample_mask;
589    }
590    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
591 
592    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
593    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
594    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
595 
596    VkGraphicsPipelineCreateInfo pci = {0};
597    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
598    pci.pNext = &gplci;
599    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
600    if (screen->info.have_EXT_attachment_feedback_loop_dynamic_state) {
601       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT;
602    } else {
603       static bool feedback_warn = false;
604       if (state->feedback_loop) {
605          if (screen->info.have_EXT_attachment_feedback_loop_layout)
606             pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
607          else
608             warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
609       }
610       if (state->feedback_loop_zs) {
611          if (screen->info.have_EXT_attachment_feedback_loop_layout)
612             pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
613          else
614             warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
615       }
616    }
617    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
618       pci.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
619    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
620    if (!screen->have_full_ds3)
621       pci.pColorBlendState = &blend_state;
622    pci.pMultisampleState = &ms_state;
623    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
624 
625    VkPipeline pipeline;
626    VkResult result;
627    VRAM_ALLOC_LOOP(result,
628       VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci, NULL, &pipeline),
629       if (result != VK_SUCCESS) {
630          mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
631          return VK_NULL_HANDLE;
632       }
633    );
634 
635    return pipeline;
636 }
637 
638 VkPipeline
zink_create_gfx_pipeline_input(struct zink_screen * screen,struct zink_gfx_pipeline_state * state,const uint8_t * binding_map,VkPrimitiveTopology primitive_topology)639 zink_create_gfx_pipeline_input(struct zink_screen *screen,
640                                struct zink_gfx_pipeline_state *state,
641                                const uint8_t *binding_map,
642                                VkPrimitiveTopology primitive_topology)
643 {
644    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
645       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
646       NULL,
647       VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT
648    };
649 
650    VkPipelineVertexInputStateCreateInfo vertex_input_state;
651    memset(&vertex_input_state, 0, sizeof(vertex_input_state));
652    vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
653    if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->uses_dynamic_stride) {
654       vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
655       vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
656       vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
657       vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
658       if (!state->uses_dynamic_stride) {
659          for (int i = 0; i < state->element_state->num_bindings; ++i) {
660             const unsigned buffer_id = binding_map[i];
661             VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
662             binding->stride = state->vertex_strides[buffer_id];
663          }
664       }
665    }
666 
667    VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
668    if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
669        memset(&vdiv_state, 0, sizeof(vdiv_state));
670        vertex_input_state.pNext = &vdiv_state;
671        vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
672        vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
673        vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
674    }
675 
676    VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
677    primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
678    primitive_state.topology = primitive_topology;
679    assert(screen->info.have_EXT_extended_dynamic_state2);
680 
681    VkDynamicState dynamicStateEnables[30];
682    unsigned state_count = 0;
683    if (screen->info.have_EXT_vertex_input_dynamic_state)
684       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
685    else if (state->uses_dynamic_stride && state->element_state->num_attribs)
686       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE;
687    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
688    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
689    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
690 
691    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
692    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
693    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
694    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
695 
696    VkGraphicsPipelineCreateInfo pci = {0};
697    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
698    pci.pNext = &gplci;
699    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
700    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
701       pci.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
702    pci.pVertexInputState = &vertex_input_state;
703    pci.pInputAssemblyState = &primitive_state;
704    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
705 
706    VkPipeline pipeline;
707    VkResult result;
708    VRAM_ALLOC_LOOP(result,
709       VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci, NULL, &pipeline),
710       if (result != VK_SUCCESS) {
711          mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
712          return VK_NULL_HANDLE;
713       }
714    );
715 
716    return pipeline;
717 }
718 
719 static VkPipeline
create_gfx_pipeline_library(struct zink_screen * screen,struct zink_shader_object * objs,unsigned stage_mask,VkPipelineLayout layout,VkPipelineCache pipeline_cache)720 create_gfx_pipeline_library(struct zink_screen *screen, struct zink_shader_object *objs, unsigned stage_mask, VkPipelineLayout layout, VkPipelineCache pipeline_cache)
721 {
722    assert(screen->info.have_EXT_extended_dynamic_state && screen->info.have_EXT_extended_dynamic_state2);
723    VkPipelineRenderingCreateInfo rendering_info;
724    rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
725    rendering_info.pNext = NULL;
726    rendering_info.viewMask = 0;
727    VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
728       VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
729       &rendering_info,
730       0
731    };
732    if (stage_mask & BITFIELD_BIT(MESA_SHADER_VERTEX))
733       gplci.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT;
734    if (stage_mask & BITFIELD_BIT(MESA_SHADER_FRAGMENT))
735       gplci.flags |= VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT;
736 
737    VkPipelineViewportStateCreateInfo viewport_state = {0};
738    viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
739    viewport_state.viewportCount = 0;
740    viewport_state.pViewports = NULL;
741    viewport_state.scissorCount = 0;
742    viewport_state.pScissors = NULL;
743 
744    VkPipelineRasterizationStateCreateInfo rast_state = {0};
745    rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
746    rast_state.depthBiasEnable = VK_TRUE;
747 
748    VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
749    depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
750 
751    VkDynamicState dynamicStateEnables[64] = {
752       VK_DYNAMIC_STATE_LINE_WIDTH,
753       VK_DYNAMIC_STATE_DEPTH_BIAS,
754       VK_DYNAMIC_STATE_STENCIL_REFERENCE,
755    };
756    unsigned state_count = 3;
757    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
758    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
759    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
760    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
761    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
762    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
763    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
764    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
765    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
766    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
767    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
768    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
769    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
770    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
771    if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
772       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
773 
774    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
775    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
776    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
777    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
778    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
779    dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
780    if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
781       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
782    if (!screen->driver_workarounds.no_linestipple)
783       dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
784    assert(state_count < ARRAY_SIZE(dynamicStateEnables));
785 
786    VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
787    pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
788    pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
789    pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
790 
791    VkGraphicsPipelineCreateInfo pci = {0};
792    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
793    pci.pNext = &gplci;
794    pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
795    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
796       pci.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
797    pci.layout = layout;
798    pci.pRasterizationState = &rast_state;
799    pci.pViewportState = &viewport_state;
800    pci.pDepthStencilState = &depth_stencil_state;
801    pci.pDynamicState = &pipelineDynamicStateCreateInfo;
802 
803    VkPipelineTessellationStateCreateInfo tci = {0};
804    VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
805    unsigned tess_bits = BITFIELD_BIT(MESA_SHADER_TESS_CTRL) | BITFIELD_BIT(MESA_SHADER_TESS_EVAL);
806    if ((stage_mask & tess_bits) == tess_bits) {
807       tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
808       //this is a wild guess; pray for extendedDynamicState2PatchControlPoints
809       if (!screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) {
810          static bool warned = false;
811          warn_missing_feature(warned, "extendedDynamicState2PatchControlPoints");
812       }
813       tci.patchControlPoints = 32;
814       pci.pTessellationState = &tci;
815       tci.pNext = &tdci;
816       tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
817       tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
818    }
819 
820    VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
821    uint32_t num_stages = 0;
822    for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
823       if (!(stage_mask & BITFIELD_BIT(i)))
824          continue;
825 
826       VkPipelineShaderStageCreateInfo stage = {0};
827       stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
828       stage.stage = mesa_to_vk_shader_stage(i);
829       stage.module = objs[i].mod;
830       stage.pName = "main";
831       shader_stages[num_stages++] = stage;
832    }
833    assert(num_stages > 0);
834 
835    pci.pStages = shader_stages;
836    pci.stageCount = num_stages;
837    /* Only keep LTO information for full pipeline libs.  For separable shaders, they will only
838    * ever be used with fast linking, and to optimize them a new pipeline lib will be created with full
839    * link time information for the full set of shader stages (rather than linking in these single-stage libs).
840    */
841    if (num_stages > 1)
842       pci.flags |= VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
843 
844    VkPipeline pipeline;
845    VkResult result;
846    VRAM_ALLOC_LOOP(result,
847       VKSCR(CreateGraphicsPipelines)(screen->dev, pipeline_cache, 1, &pci, NULL, &pipeline),
848       if (result != VK_SUCCESS) {
849          mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
850          return VK_NULL_HANDLE;
851       }
852    );
853 
854    return pipeline;
855 }
856 
857 VkPipeline
zink_create_gfx_pipeline_library(struct zink_screen * screen,struct zink_gfx_program * prog)858 zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_program *prog)
859 {
860    u_rwlock_wrlock(&prog->base.pipeline_cache_lock);
861    VkPipeline pipeline = create_gfx_pipeline_library(screen, prog->objs, prog->stages_present, prog->base.layout, prog->base.pipeline_cache);
862    u_rwlock_wrunlock(&prog->base.pipeline_cache_lock);
863    return pipeline;
864 }
865 
866 VkPipeline
zink_create_gfx_pipeline_separate(struct zink_screen * screen,struct zink_shader_object * objs,VkPipelineLayout layout,gl_shader_stage stage)867 zink_create_gfx_pipeline_separate(struct zink_screen *screen, struct zink_shader_object *objs, VkPipelineLayout layout, gl_shader_stage stage)
868 {
869    return create_gfx_pipeline_library(screen, objs, BITFIELD_BIT(stage), layout, VK_NULL_HANDLE);
870 }
871 
872 VkPipeline
zink_create_gfx_pipeline_combined(struct zink_screen * screen,struct zink_gfx_program * prog,VkPipeline input,VkPipeline * library,unsigned libcount,VkPipeline output,bool optimized,bool testonly)873 zink_create_gfx_pipeline_combined(struct zink_screen *screen, struct zink_gfx_program *prog, VkPipeline input, VkPipeline *library, unsigned libcount, VkPipeline output, bool optimized, bool testonly)
874 {
875    VkPipeline libraries[4];
876    VkPipelineLibraryCreateInfoKHR libstate = {0};
877    libstate.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
878    if (input)
879       libraries[libstate.libraryCount++] = input;
880    for (unsigned i = 0; i < libcount; i++)
881       libraries[libstate.libraryCount++] = library[i];
882    if (output)
883       libraries[libstate.libraryCount++] = output;
884    libstate.pLibraries = libraries;
885 
886    VkGraphicsPipelineCreateInfo pci = {0};
887    pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
888    pci.layout = prog->base.layout;
889    if (optimized)
890       pci.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
891    else
892       pci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
893    if (testonly)
894       pci.flags |= VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT;
895    if (zink_descriptor_mode == ZINK_DESCRIPTOR_MODE_DB)
896       pci.flags |= VK_PIPELINE_CREATE_DESCRIPTOR_BUFFER_BIT_EXT;
897    pci.pNext = &libstate;
898 
899    if (!input && !output)
900       pci.flags |= VK_PIPELINE_CREATE_LIBRARY_BIT_KHR;
901 
902    VkPipeline pipeline;
903    u_rwlock_wrlock(&prog->base.pipeline_cache_lock);
904    VkResult result;
905    VRAM_ALLOC_LOOP(result,
906       VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci, NULL, &pipeline),
907       u_rwlock_wrunlock(&prog->base.pipeline_cache_lock);
908       if (result != VK_SUCCESS && result != VK_PIPELINE_COMPILE_REQUIRED) {
909          mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
910          return VK_NULL_HANDLE;
911       }
912    );
913 
914    return pipeline;
915 }
916 
917 
918 /* vertex input pipeline library states with dynamic vertex input: only the topology matters */
919 struct zink_gfx_input_key *
zink_find_or_create_input_dynamic(struct zink_context * ctx,VkPrimitiveTopology vkmode)920 zink_find_or_create_input_dynamic(struct zink_context *ctx, VkPrimitiveTopology vkmode)
921 {
922    uint32_t hash = hash_gfx_input_dynamic(&ctx->gfx_pipeline_state.input);
923    struct set_entry *he = _mesa_set_search_pre_hashed(&ctx->gfx_inputs, hash, &ctx->gfx_pipeline_state.input);
924    if (!he) {
925       struct zink_gfx_input_key *ikey = rzalloc(ctx, struct zink_gfx_input_key);
926       ikey->idx = ctx->gfx_pipeline_state.idx;
927       ikey->pipeline = zink_create_gfx_pipeline_input(zink_screen(ctx->base.screen), &ctx->gfx_pipeline_state, NULL, vkmode);
928       he = _mesa_set_add_pre_hashed(&ctx->gfx_inputs, hash, ikey);
929    }
930    return (struct zink_gfx_input_key *)he->key;
931 }
932 
933 /* vertex input pipeline library states without dynamic vertex input: everything is hashed */
934 struct zink_gfx_input_key *
zink_find_or_create_input(struct zink_context * ctx,VkPrimitiveTopology vkmode)935 zink_find_or_create_input(struct zink_context *ctx, VkPrimitiveTopology vkmode)
936 {
937    uint32_t hash = hash_gfx_input(&ctx->gfx_pipeline_state.input);
938    struct set_entry *he = _mesa_set_search_pre_hashed(&ctx->gfx_inputs, hash, &ctx->gfx_pipeline_state.input);
939    if (!he) {
940       struct zink_gfx_input_key *ikey = rzalloc(ctx, struct zink_gfx_input_key);
941       if (ctx->gfx_pipeline_state.uses_dynamic_stride) {
942          memcpy(ikey, &ctx->gfx_pipeline_state.input, offsetof(struct zink_gfx_input_key, vertex_buffers_enabled_mask));
943          ikey->element_state = ctx->gfx_pipeline_state.element_state;
944       } else {
945          memcpy(ikey, &ctx->gfx_pipeline_state.input, offsetof(struct zink_gfx_input_key, pipeline));
946       }
947       ikey->pipeline = zink_create_gfx_pipeline_input(zink_screen(ctx->base.screen), &ctx->gfx_pipeline_state, ikey->element_state->binding_map, vkmode);
948       he = _mesa_set_add_pre_hashed(&ctx->gfx_inputs, hash, ikey);
949    }
950    return (struct zink_gfx_input_key*)he->key;
951 }
952 
953 /* fragment output pipeline library states with dynamic state3 */
954 struct zink_gfx_output_key *
zink_find_or_create_output_ds3(struct zink_context * ctx)955 zink_find_or_create_output_ds3(struct zink_context *ctx)
956 {
957    uint32_t hash = hash_gfx_output_ds3(&ctx->gfx_pipeline_state);
958    struct set_entry *he = _mesa_set_search_pre_hashed(&ctx->gfx_outputs, hash, &ctx->gfx_pipeline_state);
959    if (!he) {
960       struct zink_gfx_output_key *okey = rzalloc(ctx, struct zink_gfx_output_key);
961       memcpy(okey, &ctx->gfx_pipeline_state, sizeof(uint32_t));
962       okey->pipeline = zink_create_gfx_pipeline_output(zink_screen(ctx->base.screen), &ctx->gfx_pipeline_state);
963       he = _mesa_set_add_pre_hashed(&ctx->gfx_outputs, hash, okey);
964    }
965    return (struct zink_gfx_output_key*)he->key;
966 }
967 
968 /* fragment output pipeline library states without dynamic state3 */
969 struct zink_gfx_output_key *
zink_find_or_create_output(struct zink_context * ctx)970 zink_find_or_create_output(struct zink_context *ctx)
971 {
972    uint32_t hash = hash_gfx_output(&ctx->gfx_pipeline_state);
973    struct set_entry *he = _mesa_set_search_pre_hashed(&ctx->gfx_outputs, hash, &ctx->gfx_pipeline_state);
974    if (!he) {
975       struct zink_gfx_output_key *okey = rzalloc(ctx, struct zink_gfx_output_key);
976       memcpy(okey, &ctx->gfx_pipeline_state, offsetof(struct zink_gfx_output_key, pipeline));
977       okey->pipeline = zink_create_gfx_pipeline_output(zink_screen(ctx->base.screen), &ctx->gfx_pipeline_state);
978       he = _mesa_set_add_pre_hashed(&ctx->gfx_outputs, hash, okey);
979    }
980    return (struct zink_gfx_output_key*)he->key;
981 }
982