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
clamp_void_blend_factor(VkBlendFactor f)
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;
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)
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];
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;
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_LINE_LIST_WITH_ADJACENCY:
90
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
91
case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
92
if (screen->info.have_EXT_primitive_topology_list_restart) {
93
primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
97
case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
98
if (state->dyn_state2.primitive_restart)
99
mesa_loge("zink: restart_index set with unsupported primitive topology %u\n", primitive_topology);
100
primitive_state.primitiveRestartEnable = VK_FALSE;
103
primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
107
VkPipelineColorBlendAttachmentState blend_att[PIPE_MAX_COLOR_BUFS];
108
VkPipelineColorBlendStateCreateInfo blend_state = {0};
109
blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
110
if (state->blend_state) {
111
unsigned num_attachments = state->render_pass->state.num_rts;
112
if (state->render_pass->state.have_zsbuf)
114
if (state->void_alpha_attachments) {
115
for (unsigned i = 0; i < num_attachments; i++) {
116
blend_att[i] = state->blend_state->attachments[i];
117
if (state->void_alpha_attachments & BITFIELD_BIT(i)) {
118
blend_att[i].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
119
blend_att[i].srcColorBlendFactor = clamp_void_blend_factor(blend_att[i].srcColorBlendFactor);
120
blend_att[i].dstColorBlendFactor = clamp_void_blend_factor(blend_att[i].dstColorBlendFactor);
123
blend_state.pAttachments = blend_att;
125
blend_state.pAttachments = state->blend_state->attachments;
126
blend_state.attachmentCount = num_attachments;
127
blend_state.logicOpEnable = state->blend_state->logicop_enable;
128
blend_state.logicOp = state->blend_state->logicop_func;
131
VkPipelineMultisampleStateCreateInfo ms_state = {0};
132
ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
133
ms_state.rasterizationSamples = state->rast_samples + 1;
134
if (state->blend_state) {
135
ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
136
if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
137
static bool warned = false;
138
warn_missing_feature(warned, "alphaToOne");
140
ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
142
/* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
143
* - Chapter 27. Rasterization
145
* thus it never makes sense to leave this as NULL since gallium will provide correct
146
* data here as long as sample_mask is initialized on context creation
148
ms_state.pSampleMask = &state->sample_mask;
149
if (hw_rast_state->force_persample_interp) {
150
ms_state.sampleShadingEnable = VK_TRUE;
151
ms_state.minSampleShading = 1.0;
154
VkPipelineViewportStateCreateInfo viewport_state = {0};
155
VkPipelineViewportDepthClipControlCreateInfoEXT clip = {
156
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
160
viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
161
viewport_state.viewportCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
162
viewport_state.pViewports = NULL;
163
viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
164
viewport_state.pScissors = NULL;
165
if (!screen->driver_workarounds.depth_clip_control_missing && !hw_rast_state->clip_halfz)
166
viewport_state.pNext = &clip;
168
VkPipelineRasterizationStateCreateInfo rast_state = {0};
169
rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
171
rast_state.depthClampEnable = hw_rast_state->depth_clamp;
172
rast_state.rasterizerDiscardEnable = state->dyn_state2.rasterizer_discard;
173
rast_state.polygonMode = hw_rast_state->polygon_mode;
174
rast_state.cullMode = hw_rast_state->cull_mode;
175
rast_state.frontFace = state->dyn_state1.front_face;
177
rast_state.depthBiasEnable = VK_TRUE;
178
rast_state.depthBiasConstantFactor = 0.0;
179
rast_state.depthBiasClamp = 0.0;
180
rast_state.depthBiasSlopeFactor = 0.0;
181
rast_state.lineWidth = 1.0f;
183
VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state;
184
pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
185
pv_state.provokingVertexMode = hw_rast_state->pv_last ?
186
VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
187
VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
188
if (screen->info.have_EXT_provoking_vertex && hw_rast_state->pv_last) {
189
pv_state.pNext = rast_state.pNext;
190
rast_state.pNext = &pv_state;
193
VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
194
depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
195
depth_stencil_state.depthTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_test;
196
depth_stencil_state.depthCompareOp = state->dyn_state1.depth_stencil_alpha_state->depth_compare_op;
197
depth_stencil_state.depthBoundsTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_bounds_test;
198
depth_stencil_state.minDepthBounds = state->dyn_state1.depth_stencil_alpha_state->min_depth_bounds;
199
depth_stencil_state.maxDepthBounds = state->dyn_state1.depth_stencil_alpha_state->max_depth_bounds;
200
depth_stencil_state.stencilTestEnable = state->dyn_state1.depth_stencil_alpha_state->stencil_test;
201
depth_stencil_state.front = state->dyn_state1.depth_stencil_alpha_state->stencil_front;
202
depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back;
203
depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write;
205
VkDynamicState dynamicStateEnables[30] = {
206
VK_DYNAMIC_STATE_LINE_WIDTH,
207
VK_DYNAMIC_STATE_DEPTH_BIAS,
208
VK_DYNAMIC_STATE_BLEND_CONSTANTS,
209
VK_DYNAMIC_STATE_STENCIL_REFERENCE,
211
unsigned state_count = 4;
212
if (screen->info.have_EXT_extended_dynamic_state) {
213
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT;
214
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT;
215
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
216
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE_EXT;
217
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP_EXT;
218
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE_EXT;
219
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE_EXT;
220
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
221
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
222
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP_EXT;
223
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE_EXT;
224
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE_EXT;
225
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY_EXT;
226
if (state->sample_locations_enabled)
227
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
229
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT;
230
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR;
232
if (state->element_state->num_attribs) {
233
if (screen->info.have_EXT_vertex_input_dynamic_state)
234
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
235
else if (screen->info.have_EXT_extended_dynamic_state)
236
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE_EXT;
238
if (screen->info.have_EXT_extended_dynamic_state2) {
239
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE_EXT;
240
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT;
242
if (!screen->driver_workarounds.color_write_missing)
243
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
245
VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
246
if (screen->info.have_EXT_line_rasterization) {
247
rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
248
rast_line_state.pNext = rast_state.pNext;
249
rast_line_state.stippledLineEnable = VK_FALSE;
250
rast_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
252
bool check_warn = false;
253
switch (primitive_topology) {
254
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
255
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
256
case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
257
case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
262
if (prog->nir[PIPE_SHADER_TESS_EVAL]) {
263
check_warn |= !prog->nir[PIPE_SHADER_TESS_EVAL]->info.tess.point_mode &&
264
prog->nir[PIPE_SHADER_TESS_EVAL]->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES;
266
if (prog->nir[PIPE_SHADER_GEOMETRY]) {
267
switch (prog->nir[PIPE_SHADER_GEOMETRY]->info.gs.output_primitive) {
268
case SHADER_PRIM_LINES:
269
case SHADER_PRIM_LINE_LOOP:
270
case SHADER_PRIM_LINE_STRIP:
271
case SHADER_PRIM_LINES_ADJACENCY:
272
case SHADER_PRIM_LINE_STRIP_ADJACENCY:
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
dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
303
rast_line_state.stippledLineEnable = VK_TRUE;
306
rast_state.pNext = &rast_line_state;
308
assert(state_count < ARRAY_SIZE(dynamicStateEnables));
310
VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
311
pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
312
pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
313
pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
315
VkGraphicsPipelineCreateInfo pci = {0};
316
pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
317
pci.layout = prog->base.layout;
318
pci.renderPass = state->render_pass->render_pass;
319
if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs)
320
pci.pVertexInputState = &vertex_input_state;
321
pci.pInputAssemblyState = &primitive_state;
322
pci.pRasterizationState = &rast_state;
323
pci.pColorBlendState = &blend_state;
324
pci.pMultisampleState = &ms_state;
325
pci.pViewportState = &viewport_state;
326
pci.pDepthStencilState = &depth_stencil_state;
327
pci.pDynamicState = &pipelineDynamicStateCreateInfo;
329
VkPipelineTessellationStateCreateInfo tci = {0};
330
VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
331
if (prog->shaders[PIPE_SHADER_TESS_CTRL] && prog->shaders[PIPE_SHADER_TESS_EVAL]) {
332
tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
333
tci.patchControlPoints = state->vertices_per_patch + 1;
334
pci.pTessellationState = &tci;
336
tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
337
tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
340
VkPipelineShaderStageCreateInfo shader_stages[ZINK_SHADER_COUNT];
341
uint32_t num_stages = 0;
342
for (int i = 0; i < ZINK_SHADER_COUNT; ++i) {
343
if (!prog->modules[i])
346
VkPipelineShaderStageCreateInfo stage = {0};
347
stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
348
stage.stage = zink_shader_stage(i);
349
stage.module = prog->modules[i]->shader;
350
stage.pName = "main";
351
shader_stages[num_stages++] = stage;
353
assert(num_stages > 0);
355
pci.pStages = shader_stages;
356
pci.stageCount = num_stages;
359
if (vkCreateGraphicsPipelines(screen->dev, prog->base.pipeline_cache, 1, &pci,
360
NULL, &pipeline) != VK_SUCCESS) {
361
mesa_loge("ZINK: vkCreateGraphicsPipelines failed");
362
return VK_NULL_HANDLE;
369
zink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
371
VkComputePipelineCreateInfo pci = {0};
372
pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
373
pci.layout = comp->base.layout;
375
VkPipelineShaderStageCreateInfo stage = {0};
376
stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
377
stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
378
stage.module = comp->curr->shader;
379
stage.pName = "main";
381
VkSpecializationInfo sinfo = {0};
382
VkSpecializationMapEntry me[3];
383
if (state->use_local_size) {
384
stage.pSpecializationInfo = &sinfo;
385
sinfo.mapEntryCount = 3;
386
sinfo.pMapEntries = &me[0];
387
sinfo.dataSize = sizeof(state->local_size);
388
sinfo.pData = &state->local_size[0];
389
uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
390
for (int i = 0; i < 3; i++) {
391
me[i].size = sizeof(uint32_t);
392
me[i].constantID = ids[i];
393
me[i].offset = i * sizeof(uint32_t);
400
if (vkCreateComputePipelines(screen->dev, comp->base.pipeline_cache, 1, &pci,
401
NULL, &pipeline) != VK_SUCCESS) {
402
mesa_loge("ZINK: vkCreateComputePipelines failed");
403
return VK_NULL_HANDLE;
405
zink_screen_update_pipeline_cache(screen, &comp->base);