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