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