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