2 * Copyright 2018 Collabora Ltd.
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:
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
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.
24 #include "compiler/spirv/spirv.h"
26 #include "zink_pipeline.h"
28 #include "zink_compiler.h"
29 #include "zink_context.h"
30 #include "zink_program.h"
31 #include "zink_render_pass.h"
32 #include "zink_screen.h"
33 #include "zink_state.h"
35 #include "util/u_debug.h"
36 #include "util/u_prim.h"
39 zink_create_gfx_pipeline(struct zink_screen *screen,
40 struct zink_gfx_program *prog,
41 struct zink_gfx_pipeline_state *state,
42 const uint8_t *binding_map,
43 VkPrimitiveTopology primitive_topology,
46 struct zink_rasterizer_hw_state *hw_rast_state = (void*)&state->dyn_state3;
47 VkPipelineVertexInputStateCreateInfo vertex_input_state;
48 if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride) {
49 memset(&vertex_input_state, 0, sizeof(vertex_input_state));
50 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
51 vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
52 vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
53 vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
54 vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
55 if (!screen->info.have_EXT_extended_dynamic_state || !state->uses_dynamic_stride) {
56 for (int i = 0; i < state->element_state->num_bindings; ++i) {
57 const unsigned buffer_id = binding_map[i];
58 VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
59 binding->stride = state->vertex_strides[buffer_id];
64 VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
65 if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
66 memset(&vdiv_state, 0, sizeof(vdiv_state));
67 vertex_input_state.pNext = &vdiv_state;
68 vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
69 vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
70 vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
73 VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
74 primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
75 primitive_state.topology = primitive_topology;
76 if (!screen->info.have_EXT_extended_dynamic_state2) {
77 switch (primitive_topology) {
78 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
79 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
80 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
81 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
82 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
83 if (screen->info.have_EXT_primitive_topology_list_restart) {
84 primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
88 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
89 if (state->dyn_state2.primitive_restart)
90 mesa_loge("zink: restart_index set with unsupported primitive topology %u\n", primitive_topology);
91 primitive_state.primitiveRestartEnable = VK_FALSE;
94 primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
98 VkPipelineColorBlendStateCreateInfo blend_state = {0};
99 blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
100 if (state->blend_state) {
101 unsigned num_attachments = state->render_pass ?
102 state->render_pass->state.num_rts :
103 state->rendering_info.colorAttachmentCount;
104 if (state->render_pass && state->render_pass->state.have_zsbuf)
106 blend_state.pAttachments = state->blend_state->attachments;
107 blend_state.attachmentCount = num_attachments;
108 blend_state.logicOpEnable = state->blend_state->logicop_enable;
109 blend_state.logicOp = state->blend_state->logicop_func;
111 if (state->rast_attachment_order)
112 blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
114 VkPipelineMultisampleStateCreateInfo ms_state = {0};
115 ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
116 ms_state.rasterizationSamples = state->rast_samples + 1;
117 if (state->blend_state) {
118 ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
119 if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
120 static bool warned = false;
121 warn_missing_feature(warned, "alphaToOne");
123 ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
125 /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
126 * - Chapter 27. Rasterization
128 * thus it never makes sense to leave this as NULL since gallium will provide correct
129 * data here as long as sample_mask is initialized on context creation
131 ms_state.pSampleMask = &state->sample_mask;
132 if (state->force_persample_interp) {
133 ms_state.sampleShadingEnable = VK_TRUE;
134 ms_state.minSampleShading = 1.0;
135 } else if (state->min_samples > 0) {
136 ms_state.sampleShadingEnable = VK_TRUE;
137 ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
140 VkPipelineViewportStateCreateInfo viewport_state = {0};
141 VkPipelineViewportDepthClipControlCreateInfoEXT clip = {
142 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
146 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
147 viewport_state.viewportCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
148 viewport_state.pViewports = NULL;
149 viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
150 viewport_state.pScissors = NULL;
151 if (!screen->driver_workarounds.depth_clip_control_missing && !hw_rast_state->clip_halfz)
152 viewport_state.pNext = &clip;
154 VkPipelineRasterizationStateCreateInfo rast_state = {0};
155 rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
157 rast_state.depthClampEnable = hw_rast_state->depth_clamp;
158 rast_state.rasterizerDiscardEnable = state->dyn_state2.rasterizer_discard;
159 rast_state.polygonMode = hw_rast_state->polygon_mode;
160 rast_state.cullMode = state->dyn_state1.cull_mode;
161 rast_state.frontFace = state->dyn_state1.front_face;
163 rast_state.depthBiasEnable = VK_TRUE;
164 rast_state.depthBiasConstantFactor = 0.0;
165 rast_state.depthBiasClamp = 0.0;
166 rast_state.depthBiasSlopeFactor = 0.0;
167 rast_state.lineWidth = 1.0f;
169 VkPipelineRasterizationDepthClipStateCreateInfoEXT depth_clip_state = {0};
170 depth_clip_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT;
171 depth_clip_state.depthClipEnable = hw_rast_state->depth_clip;
172 if (screen->info.have_EXT_depth_clip_enable) {
173 depth_clip_state.pNext = rast_state.pNext;
174 rast_state.pNext = &depth_clip_state;
176 static bool warned = false;
177 warn_missing_feature(warned, "VK_EXT_depth_clip_enable");
180 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state;
181 pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
182 pv_state.provokingVertexMode = hw_rast_state->pv_last ?
183 VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
184 VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
185 if (screen->info.have_EXT_provoking_vertex && hw_rast_state->pv_last) {
186 pv_state.pNext = rast_state.pNext;
187 rast_state.pNext = &pv_state;
190 VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
191 depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
192 depth_stencil_state.depthTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_test;
193 depth_stencil_state.depthCompareOp = state->dyn_state1.depth_stencil_alpha_state->depth_compare_op;
194 depth_stencil_state.depthBoundsTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_bounds_test;
195 depth_stencil_state.minDepthBounds = state->dyn_state1.depth_stencil_alpha_state->min_depth_bounds;
196 depth_stencil_state.maxDepthBounds = state->dyn_state1.depth_stencil_alpha_state->max_depth_bounds;
197 depth_stencil_state.stencilTestEnable = state->dyn_state1.depth_stencil_alpha_state->stencil_test;
198 depth_stencil_state.front = state->dyn_state1.depth_stencil_alpha_state->stencil_front;
199 depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back;
200 depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write;
202 VkDynamicState dynamicStateEnables[80] = {
203 VK_DYNAMIC_STATE_LINE_WIDTH,
204 VK_DYNAMIC_STATE_DEPTH_BIAS,
205 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
206 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
208 unsigned state_count = 4;
209 if (screen->info.have_EXT_extended_dynamic_state) {
210 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
211 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
212 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
213 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
214 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
215 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
216 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
217 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
218 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
219 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
220 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
221 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
222 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
223 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
224 if (state->sample_locations_enabled)
225 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
227 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT;
228 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR;
230 if (screen->info.have_EXT_vertex_input_dynamic_state)
231 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
232 else if (screen->info.have_EXT_extended_dynamic_state && state->uses_dynamic_stride && state->element_state->num_attribs)
233 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE;
234 if (screen->info.have_EXT_extended_dynamic_state2) {
235 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
236 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
237 if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
238 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
240 if (screen->info.have_EXT_extended_dynamic_state3) {
241 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
242 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
243 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
244 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
245 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
246 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
247 if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
248 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
249 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
250 if (screen->have_full_ds3) {
251 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
252 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
253 if (state->blend_state) {
254 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
255 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
256 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
257 if (screen->info.feats.features.alphaToOne)
258 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
259 if (state->rendering_info.colorAttachmentCount) {
260 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
261 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
262 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
267 if (screen->info.have_EXT_color_write_enable)
268 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
270 assert(state->rast_prim != PIPE_PRIM_MAX);
272 VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
273 if (screen->info.have_EXT_line_rasterization) {
274 rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
275 rast_line_state.pNext = rast_state.pNext;
276 rast_line_state.stippledLineEnable = VK_FALSE;
277 rast_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
279 if (state->rast_prim == PIPE_PRIM_LINES) {
280 const char *features[4][2] = {
281 [VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT] = {"",""},
282 [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT] = {"rectangularLines", "stippledRectangularLines"},
283 [VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT] = {"bresenhamLines", "stippledBresenhamLines"},
284 [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT] = {"smoothLines", "stippledSmoothLines"},
286 static bool warned[6] = {0};
287 const VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats = &screen->info.line_rast_feats;
288 /* line features can be represented as an array VkBool32[6],
289 * with the 3 base features preceding the 3 (matching) stippled features
291 const VkBool32 *feat = &line_feats->rectangularLines;
292 unsigned mode_idx = hw_rast_state->line_mode - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
293 /* add base mode index, add 3 if stippling is enabled */
294 mode_idx += hw_rast_state->line_stipple_enable * 3;
295 if (*(feat + mode_idx))
296 rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
298 warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]);
301 if (hw_rast_state->line_stipple_enable) {
302 if (!screen->info.have_EXT_extended_dynamic_state3)
303 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
304 rast_line_state.stippledLineEnable = VK_TRUE;
307 rast_state.pNext = &rast_line_state;
309 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
311 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
312 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
313 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
314 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
316 VkGraphicsPipelineCreateInfo pci = {0};
317 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
318 static bool feedback_warn = false;
320 pci.flags |= VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
321 if (state->feedback_loop) {
322 if (screen->info.have_EXT_attachment_feedback_loop_layout)
323 pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
325 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
327 if (state->feedback_loop_zs) {
328 if (screen->info.have_EXT_attachment_feedback_loop_layout)
329 pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
331 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
333 pci.layout = prog->base.layout;
334 if (state->render_pass)
335 pci.renderPass = state->render_pass->render_pass;
337 pci.pNext = &state->rendering_info;
338 if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride)
339 pci.pVertexInputState = &vertex_input_state;
340 pci.pInputAssemblyState = &primitive_state;
341 pci.pRasterizationState = &rast_state;
342 pci.pColorBlendState = &blend_state;
343 pci.pMultisampleState = &ms_state;
344 pci.pViewportState = &viewport_state;
345 pci.pDepthStencilState = &depth_stencil_state;
346 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
348 VkPipelineTessellationStateCreateInfo tci = {0};
349 VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
350 if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
351 tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
352 tci.patchControlPoints = state->dyn_state2.vertices_per_patch;
353 pci.pTessellationState = &tci;
355 tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
356 tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
359 VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
360 uint32_t num_stages = 0;
361 for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
362 if (!prog->modules[i])
365 VkPipelineShaderStageCreateInfo stage = {0};
366 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
367 stage.stage = mesa_to_vk_shader_stage(i);
368 stage.module = prog->modules[i];
369 stage.pName = "main";
370 shader_stages[num_stages++] = stage;
372 assert(num_stages > 0);
374 pci.pStages = shader_stages;
375 pci.stageCount = num_stages;
378 VkResult result = VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache,
379 1, &pci, NULL, &pipeline);
380 if (result != VK_SUCCESS) {
381 mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
382 return VK_NULL_HANDLE;
389 zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
391 VkComputePipelineCreateInfo pci = {0};
392 pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
393 pci.layout = comp->base.layout;
395 VkPipelineShaderStageCreateInfo stage = {0};
396 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
397 stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
398 stage.module = comp->curr->shader;
399 stage.pName = "main";
401 VkSpecializationInfo sinfo = {0};
402 VkSpecializationMapEntry me[3];
403 if (comp->use_local_size) {
404 stage.pSpecializationInfo = &sinfo;
405 sinfo.mapEntryCount = 3;
406 sinfo.pMapEntries = &me[0];
407 sinfo.dataSize = sizeof(state->local_size);
408 sinfo.pData = &state->local_size[0];
409 uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
410 for (int i = 0; i < 3; i++) {
411 me[i].size = sizeof(uint32_t);
412 me[i].constantID = ids[i];
413 me[i].offset = i * sizeof(uint32_t);
420 VkResult result = VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache,
421 1, &pci, NULL, &pipeline);
422 if (result != VK_SUCCESS) {
423 mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result));
424 return VK_NULL_HANDLE;
431 zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipeline_state *state)
433 VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
434 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
435 &state->rendering_info,
436 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT,
439 VkPipelineColorBlendStateCreateInfo blend_state = {0};
440 blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
441 if (state->rast_attachment_order)
442 blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
443 blend_state.attachmentCount = state->rendering_info.colorAttachmentCount;
444 if (state->blend_state)
445 blend_state.logicOp = state->blend_state->logicop_func;
447 VkPipelineMultisampleStateCreateInfo ms_state = {0};
448 ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
449 if (state->force_persample_interp) {
450 ms_state.sampleShadingEnable = VK_TRUE;
451 ms_state.minSampleShading = 1.0;
452 } else if (state->min_samples > 0) {
453 ms_state.sampleShadingEnable = VK_TRUE;
454 ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
457 VkDynamicState dynamicStateEnables[30] = {
458 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
460 unsigned state_count = 1;
461 if (screen->info.have_EXT_extended_dynamic_state) {
462 if (state->sample_locations_enabled)
463 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
465 if (screen->info.have_EXT_color_write_enable)
466 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
468 if (screen->have_full_ds3) {
469 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
470 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
471 if (state->blend_state) {
472 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
473 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
474 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
475 if (screen->info.feats.features.alphaToOne)
476 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
477 if (state->rendering_info.colorAttachmentCount) {
478 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
479 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
480 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
484 if (state->blend_state) {
485 unsigned num_attachments = state->render_pass ?
486 state->render_pass->state.num_rts :
487 state->rendering_info.colorAttachmentCount;
488 if (state->render_pass && state->render_pass->state.have_zsbuf)
490 blend_state.pAttachments = state->blend_state->attachments;
491 blend_state.attachmentCount = num_attachments;
492 blend_state.logicOpEnable = state->blend_state->logicop_enable;
493 blend_state.logicOp = state->blend_state->logicop_func;
495 ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
496 if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
497 static bool warned = false;
498 warn_missing_feature(warned, "alphaToOne");
500 ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
502 ms_state.rasterizationSamples = state->rast_samples + 1;
503 /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
504 * - Chapter 27. Rasterization
506 * thus it never makes sense to leave this as NULL since gallium will provide correct
507 * data here as long as sample_mask is initialized on context creation
509 ms_state.pSampleMask = &state->sample_mask;
511 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
513 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
514 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
515 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
516 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
518 VkGraphicsPipelineCreateInfo pci = {0};
519 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
521 pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
522 static bool feedback_warn = false;
523 if (state->feedback_loop) {
524 if (screen->info.have_EXT_attachment_feedback_loop_layout)
525 pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
527 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
529 if (state->feedback_loop_zs) {
530 if (screen->info.have_EXT_attachment_feedback_loop_layout)
531 pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
533 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
535 pci.pColorBlendState = &blend_state;
536 pci.pMultisampleState = &ms_state;
537 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
540 if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
541 NULL, &pipeline) != VK_SUCCESS) {
542 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
543 return VK_NULL_HANDLE;
550 zink_create_gfx_pipeline_input(struct zink_screen *screen,
551 struct zink_gfx_pipeline_state *state,
552 const uint8_t *binding_map,
553 VkPrimitiveTopology primitive_topology)
555 VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
556 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
558 VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT
561 VkPipelineVertexInputStateCreateInfo vertex_input_state;
562 memset(&vertex_input_state, 0, sizeof(vertex_input_state));
563 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
564 if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->uses_dynamic_stride) {
565 vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
566 vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
567 vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
568 vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
569 if (!state->uses_dynamic_stride) {
570 for (int i = 0; i < state->element_state->num_bindings; ++i) {
571 const unsigned buffer_id = binding_map[i];
572 VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
573 binding->stride = state->vertex_strides[buffer_id];
578 VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
579 if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
580 memset(&vdiv_state, 0, sizeof(vdiv_state));
581 vertex_input_state.pNext = &vdiv_state;
582 vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
583 vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
584 vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
587 VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
588 primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
589 primitive_state.topology = primitive_topology;
590 assert(screen->info.have_EXT_extended_dynamic_state2);
592 VkDynamicState dynamicStateEnables[30];
593 unsigned state_count = 0;
594 if (screen->info.have_EXT_vertex_input_dynamic_state)
595 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
596 else if (state->uses_dynamic_stride && state->element_state->num_attribs)
597 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
598 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
599 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
600 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
602 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
603 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
604 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
605 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
607 VkGraphicsPipelineCreateInfo pci = {0};
608 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
610 pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
611 pci.pVertexInputState = &vertex_input_state;
612 pci.pInputAssemblyState = &primitive_state;
613 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
616 if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
617 NULL, &pipeline) != VK_SUCCESS) {
618 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
619 return VK_NULL_HANDLE;
626 zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_program *prog)
628 assert(screen->info.have_EXT_extended_dynamic_state && screen->info.have_EXT_extended_dynamic_state2);
629 VkPipelineRenderingCreateInfo rendering_info;
630 rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
631 rendering_info.pNext = NULL;
632 rendering_info.viewMask = 0;
633 VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
634 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
636 VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT
639 VkPipelineViewportStateCreateInfo viewport_state = {0};
640 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
641 viewport_state.viewportCount = 0;
642 viewport_state.pViewports = NULL;
643 viewport_state.scissorCount = 0;
644 viewport_state.pScissors = NULL;
646 VkPipelineRasterizationStateCreateInfo rast_state = {0};
647 rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
648 rast_state.depthBiasEnable = VK_TRUE;
650 VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
651 depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
653 VkDynamicState dynamicStateEnables[64] = {
654 VK_DYNAMIC_STATE_LINE_WIDTH,
655 VK_DYNAMIC_STATE_DEPTH_BIAS,
656 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
658 unsigned state_count = 3;
659 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
660 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
661 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
662 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
663 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
664 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
665 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
666 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
667 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
668 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
669 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
670 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
671 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
672 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
673 if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
674 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
676 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
677 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
678 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
679 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
680 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
681 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
682 if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
683 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
684 if (screen->info.have_EXT_line_rasterization)
685 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
686 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
688 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
689 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
690 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
691 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
693 VkGraphicsPipelineCreateInfo pci = {0};
694 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
696 pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
697 pci.layout = prog->base.layout;
698 pci.pRasterizationState = &rast_state;
699 pci.pViewportState = &viewport_state;
700 pci.pDepthStencilState = &depth_stencil_state;
701 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
703 VkPipelineTessellationStateCreateInfo tci = {0};
704 VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
705 if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
706 tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
707 //this is a wild guess; pray for extendedDynamicState2PatchControlPoints
708 if (!screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) {
709 static bool warned = false;
710 warn_missing_feature(warned, "extendedDynamicState2PatchControlPoints");
712 tci.patchControlPoints = 32;
713 pci.pTessellationState = &tci;
715 tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
716 tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
719 VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
720 uint32_t num_stages = 0;
721 for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
722 if (!prog->modules[i])
725 VkPipelineShaderStageCreateInfo stage = {0};
726 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
727 stage.stage = mesa_to_vk_shader_stage(i);
728 stage.module = prog->modules[i];
729 stage.pName = "main";
730 shader_stages[num_stages++] = stage;
732 assert(num_stages > 0);
734 pci.pStages = shader_stages;
735 pci.stageCount = num_stages;
738 if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
739 NULL, &pipeline) != VK_SUCCESS) {
740 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
741 return VK_NULL_HANDLE;
748 zink_create_gfx_pipeline_combined(struct zink_screen *screen, struct zink_gfx_program *prog, VkPipeline input, VkPipeline library, VkPipeline output, bool optimized)
750 VkPipeline libraries[] = {input, library, output};
751 VkPipelineLibraryCreateInfoKHR libstate = {0};
752 libstate.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
753 libstate.libraryCount = 3;
754 libstate.pLibraries = libraries;
756 VkGraphicsPipelineCreateInfo pci = {0};
757 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
759 pci.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
761 pci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
762 pci.pNext = &libstate;
765 if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
766 NULL, &pipeline) != VK_SUCCESS) {
767 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
768 return VK_NULL_HANDLE;