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 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
260 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
261 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
265 if (screen->info.have_EXT_color_write_enable)
266 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
268 assert(state->rast_prim != PIPE_PRIM_MAX);
270 VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
271 if (screen->info.have_EXT_line_rasterization) {
272 rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
273 rast_line_state.pNext = rast_state.pNext;
274 rast_line_state.stippledLineEnable = VK_FALSE;
275 rast_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
277 if (state->rast_prim == PIPE_PRIM_LINES) {
278 const char *features[4][2] = {
279 [VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT] = {"",""},
280 [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT] = {"rectangularLines", "stippledRectangularLines"},
281 [VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT] = {"bresenhamLines", "stippledBresenhamLines"},
282 [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT] = {"smoothLines", "stippledSmoothLines"},
284 static bool warned[6] = {0};
285 const VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats = &screen->info.line_rast_feats;
286 /* line features can be represented as an array VkBool32[6],
287 * with the 3 base features preceding the 3 (matching) stippled features
289 const VkBool32 *feat = &line_feats->rectangularLines;
290 unsigned mode_idx = hw_rast_state->line_mode - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
291 /* add base mode index, add 3 if stippling is enabled */
292 mode_idx += hw_rast_state->line_stipple_enable * 3;
293 if (*(feat + mode_idx))
294 rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
296 warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]);
299 if (hw_rast_state->line_stipple_enable) {
300 if (!screen->info.have_EXT_extended_dynamic_state3)
301 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
302 rast_line_state.stippledLineEnable = VK_TRUE;
305 rast_state.pNext = &rast_line_state;
307 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
309 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
310 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
311 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
312 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
314 VkGraphicsPipelineCreateInfo pci = {0};
315 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
316 static bool feedback_warn = false;
318 pci.flags |= VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
319 if (state->feedback_loop) {
320 if (screen->info.have_EXT_attachment_feedback_loop_layout)
321 pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
323 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
325 if (state->feedback_loop_zs) {
326 if (screen->info.have_EXT_attachment_feedback_loop_layout)
327 pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
329 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
331 pci.layout = prog->base.layout;
332 if (state->render_pass)
333 pci.renderPass = state->render_pass->render_pass;
335 pci.pNext = &state->rendering_info;
336 if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride)
337 pci.pVertexInputState = &vertex_input_state;
338 pci.pInputAssemblyState = &primitive_state;
339 pci.pRasterizationState = &rast_state;
340 pci.pColorBlendState = &blend_state;
341 pci.pMultisampleState = &ms_state;
342 pci.pViewportState = &viewport_state;
343 pci.pDepthStencilState = &depth_stencil_state;
344 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
346 VkPipelineTessellationStateCreateInfo tci = {0};
347 VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
348 if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
349 tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
350 tci.patchControlPoints = state->dyn_state2.vertices_per_patch;
351 pci.pTessellationState = &tci;
353 tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
354 tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
357 VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
358 uint32_t num_stages = 0;
359 for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
360 if (!prog->modules[i])
363 VkPipelineShaderStageCreateInfo stage = {0};
364 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
365 stage.stage = mesa_to_vk_shader_stage(i);
366 stage.module = prog->modules[i];
367 stage.pName = "main";
368 shader_stages[num_stages++] = stage;
370 assert(num_stages > 0);
372 pci.pStages = shader_stages;
373 pci.stageCount = num_stages;
376 VkResult result = VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache,
377 1, &pci, NULL, &pipeline);
378 if (result != VK_SUCCESS) {
379 mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
380 return VK_NULL_HANDLE;
387 zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
389 VkComputePipelineCreateInfo pci = {0};
390 pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
391 pci.layout = comp->base.layout;
393 VkPipelineShaderStageCreateInfo stage = {0};
394 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
395 stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
396 stage.module = comp->curr->shader;
397 stage.pName = "main";
399 VkSpecializationInfo sinfo = {0};
400 VkSpecializationMapEntry me[3];
401 if (comp->use_local_size) {
402 stage.pSpecializationInfo = &sinfo;
403 sinfo.mapEntryCount = 3;
404 sinfo.pMapEntries = &me[0];
405 sinfo.dataSize = sizeof(state->local_size);
406 sinfo.pData = &state->local_size[0];
407 uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
408 for (int i = 0; i < 3; i++) {
409 me[i].size = sizeof(uint32_t);
410 me[i].constantID = ids[i];
411 me[i].offset = i * sizeof(uint32_t);
418 VkResult result = VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache,
419 1, &pci, NULL, &pipeline);
420 if (result != VK_SUCCESS) {
421 mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result));
422 return VK_NULL_HANDLE;
429 zink_create_gfx_pipeline_output(struct zink_screen *screen, struct zink_gfx_pipeline_state *state)
431 VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
432 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
433 &state->rendering_info,
434 VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_OUTPUT_INTERFACE_BIT_EXT,
437 VkPipelineColorBlendStateCreateInfo blend_state = {0};
438 blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
439 if (state->rast_attachment_order)
440 blend_state.flags |= VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_EXT;
441 blend_state.attachmentCount = state->rendering_info.colorAttachmentCount;
442 if (state->blend_state)
443 blend_state.logicOp = state->blend_state->logicop_func;
445 VkPipelineMultisampleStateCreateInfo ms_state = {0};
446 ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
447 if (state->force_persample_interp) {
448 ms_state.sampleShadingEnable = VK_TRUE;
449 ms_state.minSampleShading = 1.0;
450 } else if (state->min_samples > 0) {
451 ms_state.sampleShadingEnable = VK_TRUE;
452 ms_state.minSampleShading = (float)(state->rast_samples + 1) / (state->min_samples + 1);
455 VkDynamicState dynamicStateEnables[30] = {
456 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
458 unsigned state_count = 1;
459 if (screen->info.have_EXT_extended_dynamic_state) {
460 if (state->sample_locations_enabled)
461 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
463 if (screen->info.have_EXT_color_write_enable)
464 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
466 if (screen->have_full_ds3) {
467 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_MASK_EXT;
468 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZATION_SAMPLES_EXT;
469 if (state->blend_state) {
470 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_EXT;
471 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LOGIC_OP_ENABLE_EXT;
472 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_COVERAGE_ENABLE_EXT;
473 if (screen->info.feats.features.alphaToOne)
474 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_ALPHA_TO_ONE_ENABLE_EXT;
475 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_ENABLE_EXT;
476 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_BLEND_EQUATION_EXT;
477 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_MASK_EXT;
480 if (state->blend_state) {
481 unsigned num_attachments = state->render_pass ?
482 state->render_pass->state.num_rts :
483 state->rendering_info.colorAttachmentCount;
484 if (state->render_pass && state->render_pass->state.have_zsbuf)
486 blend_state.pAttachments = state->blend_state->attachments;
487 blend_state.attachmentCount = num_attachments;
488 blend_state.logicOpEnable = state->blend_state->logicop_enable;
489 blend_state.logicOp = state->blend_state->logicop_func;
491 ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
492 if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
493 static bool warned = false;
494 warn_missing_feature(warned, "alphaToOne");
496 ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
498 ms_state.rasterizationSamples = state->rast_samples + 1;
499 /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
500 * - Chapter 27. Rasterization
502 * thus it never makes sense to leave this as NULL since gallium will provide correct
503 * data here as long as sample_mask is initialized on context creation
505 ms_state.pSampleMask = &state->sample_mask;
507 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
509 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
510 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
511 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
512 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
514 VkGraphicsPipelineCreateInfo pci = {0};
515 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
517 pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
518 static bool feedback_warn = false;
519 if (state->feedback_loop) {
520 if (screen->info.have_EXT_attachment_feedback_loop_layout)
521 pci.flags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
523 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
525 if (state->feedback_loop_zs) {
526 if (screen->info.have_EXT_attachment_feedback_loop_layout)
527 pci.flags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
529 warn_missing_feature(feedback_warn, "EXT_attachment_feedback_loop_layout");
531 pci.pColorBlendState = &blend_state;
532 pci.pMultisampleState = &ms_state;
533 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
536 if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
537 NULL, &pipeline) != VK_SUCCESS) {
538 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
539 return VK_NULL_HANDLE;
546 zink_create_gfx_pipeline_input(struct zink_screen *screen,
547 struct zink_gfx_pipeline_state *state,
548 const uint8_t *binding_map,
549 VkPrimitiveTopology primitive_topology)
551 VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
552 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
554 VK_GRAPHICS_PIPELINE_LIBRARY_VERTEX_INPUT_INTERFACE_BIT_EXT
557 VkPipelineVertexInputStateCreateInfo vertex_input_state;
558 memset(&vertex_input_state, 0, sizeof(vertex_input_state));
559 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
560 if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->uses_dynamic_stride) {
561 vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
562 vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
563 vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
564 vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
565 if (!state->uses_dynamic_stride) {
566 for (int i = 0; i < state->element_state->num_bindings; ++i) {
567 const unsigned buffer_id = binding_map[i];
568 VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
569 binding->stride = state->vertex_strides[buffer_id];
574 VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
575 if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
576 memset(&vdiv_state, 0, sizeof(vdiv_state));
577 vertex_input_state.pNext = &vdiv_state;
578 vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
579 vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
580 vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
583 VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
584 primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
585 primitive_state.topology = primitive_topology;
586 assert(screen->info.have_EXT_extended_dynamic_state2);
588 VkDynamicState dynamicStateEnables[30];
589 unsigned state_count = 0;
590 if (screen->info.have_EXT_vertex_input_dynamic_state)
591 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
592 else if (state->uses_dynamic_stride && state->element_state->num_attribs)
593 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
594 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
595 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
596 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
598 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
599 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
600 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
601 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
603 VkGraphicsPipelineCreateInfo pci = {0};
604 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
606 pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
607 pci.pVertexInputState = &vertex_input_state;
608 pci.pInputAssemblyState = &primitive_state;
609 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
612 if (VKSCR(CreateGraphicsPipelines)(screen->dev, VK_NULL_HANDLE, 1, &pci,
613 NULL, &pipeline) != VK_SUCCESS) {
614 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
615 return VK_NULL_HANDLE;
622 zink_create_gfx_pipeline_library(struct zink_screen *screen, struct zink_gfx_program *prog)
624 assert(screen->info.have_EXT_extended_dynamic_state && screen->info.have_EXT_extended_dynamic_state2);
625 VkPipelineRenderingCreateInfo rendering_info;
626 rendering_info.sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO;
627 rendering_info.pNext = NULL;
628 rendering_info.viewMask = 0;
629 VkGraphicsPipelineLibraryCreateInfoEXT gplci = {
630 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_LIBRARY_CREATE_INFO_EXT,
632 VK_GRAPHICS_PIPELINE_LIBRARY_PRE_RASTERIZATION_SHADERS_BIT_EXT | VK_GRAPHICS_PIPELINE_LIBRARY_FRAGMENT_SHADER_BIT_EXT
635 VkPipelineViewportStateCreateInfo viewport_state = {0};
636 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
637 viewport_state.viewportCount = 0;
638 viewport_state.pViewports = NULL;
639 viewport_state.scissorCount = 0;
640 viewport_state.pScissors = NULL;
642 VkPipelineRasterizationStateCreateInfo rast_state = {0};
643 rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
644 rast_state.depthBiasEnable = VK_TRUE;
646 VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
647 depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
649 VkDynamicState dynamicStateEnables[64] = {
650 VK_DYNAMIC_STATE_LINE_WIDTH,
651 VK_DYNAMIC_STATE_DEPTH_BIAS,
652 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
654 unsigned state_count = 3;
655 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
656 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
657 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
658 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
659 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
660 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
661 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
662 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
663 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
664 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
665 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
666 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
667 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
668 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
669 if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
670 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
672 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLAMP_ENABLE_EXT;
673 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_ENABLE_EXT;
674 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_POLYGON_MODE_EXT;
675 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PROVOKING_VERTEX_MODE_EXT;
676 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_CLIP_NEGATIVE_ONE_TO_ONE_EXT;
677 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_RASTERIZATION_MODE_EXT;
678 if (screen->info.dynamic_state3_feats.extendedDynamicState3LineStippleEnable)
679 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_ENABLE_EXT;
680 if (screen->info.have_EXT_line_rasterization)
681 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
682 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
684 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
685 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
686 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
687 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
689 VkGraphicsPipelineCreateInfo pci = {0};
690 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
692 pci.flags = VK_PIPELINE_CREATE_LIBRARY_BIT_KHR | VK_PIPELINE_CREATE_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT;
693 pci.layout = prog->base.layout;
694 pci.pRasterizationState = &rast_state;
695 pci.pViewportState = &viewport_state;
696 pci.pDepthStencilState = &depth_stencil_state;
697 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
699 VkPipelineTessellationStateCreateInfo tci = {0};
700 VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
701 if (prog->modules[MESA_SHADER_TESS_CTRL] && prog->modules[MESA_SHADER_TESS_EVAL]) {
702 tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
703 //this is a wild guess; pray for extendedDynamicState2PatchControlPoints
704 if (!screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints) {
705 static bool warned = false;
706 warn_missing_feature(warned, "extendedDynamicState2PatchControlPoints");
708 tci.patchControlPoints = 32;
709 pci.pTessellationState = &tci;
711 tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
712 tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
715 VkPipelineShaderStageCreateInfo shader_stages[ZINK_GFX_SHADER_COUNT];
716 uint32_t num_stages = 0;
717 for (int i = 0; i < ZINK_GFX_SHADER_COUNT; ++i) {
718 if (!prog->modules[i])
721 VkPipelineShaderStageCreateInfo stage = {0};
722 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
723 stage.stage = mesa_to_vk_shader_stage(i);
724 stage.module = prog->modules[i];
725 stage.pName = "main";
726 shader_stages[num_stages++] = stage;
728 assert(num_stages > 0);
730 pci.pStages = shader_stages;
731 pci.stageCount = num_stages;
734 if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
735 NULL, &pipeline) != VK_SUCCESS) {
736 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
737 return VK_NULL_HANDLE;
744 zink_create_gfx_pipeline_combined(struct zink_screen *screen, struct zink_gfx_program *prog, VkPipeline input, VkPipeline library, VkPipeline output, bool optimized)
746 VkPipeline libraries[] = {input, library, output};
747 VkPipelineLibraryCreateInfoKHR libstate = {0};
748 libstate.sType = VK_STRUCTURE_TYPE_PIPELINE_LIBRARY_CREATE_INFO_KHR;
749 libstate.libraryCount = 3;
750 libstate.pLibraries = libraries;
752 VkGraphicsPipelineCreateInfo pci = {0};
753 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
755 pci.flags = VK_PIPELINE_CREATE_LINK_TIME_OPTIMIZATION_BIT_EXT;
757 pci.flags = VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT;
758 pci.pNext = &libstate;
761 if (VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache, 1, &pci,
762 NULL, &pipeline) != VK_SUCCESS) {
763 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
764 return VK_NULL_HANDLE;