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 "zink_pipeline.h"
26 #include "zink_compiler.h"
27 #include "zink_context.h"
28 #include "zink_program.h"
29 #include "zink_render_pass.h"
30 #include "zink_screen.h"
31 #include "zink_state.h"
33 #include "util/u_debug.h"
34 #include "util/u_prim.h"
37 zink_create_gfx_pipeline(struct zink_screen
*screen
,
38 struct zink_gfx_program
*prog
,
39 struct zink_gfx_pipeline_state
*state
,
40 VkPrimitiveTopology primitive_topology
)
42 VkPipelineVertexInputStateCreateInfo vertex_input_state
= {};
43 vertex_input_state
.sType
= VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
;
44 vertex_input_state
.pVertexBindingDescriptions
= state
->bindings
;
45 vertex_input_state
.vertexBindingDescriptionCount
= state
->element_state
->num_bindings
;
46 vertex_input_state
.pVertexAttributeDescriptions
= state
->element_state
->attribs
;
47 vertex_input_state
.vertexAttributeDescriptionCount
= state
->element_state
->num_attribs
;
49 VkPipelineInputAssemblyStateCreateInfo primitive_state
= {};
50 primitive_state
.sType
= VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
;
51 primitive_state
.topology
= primitive_topology
;
52 switch (primitive_topology
) {
53 case VK_PRIMITIVE_TOPOLOGY_POINT_LIST
:
54 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST
:
55 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
:
56 case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY
:
57 case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY
:
58 case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
:
59 if (state
->primitive_restart
)
60 debug_printf("restart_index set with unsupported primitive topology %u\n", primitive_topology
);
61 primitive_state
.primitiveRestartEnable
= VK_FALSE
;
64 primitive_state
.primitiveRestartEnable
= state
->primitive_restart
? VK_TRUE
: VK_FALSE
;
67 VkPipelineColorBlendStateCreateInfo blend_state
= {};
68 blend_state
.sType
= VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
;
69 blend_state
.pAttachments
= state
->blend_state
->attachments
;
70 blend_state
.attachmentCount
= state
->num_attachments
;
71 blend_state
.logicOpEnable
= state
->blend_state
->logicop_enable
;
72 blend_state
.logicOp
= state
->blend_state
->logicop_func
;
74 VkPipelineMultisampleStateCreateInfo ms_state
= {};
75 ms_state
.sType
= VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
;
76 ms_state
.rasterizationSamples
= state
->rast_samples
;
77 ms_state
.alphaToCoverageEnable
= state
->blend_state
->alpha_to_coverage
;
78 ms_state
.alphaToOneEnable
= state
->blend_state
->alpha_to_one
;
79 ms_state
.pSampleMask
= state
->sample_mask
? &state
->sample_mask
: NULL
;
81 VkPipelineViewportStateCreateInfo viewport_state
= {};
82 viewport_state
.sType
= VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
;
83 viewport_state
.viewportCount
= 1;
84 viewport_state
.pViewports
= NULL
;
85 viewport_state
.scissorCount
= 1;
86 viewport_state
.pScissors
= NULL
;
88 VkPipelineRasterizationStateCreateInfo rast_state
= {};
89 rast_state
.sType
= VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO
;
91 rast_state
.depthClampEnable
= state
->rast_state
->depth_clamp
;
92 rast_state
.rasterizerDiscardEnable
= state
->rast_state
->rasterizer_discard
;
93 rast_state
.polygonMode
= state
->rast_state
->polygon_mode
;
94 rast_state
.cullMode
= state
->rast_state
->cull_mode
;
95 rast_state
.frontFace
= state
->rast_state
->front_face
;
97 rast_state
.depthBiasEnable
= VK_TRUE
;
98 rast_state
.depthBiasConstantFactor
= 0.0;
99 rast_state
.depthBiasClamp
= 0.0;
100 rast_state
.depthBiasSlopeFactor
= 0.0;
101 rast_state
.lineWidth
= 1.0f
;
103 VkPipelineDepthStencilStateCreateInfo depth_stencil_state
= {};
104 depth_stencil_state
.sType
= VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
;
105 depth_stencil_state
.depthTestEnable
= state
->depth_stencil_alpha_state
->depth_test
;
106 depth_stencil_state
.depthCompareOp
= state
->depth_stencil_alpha_state
->depth_compare_op
;
107 depth_stencil_state
.depthBoundsTestEnable
= state
->depth_stencil_alpha_state
->depth_bounds_test
;
108 depth_stencil_state
.minDepthBounds
= state
->depth_stencil_alpha_state
->min_depth_bounds
;
109 depth_stencil_state
.maxDepthBounds
= state
->depth_stencil_alpha_state
->max_depth_bounds
;
110 depth_stencil_state
.stencilTestEnable
= state
->depth_stencil_alpha_state
->stencil_test
;
111 depth_stencil_state
.front
= state
->depth_stencil_alpha_state
->stencil_front
;
112 depth_stencil_state
.back
= state
->depth_stencil_alpha_state
->stencil_back
;
113 depth_stencil_state
.depthWriteEnable
= state
->depth_stencil_alpha_state
->depth_write
;
115 VkDynamicState dynamicStateEnables
[] = {
116 VK_DYNAMIC_STATE_VIEWPORT
,
117 VK_DYNAMIC_STATE_SCISSOR
,
118 VK_DYNAMIC_STATE_LINE_WIDTH
,
119 VK_DYNAMIC_STATE_DEPTH_BIAS
,
120 VK_DYNAMIC_STATE_BLEND_CONSTANTS
,
121 VK_DYNAMIC_STATE_STENCIL_REFERENCE
,
124 VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo
= {};
125 pipelineDynamicStateCreateInfo
.sType
= VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
;
126 pipelineDynamicStateCreateInfo
.pDynamicStates
= dynamicStateEnables
;
127 pipelineDynamicStateCreateInfo
.dynamicStateCount
= ARRAY_SIZE(dynamicStateEnables
);
129 VkGraphicsPipelineCreateInfo pci
= {};
130 pci
.sType
= VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
;
131 pci
.flags
= VK_PIPELINE_CREATE_DISABLE_OPTIMIZATION_BIT
;
132 pci
.layout
= prog
->layout
;
133 pci
.renderPass
= state
->render_pass
->render_pass
;
134 pci
.pVertexInputState
= &vertex_input_state
;
135 pci
.pInputAssemblyState
= &primitive_state
;
136 pci
.pRasterizationState
= &rast_state
;
137 pci
.pColorBlendState
= &blend_state
;
138 pci
.pMultisampleState
= &ms_state
;
139 pci
.pViewportState
= &viewport_state
;
140 pci
.pDepthStencilState
= &depth_stencil_state
;
141 pci
.pDynamicState
= &pipelineDynamicStateCreateInfo
;
143 VkPipelineShaderStageCreateInfo shader_stages
[ZINK_SHADER_COUNT
];
144 uint32_t num_stages
= 0;
145 for (int i
= 0; i
< ZINK_SHADER_COUNT
; ++i
) {
146 if (!prog
->modules
[i
])
149 VkPipelineShaderStageCreateInfo stage
= {};
150 stage
.sType
= VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
;
151 stage
.stage
= zink_shader_stage(i
);
152 stage
.module
= prog
->modules
[i
]->shader
;
153 stage
.pName
= "main";
154 shader_stages
[num_stages
++] = stage
;
156 assert(num_stages
> 0);
158 pci
.pStages
= shader_stages
;
159 pci
.stageCount
= num_stages
;
162 if (vkCreateGraphicsPipelines(screen
->dev
, VK_NULL_HANDLE
, 1, &pci
,
163 NULL
, &pipeline
) != VK_SUCCESS
) {
164 debug_printf("vkCreateGraphicsPipelines failed\n");
165 return VK_NULL_HANDLE
;