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