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