1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright 2018 Collabora Ltd.
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * on the rights to use, copy, modify, merge, publish, distribute, sub
8bf215546Sopenharmony_ci * license, and/or sell copies of the Software, and to permit persons to whom
9bf215546Sopenharmony_ci * the Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19bf215546Sopenharmony_ci * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20bf215546Sopenharmony_ci * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21bf215546Sopenharmony_ci * USE OR OTHER DEALINGS IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include "compiler/spirv/spirv.h"
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci#include "zink_pipeline.h"
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "zink_compiler.h"
29bf215546Sopenharmony_ci#include "zink_context.h"
30bf215546Sopenharmony_ci#include "zink_program.h"
31bf215546Sopenharmony_ci#include "zink_render_pass.h"
32bf215546Sopenharmony_ci#include "zink_screen.h"
33bf215546Sopenharmony_ci#include "zink_state.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci#include "util/u_debug.h"
36bf215546Sopenharmony_ci#include "util/u_prim.h"
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_cistatic VkBlendFactor
39bf215546Sopenharmony_ciclamp_void_blend_factor(VkBlendFactor f)
40bf215546Sopenharmony_ci{
41bf215546Sopenharmony_ci   if (f == VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA)
42bf215546Sopenharmony_ci      return VK_BLEND_FACTOR_ZERO;
43bf215546Sopenharmony_ci   if (f == VK_BLEND_FACTOR_DST_ALPHA)
44bf215546Sopenharmony_ci      return VK_BLEND_FACTOR_ONE;
45bf215546Sopenharmony_ci   return f;
46bf215546Sopenharmony_ci}
47bf215546Sopenharmony_ci
48bf215546Sopenharmony_ciVkPipeline
49bf215546Sopenharmony_cizink_create_gfx_pipeline(struct zink_screen *screen,
50bf215546Sopenharmony_ci                         struct zink_gfx_program *prog,
51bf215546Sopenharmony_ci                         struct zink_gfx_pipeline_state *state,
52bf215546Sopenharmony_ci                         const uint8_t *binding_map,
53bf215546Sopenharmony_ci                         VkPrimitiveTopology primitive_topology)
54bf215546Sopenharmony_ci{
55bf215546Sopenharmony_ci   struct zink_rasterizer_hw_state *hw_rast_state = (void*)state;
56bf215546Sopenharmony_ci   VkPipelineVertexInputStateCreateInfo vertex_input_state;
57bf215546Sopenharmony_ci   if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride) {
58bf215546Sopenharmony_ci      memset(&vertex_input_state, 0, sizeof(vertex_input_state));
59bf215546Sopenharmony_ci      vertex_input_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO;
60bf215546Sopenharmony_ci      vertex_input_state.pVertexBindingDescriptions = state->element_state->b.bindings;
61bf215546Sopenharmony_ci      vertex_input_state.vertexBindingDescriptionCount = state->element_state->num_bindings;
62bf215546Sopenharmony_ci      vertex_input_state.pVertexAttributeDescriptions = state->element_state->attribs;
63bf215546Sopenharmony_ci      vertex_input_state.vertexAttributeDescriptionCount = state->element_state->num_attribs;
64bf215546Sopenharmony_ci      if (!screen->info.have_EXT_extended_dynamic_state || !state->uses_dynamic_stride) {
65bf215546Sopenharmony_ci         for (int i = 0; i < state->element_state->num_bindings; ++i) {
66bf215546Sopenharmony_ci            const unsigned buffer_id = binding_map[i];
67bf215546Sopenharmony_ci            VkVertexInputBindingDescription *binding = &state->element_state->b.bindings[i];
68bf215546Sopenharmony_ci            binding->stride = state->vertex_strides[buffer_id];
69bf215546Sopenharmony_ci         }
70bf215546Sopenharmony_ci      }
71bf215546Sopenharmony_ci   }
72bf215546Sopenharmony_ci
73bf215546Sopenharmony_ci   VkPipelineVertexInputDivisorStateCreateInfoEXT vdiv_state;
74bf215546Sopenharmony_ci   if (!screen->info.have_EXT_vertex_input_dynamic_state && state->element_state->b.divisors_present) {
75bf215546Sopenharmony_ci       memset(&vdiv_state, 0, sizeof(vdiv_state));
76bf215546Sopenharmony_ci       vertex_input_state.pNext = &vdiv_state;
77bf215546Sopenharmony_ci       vdiv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT;
78bf215546Sopenharmony_ci       vdiv_state.vertexBindingDivisorCount = state->element_state->b.divisors_present;
79bf215546Sopenharmony_ci       vdiv_state.pVertexBindingDivisors = state->element_state->b.divisors;
80bf215546Sopenharmony_ci   }
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci   VkPipelineInputAssemblyStateCreateInfo primitive_state = {0};
83bf215546Sopenharmony_ci   primitive_state.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO;
84bf215546Sopenharmony_ci   primitive_state.topology = primitive_topology;
85bf215546Sopenharmony_ci   if (!screen->info.have_EXT_extended_dynamic_state2) {
86bf215546Sopenharmony_ci      switch (primitive_topology) {
87bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_POINT_LIST:
88bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
89bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
90bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST:
91bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST_WITH_ADJACENCY:
92bf215546Sopenharmony_ci         if (screen->info.have_EXT_primitive_topology_list_restart) {
93bf215546Sopenharmony_ci            primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
94bf215546Sopenharmony_ci            break;
95bf215546Sopenharmony_ci         }
96bf215546Sopenharmony_ci         FALLTHROUGH;
97bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_PATCH_LIST:
98bf215546Sopenharmony_ci         if (state->dyn_state2.primitive_restart)
99bf215546Sopenharmony_ci            mesa_loge("zink: restart_index set with unsupported primitive topology %u\n", primitive_topology);
100bf215546Sopenharmony_ci         primitive_state.primitiveRestartEnable = VK_FALSE;
101bf215546Sopenharmony_ci         break;
102bf215546Sopenharmony_ci      default:
103bf215546Sopenharmony_ci         primitive_state.primitiveRestartEnable = state->dyn_state2.primitive_restart ? VK_TRUE : VK_FALSE;
104bf215546Sopenharmony_ci      }
105bf215546Sopenharmony_ci   }
106bf215546Sopenharmony_ci
107bf215546Sopenharmony_ci   VkPipelineColorBlendAttachmentState blend_att[PIPE_MAX_COLOR_BUFS];
108bf215546Sopenharmony_ci   VkPipelineColorBlendStateCreateInfo blend_state = {0};
109bf215546Sopenharmony_ci   blend_state.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
110bf215546Sopenharmony_ci   if (state->blend_state) {
111bf215546Sopenharmony_ci      unsigned num_attachments = state->render_pass ?
112bf215546Sopenharmony_ci                                 state->render_pass->state.num_rts :
113bf215546Sopenharmony_ci                                 state->rendering_info.colorAttachmentCount;
114bf215546Sopenharmony_ci      if (state->render_pass && state->render_pass->state.have_zsbuf)
115bf215546Sopenharmony_ci         num_attachments--;
116bf215546Sopenharmony_ci      if (state->void_alpha_attachments) {
117bf215546Sopenharmony_ci         for (unsigned i = 0; i < num_attachments; i++) {
118bf215546Sopenharmony_ci            blend_att[i] = state->blend_state->attachments[i];
119bf215546Sopenharmony_ci            if (state->void_alpha_attachments & BITFIELD_BIT(i)) {
120bf215546Sopenharmony_ci               blend_att[i].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
121bf215546Sopenharmony_ci               blend_att[i].srcColorBlendFactor = clamp_void_blend_factor(blend_att[i].srcColorBlendFactor);
122bf215546Sopenharmony_ci               blend_att[i].dstColorBlendFactor = clamp_void_blend_factor(blend_att[i].dstColorBlendFactor);
123bf215546Sopenharmony_ci            }
124bf215546Sopenharmony_ci         }
125bf215546Sopenharmony_ci         blend_state.pAttachments = blend_att;
126bf215546Sopenharmony_ci      } else
127bf215546Sopenharmony_ci         blend_state.pAttachments = state->blend_state->attachments;
128bf215546Sopenharmony_ci      blend_state.attachmentCount = num_attachments;
129bf215546Sopenharmony_ci      blend_state.logicOpEnable = state->blend_state->logicop_enable;
130bf215546Sopenharmony_ci      blend_state.logicOp = state->blend_state->logicop_func;
131bf215546Sopenharmony_ci   }
132bf215546Sopenharmony_ci
133bf215546Sopenharmony_ci   VkPipelineMultisampleStateCreateInfo ms_state = {0};
134bf215546Sopenharmony_ci   ms_state.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO;
135bf215546Sopenharmony_ci   ms_state.rasterizationSamples = state->rast_samples + 1;
136bf215546Sopenharmony_ci   if (state->blend_state) {
137bf215546Sopenharmony_ci      ms_state.alphaToCoverageEnable = state->blend_state->alpha_to_coverage;
138bf215546Sopenharmony_ci      if (state->blend_state->alpha_to_one && !screen->info.feats.features.alphaToOne) {
139bf215546Sopenharmony_ci         static bool warned = false;
140bf215546Sopenharmony_ci         warn_missing_feature(warned, "alphaToOne");
141bf215546Sopenharmony_ci      }
142bf215546Sopenharmony_ci      ms_state.alphaToOneEnable = state->blend_state->alpha_to_one;
143bf215546Sopenharmony_ci   }
144bf215546Sopenharmony_ci   /* "If pSampleMask is NULL, it is treated as if the mask has all bits set to 1."
145bf215546Sopenharmony_ci    * - Chapter 27. Rasterization
146bf215546Sopenharmony_ci    *
147bf215546Sopenharmony_ci    * thus it never makes sense to leave this as NULL since gallium will provide correct
148bf215546Sopenharmony_ci    * data here as long as sample_mask is initialized on context creation
149bf215546Sopenharmony_ci    */
150bf215546Sopenharmony_ci   ms_state.pSampleMask = &state->sample_mask;
151bf215546Sopenharmony_ci   if (hw_rast_state->force_persample_interp) {
152bf215546Sopenharmony_ci      ms_state.sampleShadingEnable = VK_TRUE;
153bf215546Sopenharmony_ci      ms_state.minSampleShading = 1.0;
154bf215546Sopenharmony_ci   }
155bf215546Sopenharmony_ci
156bf215546Sopenharmony_ci   VkPipelineViewportStateCreateInfo viewport_state = {0};
157bf215546Sopenharmony_ci   VkPipelineViewportDepthClipControlCreateInfoEXT clip = {
158bf215546Sopenharmony_ci      VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_DEPTH_CLIP_CONTROL_CREATE_INFO_EXT,
159bf215546Sopenharmony_ci      NULL,
160bf215546Sopenharmony_ci      VK_TRUE
161bf215546Sopenharmony_ci   };
162bf215546Sopenharmony_ci   viewport_state.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
163bf215546Sopenharmony_ci   viewport_state.viewportCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
164bf215546Sopenharmony_ci   viewport_state.pViewports = NULL;
165bf215546Sopenharmony_ci   viewport_state.scissorCount = screen->info.have_EXT_extended_dynamic_state ? 0 : state->dyn_state1.num_viewports;
166bf215546Sopenharmony_ci   viewport_state.pScissors = NULL;
167bf215546Sopenharmony_ci   if (!screen->driver_workarounds.depth_clip_control_missing && !hw_rast_state->clip_halfz)
168bf215546Sopenharmony_ci      viewport_state.pNext = &clip;
169bf215546Sopenharmony_ci
170bf215546Sopenharmony_ci   VkPipelineRasterizationStateCreateInfo rast_state = {0};
171bf215546Sopenharmony_ci   rast_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci   rast_state.depthClampEnable = true;
174bf215546Sopenharmony_ci   rast_state.rasterizerDiscardEnable = state->dyn_state2.rasterizer_discard;
175bf215546Sopenharmony_ci   rast_state.polygonMode = hw_rast_state->polygon_mode;
176bf215546Sopenharmony_ci   rast_state.cullMode = state->dyn_state1.cull_mode;
177bf215546Sopenharmony_ci   rast_state.frontFace = state->dyn_state1.front_face;
178bf215546Sopenharmony_ci
179bf215546Sopenharmony_ci   rast_state.depthBiasEnable = VK_TRUE;
180bf215546Sopenharmony_ci   rast_state.depthBiasConstantFactor = 0.0;
181bf215546Sopenharmony_ci   rast_state.depthBiasClamp = 0.0;
182bf215546Sopenharmony_ci   rast_state.depthBiasSlopeFactor = 0.0;
183bf215546Sopenharmony_ci   rast_state.lineWidth = 1.0f;
184bf215546Sopenharmony_ci
185bf215546Sopenharmony_ci   VkPipelineRasterizationDepthClipStateCreateInfoEXT depth_clip_state = {0};
186bf215546Sopenharmony_ci   depth_clip_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT;
187bf215546Sopenharmony_ci   depth_clip_state.depthClipEnable = hw_rast_state->depth_clip;
188bf215546Sopenharmony_ci   if (screen->info.have_EXT_depth_clip_enable) {
189bf215546Sopenharmony_ci      depth_clip_state.pNext = rast_state.pNext;
190bf215546Sopenharmony_ci      rast_state.pNext = &depth_clip_state;
191bf215546Sopenharmony_ci   } else {
192bf215546Sopenharmony_ci      static bool warned = false;
193bf215546Sopenharmony_ci      warn_missing_feature(warned, "VK_EXT_depth_clip_enable");
194bf215546Sopenharmony_ci      rast_state.depthClampEnable = !hw_rast_state->depth_clip;
195bf215546Sopenharmony_ci   }
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_ci   VkPipelineRasterizationProvokingVertexStateCreateInfoEXT pv_state;
198bf215546Sopenharmony_ci   pv_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT;
199bf215546Sopenharmony_ci   pv_state.provokingVertexMode = hw_rast_state->pv_last ?
200bf215546Sopenharmony_ci                                  VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT :
201bf215546Sopenharmony_ci                                  VK_PROVOKING_VERTEX_MODE_FIRST_VERTEX_EXT;
202bf215546Sopenharmony_ci   if (screen->info.have_EXT_provoking_vertex && hw_rast_state->pv_last) {
203bf215546Sopenharmony_ci      pv_state.pNext = rast_state.pNext;
204bf215546Sopenharmony_ci      rast_state.pNext = &pv_state;
205bf215546Sopenharmony_ci   }
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci   VkPipelineDepthStencilStateCreateInfo depth_stencil_state = {0};
208bf215546Sopenharmony_ci   depth_stencil_state.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO;
209bf215546Sopenharmony_ci   depth_stencil_state.depthTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_test;
210bf215546Sopenharmony_ci   depth_stencil_state.depthCompareOp = state->dyn_state1.depth_stencil_alpha_state->depth_compare_op;
211bf215546Sopenharmony_ci   depth_stencil_state.depthBoundsTestEnable = state->dyn_state1.depth_stencil_alpha_state->depth_bounds_test;
212bf215546Sopenharmony_ci   depth_stencil_state.minDepthBounds = state->dyn_state1.depth_stencil_alpha_state->min_depth_bounds;
213bf215546Sopenharmony_ci   depth_stencil_state.maxDepthBounds = state->dyn_state1.depth_stencil_alpha_state->max_depth_bounds;
214bf215546Sopenharmony_ci   depth_stencil_state.stencilTestEnable = state->dyn_state1.depth_stencil_alpha_state->stencil_test;
215bf215546Sopenharmony_ci   depth_stencil_state.front = state->dyn_state1.depth_stencil_alpha_state->stencil_front;
216bf215546Sopenharmony_ci   depth_stencil_state.back = state->dyn_state1.depth_stencil_alpha_state->stencil_back;
217bf215546Sopenharmony_ci   depth_stencil_state.depthWriteEnable = state->dyn_state1.depth_stencil_alpha_state->depth_write;
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   VkDynamicState dynamicStateEnables[30] = {
220bf215546Sopenharmony_ci      VK_DYNAMIC_STATE_LINE_WIDTH,
221bf215546Sopenharmony_ci      VK_DYNAMIC_STATE_DEPTH_BIAS,
222bf215546Sopenharmony_ci      VK_DYNAMIC_STATE_BLEND_CONSTANTS,
223bf215546Sopenharmony_ci      VK_DYNAMIC_STATE_STENCIL_REFERENCE,
224bf215546Sopenharmony_ci   };
225bf215546Sopenharmony_ci   unsigned state_count = 4;
226bf215546Sopenharmony_ci   if (screen->info.have_EXT_extended_dynamic_state) {
227bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT;
228bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT;
229bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS;
230bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_BOUNDS_TEST_ENABLE;
231bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_COMPARE_OP;
232bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_TEST_ENABLE;
233bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_DEPTH_WRITE_ENABLE;
234bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_WRITE_MASK;
235bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_COMPARE_MASK;
236bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_OP;
237bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_STENCIL_TEST_ENABLE;
238bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_FRONT_FACE;
239bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_TOPOLOGY;
240bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_CULL_MODE;
241bf215546Sopenharmony_ci      if (state->sample_locations_enabled)
242bf215546Sopenharmony_ci         dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SAMPLE_LOCATIONS_EXT;
243bf215546Sopenharmony_ci   } else {
244bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VIEWPORT;
245bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_SCISSOR;
246bf215546Sopenharmony_ci   }
247bf215546Sopenharmony_ci   if (state->element_state->num_attribs) {
248bf215546Sopenharmony_ci      if (screen->info.have_EXT_vertex_input_dynamic_state)
249bf215546Sopenharmony_ci         dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_EXT;
250bf215546Sopenharmony_ci      else if (screen->info.have_EXT_extended_dynamic_state && state->uses_dynamic_stride)
251bf215546Sopenharmony_ci         dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_VERTEX_INPUT_BINDING_STRIDE;
252bf215546Sopenharmony_ci   }
253bf215546Sopenharmony_ci   if (screen->info.have_EXT_extended_dynamic_state2) {
254bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PRIMITIVE_RESTART_ENABLE;
255bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE;
256bf215546Sopenharmony_ci      if (screen->info.dynamic_state2_feats.extendedDynamicState2PatchControlPoints)
257bf215546Sopenharmony_ci         dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_PATCH_CONTROL_POINTS_EXT;
258bf215546Sopenharmony_ci   }
259bf215546Sopenharmony_ci   if (!screen->driver_workarounds.color_write_missing)
260bf215546Sopenharmony_ci      dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT;
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_ci   VkPipelineRasterizationLineStateCreateInfoEXT rast_line_state;
263bf215546Sopenharmony_ci   if (screen->info.have_EXT_line_rasterization) {
264bf215546Sopenharmony_ci      rast_line_state.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT;
265bf215546Sopenharmony_ci      rast_line_state.pNext = rast_state.pNext;
266bf215546Sopenharmony_ci      rast_line_state.stippledLineEnable = VK_FALSE;
267bf215546Sopenharmony_ci      rast_line_state.lineRasterizationMode = VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT;
268bf215546Sopenharmony_ci
269bf215546Sopenharmony_ci      bool check_warn = false;
270bf215546Sopenharmony_ci      switch (primitive_topology) {
271bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_LINE_LIST:
272bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP:
273bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_LINE_LIST_WITH_ADJACENCY:
274bf215546Sopenharmony_ci      case VK_PRIMITIVE_TOPOLOGY_LINE_STRIP_WITH_ADJACENCY:
275bf215546Sopenharmony_ci         check_warn = true;
276bf215546Sopenharmony_ci         break;
277bf215546Sopenharmony_ci      default: break;
278bf215546Sopenharmony_ci      }
279bf215546Sopenharmony_ci      if (prog->nir[PIPE_SHADER_TESS_EVAL]) {
280bf215546Sopenharmony_ci         check_warn |= !prog->nir[PIPE_SHADER_TESS_EVAL]->info.tess.point_mode &&
281bf215546Sopenharmony_ci                       prog->nir[PIPE_SHADER_TESS_EVAL]->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES;
282bf215546Sopenharmony_ci      }
283bf215546Sopenharmony_ci      if (prog->nir[PIPE_SHADER_GEOMETRY]) {
284bf215546Sopenharmony_ci         switch (prog->nir[PIPE_SHADER_GEOMETRY]->info.gs.output_primitive) {
285bf215546Sopenharmony_ci         case SHADER_PRIM_LINES:
286bf215546Sopenharmony_ci         case SHADER_PRIM_LINE_LOOP:
287bf215546Sopenharmony_ci         case SHADER_PRIM_LINE_STRIP:
288bf215546Sopenharmony_ci         case SHADER_PRIM_LINES_ADJACENCY:
289bf215546Sopenharmony_ci         case SHADER_PRIM_LINE_STRIP_ADJACENCY:
290bf215546Sopenharmony_ci            check_warn = true;
291bf215546Sopenharmony_ci            break;
292bf215546Sopenharmony_ci         default: break;
293bf215546Sopenharmony_ci         }
294bf215546Sopenharmony_ci      }
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ci      if (check_warn) {
297bf215546Sopenharmony_ci         const char *features[4][2] = {
298bf215546Sopenharmony_ci            [VK_LINE_RASTERIZATION_MODE_DEFAULT_EXT] = {"",""},
299bf215546Sopenharmony_ci            [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT] = {"rectangularLines", "stippledRectangularLines"},
300bf215546Sopenharmony_ci            [VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT] = {"bresenhamLines", "stippledBresenhamLines"},
301bf215546Sopenharmony_ci            [VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT] = {"smoothLines", "stippledSmoothLines"},
302bf215546Sopenharmony_ci         };
303bf215546Sopenharmony_ci         static bool warned[6] = {0};
304bf215546Sopenharmony_ci         const VkPhysicalDeviceLineRasterizationFeaturesEXT *line_feats = &screen->info.line_rast_feats;
305bf215546Sopenharmony_ci         /* line features can be represented as an array VkBool32[6],
306bf215546Sopenharmony_ci          * with the 3 base features preceding the 3 (matching) stippled features
307bf215546Sopenharmony_ci          */
308bf215546Sopenharmony_ci         const VkBool32 *feat = &line_feats->rectangularLines;
309bf215546Sopenharmony_ci         unsigned mode_idx = hw_rast_state->line_mode - VK_LINE_RASTERIZATION_MODE_RECTANGULAR_EXT;
310bf215546Sopenharmony_ci         /* add base mode index, add 3 if stippling is enabled */
311bf215546Sopenharmony_ci         mode_idx += hw_rast_state->line_stipple_enable * 3;
312bf215546Sopenharmony_ci         if (*(feat + mode_idx))
313bf215546Sopenharmony_ci            rast_line_state.lineRasterizationMode = hw_rast_state->line_mode;
314bf215546Sopenharmony_ci         else
315bf215546Sopenharmony_ci            warn_missing_feature(warned[mode_idx], features[hw_rast_state->line_mode][hw_rast_state->line_stipple_enable]);
316bf215546Sopenharmony_ci      }
317bf215546Sopenharmony_ci
318bf215546Sopenharmony_ci      if (hw_rast_state->line_stipple_enable) {
319bf215546Sopenharmony_ci         dynamicStateEnables[state_count++] = VK_DYNAMIC_STATE_LINE_STIPPLE_EXT;
320bf215546Sopenharmony_ci         rast_line_state.stippledLineEnable = VK_TRUE;
321bf215546Sopenharmony_ci      }
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_ci      rast_state.pNext = &rast_line_state;
324bf215546Sopenharmony_ci   }
325bf215546Sopenharmony_ci   assert(state_count < ARRAY_SIZE(dynamicStateEnables));
326bf215546Sopenharmony_ci
327bf215546Sopenharmony_ci   VkPipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo = {0};
328bf215546Sopenharmony_ci   pipelineDynamicStateCreateInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO;
329bf215546Sopenharmony_ci   pipelineDynamicStateCreateInfo.pDynamicStates = dynamicStateEnables;
330bf215546Sopenharmony_ci   pipelineDynamicStateCreateInfo.dynamicStateCount = state_count;
331bf215546Sopenharmony_ci
332bf215546Sopenharmony_ci   VkGraphicsPipelineCreateInfo pci = {0};
333bf215546Sopenharmony_ci   pci.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
334bf215546Sopenharmony_ci   pci.layout = prog->base.layout;
335bf215546Sopenharmony_ci   if (state->render_pass)
336bf215546Sopenharmony_ci      pci.renderPass = state->render_pass->render_pass;
337bf215546Sopenharmony_ci   else
338bf215546Sopenharmony_ci      pci.pNext = &state->rendering_info;
339bf215546Sopenharmony_ci   if (!screen->info.have_EXT_vertex_input_dynamic_state || !state->element_state->num_attribs || !state->uses_dynamic_stride)
340bf215546Sopenharmony_ci      pci.pVertexInputState = &vertex_input_state;
341bf215546Sopenharmony_ci   pci.pInputAssemblyState = &primitive_state;
342bf215546Sopenharmony_ci   pci.pRasterizationState = &rast_state;
343bf215546Sopenharmony_ci   pci.pColorBlendState = &blend_state;
344bf215546Sopenharmony_ci   pci.pMultisampleState = &ms_state;
345bf215546Sopenharmony_ci   pci.pViewportState = &viewport_state;
346bf215546Sopenharmony_ci   pci.pDepthStencilState = &depth_stencil_state;
347bf215546Sopenharmony_ci   pci.pDynamicState = &pipelineDynamicStateCreateInfo;
348bf215546Sopenharmony_ci
349bf215546Sopenharmony_ci   VkPipelineTessellationStateCreateInfo tci = {0};
350bf215546Sopenharmony_ci   VkPipelineTessellationDomainOriginStateCreateInfo tdci = {0};
351bf215546Sopenharmony_ci   if (prog->shaders[PIPE_SHADER_TESS_CTRL] && prog->shaders[PIPE_SHADER_TESS_EVAL]) {
352bf215546Sopenharmony_ci      tci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO;
353bf215546Sopenharmony_ci      tci.patchControlPoints = state->dyn_state2.vertices_per_patch;
354bf215546Sopenharmony_ci      pci.pTessellationState = &tci;
355bf215546Sopenharmony_ci      tci.pNext = &tdci;
356bf215546Sopenharmony_ci      tdci.sType = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO;
357bf215546Sopenharmony_ci      tdci.domainOrigin = VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT;
358bf215546Sopenharmony_ci   }
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo shader_stages[ZINK_SHADER_COUNT];
361bf215546Sopenharmony_ci   uint32_t num_stages = 0;
362bf215546Sopenharmony_ci   for (int i = 0; i < ZINK_SHADER_COUNT; ++i) {
363bf215546Sopenharmony_ci      if (!prog->modules[i])
364bf215546Sopenharmony_ci         continue;
365bf215546Sopenharmony_ci
366bf215546Sopenharmony_ci      VkPipelineShaderStageCreateInfo stage = {0};
367bf215546Sopenharmony_ci      stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
368bf215546Sopenharmony_ci      stage.stage = zink_shader_stage(i);
369bf215546Sopenharmony_ci      stage.module = prog->modules[i]->shader;
370bf215546Sopenharmony_ci      stage.pName = "main";
371bf215546Sopenharmony_ci      shader_stages[num_stages++] = stage;
372bf215546Sopenharmony_ci   }
373bf215546Sopenharmony_ci   assert(num_stages > 0);
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ci   pci.pStages = shader_stages;
376bf215546Sopenharmony_ci   pci.stageCount = num_stages;
377bf215546Sopenharmony_ci
378bf215546Sopenharmony_ci   VkPipeline pipeline;
379bf215546Sopenharmony_ci   VkResult result = VKSCR(CreateGraphicsPipelines)(screen->dev, prog->base.pipeline_cache,
380bf215546Sopenharmony_ci                                                    1, &pci, NULL, &pipeline);
381bf215546Sopenharmony_ci   if (result != VK_SUCCESS) {
382bf215546Sopenharmony_ci      mesa_loge("ZINK: vkCreateGraphicsPipelines failed (%s)", vk_Result_to_str(result));
383bf215546Sopenharmony_ci      return VK_NULL_HANDLE;
384bf215546Sopenharmony_ci   }
385bf215546Sopenharmony_ci
386bf215546Sopenharmony_ci   return pipeline;
387bf215546Sopenharmony_ci}
388bf215546Sopenharmony_ci
389bf215546Sopenharmony_ciVkPipeline
390bf215546Sopenharmony_cizink_create_compute_pipeline(struct zink_screen *screen, struct zink_compute_program *comp, struct zink_compute_pipeline_state *state)
391bf215546Sopenharmony_ci{
392bf215546Sopenharmony_ci   VkComputePipelineCreateInfo pci = {0};
393bf215546Sopenharmony_ci   pci.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO;
394bf215546Sopenharmony_ci   pci.layout = comp->base.layout;
395bf215546Sopenharmony_ci
396bf215546Sopenharmony_ci   VkPipelineShaderStageCreateInfo stage = {0};
397bf215546Sopenharmony_ci   stage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
398bf215546Sopenharmony_ci   stage.stage = VK_SHADER_STAGE_COMPUTE_BIT;
399bf215546Sopenharmony_ci   stage.module = comp->curr->shader;
400bf215546Sopenharmony_ci   stage.pName = "main";
401bf215546Sopenharmony_ci
402bf215546Sopenharmony_ci   VkSpecializationInfo sinfo = {0};
403bf215546Sopenharmony_ci   VkSpecializationMapEntry me[3];
404bf215546Sopenharmony_ci   if (state->use_local_size) {
405bf215546Sopenharmony_ci      stage.pSpecializationInfo = &sinfo;
406bf215546Sopenharmony_ci      sinfo.mapEntryCount = 3;
407bf215546Sopenharmony_ci      sinfo.pMapEntries = &me[0];
408bf215546Sopenharmony_ci      sinfo.dataSize = sizeof(state->local_size);
409bf215546Sopenharmony_ci      sinfo.pData = &state->local_size[0];
410bf215546Sopenharmony_ci      uint32_t ids[] = {ZINK_WORKGROUP_SIZE_X, ZINK_WORKGROUP_SIZE_Y, ZINK_WORKGROUP_SIZE_Z};
411bf215546Sopenharmony_ci      for (int i = 0; i < 3; i++) {
412bf215546Sopenharmony_ci         me[i].size = sizeof(uint32_t);
413bf215546Sopenharmony_ci         me[i].constantID = ids[i];
414bf215546Sopenharmony_ci         me[i].offset = i * sizeof(uint32_t);
415bf215546Sopenharmony_ci      }
416bf215546Sopenharmony_ci   }
417bf215546Sopenharmony_ci
418bf215546Sopenharmony_ci   pci.stage = stage;
419bf215546Sopenharmony_ci
420bf215546Sopenharmony_ci   VkPipeline pipeline;
421bf215546Sopenharmony_ci   VkResult result = VKSCR(CreateComputePipelines)(screen->dev, comp->base.pipeline_cache,
422bf215546Sopenharmony_ci                                                   1, &pci, NULL, &pipeline);
423bf215546Sopenharmony_ci   if (result != VK_SUCCESS) {
424bf215546Sopenharmony_ci      mesa_loge("ZINK: vkCreateComputePipelines failed (%s)", vk_Result_to_str(result));
425bf215546Sopenharmony_ci      return VK_NULL_HANDLE;
426bf215546Sopenharmony_ci   }
427bf215546Sopenharmony_ci   zink_screen_update_pipeline_cache(screen, &comp->base);
428bf215546Sopenharmony_ci
429bf215546Sopenharmony_ci   return pipeline;
430bf215546Sopenharmony_ci}
431