1 /*
2 * Copyright © 2019 Red Hat.
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include "lvp_private.h"
25 #include "vk_util.h"
26 #include "glsl_types.h"
27 #include "spirv/nir_spirv.h"
28 #include "nir/nir_builder.h"
29 #include "lvp_lower_vulkan_resource.h"
30 #include "pipe/p_state.h"
31 #include "pipe/p_context.h"
32 #include "nir/nir_xfb_info.h"
33
34 #define SPIR_V_MAGIC_NUMBER 0x07230203
35
36 #define LVP_PIPELINE_DUP(dst, src, type, count) do { \
37 type *temp = ralloc_array(mem_ctx, type, count); \
38 if (!temp) return VK_ERROR_OUT_OF_HOST_MEMORY; \
39 memcpy(temp, (src), sizeof(type) * count); \
40 dst = temp; \
41 } while(0)
42
lvp_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)43 VKAPI_ATTR void VKAPI_CALL lvp_DestroyPipeline(
44 VkDevice _device,
45 VkPipeline _pipeline,
46 const VkAllocationCallbacks* pAllocator)
47 {
48 LVP_FROM_HANDLE(lvp_device, device, _device);
49 LVP_FROM_HANDLE(lvp_pipeline, pipeline, _pipeline);
50
51 if (!_pipeline)
52 return;
53
54 if (pipeline->shader_cso[PIPE_SHADER_VERTEX])
55 device->queue.ctx->delete_vs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_VERTEX]);
56 if (pipeline->shader_cso[PIPE_SHADER_FRAGMENT])
57 device->queue.ctx->delete_fs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_FRAGMENT]);
58 if (pipeline->shader_cso[PIPE_SHADER_GEOMETRY])
59 device->queue.ctx->delete_gs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_GEOMETRY]);
60 if (pipeline->shader_cso[PIPE_SHADER_TESS_CTRL])
61 device->queue.ctx->delete_tcs_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_CTRL]);
62 if (pipeline->shader_cso[PIPE_SHADER_TESS_EVAL])
63 device->queue.ctx->delete_tes_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_TESS_EVAL]);
64 if (pipeline->shader_cso[PIPE_SHADER_COMPUTE])
65 device->queue.ctx->delete_compute_state(device->queue.ctx, pipeline->shader_cso[PIPE_SHADER_COMPUTE]);
66
67 ralloc_free(pipeline->mem_ctx);
68 vk_object_base_finish(&pipeline->base);
69 vk_free2(&device->vk.alloc, pAllocator, pipeline);
70 }
71
72 static VkResult
deep_copy_shader_stage(void * mem_ctx,struct VkPipelineShaderStageCreateInfo * dst,const struct VkPipelineShaderStageCreateInfo * src)73 deep_copy_shader_stage(void *mem_ctx,
74 struct VkPipelineShaderStageCreateInfo *dst,
75 const struct VkPipelineShaderStageCreateInfo *src)
76 {
77 dst->sType = src->sType;
78 dst->pNext = NULL;
79 dst->flags = src->flags;
80 dst->stage = src->stage;
81 dst->module = src->module;
82 dst->pName = src->pName;
83 dst->pSpecializationInfo = NULL;
84 if (src->pSpecializationInfo) {
85 const VkSpecializationInfo *src_spec = src->pSpecializationInfo;
86 VkSpecializationInfo *dst_spec = ralloc_size(mem_ctx, sizeof(VkSpecializationInfo) +
87 src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry) +
88 src_spec->dataSize);
89 VkSpecializationMapEntry *maps = (VkSpecializationMapEntry *)(dst_spec + 1);
90 dst_spec->pMapEntries = maps;
91 void *pdata = (void *)(dst_spec->pMapEntries + src_spec->mapEntryCount);
92 dst_spec->pData = pdata;
93
94
95 dst_spec->mapEntryCount = src_spec->mapEntryCount;
96 dst_spec->dataSize = src_spec->dataSize;
97 memcpy(pdata, src_spec->pData, src->pSpecializationInfo->dataSize);
98 memcpy(maps, src_spec->pMapEntries, src_spec->mapEntryCount * sizeof(VkSpecializationMapEntry));
99 dst->pSpecializationInfo = dst_spec;
100 }
101 return VK_SUCCESS;
102 }
103
104 static VkResult
deep_copy_vertex_input_state(void * mem_ctx,struct VkPipelineVertexInputStateCreateInfo * dst,const struct VkPipelineVertexInputStateCreateInfo * src)105 deep_copy_vertex_input_state(void *mem_ctx,
106 struct VkPipelineVertexInputStateCreateInfo *dst,
107 const struct VkPipelineVertexInputStateCreateInfo *src)
108 {
109 dst->sType = src->sType;
110 dst->pNext = NULL;
111 dst->flags = src->flags;
112 dst->vertexBindingDescriptionCount = src->vertexBindingDescriptionCount;
113
114 LVP_PIPELINE_DUP(dst->pVertexBindingDescriptions,
115 src->pVertexBindingDescriptions,
116 VkVertexInputBindingDescription,
117 src->vertexBindingDescriptionCount);
118
119 dst->vertexAttributeDescriptionCount = src->vertexAttributeDescriptionCount;
120
121 LVP_PIPELINE_DUP(dst->pVertexAttributeDescriptions,
122 src->pVertexAttributeDescriptions,
123 VkVertexInputAttributeDescription,
124 src->vertexAttributeDescriptionCount);
125
126 if (src->pNext) {
127 vk_foreach_struct(ext, src->pNext) {
128 switch (ext->sType) {
129 case VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT: {
130 VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_src = (VkPipelineVertexInputDivisorStateCreateInfoEXT *)ext;
131 VkPipelineVertexInputDivisorStateCreateInfoEXT *ext_dst = ralloc(mem_ctx, VkPipelineVertexInputDivisorStateCreateInfoEXT);
132
133 ext_dst->sType = ext_src->sType;
134 ext_dst->vertexBindingDivisorCount = ext_src->vertexBindingDivisorCount;
135
136 LVP_PIPELINE_DUP(ext_dst->pVertexBindingDivisors,
137 ext_src->pVertexBindingDivisors,
138 VkVertexInputBindingDivisorDescriptionEXT,
139 ext_src->vertexBindingDivisorCount);
140
141 dst->pNext = ext_dst;
142 break;
143 }
144 default:
145 break;
146 }
147 }
148 }
149 return VK_SUCCESS;
150 }
151
152 static bool
dynamic_state_contains(const VkPipelineDynamicStateCreateInfo * src,VkDynamicState state)153 dynamic_state_contains(const VkPipelineDynamicStateCreateInfo *src, VkDynamicState state)
154 {
155 if (!src)
156 return false;
157
158 for (unsigned i = 0; i < src->dynamicStateCount; i++)
159 if (src->pDynamicStates[i] == state)
160 return true;
161 return false;
162 }
163
164 static VkResult
deep_copy_viewport_state(void * mem_ctx,const VkPipelineDynamicStateCreateInfo * dyn_state,VkPipelineViewportStateCreateInfo * dst,const VkPipelineViewportStateCreateInfo * src)165 deep_copy_viewport_state(void *mem_ctx,
166 const VkPipelineDynamicStateCreateInfo *dyn_state,
167 VkPipelineViewportStateCreateInfo *dst,
168 const VkPipelineViewportStateCreateInfo *src)
169 {
170 dst->sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO;
171 dst->pNext = NULL;
172 dst->pViewports = NULL;
173 dst->pScissors = NULL;
174
175 if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_VIEWPORT) &&
176 !dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT)) {
177 LVP_PIPELINE_DUP(dst->pViewports,
178 src->pViewports,
179 VkViewport,
180 src->viewportCount);
181 }
182 if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_VIEWPORT_WITH_COUNT_EXT))
183 dst->viewportCount = src->viewportCount;
184 else
185 dst->viewportCount = 0;
186
187 if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_SCISSOR) &&
188 !dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT)) {
189 if (src->pScissors)
190 LVP_PIPELINE_DUP(dst->pScissors,
191 src->pScissors,
192 VkRect2D,
193 src->scissorCount);
194 }
195 if (!dynamic_state_contains(dyn_state, VK_DYNAMIC_STATE_SCISSOR_WITH_COUNT_EXT))
196 dst->scissorCount = src->scissorCount;
197 else
198 dst->scissorCount = 0;
199
200 return VK_SUCCESS;
201 }
202
203 static VkResult
deep_copy_color_blend_state(void * mem_ctx,VkPipelineColorBlendStateCreateInfo * dst,const VkPipelineColorBlendStateCreateInfo * src)204 deep_copy_color_blend_state(void *mem_ctx,
205 VkPipelineColorBlendStateCreateInfo *dst,
206 const VkPipelineColorBlendStateCreateInfo *src)
207 {
208 dst->sType = src->sType;
209 dst->pNext = NULL;
210 dst->flags = src->flags;
211 dst->logicOpEnable = src->logicOpEnable;
212 dst->logicOp = src->logicOp;
213
214 LVP_PIPELINE_DUP(dst->pAttachments,
215 src->pAttachments,
216 VkPipelineColorBlendAttachmentState,
217 src->attachmentCount);
218 dst->attachmentCount = src->attachmentCount;
219
220 memcpy(&dst->blendConstants, &src->blendConstants, sizeof(float) * 4);
221
222 return VK_SUCCESS;
223 }
224
225 static VkResult
deep_copy_dynamic_state(void * mem_ctx,VkPipelineDynamicStateCreateInfo * dst,const VkPipelineDynamicStateCreateInfo * src)226 deep_copy_dynamic_state(void *mem_ctx,
227 VkPipelineDynamicStateCreateInfo *dst,
228 const VkPipelineDynamicStateCreateInfo *src)
229 {
230 dst->sType = src->sType;
231 dst->pNext = NULL;
232 dst->flags = src->flags;
233
234 LVP_PIPELINE_DUP(dst->pDynamicStates,
235 src->pDynamicStates,
236 VkDynamicState,
237 src->dynamicStateCount);
238 dst->dynamicStateCount = src->dynamicStateCount;
239 return VK_SUCCESS;
240 }
241
242
243 static VkResult
deep_copy_rasterization_state(void * mem_ctx,VkPipelineRasterizationStateCreateInfo * dst,const VkPipelineRasterizationStateCreateInfo * src)244 deep_copy_rasterization_state(void *mem_ctx,
245 VkPipelineRasterizationStateCreateInfo *dst,
246 const VkPipelineRasterizationStateCreateInfo *src)
247 {
248 memcpy(dst, src, sizeof(VkPipelineRasterizationStateCreateInfo));
249 dst->pNext = NULL;
250
251 if (src->pNext) {
252 vk_foreach_struct(ext, src->pNext) {
253 switch (ext->sType) {
254 case VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_DEPTH_CLIP_STATE_CREATE_INFO_EXT: {
255 VkPipelineRasterizationDepthClipStateCreateInfoEXT *ext_src = (VkPipelineRasterizationDepthClipStateCreateInfoEXT *)ext;
256 VkPipelineRasterizationDepthClipStateCreateInfoEXT *ext_dst = ralloc(mem_ctx, VkPipelineRasterizationDepthClipStateCreateInfoEXT);
257 ext_dst->sType = ext_src->sType;
258 ext_dst->flags = ext_src->flags;
259 ext_dst->depthClipEnable = ext_src->depthClipEnable;
260 dst->pNext = ext_dst;
261 break;
262 }
263 default:
264 break;
265 }
266 }
267 }
268 return VK_SUCCESS;
269 }
270
271 static VkResult
deep_copy_graphics_create_info(void * mem_ctx,VkGraphicsPipelineCreateInfo * dst,const VkGraphicsPipelineCreateInfo * src)272 deep_copy_graphics_create_info(void *mem_ctx,
273 VkGraphicsPipelineCreateInfo *dst,
274 const VkGraphicsPipelineCreateInfo *src)
275 {
276 int i;
277 VkResult result;
278 VkPipelineShaderStageCreateInfo *stages;
279 VkPipelineVertexInputStateCreateInfo *vertex_input;
280 VkPipelineRasterizationStateCreateInfo *rasterization_state;
281 LVP_FROM_HANDLE(lvp_render_pass, pass, src->renderPass);
282
283 dst->sType = src->sType;
284 dst->pNext = NULL;
285 dst->flags = src->flags;
286 dst->layout = src->layout;
287 dst->renderPass = src->renderPass;
288 dst->subpass = src->subpass;
289 dst->basePipelineHandle = src->basePipelineHandle;
290 dst->basePipelineIndex = src->basePipelineIndex;
291
292 /* pStages */
293 VkShaderStageFlags stages_present = 0;
294 dst->stageCount = src->stageCount;
295 stages = ralloc_array(mem_ctx, VkPipelineShaderStageCreateInfo, dst->stageCount);
296 for (i = 0 ; i < dst->stageCount; i++) {
297 result = deep_copy_shader_stage(mem_ctx, &stages[i], &src->pStages[i]);
298 if (result != VK_SUCCESS)
299 return result;
300 stages_present |= src->pStages[i].stage;
301 }
302 dst->pStages = stages;
303
304 /* pVertexInputState */
305 if (!dynamic_state_contains(src->pDynamicState, VK_DYNAMIC_STATE_VERTEX_INPUT_EXT)) {
306 vertex_input = ralloc(mem_ctx, VkPipelineVertexInputStateCreateInfo);
307 result = deep_copy_vertex_input_state(mem_ctx, vertex_input,
308 src->pVertexInputState);
309 if (result != VK_SUCCESS)
310 return result;
311 dst->pVertexInputState = vertex_input;
312 } else
313 dst->pVertexInputState = NULL;
314
315 /* pInputAssemblyState */
316 LVP_PIPELINE_DUP(dst->pInputAssemblyState,
317 src->pInputAssemblyState,
318 VkPipelineInputAssemblyStateCreateInfo,
319 1);
320
321 /* pTessellationState */
322 if (src->pTessellationState &&
323 (stages_present & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) ==
324 (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)) {
325 LVP_PIPELINE_DUP(dst->pTessellationState,
326 src->pTessellationState,
327 VkPipelineTessellationStateCreateInfo,
328 1);
329 }
330
331 /* pViewportState */
332 bool rasterization_disabled = !dynamic_state_contains(src->pDynamicState, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT) &&
333 src->pRasterizationState->rasterizerDiscardEnable;
334 if (src->pViewportState && !rasterization_disabled) {
335 VkPipelineViewportStateCreateInfo *viewport_state;
336 viewport_state = ralloc(mem_ctx, VkPipelineViewportStateCreateInfo);
337 if (!viewport_state)
338 return VK_ERROR_OUT_OF_HOST_MEMORY;
339 deep_copy_viewport_state(mem_ctx, src->pDynamicState,
340 viewport_state, src->pViewportState);
341 dst->pViewportState = viewport_state;
342 } else
343 dst->pViewportState = NULL;
344
345 /* pRasterizationState */
346 rasterization_state = ralloc(mem_ctx, VkPipelineRasterizationStateCreateInfo);
347 if (!rasterization_state)
348 return VK_ERROR_OUT_OF_HOST_MEMORY;
349 deep_copy_rasterization_state(mem_ctx, rasterization_state, src->pRasterizationState);
350 dst->pRasterizationState = rasterization_state;
351
352 /* pMultisampleState */
353 if (src->pMultisampleState && !rasterization_disabled) {
354 VkPipelineMultisampleStateCreateInfo* ms_state;
355 ms_state = ralloc_size(mem_ctx, sizeof(VkPipelineMultisampleStateCreateInfo) + sizeof(VkSampleMask));
356 if (!ms_state)
357 return VK_ERROR_OUT_OF_HOST_MEMORY;
358 /* does samplemask need deep copy? */
359 memcpy(ms_state, src->pMultisampleState, sizeof(VkPipelineMultisampleStateCreateInfo));
360 if (src->pMultisampleState->pSampleMask) {
361 VkSampleMask *sample_mask = (VkSampleMask *)(ms_state + 1);
362 sample_mask[0] = src->pMultisampleState->pSampleMask[0];
363 ms_state->pSampleMask = sample_mask;
364 }
365 dst->pMultisampleState = ms_state;
366 } else
367 dst->pMultisampleState = NULL;
368
369 /* pDepthStencilState */
370 if (src->pDepthStencilState && !rasterization_disabled && pass->has_zs_attachment) {
371 LVP_PIPELINE_DUP(dst->pDepthStencilState,
372 src->pDepthStencilState,
373 VkPipelineDepthStencilStateCreateInfo,
374 1);
375 } else
376 dst->pDepthStencilState = NULL;
377
378 /* pColorBlendState */
379 if (src->pColorBlendState && !rasterization_disabled && pass->has_color_attachment) {
380 VkPipelineColorBlendStateCreateInfo* cb_state;
381
382 cb_state = ralloc(mem_ctx, VkPipelineColorBlendStateCreateInfo);
383 if (!cb_state)
384 return VK_ERROR_OUT_OF_HOST_MEMORY;
385 deep_copy_color_blend_state(mem_ctx, cb_state, src->pColorBlendState);
386 dst->pColorBlendState = cb_state;
387 } else
388 dst->pColorBlendState = NULL;
389
390 if (src->pDynamicState) {
391 VkPipelineDynamicStateCreateInfo* dyn_state;
392
393 /* pDynamicState */
394 dyn_state = ralloc(mem_ctx, VkPipelineDynamicStateCreateInfo);
395 if (!dyn_state)
396 return VK_ERROR_OUT_OF_HOST_MEMORY;
397 deep_copy_dynamic_state(mem_ctx, dyn_state, src->pDynamicState);
398 dst->pDynamicState = dyn_state;
399 } else
400 dst->pDynamicState = NULL;
401
402 return VK_SUCCESS;
403 }
404
405 static VkResult
deep_copy_compute_create_info(void * mem_ctx,VkComputePipelineCreateInfo * dst,const VkComputePipelineCreateInfo * src)406 deep_copy_compute_create_info(void *mem_ctx,
407 VkComputePipelineCreateInfo *dst,
408 const VkComputePipelineCreateInfo *src)
409 {
410 VkResult result;
411 dst->sType = src->sType;
412 dst->pNext = NULL;
413 dst->flags = src->flags;
414 dst->layout = src->layout;
415 dst->basePipelineHandle = src->basePipelineHandle;
416 dst->basePipelineIndex = src->basePipelineIndex;
417
418 result = deep_copy_shader_stage(mem_ctx, &dst->stage, &src->stage);
419 if (result != VK_SUCCESS)
420 return result;
421 return VK_SUCCESS;
422 }
423
424 static inline unsigned
st_shader_stage_to_ptarget(gl_shader_stage stage)425 st_shader_stage_to_ptarget(gl_shader_stage stage)
426 {
427 switch (stage) {
428 case MESA_SHADER_VERTEX:
429 return PIPE_SHADER_VERTEX;
430 case MESA_SHADER_FRAGMENT:
431 return PIPE_SHADER_FRAGMENT;
432 case MESA_SHADER_GEOMETRY:
433 return PIPE_SHADER_GEOMETRY;
434 case MESA_SHADER_TESS_CTRL:
435 return PIPE_SHADER_TESS_CTRL;
436 case MESA_SHADER_TESS_EVAL:
437 return PIPE_SHADER_TESS_EVAL;
438 case MESA_SHADER_COMPUTE:
439 return PIPE_SHADER_COMPUTE;
440 default:
441 break;
442 }
443
444 assert(!"should not be reached");
445 return PIPE_SHADER_VERTEX;
446 }
447
448 static void
shared_var_info(const struct glsl_type * type,unsigned * size,unsigned * align)449 shared_var_info(const struct glsl_type *type, unsigned *size, unsigned *align)
450 {
451 assert(glsl_type_is_vector_or_scalar(type));
452
453 uint32_t comp_size = glsl_type_is_boolean(type)
454 ? 4 : glsl_get_bit_size(type) / 8;
455 unsigned length = glsl_get_vector_elements(type);
456 *size = comp_size * length,
457 *align = comp_size;
458 }
459
460 static void
lvp_shader_compile_to_ir(struct lvp_pipeline * pipeline,struct vk_shader_module * module,const char * entrypoint_name,gl_shader_stage stage,const VkSpecializationInfo * spec_info)461 lvp_shader_compile_to_ir(struct lvp_pipeline *pipeline,
462 struct vk_shader_module *module,
463 const char *entrypoint_name,
464 gl_shader_stage stage,
465 const VkSpecializationInfo *spec_info)
466 {
467 nir_shader *nir;
468 const nir_shader_compiler_options *drv_options = pipeline->device->pscreen->get_compiler_options(pipeline->device->pscreen, PIPE_SHADER_IR_NIR, st_shader_stage_to_ptarget(stage));
469 bool progress;
470 uint32_t *spirv = (uint32_t *) module->data;
471 assert(spirv[0] == SPIR_V_MAGIC_NUMBER);
472 assert(module->size % 4 == 0);
473
474 uint32_t num_spec_entries = 0;
475 struct nir_spirv_specialization *spec_entries =
476 vk_spec_info_to_nir_spirv(spec_info, &num_spec_entries);
477
478 struct lvp_device *pdevice = pipeline->device;
479 const struct spirv_to_nir_options spirv_options = {
480 .environment = NIR_SPIRV_VULKAN,
481 .caps = {
482 .float64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_DOUBLES) == 1),
483 .int16 = true,
484 .int64 = (pdevice->pscreen->get_param(pdevice->pscreen, PIPE_CAP_INT64) == 1),
485 .tessellation = true,
486 .float_controls = true,
487 .image_ms_array = true,
488 .image_read_without_format = true,
489 .image_write_without_format = true,
490 .storage_image_ms = true,
491 .geometry_streams = true,
492 .storage_8bit = true,
493 .storage_16bit = true,
494 .variable_pointers = true,
495 .stencil_export = true,
496 .post_depth_coverage = true,
497 .transform_feedback = true,
498 .device_group = true,
499 .draw_parameters = true,
500 .shader_viewport_index_layer = true,
501 .multiview = true,
502 .physical_storage_buffer_address = true,
503 .int64_atomics = true,
504 .subgroup_arithmetic = true,
505 .subgroup_basic = true,
506 .subgroup_ballot = true,
507 .subgroup_quad = true,
508 .subgroup_vote = true,
509 .int8 = true,
510 .float16 = true,
511 },
512 .ubo_addr_format = nir_address_format_32bit_index_offset,
513 .ssbo_addr_format = nir_address_format_32bit_index_offset,
514 .phys_ssbo_addr_format = nir_address_format_64bit_global,
515 .push_const_addr_format = nir_address_format_logical,
516 .shared_addr_format = nir_address_format_32bit_offset,
517 };
518
519 nir = spirv_to_nir(spirv, module->size / 4,
520 spec_entries, num_spec_entries,
521 stage, entrypoint_name, &spirv_options, drv_options);
522
523 if (!nir) {
524 free(spec_entries);
525 return;
526 }
527 nir_validate_shader(nir, NULL);
528
529 free(spec_entries);
530
531 const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = {
532 .frag_coord = true,
533 .point_coord = true,
534 };
535 NIR_PASS_V(nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings);
536
537 NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp);
538 NIR_PASS_V(nir, nir_lower_returns);
539 NIR_PASS_V(nir, nir_inline_functions);
540 NIR_PASS_V(nir, nir_copy_prop);
541 NIR_PASS_V(nir, nir_opt_deref);
542
543 /* Pick off the single entrypoint that we want */
544 foreach_list_typed_safe(nir_function, func, node, &nir->functions) {
545 if (!func->is_entrypoint)
546 exec_node_remove(&func->node);
547 }
548 assert(exec_list_length(&nir->functions) == 1);
549
550 NIR_PASS_V(nir, nir_lower_variable_initializers, ~0);
551 NIR_PASS_V(nir, nir_split_var_copies);
552 NIR_PASS_V(nir, nir_split_per_member_structs);
553
554 NIR_PASS_V(nir, nir_remove_dead_variables,
555 nir_var_shader_in | nir_var_shader_out | nir_var_system_value, NULL);
556
557 if (stage == MESA_SHADER_FRAGMENT)
558 lvp_lower_input_attachments(nir, false);
559 NIR_PASS_V(nir, nir_lower_system_values);
560 NIR_PASS_V(nir, nir_lower_compute_system_values, NULL);
561
562 NIR_PASS_V(nir, nir_lower_clip_cull_distance_arrays);
563 NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_uniform, NULL);
564
565 lvp_lower_pipeline_layout(pipeline->device, pipeline->layout, nir);
566
567 NIR_PASS_V(nir, nir_lower_io_to_temporaries, nir_shader_get_entrypoint(nir), true, true);
568 NIR_PASS_V(nir, nir_split_var_copies);
569 NIR_PASS_V(nir, nir_lower_global_vars_to_local);
570
571 NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_push_const,
572 nir_address_format_32bit_offset);
573
574 NIR_PASS_V(nir, nir_lower_explicit_io,
575 nir_var_mem_ubo | nir_var_mem_ssbo,
576 nir_address_format_32bit_index_offset);
577
578 NIR_PASS_V(nir, nir_lower_explicit_io,
579 nir_var_mem_global,
580 nir_address_format_64bit_global);
581
582 if (nir->info.stage == MESA_SHADER_COMPUTE) {
583 NIR_PASS_V(nir, nir_lower_vars_to_explicit_types, nir_var_mem_shared, shared_var_info);
584 NIR_PASS_V(nir, nir_lower_explicit_io, nir_var_mem_shared, nir_address_format_32bit_offset);
585 }
586
587 NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_shader_temp, NULL);
588
589 if (nir->info.stage == MESA_SHADER_VERTEX ||
590 nir->info.stage == MESA_SHADER_GEOMETRY) {
591 NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);
592 } else if (nir->info.stage == MESA_SHADER_FRAGMENT) {
593 NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, true);
594 }
595
596 do {
597 progress = false;
598
599 NIR_PASS(progress, nir, nir_lower_flrp, 32|64, true);
600 NIR_PASS(progress, nir, nir_split_array_vars, nir_var_function_temp);
601 NIR_PASS(progress, nir, nir_shrink_vec_array_vars, nir_var_function_temp);
602 NIR_PASS(progress, nir, nir_opt_deref);
603 NIR_PASS(progress, nir, nir_lower_vars_to_ssa);
604
605 NIR_PASS(progress, nir, nir_copy_prop);
606 NIR_PASS(progress, nir, nir_opt_dce);
607 NIR_PASS(progress, nir, nir_opt_peephole_select, 8, true, true);
608
609 NIR_PASS(progress, nir, nir_opt_algebraic);
610 NIR_PASS(progress, nir, nir_opt_constant_folding);
611
612 NIR_PASS(progress, nir, nir_opt_remove_phis);
613 bool trivial_continues = false;
614 NIR_PASS(trivial_continues, nir, nir_opt_trivial_continues);
615 progress |= trivial_continues;
616 if (trivial_continues) {
617 /* If nir_opt_trivial_continues makes progress, then we need to clean
618 * things up if we want any hope of nir_opt_if or nir_opt_loop_unroll
619 * to make progress.
620 */
621 NIR_PASS(progress, nir, nir_copy_prop);
622 NIR_PASS(progress, nir, nir_opt_dce);
623 NIR_PASS(progress, nir, nir_opt_remove_phis);
624 }
625 NIR_PASS(progress, nir, nir_opt_if, true);
626 NIR_PASS(progress, nir, nir_opt_dead_cf);
627 NIR_PASS(progress, nir, nir_opt_conditional_discard);
628 NIR_PASS(progress, nir, nir_opt_remove_phis);
629 NIR_PASS(progress, nir, nir_opt_cse);
630 NIR_PASS(progress, nir, nir_opt_undef);
631
632 NIR_PASS(progress, nir, nir_opt_deref);
633 NIR_PASS(progress, nir, nir_lower_alu_to_scalar, NULL, NULL);
634 } while (progress);
635
636 NIR_PASS_V(nir, nir_lower_var_copies);
637 NIR_PASS_V(nir, nir_remove_dead_variables, nir_var_function_temp, NULL);
638 NIR_PASS_V(nir, nir_opt_dce);
639 nir_sweep(nir);
640
641 nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));
642
643 if (nir->info.stage != MESA_SHADER_VERTEX)
644 nir_assign_io_var_locations(nir, nir_var_shader_in, &nir->num_inputs, nir->info.stage);
645 else {
646 nir->num_inputs = util_last_bit64(nir->info.inputs_read);
647 nir_foreach_shader_in_variable(var, nir) {
648 var->data.driver_location = var->data.location - VERT_ATTRIB_GENERIC0;
649 }
650 }
651 nir_assign_io_var_locations(nir, nir_var_shader_out, &nir->num_outputs,
652 nir->info.stage);
653 pipeline->pipeline_nir[stage] = nir;
654 }
655
fill_shader_prog(struct pipe_shader_state * state,gl_shader_stage stage,struct lvp_pipeline * pipeline)656 static void fill_shader_prog(struct pipe_shader_state *state, gl_shader_stage stage, struct lvp_pipeline *pipeline)
657 {
658 state->type = PIPE_SHADER_IR_NIR;
659 state->ir.nir = pipeline->pipeline_nir[stage];
660 }
661
662 static void
merge_tess_info(struct shader_info * tes_info,const struct shader_info * tcs_info)663 merge_tess_info(struct shader_info *tes_info,
664 const struct shader_info *tcs_info)
665 {
666 /* The Vulkan 1.0.38 spec, section 21.1 Tessellator says:
667 *
668 * "PointMode. Controls generation of points rather than triangles
669 * or lines. This functionality defaults to disabled, and is
670 * enabled if either shader stage includes the execution mode.
671 *
672 * and about Triangles, Quads, IsoLines, VertexOrderCw, VertexOrderCcw,
673 * PointMode, SpacingEqual, SpacingFractionalEven, SpacingFractionalOdd,
674 * and OutputVertices, it says:
675 *
676 * "One mode must be set in at least one of the tessellation
677 * shader stages."
678 *
679 * So, the fields can be set in either the TCS or TES, but they must
680 * agree if set in both. Our backend looks at TES, so bitwise-or in
681 * the values from the TCS.
682 */
683 assert(tcs_info->tess.tcs_vertices_out == 0 ||
684 tes_info->tess.tcs_vertices_out == 0 ||
685 tcs_info->tess.tcs_vertices_out == tes_info->tess.tcs_vertices_out);
686 tes_info->tess.tcs_vertices_out |= tcs_info->tess.tcs_vertices_out;
687
688 assert(tcs_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
689 tes_info->tess.spacing == TESS_SPACING_UNSPECIFIED ||
690 tcs_info->tess.spacing == tes_info->tess.spacing);
691 tes_info->tess.spacing |= tcs_info->tess.spacing;
692
693 assert(tcs_info->tess.primitive_mode == 0 ||
694 tes_info->tess.primitive_mode == 0 ||
695 tcs_info->tess.primitive_mode == tes_info->tess.primitive_mode);
696 tes_info->tess.primitive_mode |= tcs_info->tess.primitive_mode;
697 tes_info->tess.ccw |= tcs_info->tess.ccw;
698 tes_info->tess.point_mode |= tcs_info->tess.point_mode;
699 }
700
701 static gl_shader_stage
lvp_shader_stage(VkShaderStageFlagBits stage)702 lvp_shader_stage(VkShaderStageFlagBits stage)
703 {
704 switch (stage) {
705 case VK_SHADER_STAGE_VERTEX_BIT:
706 return MESA_SHADER_VERTEX;
707 case VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
708 return MESA_SHADER_TESS_CTRL;
709 case VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
710 return MESA_SHADER_TESS_EVAL;
711 case VK_SHADER_STAGE_GEOMETRY_BIT:
712 return MESA_SHADER_GEOMETRY;
713 case VK_SHADER_STAGE_FRAGMENT_BIT:
714 return MESA_SHADER_FRAGMENT;
715 case VK_SHADER_STAGE_COMPUTE_BIT:
716 return MESA_SHADER_COMPUTE;
717 default:
718 unreachable("invalid VkShaderStageFlagBits");
719 return MESA_SHADER_NONE;
720 }
721 }
722
723 static VkResult
lvp_pipeline_compile(struct lvp_pipeline * pipeline,gl_shader_stage stage)724 lvp_pipeline_compile(struct lvp_pipeline *pipeline,
725 gl_shader_stage stage)
726 {
727 struct lvp_device *device = pipeline->device;
728 device->physical_device->pscreen->finalize_nir(device->physical_device->pscreen, pipeline->pipeline_nir[stage]);
729 if (stage == MESA_SHADER_COMPUTE) {
730 struct pipe_compute_state shstate = {0};
731 shstate.prog = (void *)pipeline->pipeline_nir[MESA_SHADER_COMPUTE];
732 shstate.ir_type = PIPE_SHADER_IR_NIR;
733 shstate.req_local_mem = pipeline->pipeline_nir[MESA_SHADER_COMPUTE]->info.shared_size;
734 pipeline->shader_cso[PIPE_SHADER_COMPUTE] = device->queue.ctx->create_compute_state(device->queue.ctx, &shstate);
735 } else {
736 struct pipe_shader_state shstate = {0};
737 fill_shader_prog(&shstate, stage, pipeline);
738
739 if (stage == MESA_SHADER_VERTEX ||
740 stage == MESA_SHADER_GEOMETRY ||
741 stage == MESA_SHADER_TESS_EVAL) {
742 nir_xfb_info *xfb_info = nir_gather_xfb_info(pipeline->pipeline_nir[stage], NULL);
743 if (xfb_info) {
744 uint8_t output_mapping[VARYING_SLOT_TESS_MAX];
745 memset(output_mapping, 0, sizeof(output_mapping));
746
747 nir_foreach_shader_out_variable(var, pipeline->pipeline_nir[stage]) {
748 unsigned slots = var->data.compact ? DIV_ROUND_UP(glsl_get_length(var->type), 4)
749 : glsl_count_attribute_slots(var->type, false);
750 for (unsigned i = 0; i < slots; i++)
751 output_mapping[var->data.location + i] = var->data.driver_location + i;
752 }
753
754 shstate.stream_output.num_outputs = xfb_info->output_count;
755 for (unsigned i = 0; i < PIPE_MAX_SO_BUFFERS; i++) {
756 if (xfb_info->buffers_written & (1 << i)) {
757 shstate.stream_output.stride[i] = xfb_info->buffers[i].stride / 4;
758 }
759 }
760 for (unsigned i = 0; i < xfb_info->output_count; i++) {
761 shstate.stream_output.output[i].output_buffer = xfb_info->outputs[i].buffer;
762 shstate.stream_output.output[i].dst_offset = xfb_info->outputs[i].offset / 4;
763 shstate.stream_output.output[i].register_index = output_mapping[xfb_info->outputs[i].location];
764 shstate.stream_output.output[i].num_components = util_bitcount(xfb_info->outputs[i].component_mask);
765 shstate.stream_output.output[i].start_component = ffs(xfb_info->outputs[i].component_mask) - 1;
766 shstate.stream_output.output[i].stream = xfb_info->buffer_to_stream[xfb_info->outputs[i].buffer];
767 }
768
769 ralloc_free(xfb_info);
770 }
771 }
772
773 switch (stage) {
774 case MESA_SHADER_FRAGMENT:
775 pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
776 break;
777 case MESA_SHADER_VERTEX:
778 pipeline->shader_cso[PIPE_SHADER_VERTEX] = device->queue.ctx->create_vs_state(device->queue.ctx, &shstate);
779 break;
780 case MESA_SHADER_GEOMETRY:
781 pipeline->shader_cso[PIPE_SHADER_GEOMETRY] = device->queue.ctx->create_gs_state(device->queue.ctx, &shstate);
782 break;
783 case MESA_SHADER_TESS_CTRL:
784 pipeline->shader_cso[PIPE_SHADER_TESS_CTRL] = device->queue.ctx->create_tcs_state(device->queue.ctx, &shstate);
785 break;
786 case MESA_SHADER_TESS_EVAL:
787 pipeline->shader_cso[PIPE_SHADER_TESS_EVAL] = device->queue.ctx->create_tes_state(device->queue.ctx, &shstate);
788 break;
789 default:
790 unreachable("illegal shader");
791 break;
792 }
793 }
794 return VK_SUCCESS;
795 }
796
797 static VkResult
lvp_graphics_pipeline_init(struct lvp_pipeline * pipeline,struct lvp_device * device,struct lvp_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc)798 lvp_graphics_pipeline_init(struct lvp_pipeline *pipeline,
799 struct lvp_device *device,
800 struct lvp_pipeline_cache *cache,
801 const VkGraphicsPipelineCreateInfo *pCreateInfo,
802 const VkAllocationCallbacks *alloc)
803 {
804 if (alloc == NULL)
805 alloc = &device->vk.alloc;
806 pipeline->device = device;
807 pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
808 pipeline->force_min_sample = false;
809
810 pipeline->mem_ctx = ralloc_context(NULL);
811 /* recreate createinfo */
812 deep_copy_graphics_create_info(pipeline->mem_ctx, &pipeline->graphics_create_info, pCreateInfo);
813 pipeline->is_compute_pipeline = false;
814
815 const VkPipelineRasterizationProvokingVertexStateCreateInfoEXT *pv_state =
816 vk_find_struct_const(pCreateInfo->pRasterizationState,
817 PIPELINE_RASTERIZATION_PROVOKING_VERTEX_STATE_CREATE_INFO_EXT);
818 pipeline->provoking_vertex_last = pv_state && pv_state->provokingVertexMode == VK_PROVOKING_VERTEX_MODE_LAST_VERTEX_EXT;
819
820 const VkPipelineRasterizationLineStateCreateInfoEXT *line_state =
821 vk_find_struct_const(pCreateInfo->pRasterizationState,
822 PIPELINE_RASTERIZATION_LINE_STATE_CREATE_INFO_EXT);
823 if (line_state) {
824 /* always draw bresenham if !smooth */
825 pipeline->line_stipple_enable = line_state->stippledLineEnable;
826 pipeline->line_smooth = line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
827 pipeline->disable_multisample = line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT ||
828 line_state->lineRasterizationMode == VK_LINE_RASTERIZATION_MODE_RECTANGULAR_SMOOTH_EXT;
829 pipeline->line_rectangular = line_state->lineRasterizationMode != VK_LINE_RASTERIZATION_MODE_BRESENHAM_EXT;
830 if (pipeline->line_stipple_enable) {
831 if (!dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_LINE_STIPPLE_EXT)) {
832 pipeline->line_stipple_factor = line_state->lineStippleFactor - 1;
833 pipeline->line_stipple_pattern = line_state->lineStipplePattern;
834 } else {
835 pipeline->line_stipple_factor = 0;
836 pipeline->line_stipple_pattern = UINT16_MAX;
837 }
838 }
839 } else
840 pipeline->line_rectangular = true;
841
842 bool rasterization_disabled = !dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_RASTERIZER_DISCARD_ENABLE_EXT) &&
843 pipeline->graphics_create_info.pRasterizationState->rasterizerDiscardEnable;
844 LVP_FROM_HANDLE(lvp_render_pass, pass, pipeline->graphics_create_info.renderPass);
845 if (!dynamic_state_contains(pipeline->graphics_create_info.pDynamicState, VK_DYNAMIC_STATE_COLOR_WRITE_ENABLE_EXT) &&
846 !rasterization_disabled && pass->has_color_attachment) {
847 const VkPipelineColorWriteCreateInfoEXT *cw_state =
848 vk_find_struct_const(pCreateInfo->pColorBlendState, PIPELINE_COLOR_WRITE_CREATE_INFO_EXT);
849 if (cw_state) {
850 for (unsigned i = 0; i < cw_state->attachmentCount; i++)
851 if (!cw_state->pColorWriteEnables[i]) {
852 VkPipelineColorBlendAttachmentState *att = (void*)&pipeline->graphics_create_info.pColorBlendState->pAttachments[i];
853 att->colorWriteMask = 0;
854 }
855 }
856 }
857
858
859 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
860 VK_FROM_HANDLE(vk_shader_module, module,
861 pCreateInfo->pStages[i].module);
862 gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
863 lvp_shader_compile_to_ir(pipeline, module,
864 pCreateInfo->pStages[i].pName,
865 stage,
866 pCreateInfo->pStages[i].pSpecializationInfo);
867 if (!pipeline->pipeline_nir[stage])
868 return VK_ERROR_FEATURE_NOT_PRESENT;
869 }
870
871 if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]) {
872 if (pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.fs.uses_sample_qualifier ||
873 BITSET_TEST(pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read, SYSTEM_VALUE_SAMPLE_ID) ||
874 BITSET_TEST(pipeline->pipeline_nir[MESA_SHADER_FRAGMENT]->info.system_values_read, SYSTEM_VALUE_SAMPLE_POS))
875 pipeline->force_min_sample = true;
876 }
877 if (pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]) {
878 nir_lower_patch_vertices(pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL], pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info.tess.tcs_vertices_out, NULL);
879 merge_tess_info(&pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info, &pipeline->pipeline_nir[MESA_SHADER_TESS_CTRL]->info);
880 const VkPipelineTessellationDomainOriginStateCreateInfo *domain_origin_state =
881 vk_find_struct_const(pCreateInfo->pTessellationState,
882 PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO);
883 if (!domain_origin_state || domain_origin_state->domainOrigin == VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT)
884 pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw = !pipeline->pipeline_nir[MESA_SHADER_TESS_EVAL]->info.tess.ccw;
885 }
886
887 pipeline->gs_output_lines = pipeline->pipeline_nir[MESA_SHADER_GEOMETRY] &&
888 pipeline->pipeline_nir[MESA_SHADER_GEOMETRY]->info.gs.output_primitive == GL_LINES;
889
890
891 bool has_fragment_shader = false;
892 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
893 gl_shader_stage stage = lvp_shader_stage(pCreateInfo->pStages[i].stage);
894 lvp_pipeline_compile(pipeline, stage);
895 if (stage == MESA_SHADER_FRAGMENT)
896 has_fragment_shader = true;
897 }
898
899 if (has_fragment_shader == false) {
900 /* create a dummy fragment shader for this pipeline. */
901 nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, NULL,
902 "dummy_frag");
903
904 pipeline->pipeline_nir[MESA_SHADER_FRAGMENT] = b.shader;
905 struct pipe_shader_state shstate = {0};
906 shstate.type = PIPE_SHADER_IR_NIR;
907 shstate.ir.nir = pipeline->pipeline_nir[MESA_SHADER_FRAGMENT];
908 pipeline->shader_cso[PIPE_SHADER_FRAGMENT] = device->queue.ctx->create_fs_state(device->queue.ctx, &shstate);
909 }
910 return VK_SUCCESS;
911 }
912
913 static VkResult
lvp_graphics_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)914 lvp_graphics_pipeline_create(
915 VkDevice _device,
916 VkPipelineCache _cache,
917 const VkGraphicsPipelineCreateInfo *pCreateInfo,
918 const VkAllocationCallbacks *pAllocator,
919 VkPipeline *pPipeline)
920 {
921 LVP_FROM_HANDLE(lvp_device, device, _device);
922 LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
923 struct lvp_pipeline *pipeline;
924 VkResult result;
925
926 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO);
927
928 pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
929 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
930 if (pipeline == NULL)
931 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
932
933 vk_object_base_init(&device->vk, &pipeline->base,
934 VK_OBJECT_TYPE_PIPELINE);
935 result = lvp_graphics_pipeline_init(pipeline, device, cache, pCreateInfo,
936 pAllocator);
937 if (result != VK_SUCCESS) {
938 vk_free2(&device->vk.alloc, pAllocator, pipeline);
939 return result;
940 }
941
942 *pPipeline = lvp_pipeline_to_handle(pipeline);
943
944 return VK_SUCCESS;
945 }
946
lvp_CreateGraphicsPipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)947 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateGraphicsPipelines(
948 VkDevice _device,
949 VkPipelineCache pipelineCache,
950 uint32_t count,
951 const VkGraphicsPipelineCreateInfo* pCreateInfos,
952 const VkAllocationCallbacks* pAllocator,
953 VkPipeline* pPipelines)
954 {
955 VkResult result = VK_SUCCESS;
956 unsigned i = 0;
957
958 for (; i < count; i++) {
959 VkResult r;
960 r = lvp_graphics_pipeline_create(_device,
961 pipelineCache,
962 &pCreateInfos[i],
963 pAllocator, &pPipelines[i]);
964 if (r != VK_SUCCESS) {
965 result = r;
966 pPipelines[i] = VK_NULL_HANDLE;
967 }
968 }
969
970 return result;
971 }
972
973 static VkResult
lvp_compute_pipeline_init(struct lvp_pipeline * pipeline,struct lvp_device * device,struct lvp_pipeline_cache * cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * alloc)974 lvp_compute_pipeline_init(struct lvp_pipeline *pipeline,
975 struct lvp_device *device,
976 struct lvp_pipeline_cache *cache,
977 const VkComputePipelineCreateInfo *pCreateInfo,
978 const VkAllocationCallbacks *alloc)
979 {
980 VK_FROM_HANDLE(vk_shader_module, module,
981 pCreateInfo->stage.module);
982 if (alloc == NULL)
983 alloc = &device->vk.alloc;
984 pipeline->device = device;
985 pipeline->layout = lvp_pipeline_layout_from_handle(pCreateInfo->layout);
986 pipeline->force_min_sample = false;
987
988 pipeline->mem_ctx = ralloc_context(NULL);
989 deep_copy_compute_create_info(pipeline->mem_ctx,
990 &pipeline->compute_create_info, pCreateInfo);
991 pipeline->is_compute_pipeline = true;
992
993 lvp_shader_compile_to_ir(pipeline, module,
994 pCreateInfo->stage.pName,
995 MESA_SHADER_COMPUTE,
996 pCreateInfo->stage.pSpecializationInfo);
997 if (!pipeline->pipeline_nir[MESA_SHADER_COMPUTE])
998 return VK_ERROR_FEATURE_NOT_PRESENT;
999 lvp_pipeline_compile(pipeline, MESA_SHADER_COMPUTE);
1000 return VK_SUCCESS;
1001 }
1002
1003 static VkResult
lvp_compute_pipeline_create(VkDevice _device,VkPipelineCache _cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)1004 lvp_compute_pipeline_create(
1005 VkDevice _device,
1006 VkPipelineCache _cache,
1007 const VkComputePipelineCreateInfo *pCreateInfo,
1008 const VkAllocationCallbacks *pAllocator,
1009 VkPipeline *pPipeline)
1010 {
1011 LVP_FROM_HANDLE(lvp_device, device, _device);
1012 LVP_FROM_HANDLE(lvp_pipeline_cache, cache, _cache);
1013 struct lvp_pipeline *pipeline;
1014 VkResult result;
1015
1016 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO);
1017
1018 pipeline = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*pipeline), 8,
1019 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1020 if (pipeline == NULL)
1021 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1022
1023 vk_object_base_init(&device->vk, &pipeline->base,
1024 VK_OBJECT_TYPE_PIPELINE);
1025 result = lvp_compute_pipeline_init(pipeline, device, cache, pCreateInfo,
1026 pAllocator);
1027 if (result != VK_SUCCESS) {
1028 vk_free2(&device->vk.alloc, pAllocator, pipeline);
1029 return result;
1030 }
1031
1032 *pPipeline = lvp_pipeline_to_handle(pipeline);
1033
1034 return VK_SUCCESS;
1035 }
1036
lvp_CreateComputePipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t count,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)1037 VKAPI_ATTR VkResult VKAPI_CALL lvp_CreateComputePipelines(
1038 VkDevice _device,
1039 VkPipelineCache pipelineCache,
1040 uint32_t count,
1041 const VkComputePipelineCreateInfo* pCreateInfos,
1042 const VkAllocationCallbacks* pAllocator,
1043 VkPipeline* pPipelines)
1044 {
1045 VkResult result = VK_SUCCESS;
1046 unsigned i = 0;
1047
1048 for (; i < count; i++) {
1049 VkResult r;
1050 r = lvp_compute_pipeline_create(_device,
1051 pipelineCache,
1052 &pCreateInfos[i],
1053 pAllocator, &pPipelines[i]);
1054 if (r != VK_SUCCESS) {
1055 result = r;
1056 pPipelines[i] = VK_NULL_HANDLE;
1057 }
1058 }
1059
1060 return result;
1061 }
1062