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 "zink_context.h"
30 #include "zink_program.h"
31 #include "zink_render_pass.h"
32 #include "zink_screen.h"
33 #include "zink_state.h"
34
35 #include "util/u_debug.h"
36 #include "util/u_prim.h"
37
38 static VkBlendFactor
clamp_void_blend_factor(VkBlendFactor f)39 clamp_void_blend_factor(VkBlendFactor f)
40 {
41 if (f == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA)
42 return VK_BLEND_FACTOR_ZERO;
43 if (f == VK_BLEND_FACTOR_DST_ALPHA)
44 return VK_BLEND_FACTOR_ONE;
45 return f;
46 }
47
48 VkPipeline
zink_create_gfx_pipeline(struct zink_screen * screen,struct zink_gfx_program * prog,struct zink_gfx_pipeline_state * state,const uint8_t * binding_map,VkPrimitiveTopology primitive_topology)49 zink_create_gfx_pipeline(struct zink_screen *screen,
50 struct zink_gfx_program *prog,
51 struct zink_gfx_pipeline_state *state,
52 const uint8_t *binding_map,
53 VkPrimitiveTopology primitive_topology)
54 {
55 struct zink_rasterizer_hw_state *hw_rast_state = (void*)state;
56 VkPipelineVertexInputStateCreateInfo vertex_input_state;
57 if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs) {
58 memset(&vertex_input_state, 0, sizeof(vertex_input_state));
59 vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
60 vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
61 vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
62 vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
63 vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
64 if (!screen->info.have_EXT_extended_dynamic_state) {
65 for (int i = 0; i < state->element_state->num_bindings; ++i) {
66 const unsigned buffer_id = binding_map[i];
67 VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
68 binding->stride = state->vertex_strides[buffer_id];
69 }
70 }
71 }
72
73 VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
74 if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
75 memset(&vdiv_state, 0, sizeof(vdiv_state));
76 vertex_input_state.pNext = &vdiv_state;
77 vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
78 vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
79 vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
80 }
81
82 VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
83 primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
84 primitive_state.topology = primitive_topology;
85 if (!screen->info.have_EXT_extended_dynamic_state2) {
86 switch (primitive_topology) {
87 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
88 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
89 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
90 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
91 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
92 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
93 if (state->dyn_state2.primitive_restart)
94 debug_printf("restart_index set with unsupported primitive topology %u\n", primitive_topology);
95 primitive_state.primitiveRestartEnable = VK_FALSE;
96 break;
97 default:
98 primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
99 }
100 }
101
102 VkPipelineColorBlendAttachmentState blend_att[PIPE_MAX_COLOR_BUFS];
103 VkPipelineColorBlendStateCreateInfo blend_state = {0};
104 blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
105 if (state->blend_state) {
106 unsigned num_attachments = state->render_pass->state.num_rts;
107 if (state->render_pass->state.have_zsbuf)
108 num_attachments--;
109 if (state->void_alpha_attachments) {
110 for (unsigned i = 0; i < num_attachments; i++) {
111 blend_att[i] = state->blend_state->attachments[i];
112 if (state->void_alpha_attachments & BITFIELD_BIT(i)) {
113 blend_att[i].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
114 blend_att[i].srcColorBlendFactor = clamp_void_blend_factor(blend_att[i].srcColorBlendFactor);
115 blend_att[i].dstColorBlendFactor = clamp_void_blend_factor(blend_att[i].dstColorBlendFactor);
116 }
117 }
118 blend_state.pAttachments = blend_att;
119 } else
120 blend_state.pAttachments = state->blend_state->attachments;
121 blend_state.attachmentCount = num_attachments;
122 blend_state.logicOpEnable = state->blend_state->logicop_enable;
123 blend_state.logicOp = state->blend_state->logicop_func;
124 }
125
126 VkPipelineMultisampleStateCreateInfo ms_state = {0};
127 ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
128 ms_state.rasterizationSamples = state->rast_samples + 1;
129 if (state->blend_state) {
130 ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
131 if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne)
132 warn_missing_feature("alphaToOne");
133 ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
134 }
135 /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
136 * - Chapter 27. Rasterization
137 *
138 * thus it never makes sense to leave this as NULL since gallium will provide correct
139 * data here as long as sample_mask is initialized on context creation
140 */
141 ms_state.pSampleMask = &state->sample_mask;
142 if (hw_rast_state->force_persample_interp) {
143 ms_state.sampleShadingEnable = VK_TRUE;
144 ms_state.minSampleShading = 1.0;
145 }
146
147 VkPipelineViewportStateCreateInfo viewport_state = {0};
148 VkPipelineViewportDepthClipControlCreateInfoEXT clip = {
149 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
150 NULL,
151 VK_TRUE
152 };
153 viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
154 viewport_state.viewportCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
155 viewport_state.pViewports = NULL;
156 viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
157 viewport_state.pScissors = NULL;
158 if (!screen->driver_workarounds.depth_clip_control_missing && !hw_rast_state->clip_halfz)
159 viewport_state.pNext = &clip;
160
161 VkPipelineRasterizationStateCreateInfo rast_state = {0};
162 rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
163
164 rast_state.depthClampEnable = hw_rast_state->depth_clamp;
165 rast_state.rasterizerDiscardEnable = state->dyn_state2.rasterizer_discard;
166 rast_state.polygonMode = hw_rast_state->polygon_mode;
167 rast_state.cullMode = hw_rast_state->cull_mode;
168 rast_state.frontFace = state->dyn_state1.front_face;
169
170 rast_state.depthBiasEnable = VK_TRUE;
171 rast_state.depthBiasConstantFactor = 0.0;
172 rast_state.depthBiasClamp = 0.0;
173 rast_state.depthBiasSlopeFactor = 0.0;
174 rast_state.lineWidth = 1.0f;
175
176 VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state;
177 pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
178 pv_state.provokingVertexMode = hw_rast_state->pv_last ?
179 VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
180 VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
181 if (screen->info.have_EXT_provoking_vertex && hw_rast_state->pv_last) {
182 pv_state.pNext = rast_state.pNext;
183 rast_state.pNext = &pv_state;
184 }
185
186 VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
187 depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
188 depth_stencil_state.depthTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_test;
189 depth_stencil_state.depthCompareOp = state->dyn_state1.depth_stencil_alpha_state->depth_compare_op;
190 depth_stencil_state.depthBoundsTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_bounds_test;
191 depth_stencil_state.minDepthBounds = state->dyn_state1.depth_stencil_alpha_state->min_depth_bounds;
192 depth_stencil_state.maxDepthBounds = state->dyn_state1.depth_stencil_alpha_state->max_depth_bounds;
193 depth_stencil_state.stencilTestEnable = state->dyn_state1.depth_stencil_alpha_state->stencil_test;
194 depth_stencil_state.front = state->dyn_state1.depth_stencil_alpha_state->stencil_front;
195 depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back;
196 depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write;
197
198 VkDynamicState dynamicStateEnables[30] = {
199 VK_DYNAMIC_STATE_LINE_WIDTH,
200 VK_DYNAMIC_STATE_DEPTH_BIAS,
201 VK_DYNAMIC_STATE_BLEND_CONSTANTS,
202 VK_DYNAMIC_STATE_STENCIL_REFERENCE,
203 };
204 unsigned state_count = 4;
205 if (screen->info.have_EXT_extended_dynamic_state) {
206 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT;
207 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT;
208 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
209 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT;
210 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT;
211 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT;
212 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT;
213 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
214 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
215 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP_EXT;
216 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT;
217 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT;
218 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT;
219 if (state->sample_locations_enabled)
220 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
221 } else {
222 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT;
223 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR;
224 }
225 if (state->element_state->num_attribs) {
226 if (screen->info.have_EXT_vertex_input_dynamic_state)
227 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
228 else if (screen->info.have_EXT_extended_dynamic_state)
229 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
230 }
231 if (screen->info.have_EXT_extended_dynamic_state2) {
232 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT;
233 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT;
234 }
235 if (!screen->driver_workarounds.color_write_missing)
236 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
237
238 VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
239 if (screen->info.have_EXT_line_rasterization) {
240 rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
241 rast_line_state.pNext = rast_state.pNext;
242 rast_line_state.stippledLineEnable = VK_FALSE;
243 rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
244
245 if (hw_rast_state->line_stipple_enable) {
246 dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
247 rast_line_state.stippledLineEnable = VK_TRUE;
248 }
249 rast_state.pNext = &rast_line_state;
250 }
251 assert(state_count < ARRAY_SIZE(dynamicStateEnables));
252
253 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
254 pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
255 pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
256 pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
257
258 VkGraphicsPipelineCreateInfo pci = {0};
259 pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
260 pci.layout = prog->base.layout;
261 pci.renderPass = state->render_pass->render_pass;
262 if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs)
263 pci.pVertexInputState = &vertex_input_state;
264 pci.pInputAssemblyState = &primitive_state;
265 pci.pRasterizationState = &rast_state;
266 pci.pColorBlendState = &blend_state;
267 pci.pMultisampleState = &ms_state;
268 pci.pViewportState = &viewport_state;
269 pci.pDepthStencilState = &depth_stencil_state;
270 pci.pDynamicState = &pipelineDynamicStateCreateInfo;
271
272 VkPipelineTessellationStateCreateInfo tci = {0};
273 VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
274 if (prog->shaders[PIPE_SHADER_TESS_CTRL] && prog->shaders[PIPE_SHADER_TESS_EVAL]) {
275 tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
276 tci.patchControlPoints = state->vertices_per_patch + 1;
277 pci.pTessellationState = &tci;
278 tci.pNext = &tdci;
279 tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
280 tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
281 }
282
283 VkPipelineShaderStageCreateInfo shader_stages[ZINK_SHADER_COUNT];
284 uint32_t num_stages = 0;
285 for (int i = 0; i < ZINK_SHADER_COUNT; ++i) {
286 if (!prog->modules[i])
287 continue;
288
289 VkPipelineShaderStageCreateInfo stage = {0};
290 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
291 stage.stage = zink_shader_stage(i);
292 stage.module = prog->modules[i]->shader;
293 stage.pName = "main";
294 shader_stages[num_stages++] = stage;
295 }
296 assert(num_stages > 0);
297
298 pci.pStages = shader_stages;
299 pci.stageCount = num_stages;
300
301 VkPipeline pipeline;
302 if (vkCreateGraphicsPipelines(screen->dev, prog->base.pipeline_cache, 1, &pci,
303 NULL, &pipeline) != VK_SUCCESS) {
304 mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
305 return VK_NULL_HANDLE;
306 }
307
308 return pipeline;
309 }
310
311 VkPipeline
zink_create_compute_pipeline(struct zink_screen * screen,struct zink_compute_program * comp,struct zink_compute_pipeline_state * state)312 zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
313 {
314 VkComputePipelineCreateInfo pci = {0};
315 pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
316 pci.layout = comp->base.layout;
317
318 VkPipelineShaderStageCreateInfo stage = {0};
319 stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
320 stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
321 stage.module = comp->curr->shader;
322 stage.pName = "main";
323
324 VkSpecializationInfo sinfo = {0};
325 VkSpecializationMapEntry me[3];
326 if (state->use_local_size) {
327 stage.pSpecializationInfo = &sinfo;
328 sinfo.mapEntryCount = 3;
329 sinfo.pMapEntries = &me[0];
330 sinfo.dataSize = sizeof(state->local_size);
331 sinfo.pData = &state->local_size[0];
332 uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
333 for (int i = 0; i < 3; i++) {
334 me[i].size = sizeof(uint32_t);
335 me[i].constantID = ids[i];
336 me[i].offset = i * sizeof(uint32_t);
337 }
338 }
339
340 pci.stage = stage;
341
342 VkPipeline pipeline;
343 if (vkCreateComputePipelines(screen->dev, comp->base.pipeline_cache, 1, &pci,
344 NULL, &pipeline) != VK_SUCCESS) {
345 mesa_loge("ZINK: vkCreateComputePipelines failed");
346 return VK_NULL_HANDLE;
347 }
348 zink_screen_update_pipeline_cache(screen, &comp->base);
349
350 return pipeline;
351 }
352