1 /*
2 * Copyright © 2022 Collabora, LTD
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * 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 "vk_pipeline.h"
25
26 #include "vk_alloc.h"
27 #include "vk_common_entrypoints.h"
28 #include "vk_command_buffer.h"
29 #include "vk_descriptor_set_layout.h"
30 #include "vk_device.h"
31 #include "vk_graphics_state.h"
32 #include "vk_log.h"
33 #include "vk_nir.h"
34 #include "vk_physical_device.h"
35 #include "vk_pipeline_layout.h"
36 #include "vk_shader.h"
37 #include "vk_shader_module.h"
38 #include "vk_util.h"
39
40 #include "nir_serialize.h"
41
42 #include "util/mesa-sha1.h"
43
44 bool
vk_pipeline_shader_stage_is_null(const VkPipelineShaderStageCreateInfo * info)45 vk_pipeline_shader_stage_is_null(const VkPipelineShaderStageCreateInfo *info)
46 {
47 if (info->module != VK_NULL_HANDLE)
48 return false;
49
50 vk_foreach_struct_const(ext, info->pNext) {
51 if (ext->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO ||
52 ext->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT)
53 return false;
54 }
55
56 return true;
57 }
58
59 static nir_shader *
get_builtin_nir(const VkPipelineShaderStageCreateInfo * info)60 get_builtin_nir(const VkPipelineShaderStageCreateInfo *info)
61 {
62 VK_FROM_HANDLE(vk_shader_module, module, info->module);
63
64 nir_shader *nir = NULL;
65 if (module != NULL) {
66 nir = module->nir;
67 } else {
68 const VkPipelineShaderStageNirCreateInfoMESA *nir_info =
69 vk_find_struct_const(info->pNext, PIPELINE_SHADER_STAGE_NIR_CREATE_INFO_MESA);
70 if (nir_info != NULL)
71 nir = nir_info->nir;
72 }
73
74 if (nir == NULL)
75 return NULL;
76
77 assert(nir->info.stage == vk_to_mesa_shader_stage(info->stage));
78 ASSERTED nir_function_impl *entrypoint = nir_shader_get_entrypoint(nir);
79 assert(strcmp(entrypoint->function->name, info->pName) == 0);
80 assert(info->pSpecializationInfo == NULL);
81
82 return nir;
83 }
84
85 static uint32_t
get_required_subgroup_size(const void * info_pNext)86 get_required_subgroup_size(const void *info_pNext)
87 {
88 const VkPipelineShaderStageRequiredSubgroupSizeCreateInfo *rss_info =
89 vk_find_struct_const(info_pNext,
90 PIPELINE_SHADER_STAGE_REQUIRED_SUBGROUP_SIZE_CREATE_INFO);
91 return rss_info != NULL ? rss_info->requiredSubgroupSize : 0;
92 }
93
94 enum gl_subgroup_size
vk_get_subgroup_size(uint32_t spirv_version,gl_shader_stage stage,const void * info_pNext,bool allow_varying,bool require_full)95 vk_get_subgroup_size(uint32_t spirv_version,
96 gl_shader_stage stage,
97 const void *info_pNext,
98 bool allow_varying,
99 bool require_full)
100 {
101 uint32_t req_subgroup_size = get_required_subgroup_size(info_pNext);
102 if (req_subgroup_size > 0) {
103 assert(util_is_power_of_two_nonzero(req_subgroup_size));
104 assert(req_subgroup_size >= 8 && req_subgroup_size <= 128);
105 return req_subgroup_size;
106 } else if (allow_varying || spirv_version >= 0x10600) {
107 /* Starting with SPIR-V 1.6, varying subgroup size the default */
108 return SUBGROUP_SIZE_VARYING;
109 } else if (require_full) {
110 assert(stage == MESA_SHADER_COMPUTE);
111 return SUBGROUP_SIZE_FULL_SUBGROUPS;
112 } else {
113 return SUBGROUP_SIZE_API_CONSTANT;
114 }
115 }
116
117 VkResult
vk_pipeline_shader_stage_to_nir(struct vk_device * device,const VkPipelineShaderStageCreateInfo * info,const struct spirv_to_nir_options * spirv_options,const struct nir_shader_compiler_options * nir_options,void * mem_ctx,nir_shader ** nir_out)118 vk_pipeline_shader_stage_to_nir(struct vk_device *device,
119 const VkPipelineShaderStageCreateInfo *info,
120 const struct spirv_to_nir_options *spirv_options,
121 const struct nir_shader_compiler_options *nir_options,
122 void *mem_ctx, nir_shader **nir_out)
123 {
124 VK_FROM_HANDLE(vk_shader_module, module, info->module);
125 const gl_shader_stage stage = vk_to_mesa_shader_stage(info->stage);
126
127 assert(info->sType == VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO);
128
129 nir_shader *builtin_nir = get_builtin_nir(info);
130 if (builtin_nir != NULL) {
131 nir_validate_shader(builtin_nir, "internal shader");
132
133 nir_shader *clone = nir_shader_clone(mem_ctx, builtin_nir);
134 if (clone == NULL)
135 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
136
137 assert(clone->options == NULL || clone->options == nir_options);
138 clone->options = nir_options;
139
140 *nir_out = clone;
141 return VK_SUCCESS;
142 }
143
144 const uint32_t *spirv_data;
145 uint32_t spirv_size;
146 if (module != NULL) {
147 spirv_data = (uint32_t *)module->data;
148 spirv_size = module->size;
149 } else {
150 const VkShaderModuleCreateInfo *minfo =
151 vk_find_struct_const(info->pNext, SHADER_MODULE_CREATE_INFO);
152 if (unlikely(minfo == NULL)) {
153 return vk_errorf(device, VK_ERROR_UNKNOWN,
154 "No shader module provided");
155 }
156 spirv_data = minfo->pCode;
157 spirv_size = minfo->codeSize;
158 }
159
160 enum gl_subgroup_size subgroup_size = vk_get_subgroup_size(
161 vk_spirv_version(spirv_data, spirv_size),
162 stage, info->pNext,
163 info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_ALLOW_VARYING_SUBGROUP_SIZE_BIT,
164 info->flags & VK_PIPELINE_SHADER_STAGE_CREATE_REQUIRE_FULL_SUBGROUPS_BIT);
165
166 nir_shader *nir = vk_spirv_to_nir(device, spirv_data, spirv_size, stage,
167 info->pName, subgroup_size,
168 info->pSpecializationInfo,
169 spirv_options, nir_options,
170 false /* internal */,
171 mem_ctx);
172 if (nir == NULL)
173 return vk_errorf(device, VK_ERROR_UNKNOWN, "spirv_to_nir failed");
174
175 *nir_out = nir;
176
177 return VK_SUCCESS;
178 }
179
180 void
vk_pipeline_hash_shader_stage(const VkPipelineShaderStageCreateInfo * info,const struct vk_pipeline_robustness_state * rstate,unsigned char * stage_sha1)181 vk_pipeline_hash_shader_stage(const VkPipelineShaderStageCreateInfo *info,
182 const struct vk_pipeline_robustness_state *rstate,
183 unsigned char *stage_sha1)
184 {
185 VK_FROM_HANDLE(vk_shader_module, module, info->module);
186
187 const nir_shader *builtin_nir = get_builtin_nir(info);
188 if (builtin_nir != NULL) {
189 /* Internal NIR module: serialize and hash the NIR shader.
190 * We don't need to hash other info fields since they should match the
191 * NIR data.
192 */
193 struct blob blob;
194
195 blob_init(&blob);
196 nir_serialize(&blob, builtin_nir, false);
197 assert(!blob.out_of_memory);
198 _mesa_sha1_compute(blob.data, blob.size, stage_sha1);
199 blob_finish(&blob);
200 return;
201 }
202
203 const VkShaderModuleCreateInfo *minfo =
204 vk_find_struct_const(info->pNext, SHADER_MODULE_CREATE_INFO);
205 const VkPipelineShaderStageModuleIdentifierCreateInfoEXT *iinfo =
206 vk_find_struct_const(info->pNext, PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT);
207
208 struct mesa_sha1 ctx;
209
210 _mesa_sha1_init(&ctx);
211
212 _mesa_sha1_update(&ctx, &info->flags, sizeof(info->flags));
213
214 assert(util_bitcount(info->stage) == 1);
215 _mesa_sha1_update(&ctx, &info->stage, sizeof(info->stage));
216
217 if (module) {
218 _mesa_sha1_update(&ctx, module->hash, sizeof(module->hash));
219 } else if (minfo) {
220 blake3_hash spirv_hash;
221
222 _mesa_blake3_compute(minfo->pCode, minfo->codeSize, spirv_hash);
223 _mesa_sha1_update(&ctx, spirv_hash, sizeof(spirv_hash));
224 } else {
225 /* It is legal to pass in arbitrary identifiers as long as they don't exceed
226 * the limit. Shaders with bogus identifiers are more or less guaranteed to fail. */
227 assert(iinfo);
228 assert(iinfo->identifierSize <= VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT);
229 _mesa_sha1_update(&ctx, iinfo->pIdentifier, iinfo->identifierSize);
230 }
231
232 if (rstate) {
233 _mesa_sha1_update(&ctx, &rstate->storage_buffers, sizeof(rstate->storage_buffers));
234 _mesa_sha1_update(&ctx, &rstate->uniform_buffers, sizeof(rstate->uniform_buffers));
235 _mesa_sha1_update(&ctx, &rstate->vertex_inputs, sizeof(rstate->vertex_inputs));
236 _mesa_sha1_update(&ctx, &rstate->images, sizeof(rstate->images));
237 }
238
239 _mesa_sha1_update(&ctx, info->pName, strlen(info->pName));
240
241 if (info->pSpecializationInfo) {
242 _mesa_sha1_update(&ctx, info->pSpecializationInfo->pMapEntries,
243 info->pSpecializationInfo->mapEntryCount *
244 sizeof(*info->pSpecializationInfo->pMapEntries));
245 _mesa_sha1_update(&ctx, info->pSpecializationInfo->pData,
246 info->pSpecializationInfo->dataSize);
247 }
248
249 uint32_t req_subgroup_size = get_required_subgroup_size(info);
250 _mesa_sha1_update(&ctx, &req_subgroup_size, sizeof(req_subgroup_size));
251
252 _mesa_sha1_final(&ctx, stage_sha1);
253 }
254
255 static VkPipelineRobustnessBufferBehaviorEXT
vk_device_default_robust_buffer_behavior(const struct vk_device * device)256 vk_device_default_robust_buffer_behavior(const struct vk_device *device)
257 {
258 if (device->enabled_features.robustBufferAccess2) {
259 return VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_2_EXT;
260 } else if (device->enabled_features.robustBufferAccess) {
261 return VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_ROBUST_BUFFER_ACCESS_EXT;
262 } else {
263 return VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DISABLED_EXT;
264 }
265 }
266
267 static VkPipelineRobustnessImageBehaviorEXT
vk_device_default_robust_image_behavior(const struct vk_device * device)268 vk_device_default_robust_image_behavior(const struct vk_device *device)
269 {
270 if (device->enabled_features.robustImageAccess2) {
271 return VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_2_EXT;
272 } else if (device->enabled_features.robustImageAccess) {
273 return VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_ROBUST_IMAGE_ACCESS_EXT;
274 } else {
275 return VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DISABLED_EXT;
276 }
277 }
278
279 void
vk_pipeline_robustness_state_fill(const struct vk_device * device,struct vk_pipeline_robustness_state * rs,const void * pipeline_pNext,const void * shader_stage_pNext)280 vk_pipeline_robustness_state_fill(const struct vk_device *device,
281 struct vk_pipeline_robustness_state *rs,
282 const void *pipeline_pNext,
283 const void *shader_stage_pNext)
284 {
285 rs->uniform_buffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT;
286 rs->storage_buffers = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT;
287 rs->vertex_inputs = VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT;
288 rs->images = VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT;
289
290 const VkPipelineRobustnessCreateInfoEXT *shader_info =
291 vk_find_struct_const(shader_stage_pNext,
292 PIPELINE_ROBUSTNESS_CREATE_INFO_EXT);
293 if (shader_info) {
294 rs->storage_buffers = shader_info->storageBuffers;
295 rs->uniform_buffers = shader_info->uniformBuffers;
296 rs->vertex_inputs = shader_info->vertexInputs;
297 rs->images = shader_info->images;
298 } else {
299 const VkPipelineRobustnessCreateInfoEXT *pipeline_info =
300 vk_find_struct_const(pipeline_pNext,
301 PIPELINE_ROBUSTNESS_CREATE_INFO_EXT);
302 if (pipeline_info) {
303 rs->storage_buffers = pipeline_info->storageBuffers;
304 rs->uniform_buffers = pipeline_info->uniformBuffers;
305 rs->vertex_inputs = pipeline_info->vertexInputs;
306 rs->images = pipeline_info->images;
307 }
308 }
309
310 if (rs->storage_buffers ==
311 VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT)
312 rs->storage_buffers = vk_device_default_robust_buffer_behavior(device);
313
314 if (rs->uniform_buffers ==
315 VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT)
316 rs->uniform_buffers = vk_device_default_robust_buffer_behavior(device);
317
318 if (rs->vertex_inputs ==
319 VK_PIPELINE_ROBUSTNESS_BUFFER_BEHAVIOR_DEVICE_DEFAULT_EXT)
320 rs->vertex_inputs = vk_device_default_robust_buffer_behavior(device);
321
322 if (rs->images == VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT)
323 rs->images = vk_device_default_robust_image_behavior(device);
324 }
325
326 void *
vk_pipeline_zalloc(struct vk_device * device,const struct vk_pipeline_ops * ops,VkPipelineBindPoint bind_point,VkPipelineCreateFlags2KHR flags,const VkAllocationCallbacks * alloc,size_t size)327 vk_pipeline_zalloc(struct vk_device *device,
328 const struct vk_pipeline_ops *ops,
329 VkPipelineBindPoint bind_point,
330 VkPipelineCreateFlags2KHR flags,
331 const VkAllocationCallbacks *alloc,
332 size_t size)
333 {
334 struct vk_pipeline *pipeline;
335
336 pipeline = vk_object_zalloc(device, alloc, size, VK_OBJECT_TYPE_PIPELINE);
337 if (pipeline == NULL)
338 return NULL;
339
340 pipeline->ops = ops;
341 pipeline->bind_point = bind_point;
342 pipeline->flags = flags;
343
344 return pipeline;
345 }
346
347 void
vk_pipeline_free(struct vk_device * device,const VkAllocationCallbacks * alloc,struct vk_pipeline * pipeline)348 vk_pipeline_free(struct vk_device *device,
349 const VkAllocationCallbacks *alloc,
350 struct vk_pipeline *pipeline)
351 {
352 vk_object_free(device, alloc, &pipeline->base);
353 }
354
355 VKAPI_ATTR void VKAPI_CALL
vk_common_DestroyPipeline(VkDevice _device,VkPipeline _pipeline,const VkAllocationCallbacks * pAllocator)356 vk_common_DestroyPipeline(VkDevice _device,
357 VkPipeline _pipeline,
358 const VkAllocationCallbacks *pAllocator)
359 {
360 VK_FROM_HANDLE(vk_device, device, _device);
361 VK_FROM_HANDLE(vk_pipeline, pipeline, _pipeline);
362
363 if (pipeline == NULL)
364 return;
365
366 pipeline->ops->destroy(device, pipeline, pAllocator);
367 }
368
369 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetPipelineExecutablePropertiesKHR(VkDevice _device,const VkPipelineInfoKHR * pPipelineInfo,uint32_t * pExecutableCount,VkPipelineExecutablePropertiesKHR * pProperties)370 vk_common_GetPipelineExecutablePropertiesKHR(
371 VkDevice _device,
372 const VkPipelineInfoKHR *pPipelineInfo,
373 uint32_t *pExecutableCount,
374 VkPipelineExecutablePropertiesKHR *pProperties)
375 {
376 VK_FROM_HANDLE(vk_device, device, _device);
377 VK_FROM_HANDLE(vk_pipeline, pipeline, pPipelineInfo->pipeline);
378
379 return pipeline->ops->get_executable_properties(device, pipeline,
380 pExecutableCount,
381 pProperties);
382 }
383
384 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetPipelineExecutableStatisticsKHR(VkDevice _device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pStatisticCount,VkPipelineExecutableStatisticKHR * pStatistics)385 vk_common_GetPipelineExecutableStatisticsKHR(
386 VkDevice _device,
387 const VkPipelineExecutableInfoKHR *pExecutableInfo,
388 uint32_t *pStatisticCount,
389 VkPipelineExecutableStatisticKHR *pStatistics)
390 {
391 VK_FROM_HANDLE(vk_device, device, _device);
392 VK_FROM_HANDLE(vk_pipeline, pipeline, pExecutableInfo->pipeline);
393
394 return pipeline->ops->get_executable_statistics(device, pipeline,
395 pExecutableInfo->executableIndex,
396 pStatisticCount, pStatistics);
397 }
398
399 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_GetPipelineExecutableInternalRepresentationsKHR(VkDevice _device,const VkPipelineExecutableInfoKHR * pExecutableInfo,uint32_t * pInternalRepresentationCount,VkPipelineExecutableInternalRepresentationKHR * pInternalRepresentations)400 vk_common_GetPipelineExecutableInternalRepresentationsKHR(
401 VkDevice _device,
402 const VkPipelineExecutableInfoKHR *pExecutableInfo,
403 uint32_t *pInternalRepresentationCount,
404 VkPipelineExecutableInternalRepresentationKHR* pInternalRepresentations)
405 {
406 VK_FROM_HANDLE(vk_device, device, _device);
407 VK_FROM_HANDLE(vk_pipeline, pipeline, pExecutableInfo->pipeline);
408
409 return pipeline->ops->get_internal_representations(device, pipeline,
410 pExecutableInfo->executableIndex,
411 pInternalRepresentationCount,
412 pInternalRepresentations);
413 }
414
415 VKAPI_ATTR void VKAPI_CALL
vk_common_CmdBindPipeline(VkCommandBuffer commandBuffer,VkPipelineBindPoint pipelineBindPoint,VkPipeline _pipeline)416 vk_common_CmdBindPipeline(VkCommandBuffer commandBuffer,
417 VkPipelineBindPoint pipelineBindPoint,
418 VkPipeline _pipeline)
419 {
420 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer);
421 VK_FROM_HANDLE(vk_pipeline, pipeline, _pipeline);
422
423 assert(pipeline->bind_point == pipelineBindPoint);
424
425 pipeline->ops->cmd_bind(cmd_buffer, pipeline);
426 }
427
428 static const struct vk_pipeline_cache_object_ops pipeline_shader_cache_ops;
429
430 static struct vk_shader *
vk_shader_from_cache_obj(struct vk_pipeline_cache_object * object)431 vk_shader_from_cache_obj(struct vk_pipeline_cache_object *object)
432 {
433 assert(object->ops == &pipeline_shader_cache_ops);
434 return container_of(object, struct vk_shader, pipeline.cache_obj);
435 }
436
437 static bool
vk_pipeline_shader_serialize(struct vk_pipeline_cache_object * object,struct blob * blob)438 vk_pipeline_shader_serialize(struct vk_pipeline_cache_object *object,
439 struct blob *blob)
440 {
441 struct vk_shader *shader = vk_shader_from_cache_obj(object);
442 struct vk_device *device = shader->base.device;
443
444 return shader->ops->serialize(device, shader, blob);
445 }
446
447 static void
vk_shader_init_cache_obj(struct vk_device * device,struct vk_shader * shader,const void * key_data,size_t key_size)448 vk_shader_init_cache_obj(struct vk_device *device, struct vk_shader *shader,
449 const void *key_data, size_t key_size)
450 {
451 assert(key_size == sizeof(shader->pipeline.cache_key));
452 memcpy(&shader->pipeline.cache_key, key_data,
453 sizeof(shader->pipeline.cache_key));
454
455 vk_pipeline_cache_object_init(device, &shader->pipeline.cache_obj,
456 &pipeline_shader_cache_ops,
457 &shader->pipeline.cache_key,
458 sizeof(shader->pipeline.cache_key));
459 }
460
461 static struct vk_pipeline_cache_object *
vk_pipeline_shader_deserialize(struct vk_pipeline_cache * cache,const void * key_data,size_t key_size,struct blob_reader * blob)462 vk_pipeline_shader_deserialize(struct vk_pipeline_cache *cache,
463 const void *key_data, size_t key_size,
464 struct blob_reader *blob)
465 {
466 struct vk_device *device = cache->base.device;
467 const struct vk_device_shader_ops *ops = device->shader_ops;
468
469 /* TODO: Do we really want to always use the latest version? */
470 const uint32_t version = device->physical->properties.shaderBinaryVersion;
471
472 struct vk_shader *shader;
473 VkResult result = ops->deserialize(device, blob, version,
474 &device->alloc, &shader);
475 if (result != VK_SUCCESS) {
476 assert(result == VK_ERROR_OUT_OF_HOST_MEMORY);
477 return NULL;
478 }
479
480 vk_shader_init_cache_obj(device, shader, key_data, key_size);
481
482 return &shader->pipeline.cache_obj;
483 }
484
485 static void
vk_pipeline_shader_destroy(struct vk_device * device,struct vk_pipeline_cache_object * object)486 vk_pipeline_shader_destroy(struct vk_device *device,
487 struct vk_pipeline_cache_object *object)
488 {
489 struct vk_shader *shader = vk_shader_from_cache_obj(object);
490 assert(shader->base.device == device);
491
492 vk_shader_destroy(device, shader, &device->alloc);
493 }
494
495 static const struct vk_pipeline_cache_object_ops pipeline_shader_cache_ops = {
496 .serialize = vk_pipeline_shader_serialize,
497 .deserialize = vk_pipeline_shader_deserialize,
498 .destroy = vk_pipeline_shader_destroy,
499 };
500
501 static struct vk_shader *
vk_shader_ref(struct vk_shader * shader)502 vk_shader_ref(struct vk_shader *shader)
503 {
504 vk_pipeline_cache_object_ref(&shader->pipeline.cache_obj);
505 return shader;
506 }
507
508 static void
vk_shader_unref(struct vk_device * device,struct vk_shader * shader)509 vk_shader_unref(struct vk_device *device, struct vk_shader *shader)
510 {
511 vk_pipeline_cache_object_unref(device, &shader->pipeline.cache_obj);
512 }
513
514 struct vk_pipeline_tess_info {
515 unsigned tcs_vertices_out : 8;
516 unsigned primitive_mode : 2; /* tess_primitive_mode */
517 unsigned spacing : 2; /* gl_tess_spacing */
518 unsigned ccw : 1;
519 unsigned point_mode : 1;
520 unsigned _pad : 18;
521 };
522 static_assert(sizeof(struct vk_pipeline_tess_info) == 4,
523 "This struct has no holes");
524
525 static void
vk_pipeline_gather_nir_tess_info(const nir_shader * nir,struct vk_pipeline_tess_info * info)526 vk_pipeline_gather_nir_tess_info(const nir_shader *nir,
527 struct vk_pipeline_tess_info *info)
528 {
529 info->tcs_vertices_out = nir->info.tess.tcs_vertices_out;
530 info->primitive_mode = nir->info.tess._primitive_mode;
531 info->spacing = nir->info.tess.spacing;
532 info->ccw = nir->info.tess.ccw;
533 info->point_mode = nir->info.tess.point_mode;
534 }
535
536 static void
vk_pipeline_replace_nir_tess_info(nir_shader * nir,const struct vk_pipeline_tess_info * info)537 vk_pipeline_replace_nir_tess_info(nir_shader *nir,
538 const struct vk_pipeline_tess_info *info)
539 {
540 nir->info.tess.tcs_vertices_out = info->tcs_vertices_out;
541 nir->info.tess._primitive_mode = info->primitive_mode;
542 nir->info.tess.spacing = info->spacing;
543 nir->info.tess.ccw = info->ccw;
544 nir->info.tess.point_mode = info->point_mode;
545 }
546
547 static void
vk_pipeline_tess_info_merge(struct vk_pipeline_tess_info * dst,const struct vk_pipeline_tess_info * src)548 vk_pipeline_tess_info_merge(struct vk_pipeline_tess_info *dst,
549 const struct vk_pipeline_tess_info *src)
550 {
551 /* The Vulkan 1.0.38 spec, section 21.1 Tessellator says:
552 *
553 * "PointMode. Controls generation of points rather than triangles
554 * or lines. This functionality defaults to disabled, and is
555 * enabled if either shader stage includes the execution mode.
556 *
557 * and about Triangles, Quads, IsoLines, VertexOrderCw, VertexOrderCcw,
558 * PointMode, SpacingEqual, SpacingFractionalEven, SpacingFractionalOdd,
559 * and OutputVertices, it says:
560 *
561 * "One mode must be set in at least one of the tessellation
562 * shader stages."
563 *
564 * So, the fields can be set in either the TCS or TES, but they must
565 * agree if set in both.
566 */
567 assert(dst->tcs_vertices_out == 0 ||
568 src->tcs_vertices_out == 0 ||
569 dst->tcs_vertices_out == src->tcs_vertices_out);
570 dst->tcs_vertices_out |= src->tcs_vertices_out;
571
572 static_assert(TESS_SPACING_UNSPECIFIED == 0, "");
573 assert(dst->spacing == TESS_SPACING_UNSPECIFIED ||
574 src->spacing == TESS_SPACING_UNSPECIFIED ||
575 dst->spacing == src->spacing);
576 dst->spacing |= src->spacing;
577
578 static_assert(TESS_PRIMITIVE_UNSPECIFIED == 0, "");
579 assert(dst->primitive_mode == TESS_PRIMITIVE_UNSPECIFIED ||
580 src->primitive_mode == TESS_PRIMITIVE_UNSPECIFIED ||
581 dst->primitive_mode == src->primitive_mode);
582 dst->primitive_mode |= src->primitive_mode;
583 dst->ccw |= src->ccw;
584 dst->point_mode |= src->point_mode;
585 }
586
587 struct vk_pipeline_precomp_shader {
588 struct vk_pipeline_cache_object cache_obj;
589
590 /* Key for this cache_obj in the pipeline cache.
591 *
592 * This is always the output of vk_pipeline_hash_shader_stage() so it must
593 * be a SHA1 hash.
594 */
595 uint8_t cache_key[SHA1_DIGEST_LENGTH];
596
597 gl_shader_stage stage;
598
599 struct vk_pipeline_robustness_state rs;
600
601 /* Tessellation info if the shader is a tessellation shader */
602 struct vk_pipeline_tess_info tess;
603
604 /* Hash of the vk_pipeline_precomp_shader
605 *
606 * This is the hash of the final compiled NIR together with tess info and
607 * robustness state. It's used as a key for final binary lookups. By
608 * having this as a separate key, we can de-duplicate cases where you have
609 * different SPIR-V or specialization constants but end up compiling the
610 * same NIR shader in the end anyway.
611 */
612 blake3_hash blake3;
613
614 struct blob nir_blob;
615 };
616
617 static struct vk_pipeline_precomp_shader *
vk_pipeline_precomp_shader_ref(struct vk_pipeline_precomp_shader * shader)618 vk_pipeline_precomp_shader_ref(struct vk_pipeline_precomp_shader *shader)
619 {
620 vk_pipeline_cache_object_ref(&shader->cache_obj);
621 return shader;
622 }
623
624 static void
vk_pipeline_precomp_shader_unref(struct vk_device * device,struct vk_pipeline_precomp_shader * shader)625 vk_pipeline_precomp_shader_unref(struct vk_device *device,
626 struct vk_pipeline_precomp_shader *shader)
627 {
628 vk_pipeline_cache_object_unref(device, &shader->cache_obj);
629 }
630
631 static const struct vk_pipeline_cache_object_ops pipeline_precomp_shader_cache_ops;
632
633 static struct vk_pipeline_precomp_shader *
vk_pipeline_precomp_shader_from_cache_obj(struct vk_pipeline_cache_object * obj)634 vk_pipeline_precomp_shader_from_cache_obj(struct vk_pipeline_cache_object *obj)
635 {
636 assert(obj->ops == & pipeline_precomp_shader_cache_ops);
637 return container_of(obj, struct vk_pipeline_precomp_shader, cache_obj);
638 }
639
640 static struct vk_pipeline_precomp_shader *
vk_pipeline_precomp_shader_create(struct vk_device * device,const void * key_data,size_t key_size,const struct vk_pipeline_robustness_state * rs,nir_shader * nir)641 vk_pipeline_precomp_shader_create(struct vk_device *device,
642 const void *key_data, size_t key_size,
643 const struct vk_pipeline_robustness_state *rs,
644 nir_shader *nir)
645 {
646 struct blob blob;
647 blob_init(&blob);
648
649 nir_serialize(&blob, nir, false);
650
651 if (blob.out_of_memory)
652 goto fail_blob;
653
654 struct vk_pipeline_precomp_shader *shader =
655 vk_zalloc(&device->alloc, sizeof(*shader), 8,
656 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
657 if (shader == NULL)
658 goto fail_blob;
659
660 assert(sizeof(shader->cache_key) == key_size);
661 memcpy(shader->cache_key, key_data, sizeof(shader->cache_key));
662
663 vk_pipeline_cache_object_init(device, &shader->cache_obj,
664 &pipeline_precomp_shader_cache_ops,
665 shader->cache_key,
666 sizeof(shader->cache_key));
667
668 shader->stage = nir->info.stage;
669 shader->rs = *rs;
670
671 vk_pipeline_gather_nir_tess_info(nir, &shader->tess);
672
673 struct mesa_blake3 blake3_ctx;
674 _mesa_blake3_init(&blake3_ctx);
675 _mesa_blake3_update(&blake3_ctx, rs, sizeof(*rs));
676 _mesa_blake3_update(&blake3_ctx, blob.data, blob.size);
677 _mesa_blake3_final(&blake3_ctx, shader->blake3);
678
679 shader->nir_blob = blob;
680
681 return shader;
682
683 fail_blob:
684 blob_finish(&blob);
685
686 return NULL;
687 }
688
689 static bool
vk_pipeline_precomp_shader_serialize(struct vk_pipeline_cache_object * obj,struct blob * blob)690 vk_pipeline_precomp_shader_serialize(struct vk_pipeline_cache_object *obj,
691 struct blob *blob)
692 {
693 struct vk_pipeline_precomp_shader *shader =
694 vk_pipeline_precomp_shader_from_cache_obj(obj);
695
696 blob_write_uint32(blob, shader->stage);
697 blob_write_bytes(blob, &shader->rs, sizeof(shader->rs));
698 blob_write_bytes(blob, &shader->tess, sizeof(shader->tess));
699 blob_write_bytes(blob, shader->blake3, sizeof(shader->blake3));
700 blob_write_uint64(blob, shader->nir_blob.size);
701 blob_write_bytes(blob, shader->nir_blob.data, shader->nir_blob.size);
702
703 return !blob->out_of_memory;
704 }
705
706 static struct vk_pipeline_cache_object *
vk_pipeline_precomp_shader_deserialize(struct vk_pipeline_cache * cache,const void * key_data,size_t key_size,struct blob_reader * blob)707 vk_pipeline_precomp_shader_deserialize(struct vk_pipeline_cache *cache,
708 const void *key_data, size_t key_size,
709 struct blob_reader *blob)
710 {
711 struct vk_device *device = cache->base.device;
712
713 struct vk_pipeline_precomp_shader *shader =
714 vk_zalloc(&device->alloc, sizeof(*shader), 8,
715 VK_SYSTEM_ALLOCATION_SCOPE_DEVICE);
716 if (shader == NULL)
717 return NULL;
718
719 assert(sizeof(shader->cache_key) == key_size);
720 memcpy(shader->cache_key, key_data, sizeof(shader->cache_key));
721
722 vk_pipeline_cache_object_init(device, &shader->cache_obj,
723 &pipeline_precomp_shader_cache_ops,
724 shader->cache_key,
725 sizeof(shader->cache_key));
726
727 shader->stage = blob_read_uint32(blob);
728 blob_copy_bytes(blob, &shader->rs, sizeof(shader->rs));
729 blob_copy_bytes(blob, &shader->tess, sizeof(shader->tess));
730 blob_copy_bytes(blob, shader->blake3, sizeof(shader->blake3));
731
732 uint64_t nir_size = blob_read_uint64(blob);
733 if (blob->overrun || nir_size > SIZE_MAX)
734 goto fail_shader;
735
736 const void *nir_data = blob_read_bytes(blob, nir_size);
737 if (blob->overrun)
738 goto fail_shader;
739
740 blob_init(&shader->nir_blob);
741 blob_write_bytes(&shader->nir_blob, nir_data, nir_size);
742 if (shader->nir_blob.out_of_memory)
743 goto fail_nir_blob;
744
745 return &shader->cache_obj;
746
747 fail_nir_blob:
748 blob_finish(&shader->nir_blob);
749 fail_shader:
750 vk_pipeline_cache_object_finish(&shader->cache_obj);
751 vk_free(&device->alloc, shader);
752
753 return NULL;
754 }
755
756 static void
vk_pipeline_precomp_shader_destroy(struct vk_device * device,struct vk_pipeline_cache_object * obj)757 vk_pipeline_precomp_shader_destroy(struct vk_device *device,
758 struct vk_pipeline_cache_object *obj)
759 {
760 struct vk_pipeline_precomp_shader *shader =
761 vk_pipeline_precomp_shader_from_cache_obj(obj);
762
763 blob_finish(&shader->nir_blob);
764 vk_pipeline_cache_object_finish(&shader->cache_obj);
765 vk_free(&device->alloc, shader);
766 }
767
768 static nir_shader *
vk_pipeline_precomp_shader_get_nir(const struct vk_pipeline_precomp_shader * shader,const struct nir_shader_compiler_options * nir_options)769 vk_pipeline_precomp_shader_get_nir(const struct vk_pipeline_precomp_shader *shader,
770 const struct nir_shader_compiler_options *nir_options)
771 {
772 struct blob_reader blob;
773 blob_reader_init(&blob, shader->nir_blob.data, shader->nir_blob.size);
774
775 nir_shader *nir = nir_deserialize(NULL, nir_options, &blob);
776 if (blob.overrun) {
777 ralloc_free(nir);
778 return NULL;
779 }
780
781 return nir;
782 }
783
784 static const struct vk_pipeline_cache_object_ops pipeline_precomp_shader_cache_ops = {
785 .serialize = vk_pipeline_precomp_shader_serialize,
786 .deserialize = vk_pipeline_precomp_shader_deserialize,
787 .destroy = vk_pipeline_precomp_shader_destroy,
788 };
789
790 static VkResult
vk_pipeline_precompile_shader(struct vk_device * device,struct vk_pipeline_cache * cache,VkPipelineCreateFlags2KHR pipeline_flags,const void * pipeline_info_pNext,const VkPipelineShaderStageCreateInfo * info,struct vk_pipeline_precomp_shader ** ps_out)791 vk_pipeline_precompile_shader(struct vk_device *device,
792 struct vk_pipeline_cache *cache,
793 VkPipelineCreateFlags2KHR pipeline_flags,
794 const void *pipeline_info_pNext,
795 const VkPipelineShaderStageCreateInfo *info,
796 struct vk_pipeline_precomp_shader **ps_out)
797 {
798 const struct vk_device_shader_ops *ops = device->shader_ops;
799 VkResult result;
800
801 struct vk_pipeline_robustness_state rs;
802 vk_pipeline_robustness_state_fill(device, &rs,
803 pipeline_info_pNext,
804 info->pNext);
805
806 uint8_t stage_sha1[SHA1_DIGEST_LENGTH];
807 vk_pipeline_hash_shader_stage(info, &rs, stage_sha1);
808
809 if (cache != NULL) {
810 struct vk_pipeline_cache_object *cache_obj =
811 vk_pipeline_cache_lookup_object(cache, stage_sha1, sizeof(stage_sha1),
812 &pipeline_precomp_shader_cache_ops,
813 NULL /* cache_hit */);
814 if (cache_obj != NULL) {
815 *ps_out = vk_pipeline_precomp_shader_from_cache_obj(cache_obj);
816 return VK_SUCCESS;
817 }
818 }
819
820 if (pipeline_flags &
821 VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR)
822 return VK_PIPELINE_COMPILE_REQUIRED;
823
824 const gl_shader_stage stage = vk_to_mesa_shader_stage(info->stage);
825 const struct nir_shader_compiler_options *nir_options =
826 ops->get_nir_options(device->physical, stage, &rs);
827 const struct spirv_to_nir_options spirv_options =
828 ops->get_spirv_options(device->physical, stage, &rs);
829
830 nir_shader *nir;
831 result = vk_pipeline_shader_stage_to_nir(device, info, &spirv_options,
832 nir_options, NULL, &nir);
833 if (result != VK_SUCCESS)
834 return result;
835
836 if (ops->preprocess_nir != NULL)
837 ops->preprocess_nir(device->physical, nir);
838
839 struct vk_pipeline_precomp_shader *shader =
840 vk_pipeline_precomp_shader_create(device, stage_sha1,
841 sizeof(stage_sha1),
842 &rs, nir);
843 ralloc_free(nir);
844 if (shader == NULL)
845 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
846
847 if (cache != NULL) {
848 struct vk_pipeline_cache_object *cache_obj = &shader->cache_obj;
849 cache_obj = vk_pipeline_cache_add_object(cache, cache_obj);
850 shader = vk_pipeline_precomp_shader_from_cache_obj(cache_obj);
851 }
852
853 *ps_out = shader;
854
855 return VK_SUCCESS;
856 }
857
858 struct vk_pipeline_stage {
859 gl_shader_stage stage;
860
861 struct vk_pipeline_precomp_shader *precomp;
862 struct vk_shader *shader;
863 };
864
865 static int
cmp_vk_pipeline_stages(const void * _a,const void * _b)866 cmp_vk_pipeline_stages(const void *_a, const void *_b)
867 {
868 const struct vk_pipeline_stage *a = _a, *b = _b;
869 return vk_shader_cmp_graphics_stages(a->stage, b->stage);
870 }
871
872 static bool
vk_pipeline_stage_is_null(const struct vk_pipeline_stage * stage)873 vk_pipeline_stage_is_null(const struct vk_pipeline_stage *stage)
874 {
875 return stage->precomp == NULL && stage->shader == NULL;
876 }
877
878 static void
vk_pipeline_stage_finish(struct vk_device * device,struct vk_pipeline_stage * stage)879 vk_pipeline_stage_finish(struct vk_device *device,
880 struct vk_pipeline_stage *stage)
881 {
882 if (stage->precomp != NULL)
883 vk_pipeline_precomp_shader_unref(device, stage->precomp);
884
885 if (stage->shader)
886 vk_shader_unref(device, stage->shader);
887 }
888
889 static struct vk_pipeline_stage
vk_pipeline_stage_clone(const struct vk_pipeline_stage * in)890 vk_pipeline_stage_clone(const struct vk_pipeline_stage *in)
891 {
892 struct vk_pipeline_stage out = {
893 .stage = in->stage,
894 };
895
896 if (in->precomp)
897 out.precomp = vk_pipeline_precomp_shader_ref(in->precomp);
898
899 if (in->shader)
900 out.shader = vk_shader_ref(in->shader);
901
902 return out;
903 }
904
905 struct vk_graphics_pipeline {
906 struct vk_pipeline base;
907
908 union {
909 struct {
910 struct vk_graphics_pipeline_all_state all_state;
911 struct vk_graphics_pipeline_state state;
912 } lib;
913
914 struct {
915 struct vk_vertex_input_state _dynamic_vi;
916 struct vk_sample_locations_state _dynamic_sl;
917 struct vk_dynamic_graphics_state dynamic;
918 } linked;
919 };
920
921 uint32_t set_layout_count;
922 struct vk_descriptor_set_layout *set_layouts[MESA_VK_MAX_DESCRIPTOR_SETS];
923
924 uint32_t stage_count;
925 struct vk_pipeline_stage stages[MESA_VK_MAX_GRAPHICS_PIPELINE_STAGES];
926 };
927
928 static void
vk_graphics_pipeline_destroy(struct vk_device * device,struct vk_pipeline * pipeline,const VkAllocationCallbacks * pAllocator)929 vk_graphics_pipeline_destroy(struct vk_device *device,
930 struct vk_pipeline *pipeline,
931 const VkAllocationCallbacks *pAllocator)
932 {
933 struct vk_graphics_pipeline *gfx_pipeline =
934 container_of(pipeline, struct vk_graphics_pipeline, base);
935
936 for (uint32_t i = 0; i < gfx_pipeline->stage_count; i++)
937 vk_pipeline_stage_finish(device, &gfx_pipeline->stages[i]);
938
939 for (uint32_t i = 0; i < gfx_pipeline->set_layout_count; i++) {
940 if (gfx_pipeline->set_layouts[i] != NULL)
941 vk_descriptor_set_layout_unref(device, gfx_pipeline->set_layouts[i]);
942 }
943
944 vk_pipeline_free(device, pAllocator, pipeline);
945 }
946
947 static bool
vk_device_supports_stage(struct vk_device * device,gl_shader_stage stage)948 vk_device_supports_stage(struct vk_device *device,
949 gl_shader_stage stage)
950 {
951 const struct vk_features *features = &device->physical->supported_features;
952
953 switch (stage) {
954 case MESA_SHADER_VERTEX:
955 case MESA_SHADER_FRAGMENT:
956 case MESA_SHADER_COMPUTE:
957 return true;
958 case MESA_SHADER_TESS_CTRL:
959 case MESA_SHADER_TESS_EVAL:
960 return features->tessellationShader;
961 case MESA_SHADER_GEOMETRY:
962 return features->geometryShader;
963 case MESA_SHADER_TASK:
964 return features->taskShader;
965 case MESA_SHADER_MESH:
966 return features->meshShader;
967 default:
968 return false;
969 }
970 }
971
972 static const gl_shader_stage all_gfx_stages[] = {
973 MESA_SHADER_VERTEX,
974 MESA_SHADER_TESS_CTRL,
975 MESA_SHADER_TESS_EVAL,
976 MESA_SHADER_GEOMETRY,
977 MESA_SHADER_TASK,
978 MESA_SHADER_MESH,
979 MESA_SHADER_FRAGMENT,
980 };
981
982 static void
vk_graphics_pipeline_cmd_bind(struct vk_command_buffer * cmd_buffer,struct vk_pipeline * pipeline)983 vk_graphics_pipeline_cmd_bind(struct vk_command_buffer *cmd_buffer,
984 struct vk_pipeline *pipeline)
985 {
986 struct vk_device *device = cmd_buffer->base.device;
987 const struct vk_device_shader_ops *ops = device->shader_ops;
988
989 struct vk_graphics_pipeline *gfx_pipeline = NULL;
990 struct vk_shader *stage_shader[PIPE_SHADER_MESH_TYPES] = { NULL, };
991 if (pipeline != NULL) {
992 assert(pipeline->bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
993 assert(!(pipeline->flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR));
994 gfx_pipeline = container_of(pipeline, struct vk_graphics_pipeline, base);
995
996 for (uint32_t i = 0; i < gfx_pipeline->stage_count; i++) {
997 struct vk_shader *shader = gfx_pipeline->stages[i].shader;
998 stage_shader[shader->stage] = shader;
999 }
1000 }
1001
1002 uint32_t stage_count = 0;
1003 gl_shader_stage stages[ARRAY_SIZE(all_gfx_stages)];
1004 struct vk_shader *shaders[ARRAY_SIZE(all_gfx_stages)];
1005
1006 VkShaderStageFlags vk_stages = 0;
1007 for (uint32_t i = 0; i < ARRAY_SIZE(all_gfx_stages); i++) {
1008 gl_shader_stage stage = all_gfx_stages[i];
1009 if (!vk_device_supports_stage(device, stage)) {
1010 assert(stage_shader[stage] == NULL);
1011 continue;
1012 }
1013
1014 vk_stages |= mesa_to_vk_shader_stage(stage);
1015
1016 stages[stage_count] = stage;
1017 shaders[stage_count] = stage_shader[stage];
1018 stage_count++;
1019 }
1020 ops->cmd_bind_shaders(cmd_buffer, stage_count, stages, shaders);
1021
1022 if (gfx_pipeline != NULL) {
1023 cmd_buffer->pipeline_shader_stages |= vk_stages;
1024 ops->cmd_set_dynamic_graphics_state(cmd_buffer,
1025 &gfx_pipeline->linked.dynamic);
1026 } else {
1027 cmd_buffer->pipeline_shader_stages &= ~vk_stages;
1028 }
1029 }
1030
1031 static VkShaderCreateFlagsEXT
vk_pipeline_to_shader_flags(VkPipelineCreateFlags2KHR pipeline_flags,gl_shader_stage stage)1032 vk_pipeline_to_shader_flags(VkPipelineCreateFlags2KHR pipeline_flags,
1033 gl_shader_stage stage)
1034 {
1035 VkShaderCreateFlagsEXT shader_flags = 0;
1036
1037 if (pipeline_flags & VK_PIPELINE_CREATE_2_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_KHR)
1038 shader_flags |= VK_SHADER_CREATE_CAPTURE_INTERNAL_REPRESENTATIONS_BIT_MESA;
1039
1040 if (stage == MESA_SHADER_FRAGMENT) {
1041 if (pipeline_flags & VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)
1042 shader_flags |= VK_SHADER_CREATE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_EXT;
1043
1044 if (pipeline_flags & VK_PIPELINE_CREATE_2_RENDERING_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT)
1045 shader_flags |= VK_SHADER_CREATE_FRAGMENT_DENSITY_MAP_ATTACHMENT_BIT_EXT;
1046 }
1047
1048 if (stage == MESA_SHADER_COMPUTE) {
1049 if (pipeline_flags & VK_PIPELINE_CREATE_2_DISPATCH_BASE_BIT_KHR)
1050 shader_flags |= VK_SHADER_CREATE_DISPATCH_BASE_BIT_EXT;
1051 }
1052
1053 return shader_flags;
1054 }
1055
1056 static VkResult
vk_graphics_pipeline_compile_shaders(struct vk_device * device,struct vk_pipeline_cache * cache,struct vk_graphics_pipeline * pipeline,struct vk_pipeline_layout * pipeline_layout,const struct vk_graphics_pipeline_state * state,uint32_t stage_count,struct vk_pipeline_stage * stages,VkPipelineCreationFeedback * stage_feedbacks)1057 vk_graphics_pipeline_compile_shaders(struct vk_device *device,
1058 struct vk_pipeline_cache *cache,
1059 struct vk_graphics_pipeline *pipeline,
1060 struct vk_pipeline_layout *pipeline_layout,
1061 const struct vk_graphics_pipeline_state *state,
1062 uint32_t stage_count,
1063 struct vk_pipeline_stage *stages,
1064 VkPipelineCreationFeedback *stage_feedbacks)
1065 {
1066 const struct vk_device_shader_ops *ops = device->shader_ops;
1067 VkResult result;
1068
1069 if (stage_count == 0)
1070 return VK_SUCCESS;
1071
1072 /* If we're linking, throw away any previously compiled shaders as they
1073 * likely haven't been properly linked. We keep the precompiled shaders
1074 * and we still look it up in the cache so it may still be fast.
1075 */
1076 if (pipeline->base.flags & VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT) {
1077 for (uint32_t i = 0; i < stage_count; i++) {
1078 if (stages[i].shader != NULL) {
1079 vk_shader_unref(device, stages[i].shader);
1080 stages[i].shader = NULL;
1081 }
1082 }
1083 }
1084
1085 bool have_all_shaders = true;
1086 VkShaderStageFlags all_stages = 0;
1087 struct vk_pipeline_precomp_shader *tcs_precomp = NULL, *tes_precomp = NULL;
1088 for (uint32_t i = 0; i < stage_count; i++) {
1089 all_stages |= mesa_to_vk_shader_stage(stages[i].stage);
1090
1091 if (stages[i].shader == NULL)
1092 have_all_shaders = false;
1093
1094 if (stages[i].stage == MESA_SHADER_TESS_CTRL)
1095 tcs_precomp = stages[i].precomp;
1096
1097 if (stages[i].stage == MESA_SHADER_TESS_EVAL)
1098 tes_precomp = stages[i].precomp;
1099 }
1100
1101 /* If we already have a shader for each stage, there's nothing to do. */
1102 if (have_all_shaders)
1103 return VK_SUCCESS;
1104
1105 struct vk_pipeline_tess_info tess_info = { ._pad = 0 };
1106 if (tcs_precomp != NULL && tes_precomp != NULL) {
1107 tess_info = tcs_precomp->tess;
1108 vk_pipeline_tess_info_merge(&tess_info, &tes_precomp->tess);
1109 }
1110
1111 struct mesa_blake3 blake3_ctx;
1112 _mesa_blake3_init(&blake3_ctx);
1113 for (uint32_t i = 0; i < pipeline->set_layout_count; i++) {
1114 if (pipeline->set_layouts[i] != NULL) {
1115 _mesa_blake3_update(&blake3_ctx, pipeline->set_layouts[i]->blake3,
1116 sizeof(pipeline->set_layouts[i]->blake3));
1117 }
1118 }
1119 if (pipeline_layout != NULL) {
1120 _mesa_blake3_update(&blake3_ctx, &pipeline_layout->push_ranges,
1121 sizeof(pipeline_layout->push_ranges[0]) *
1122 pipeline_layout->push_range_count);
1123 }
1124 blake3_hash layout_blake3;
1125 _mesa_blake3_final(&blake3_ctx, layout_blake3);
1126
1127 /* Partition the shaders */
1128 uint32_t part_count;
1129 uint32_t partition[MESA_VK_MAX_GRAPHICS_PIPELINE_STAGES + 1] = { 0 };
1130 if (pipeline->base.flags & VK_PIPELINE_CREATE_2_LINK_TIME_OPTIMIZATION_BIT_EXT) {
1131 partition[1] = stage_count;
1132 part_count = 1;
1133 } else if (ops->link_geom_stages) {
1134 if (stages[0].stage == MESA_SHADER_FRAGMENT) {
1135 assert(stage_count == 1);
1136 partition[1] = stage_count;
1137 part_count = 1;
1138 } else if (stages[stage_count - 1].stage == MESA_SHADER_FRAGMENT) {
1139 /* In this case we have both */
1140 assert(stage_count > 1);
1141 partition[1] = stage_count - 1;
1142 partition[2] = stage_count;
1143 part_count = 2;
1144 } else {
1145 /* In this case we only have geometry */
1146 partition[1] = stage_count;
1147 part_count = 1;
1148 }
1149 } else {
1150 /* Otherwise, we're don't want to link anything */
1151 part_count = stage_count;
1152 for (uint32_t i = 0; i < stage_count; i++)
1153 partition[i + 1] = i + 1;
1154 }
1155
1156 for (uint32_t p = 0; p < part_count; p++) {
1157 const int64_t part_start = os_time_get_nano();
1158
1159 struct vk_shader_pipeline_cache_key shader_key = { 0 };
1160
1161 _mesa_blake3_init(&blake3_ctx);
1162
1163 VkShaderStageFlags part_stages = 0;
1164 for (uint32_t i = partition[p]; i < partition[p + 1]; i++) {
1165 const struct vk_pipeline_stage *stage = &stages[i];
1166
1167 part_stages |= mesa_to_vk_shader_stage(stage->stage);
1168 _mesa_blake3_update(&blake3_ctx, stage->precomp->blake3,
1169 sizeof(stage->precomp->blake3));
1170
1171 VkShaderCreateFlagsEXT shader_flags =
1172 vk_pipeline_to_shader_flags(pipeline->base.flags, stage->stage);
1173 _mesa_blake3_update(&blake3_ctx, &shader_flags, sizeof(shader_flags));
1174 }
1175
1176 blake3_hash state_blake3;
1177 ops->hash_graphics_state(device->physical, state,
1178 part_stages, state_blake3);
1179
1180 _mesa_blake3_update(&blake3_ctx, state_blake3, sizeof(state_blake3));
1181 _mesa_blake3_update(&blake3_ctx, layout_blake3, sizeof(layout_blake3));
1182
1183 if (part_stages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
1184 VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT))
1185 _mesa_blake3_update(&blake3_ctx, &tess_info, sizeof(tess_info));
1186
1187 /* The set of geometry stages used together is used to generate the
1188 * nextStage mask as well as VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT.
1189 */
1190 const VkShaderStageFlags geom_stages =
1191 all_stages & ~VK_SHADER_STAGE_FRAGMENT_BIT;
1192 _mesa_blake3_update(&blake3_ctx, &geom_stages, sizeof(geom_stages));
1193
1194 _mesa_blake3_final(&blake3_ctx, shader_key.blake3);
1195
1196 if (cache != NULL) {
1197 /* From the Vulkan 1.3.278 spec:
1198 *
1199 * "VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT
1200 * indicates that a readily usable pipeline or pipeline stage was
1201 * found in the pipelineCache specified by the application in the
1202 * pipeline creation command.
1203 *
1204 * [...]
1205 *
1206 * Note
1207 *
1208 * Implementations are encouraged to provide a meaningful signal
1209 * to applications using this bit. The intention is to communicate
1210 * to the application that the pipeline or pipeline stage was
1211 * created “as fast as it gets” using the pipeline cache provided
1212 * by the application. If an implementation uses an internal
1213 * cache, it is discouraged from setting this bit as the feedback
1214 * would be unactionable."
1215 *
1216 * The cache_hit value returned by vk_pipeline_cache_lookup_object()
1217 * is only set to true when the shader is found in the provided
1218 * pipeline cache. It is left false if we fail to find it in the
1219 * memory cache but find it in the disk cache even though that's
1220 * still a cache hit from the perspective of the compile pipeline.
1221 */
1222 bool all_shaders_found = true;
1223 bool all_cache_hits = true;
1224 for (uint32_t i = partition[p]; i < partition[p + 1]; i++) {
1225 struct vk_pipeline_stage *stage = &stages[i];
1226
1227 shader_key.stage = stage->stage;
1228
1229 bool cache_hit = false;
1230 struct vk_pipeline_cache_object *cache_obj =
1231 vk_pipeline_cache_lookup_object(cache, &shader_key,
1232 sizeof(shader_key),
1233 &pipeline_shader_cache_ops,
1234 &cache_hit);
1235 if (cache_obj != NULL) {
1236 stage->shader = vk_shader_from_cache_obj(cache_obj);
1237 } else {
1238 all_shaders_found = false;
1239 }
1240
1241 if (cache_obj == NULL && !cache_hit)
1242 all_cache_hits = false;
1243 }
1244
1245 if (all_cache_hits) {
1246 /* The pipeline cache only really helps if we hit for everything
1247 * in the partition. Otherwise, we have to go re-compile it all
1248 * anyway.
1249 */
1250 for (uint32_t i = partition[p]; i < partition[p + 1]; i++) {
1251 struct vk_pipeline_stage *stage = &stages[i];
1252
1253 stage_feedbacks[stage->stage].flags |=
1254 VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
1255 }
1256 }
1257
1258 if (all_shaders_found) {
1259 /* Update duration to take cache lookups into account */
1260 const int64_t part_end = os_time_get_nano();
1261 for (uint32_t i = partition[p]; i < partition[p + 1]; i++) {
1262 struct vk_pipeline_stage *stage = &stages[i];
1263 stage_feedbacks[stage->stage].duration += part_end - part_start;
1264 }
1265 continue;
1266 }
1267 }
1268
1269 if (pipeline->base.flags &
1270 VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR)
1271 return VK_PIPELINE_COMPILE_REQUIRED;
1272
1273 struct vk_shader_compile_info infos[MESA_VK_MAX_GRAPHICS_PIPELINE_STAGES];
1274 for (uint32_t i = partition[p]; i < partition[p + 1]; i++) {
1275 struct vk_pipeline_stage *stage = &stages[i];
1276
1277 VkShaderCreateFlagsEXT shader_flags =
1278 vk_pipeline_to_shader_flags(pipeline->base.flags, stage->stage);
1279
1280 if (partition[p + 1] - partition[p] > 1)
1281 shader_flags |= VK_SHADER_CREATE_LINK_STAGE_BIT_EXT;
1282
1283 if ((part_stages & VK_SHADER_STAGE_MESH_BIT_EXT) &&
1284 !(geom_stages & VK_SHADER_STAGE_TASK_BIT_EXT))
1285 shader_flags = VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT;
1286
1287 VkShaderStageFlags next_stage;
1288 if (stage->stage == MESA_SHADER_FRAGMENT) {
1289 next_stage = 0;
1290 } else if (i + 1 < stage_count) {
1291 /* We hash geom_stages above so this is safe */
1292 next_stage = mesa_to_vk_shader_stage(stages[i + 1].stage);
1293 } else {
1294 /* We're the last geometry stage */
1295 next_stage = VK_SHADER_STAGE_FRAGMENT_BIT;
1296 }
1297
1298 const struct nir_shader_compiler_options *nir_options =
1299 ops->get_nir_options(device->physical, stage->stage,
1300 &stage->precomp->rs);
1301
1302 nir_shader *nir =
1303 vk_pipeline_precomp_shader_get_nir(stage->precomp, nir_options);
1304 if (nir == NULL) {
1305 for (uint32_t j = partition[p]; j < i; j++)
1306 ralloc_free(infos[i].nir);
1307
1308 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1309 }
1310
1311 if (stage->stage == MESA_SHADER_TESS_CTRL ||
1312 stage->stage == MESA_SHADER_TESS_EVAL)
1313 vk_pipeline_replace_nir_tess_info(nir, &tess_info);
1314
1315 const VkPushConstantRange *push_range = NULL;
1316 if (pipeline_layout != NULL) {
1317 for (uint32_t r = 0; r < pipeline_layout->push_range_count; r++) {
1318 if (pipeline_layout->push_ranges[r].stageFlags &
1319 mesa_to_vk_shader_stage(stage->stage)) {
1320 assert(push_range == NULL);
1321 push_range = &pipeline_layout->push_ranges[r];
1322 }
1323 }
1324 }
1325
1326 infos[i] = (struct vk_shader_compile_info) {
1327 .stage = stage->stage,
1328 .flags = shader_flags,
1329 .next_stage_mask = next_stage,
1330 .nir = nir,
1331 .robustness = &stage->precomp->rs,
1332 .set_layout_count = pipeline->set_layout_count,
1333 .set_layouts = pipeline->set_layouts,
1334 .push_constant_range_count = push_range != NULL,
1335 .push_constant_ranges = push_range != NULL ? push_range : NULL,
1336 };
1337 }
1338
1339 /* vk_shader_ops::compile() consumes the NIR regardless of whether or
1340 * not it succeeds and only generates shaders on success. Once this
1341 * returns, we own the shaders but not the NIR in infos.
1342 */
1343 struct vk_shader *shaders[MESA_VK_MAX_GRAPHICS_PIPELINE_STAGES];
1344 result = ops->compile(device, partition[p + 1] - partition[p],
1345 &infos[partition[p]],
1346 state,
1347 &device->alloc,
1348 &shaders[partition[p]]);
1349 if (result != VK_SUCCESS)
1350 return result;
1351
1352 const int64_t part_end = os_time_get_nano();
1353 for (uint32_t i = partition[p]; i < partition[p + 1]; i++) {
1354 struct vk_pipeline_stage *stage = &stages[i];
1355
1356 if (stage->shader == NULL) {
1357 shader_key.stage = stage->stage;
1358 vk_shader_init_cache_obj(device, shaders[i], &shader_key,
1359 sizeof(shader_key));
1360
1361 struct vk_pipeline_cache_object *cache_obj =
1362 &shaders[i]->pipeline.cache_obj;
1363 if (cache != NULL)
1364 cache_obj = vk_pipeline_cache_add_object(cache, cache_obj);
1365
1366 stage->shader = vk_shader_from_cache_obj(cache_obj);
1367 } else {
1368 /* This can fail to happen if only some of the shaders were found
1369 * in the pipeline cache. In this case, we just throw away the
1370 * shader as vk_pipeline_cache_add_object() would throw it away
1371 * for us anyway.
1372 */
1373 vk_shader_destroy(device, shaders[i], &device->alloc);
1374 }
1375
1376 stage_feedbacks[stage->stage].duration += part_end - part_start;
1377 }
1378 }
1379
1380 return VK_SUCCESS;
1381 }
1382
1383 static VkResult
vk_graphics_pipeline_get_executable_properties(struct vk_device * device,struct vk_pipeline * pipeline,uint32_t * executable_count,VkPipelineExecutablePropertiesKHR * properties)1384 vk_graphics_pipeline_get_executable_properties(
1385 struct vk_device *device,
1386 struct vk_pipeline *pipeline,
1387 uint32_t *executable_count,
1388 VkPipelineExecutablePropertiesKHR *properties)
1389 {
1390 struct vk_graphics_pipeline *gfx_pipeline =
1391 container_of(pipeline, struct vk_graphics_pipeline, base);
1392 VkResult result;
1393
1394 if (properties == NULL) {
1395 *executable_count = 0;
1396 for (uint32_t i = 0; i < gfx_pipeline->stage_count; i++) {
1397 struct vk_shader *shader = gfx_pipeline->stages[i].shader;
1398
1399 uint32_t shader_exec_count = 0;
1400 result = shader->ops->get_executable_properties(device, shader,
1401 &shader_exec_count,
1402 NULL);
1403 assert(result == VK_SUCCESS);
1404 *executable_count += shader_exec_count;
1405 }
1406 } else {
1407 uint32_t arr_len = *executable_count;
1408 *executable_count = 0;
1409 for (uint32_t i = 0; i < gfx_pipeline->stage_count; i++) {
1410 struct vk_shader *shader = gfx_pipeline->stages[i].shader;
1411
1412 uint32_t shader_exec_count = arr_len - *executable_count;
1413 result = shader->ops->get_executable_properties(device, shader,
1414 &shader_exec_count,
1415 &properties[*executable_count]);
1416 if (result != VK_SUCCESS)
1417 return result;
1418
1419 *executable_count += shader_exec_count;
1420 }
1421 }
1422
1423 return VK_SUCCESS;
1424 }
1425
1426 static inline struct vk_shader *
vk_graphics_pipeline_executable_shader(struct vk_device * device,struct vk_graphics_pipeline * gfx_pipeline,uint32_t * executable_index)1427 vk_graphics_pipeline_executable_shader(struct vk_device *device,
1428 struct vk_graphics_pipeline *gfx_pipeline,
1429 uint32_t *executable_index)
1430 {
1431 for (uint32_t i = 0; i < gfx_pipeline->stage_count; i++) {
1432 struct vk_shader *shader = gfx_pipeline->stages[i].shader;
1433
1434 uint32_t shader_exec_count = 0;
1435 shader->ops->get_executable_properties(device, shader,
1436 &shader_exec_count, NULL);
1437
1438 if (*executable_index < shader_exec_count)
1439 return shader;
1440 else
1441 *executable_index -= shader_exec_count;
1442 }
1443
1444 return NULL;
1445 }
1446
1447 static VkResult
vk_graphics_pipeline_get_executable_statistics(struct vk_device * device,struct vk_pipeline * pipeline,uint32_t executable_index,uint32_t * statistic_count,VkPipelineExecutableStatisticKHR * statistics)1448 vk_graphics_pipeline_get_executable_statistics(
1449 struct vk_device *device,
1450 struct vk_pipeline *pipeline,
1451 uint32_t executable_index,
1452 uint32_t *statistic_count,
1453 VkPipelineExecutableStatisticKHR *statistics)
1454 {
1455 struct vk_graphics_pipeline *gfx_pipeline =
1456 container_of(pipeline, struct vk_graphics_pipeline, base);
1457
1458 struct vk_shader *shader =
1459 vk_graphics_pipeline_executable_shader(device, gfx_pipeline,
1460 &executable_index);
1461 if (shader == NULL) {
1462 *statistic_count = 0;
1463 return VK_SUCCESS;
1464 }
1465
1466 return shader->ops->get_executable_statistics(device, shader,
1467 executable_index,
1468 statistic_count,
1469 statistics);
1470 }
1471
1472 static VkResult
vk_graphics_pipeline_get_internal_representations(struct vk_device * device,struct vk_pipeline * pipeline,uint32_t executable_index,uint32_t * internal_representation_count,VkPipelineExecutableInternalRepresentationKHR * internal_representations)1473 vk_graphics_pipeline_get_internal_representations(
1474 struct vk_device *device,
1475 struct vk_pipeline *pipeline,
1476 uint32_t executable_index,
1477 uint32_t *internal_representation_count,
1478 VkPipelineExecutableInternalRepresentationKHR* internal_representations)
1479 {
1480 struct vk_graphics_pipeline *gfx_pipeline =
1481 container_of(pipeline, struct vk_graphics_pipeline, base);
1482
1483 struct vk_shader *shader =
1484 vk_graphics_pipeline_executable_shader(device, gfx_pipeline,
1485 &executable_index);
1486 if (shader == NULL) {
1487 *internal_representation_count = 0;
1488 return VK_SUCCESS;
1489 }
1490
1491 return shader->ops->get_executable_internal_representations(
1492 device, shader, executable_index,
1493 internal_representation_count, internal_representations);
1494 }
1495
1496 static const struct vk_pipeline_ops vk_graphics_pipeline_ops = {
1497 .destroy = vk_graphics_pipeline_destroy,
1498 .get_executable_statistics = vk_graphics_pipeline_get_executable_statistics,
1499 .get_executable_properties = vk_graphics_pipeline_get_executable_properties,
1500 .get_internal_representations = vk_graphics_pipeline_get_internal_representations,
1501 .cmd_bind = vk_graphics_pipeline_cmd_bind,
1502 };
1503
1504 static VkResult
vk_create_graphics_pipeline(struct vk_device * device,struct vk_pipeline_cache * cache,const VkGraphicsPipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)1505 vk_create_graphics_pipeline(struct vk_device *device,
1506 struct vk_pipeline_cache *cache,
1507 const VkGraphicsPipelineCreateInfo *pCreateInfo,
1508 const VkAllocationCallbacks *pAllocator,
1509 VkPipeline *pPipeline)
1510 {
1511 VK_FROM_HANDLE(vk_pipeline_layout, pipeline_layout, pCreateInfo->layout);
1512 const int64_t pipeline_start = os_time_get_nano();
1513 VkResult result;
1514
1515 const VkPipelineCreateFlags2KHR pipeline_flags =
1516 vk_graphics_pipeline_create_flags(pCreateInfo);
1517
1518 const VkPipelineCreationFeedbackCreateInfo *feedback_info =
1519 vk_find_struct_const(pCreateInfo->pNext,
1520 PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
1521
1522 const VkPipelineLibraryCreateInfoKHR *libs_info =
1523 vk_find_struct_const(pCreateInfo->pNext,
1524 PIPELINE_LIBRARY_CREATE_INFO_KHR);
1525
1526 struct vk_graphics_pipeline *pipeline =
1527 vk_pipeline_zalloc(device, &vk_graphics_pipeline_ops,
1528 VK_PIPELINE_BIND_POINT_GRAPHICS,
1529 pipeline_flags, pAllocator, sizeof(*pipeline));
1530 if (pipeline == NULL)
1531 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1532
1533 struct vk_pipeline_stage stages[PIPE_SHADER_MESH_TYPES];
1534 memset(stages, 0, sizeof(stages));
1535
1536 VkPipelineCreationFeedback stage_feedbacks[PIPE_SHADER_MESH_TYPES];
1537 memset(stage_feedbacks, 0, sizeof(stage_feedbacks));
1538
1539 struct vk_graphics_pipeline_state state_tmp, *state;
1540 struct vk_graphics_pipeline_all_state all_state_tmp, *all_state;
1541 if (pipeline->base.flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR) {
1542 /* For pipeline libraries, the state is stored in the pipeline */
1543 state = &pipeline->lib.state;
1544 all_state = &pipeline->lib.all_state;
1545 } else {
1546 /* For linked pipelines, we throw the state away at the end of pipeline
1547 * creation and only keep the dynamic state.
1548 */
1549 memset(&state_tmp, 0, sizeof(state_tmp));
1550 state = &state_tmp;
1551 all_state = &all_state_tmp;
1552 }
1553
1554 /* If we have libraries, import them first. */
1555 if (libs_info) {
1556 for (uint32_t i = 0; i < libs_info->libraryCount; i++) {
1557 VK_FROM_HANDLE(vk_pipeline, lib_pipeline, libs_info->pLibraries[i]);
1558 assert(lib_pipeline->bind_point == VK_PIPELINE_BIND_POINT_GRAPHICS);
1559 assert(lib_pipeline->flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR);
1560 struct vk_graphics_pipeline *lib_gfx_pipeline =
1561 container_of(lib_pipeline, struct vk_graphics_pipeline, base);
1562
1563 vk_graphics_pipeline_state_merge(state, &lib_gfx_pipeline->lib.state);
1564
1565 pipeline->set_layout_count = MAX2(pipeline->set_layout_count,
1566 lib_gfx_pipeline->set_layout_count);
1567 for (uint32_t i = 0; i < lib_gfx_pipeline->set_layout_count; i++) {
1568 if (lib_gfx_pipeline->set_layouts[i] == NULL)
1569 continue;
1570
1571 if (pipeline->set_layouts[i] == NULL) {
1572 pipeline->set_layouts[i] =
1573 vk_descriptor_set_layout_ref(lib_gfx_pipeline->set_layouts[i]);
1574 }
1575 }
1576
1577 for (uint32_t i = 0; i < lib_gfx_pipeline->stage_count; i++) {
1578 const struct vk_pipeline_stage *lib_stage =
1579 &lib_gfx_pipeline->stages[i];
1580
1581 /* We shouldn't have duplicated stages in the imported pipeline
1582 * but it's cheap enough to protect against it so we may as well.
1583 */
1584 assert(lib_stage->stage < ARRAY_SIZE(stages));
1585 assert(vk_pipeline_stage_is_null(&stages[lib_stage->stage]));
1586 if (!vk_pipeline_stage_is_null(&stages[lib_stage->stage]))
1587 continue;
1588
1589 stages[lib_stage->stage] = vk_pipeline_stage_clone(lib_stage);
1590 }
1591 }
1592 }
1593
1594 result = vk_graphics_pipeline_state_fill(device, state,
1595 pCreateInfo,
1596 NULL /* driver_rp */,
1597 0 /* driver_rp_flags */,
1598 all_state,
1599 NULL, 0, NULL);
1600 if (result != VK_SUCCESS)
1601 goto fail_stages;
1602
1603 if (!(pipeline->base.flags & VK_PIPELINE_CREATE_2_LIBRARY_BIT_KHR)) {
1604 pipeline->linked.dynamic.vi = &pipeline->linked._dynamic_vi;
1605 pipeline->linked.dynamic.ms.sample_locations =
1606 &pipeline->linked._dynamic_sl;
1607 vk_dynamic_graphics_state_fill(&pipeline->linked.dynamic, &state_tmp);
1608 }
1609
1610 if (pipeline_layout != NULL) {
1611 pipeline->set_layout_count = MAX2(pipeline->set_layout_count,
1612 pipeline_layout->set_count);
1613 for (uint32_t i = 0; i < pipeline_layout->set_count; i++) {
1614 if (pipeline_layout->set_layouts[i] == NULL)
1615 continue;
1616
1617 if (pipeline->set_layouts[i] == NULL) {
1618 pipeline->set_layouts[i] =
1619 vk_descriptor_set_layout_ref(pipeline_layout->set_layouts[i]);
1620 }
1621 }
1622 }
1623
1624 for (uint32_t i = 0; i < pCreateInfo->stageCount; i++) {
1625 const VkPipelineShaderStageCreateInfo *stage_info =
1626 &pCreateInfo->pStages[i];
1627
1628 const int64_t stage_start = os_time_get_nano();
1629
1630 assert(util_bitcount(stage_info->stage) == 1);
1631 if (!(state->shader_stages & stage_info->stage))
1632 continue;
1633
1634 gl_shader_stage stage = vk_to_mesa_shader_stage(stage_info->stage);
1635 assert(vk_device_supports_stage(device, stage));
1636
1637 stage_feedbacks[stage].flags |=
1638 VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
1639
1640 if (!vk_pipeline_stage_is_null(&stages[stage]))
1641 continue;
1642
1643 struct vk_pipeline_precomp_shader *precomp;
1644 result = vk_pipeline_precompile_shader(device, cache, pipeline_flags,
1645 pCreateInfo->pNext,
1646 stage_info,
1647 &precomp);
1648 if (result != VK_SUCCESS)
1649 goto fail_stages;
1650
1651 stages[stage] = (struct vk_pipeline_stage) {
1652 .stage = stage,
1653 .precomp = precomp,
1654 };
1655
1656 const int64_t stage_end = os_time_get_nano();
1657 stage_feedbacks[stage].duration += stage_end - stage_start;
1658 }
1659
1660 /* Compact the array of stages */
1661 uint32_t stage_count = 0;
1662 for (uint32_t s = 0; s < ARRAY_SIZE(stages); s++) {
1663 assert(s >= stage_count);
1664 if (!vk_pipeline_stage_is_null(&stages[s]))
1665 stages[stage_count++] = stages[s];
1666 }
1667 for (uint32_t s = stage_count; s < ARRAY_SIZE(stages); s++)
1668 memset(&stages[s], 0, sizeof(stages[s]));
1669
1670 /* Sort so we always give the driver shaders in order.
1671 *
1672 * This makes everything easier for everyone. This also helps stabilize
1673 * shader keys so that we get a cache hit even if the client gives us
1674 * the stages in a different order.
1675 */
1676 qsort(stages, stage_count, sizeof(*stages), cmp_vk_pipeline_stages);
1677
1678 result = vk_graphics_pipeline_compile_shaders(device, cache, pipeline,
1679 pipeline_layout, state,
1680 stage_count, stages,
1681 stage_feedbacks);
1682 if (result != VK_SUCCESS)
1683 goto fail_stages;
1684
1685 /* Throw away precompiled shaders unless the client explicitly asks us to
1686 * keep them.
1687 */
1688 if (!(pipeline_flags &
1689 VK_PIPELINE_CREATE_2_RETAIN_LINK_TIME_OPTIMIZATION_INFO_BIT_EXT)) {
1690 for (uint32_t i = 0; i < stage_count; i++) {
1691 if (stages[i].precomp != NULL) {
1692 vk_pipeline_precomp_shader_unref(device, stages[i].precomp);
1693 stages[i].precomp = NULL;
1694 }
1695 }
1696 }
1697
1698 pipeline->stage_count = stage_count;
1699 for (uint32_t i = 0; i < stage_count; i++)
1700 pipeline->stages[i] = stages[i];
1701
1702 const int64_t pipeline_end = os_time_get_nano();
1703 if (feedback_info != NULL) {
1704 VkPipelineCreationFeedback pipeline_feedback = {
1705 .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
1706 .duration = pipeline_end - pipeline_start,
1707 };
1708
1709 /* From the Vulkan 1.3.275 spec:
1710 *
1711 * "An implementation should set the
1712 * VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT
1713 * bit if it was able to avoid the large majority of pipeline or
1714 * pipeline stage creation work by using the pipelineCache parameter"
1715 *
1716 * We really shouldn't set this bit unless all the shaders hit the
1717 * cache.
1718 */
1719 uint32_t cache_hit_count = 0;
1720 for (uint32_t i = 0; i < stage_count; i++) {
1721 const gl_shader_stage stage = stages[i].stage;
1722 if (stage_feedbacks[stage].flags &
1723 VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT)
1724 cache_hit_count++;
1725 }
1726 if (cache_hit_count > 0 && cache_hit_count == stage_count) {
1727 pipeline_feedback.flags |=
1728 VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
1729 }
1730
1731 *feedback_info->pPipelineCreationFeedback = pipeline_feedback;
1732
1733 /* VUID-VkGraphicsPipelineCreateInfo-pipelineStageCreationFeedbackCount-06594 */
1734 assert(feedback_info->pipelineStageCreationFeedbackCount == 0 ||
1735 feedback_info->pipelineStageCreationFeedbackCount ==
1736 pCreateInfo->stageCount);
1737 for (uint32_t i = 0;
1738 i < feedback_info->pipelineStageCreationFeedbackCount; i++) {
1739 const gl_shader_stage stage =
1740 vk_to_mesa_shader_stage(pCreateInfo->pStages[i].stage);
1741
1742 feedback_info->pPipelineStageCreationFeedbacks[i] =
1743 stage_feedbacks[stage];
1744 }
1745 }
1746
1747 *pPipeline = vk_pipeline_to_handle(&pipeline->base);
1748
1749 return VK_SUCCESS;
1750
1751 fail_stages:
1752 for (uint32_t i = 0; i < ARRAY_SIZE(stages); i++)
1753 vk_pipeline_stage_finish(device, &stages[i]);
1754
1755 vk_graphics_pipeline_destroy(device, &pipeline->base, pAllocator);
1756
1757 return result;
1758 }
1759
1760 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateGraphicsPipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkGraphicsPipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)1761 vk_common_CreateGraphicsPipelines(VkDevice _device,
1762 VkPipelineCache pipelineCache,
1763 uint32_t createInfoCount,
1764 const VkGraphicsPipelineCreateInfo *pCreateInfos,
1765 const VkAllocationCallbacks *pAllocator,
1766 VkPipeline *pPipelines)
1767 {
1768 VK_FROM_HANDLE(vk_device, device, _device);
1769 VK_FROM_HANDLE(vk_pipeline_cache, cache, pipelineCache);
1770 VkResult first_error_or_success = VK_SUCCESS;
1771
1772 /* From the Vulkan 1.3.274 spec:
1773 *
1774 * "When attempting to create many pipelines in a single command, it is
1775 * possible that creation may fail for a subset of them. In this case,
1776 * the corresponding elements of pPipelines will be set to
1777 * VK_NULL_HANDLE.
1778 */
1779 memset(pPipelines, 0, createInfoCount * sizeof(*pPipelines));
1780
1781 unsigned i = 0;
1782 for (; i < createInfoCount; i++) {
1783 VkResult result = vk_create_graphics_pipeline(device, cache,
1784 &pCreateInfos[i],
1785 pAllocator,
1786 &pPipelines[i]);
1787 if (result == VK_SUCCESS)
1788 continue;
1789
1790 if (first_error_or_success == VK_SUCCESS)
1791 first_error_or_success = result;
1792
1793 /* Bail out on the first error != VK_PIPELINE_COMPILE_REQUIRED as it
1794 * is not obvious what error should be report upon 2 different failures.
1795 */
1796 if (result != VK_PIPELINE_COMPILE_REQUIRED)
1797 return result;
1798
1799 const VkPipelineCreateFlags2KHR flags =
1800 vk_graphics_pipeline_create_flags(&pCreateInfos[i]);
1801 if (flags & VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR)
1802 return result;
1803 }
1804
1805 return first_error_or_success;
1806 }
1807
1808 struct vk_compute_pipeline {
1809 struct vk_pipeline base;
1810 struct vk_shader *shader;
1811 };
1812
1813 static void
vk_compute_pipeline_destroy(struct vk_device * device,struct vk_pipeline * pipeline,const VkAllocationCallbacks * pAllocator)1814 vk_compute_pipeline_destroy(struct vk_device *device,
1815 struct vk_pipeline *pipeline,
1816 const VkAllocationCallbacks *pAllocator)
1817 {
1818 struct vk_compute_pipeline *comp_pipeline =
1819 container_of(pipeline, struct vk_compute_pipeline, base);
1820
1821 vk_shader_unref(device, comp_pipeline->shader);
1822 vk_pipeline_free(device, pAllocator, pipeline);
1823 }
1824
1825 static void
vk_compute_pipeline_cmd_bind(struct vk_command_buffer * cmd_buffer,struct vk_pipeline * pipeline)1826 vk_compute_pipeline_cmd_bind(struct vk_command_buffer *cmd_buffer,
1827 struct vk_pipeline *pipeline)
1828 {
1829 struct vk_device *device = cmd_buffer->base.device;
1830 const struct vk_device_shader_ops *ops = device->shader_ops;
1831
1832 struct vk_shader *shader = NULL;
1833 if (pipeline != NULL) {
1834 assert(pipeline->bind_point == VK_PIPELINE_BIND_POINT_COMPUTE);
1835 struct vk_compute_pipeline *comp_pipeline =
1836 container_of(pipeline, struct vk_compute_pipeline, base);
1837
1838 shader = comp_pipeline->shader;
1839
1840 cmd_buffer->pipeline_shader_stages |= VK_SHADER_STAGE_COMPUTE_BIT;
1841 } else {
1842 cmd_buffer->pipeline_shader_stages &= ~VK_SHADER_STAGE_COMPUTE_BIT;
1843 }
1844
1845 gl_shader_stage stage = MESA_SHADER_COMPUTE;
1846 ops->cmd_bind_shaders(cmd_buffer, 1, &stage, &shader);
1847 }
1848
1849 static VkResult
vk_pipeline_compile_compute_stage(struct vk_device * device,struct vk_pipeline_cache * cache,struct vk_compute_pipeline * pipeline,struct vk_pipeline_layout * pipeline_layout,struct vk_pipeline_stage * stage,bool * cache_hit)1850 vk_pipeline_compile_compute_stage(struct vk_device *device,
1851 struct vk_pipeline_cache *cache,
1852 struct vk_compute_pipeline *pipeline,
1853 struct vk_pipeline_layout *pipeline_layout,
1854 struct vk_pipeline_stage *stage,
1855 bool *cache_hit)
1856 {
1857 const struct vk_device_shader_ops *ops = device->shader_ops;
1858 VkResult result;
1859
1860 const VkPushConstantRange *push_range = NULL;
1861 if (pipeline_layout != NULL) {
1862 for (uint32_t r = 0; r < pipeline_layout->push_range_count; r++) {
1863 if (pipeline_layout->push_ranges[r].stageFlags &
1864 VK_SHADER_STAGE_COMPUTE_BIT) {
1865 assert(push_range == NULL);
1866 push_range = &pipeline_layout->push_ranges[r];
1867 }
1868 }
1869 }
1870
1871 VkShaderCreateFlagsEXT shader_flags =
1872 vk_pipeline_to_shader_flags(pipeline->base.flags, MESA_SHADER_COMPUTE);
1873
1874 struct mesa_blake3 blake3_ctx;
1875 _mesa_blake3_init(&blake3_ctx);
1876
1877 _mesa_blake3_update(&blake3_ctx, stage->precomp->blake3,
1878 sizeof(stage->precomp->blake3));
1879
1880 _mesa_blake3_update(&blake3_ctx, &shader_flags, sizeof(shader_flags));
1881
1882 for (uint32_t i = 0; i < pipeline_layout->set_count; i++) {
1883 if (pipeline_layout->set_layouts[i] != NULL) {
1884 _mesa_blake3_update(&blake3_ctx,
1885 pipeline_layout->set_layouts[i]->blake3,
1886 sizeof(pipeline_layout->set_layouts[i]->blake3));
1887 }
1888 }
1889 if (push_range != NULL)
1890 _mesa_blake3_update(&blake3_ctx, push_range, sizeof(*push_range));
1891
1892 struct vk_shader_pipeline_cache_key shader_key = {
1893 .stage = MESA_SHADER_COMPUTE,
1894 };
1895 _mesa_blake3_final(&blake3_ctx, shader_key.blake3);
1896
1897 if (cache != NULL) {
1898 struct vk_pipeline_cache_object *cache_obj =
1899 vk_pipeline_cache_lookup_object(cache, &shader_key,
1900 sizeof(shader_key),
1901 &pipeline_shader_cache_ops,
1902 cache_hit);
1903 if (cache_obj != NULL) {
1904 stage->shader = vk_shader_from_cache_obj(cache_obj);
1905 return VK_SUCCESS;
1906 }
1907 }
1908
1909 if (pipeline->base.flags &
1910 VK_PIPELINE_CREATE_2_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT_KHR)
1911 return VK_PIPELINE_COMPILE_REQUIRED;
1912
1913 const struct nir_shader_compiler_options *nir_options =
1914 ops->get_nir_options(device->physical, stage->stage,
1915 &stage->precomp->rs);
1916
1917 nir_shader *nir = vk_pipeline_precomp_shader_get_nir(stage->precomp,
1918 nir_options);
1919 if (nir == NULL)
1920 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1921
1922 /* vk_device_shader_ops::compile() consumes the NIR regardless of whether
1923 * or not it succeeds and only generates shaders on success. Once compile()
1924 * returns, we own the shaders but not the NIR in infos.
1925 */
1926 struct vk_shader_compile_info compile_info = {
1927 .stage = stage->stage,
1928 .flags = shader_flags,
1929 .next_stage_mask = 0,
1930 .nir = nir,
1931 .robustness = &stage->precomp->rs,
1932 .set_layout_count = pipeline_layout->set_count,
1933 .set_layouts = pipeline_layout->set_layouts,
1934 .push_constant_range_count = push_range != NULL,
1935 .push_constant_ranges = push_range != NULL ? push_range : NULL,
1936 };
1937
1938 struct vk_shader *shader;
1939 result = ops->compile(device, 1, &compile_info, NULL,
1940 &device->alloc, &shader);
1941 if (result != VK_SUCCESS)
1942 return result;
1943
1944 vk_shader_init_cache_obj(device, shader, &shader_key, sizeof(shader_key));
1945
1946 struct vk_pipeline_cache_object *cache_obj = &shader->pipeline.cache_obj;
1947 if (cache != NULL)
1948 cache_obj = vk_pipeline_cache_add_object(cache, cache_obj);
1949
1950 stage->shader = vk_shader_from_cache_obj(cache_obj);
1951
1952 return VK_SUCCESS;
1953 }
1954
1955 static VkResult
vk_compute_pipeline_get_executable_properties(struct vk_device * device,struct vk_pipeline * pipeline,uint32_t * executable_count,VkPipelineExecutablePropertiesKHR * properties)1956 vk_compute_pipeline_get_executable_properties(
1957 struct vk_device *device,
1958 struct vk_pipeline *pipeline,
1959 uint32_t *executable_count,
1960 VkPipelineExecutablePropertiesKHR *properties)
1961 {
1962 struct vk_compute_pipeline *comp_pipeline =
1963 container_of(pipeline, struct vk_compute_pipeline, base);
1964 struct vk_shader *shader = comp_pipeline->shader;
1965
1966 return shader->ops->get_executable_properties(device, shader,
1967 executable_count,
1968 properties);
1969 }
1970
1971 static VkResult
vk_compute_pipeline_get_executable_statistics(struct vk_device * device,struct vk_pipeline * pipeline,uint32_t executable_index,uint32_t * statistic_count,VkPipelineExecutableStatisticKHR * statistics)1972 vk_compute_pipeline_get_executable_statistics(
1973 struct vk_device *device,
1974 struct vk_pipeline *pipeline,
1975 uint32_t executable_index,
1976 uint32_t *statistic_count,
1977 VkPipelineExecutableStatisticKHR *statistics)
1978 {
1979 struct vk_compute_pipeline *comp_pipeline =
1980 container_of(pipeline, struct vk_compute_pipeline, base);
1981 struct vk_shader *shader = comp_pipeline->shader;
1982
1983 return shader->ops->get_executable_statistics(device, shader,
1984 executable_index,
1985 statistic_count,
1986 statistics);
1987 }
1988
1989 static VkResult
vk_compute_pipeline_get_internal_representations(struct vk_device * device,struct vk_pipeline * pipeline,uint32_t executable_index,uint32_t * internal_representation_count,VkPipelineExecutableInternalRepresentationKHR * internal_representations)1990 vk_compute_pipeline_get_internal_representations(
1991 struct vk_device *device,
1992 struct vk_pipeline *pipeline,
1993 uint32_t executable_index,
1994 uint32_t *internal_representation_count,
1995 VkPipelineExecutableInternalRepresentationKHR* internal_representations)
1996 {
1997 struct vk_compute_pipeline *comp_pipeline =
1998 container_of(pipeline, struct vk_compute_pipeline, base);
1999 struct vk_shader *shader = comp_pipeline->shader;
2000
2001 return shader->ops->get_executable_internal_representations(
2002 device, shader, executable_index,
2003 internal_representation_count, internal_representations);
2004 }
2005
2006 static const struct vk_pipeline_ops vk_compute_pipeline_ops = {
2007 .destroy = vk_compute_pipeline_destroy,
2008 .get_executable_statistics = vk_compute_pipeline_get_executable_statistics,
2009 .get_executable_properties = vk_compute_pipeline_get_executable_properties,
2010 .get_internal_representations = vk_compute_pipeline_get_internal_representations,
2011 .cmd_bind = vk_compute_pipeline_cmd_bind,
2012 };
2013
2014 static VkResult
vk_create_compute_pipeline(struct vk_device * device,struct vk_pipeline_cache * cache,const VkComputePipelineCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipeline)2015 vk_create_compute_pipeline(struct vk_device *device,
2016 struct vk_pipeline_cache *cache,
2017 const VkComputePipelineCreateInfo *pCreateInfo,
2018 const VkAllocationCallbacks *pAllocator,
2019 VkPipeline *pPipeline)
2020 {
2021 VK_FROM_HANDLE(vk_pipeline_layout, pipeline_layout, pCreateInfo->layout);
2022 int64_t pipeline_start = os_time_get_nano();
2023 VkResult result;
2024
2025 const VkPipelineCreateFlags2KHR pipeline_flags =
2026 vk_compute_pipeline_create_flags(pCreateInfo);
2027
2028 const VkPipelineCreationFeedbackCreateInfo *feedback_info =
2029 vk_find_struct_const(pCreateInfo->pNext,
2030 PIPELINE_CREATION_FEEDBACK_CREATE_INFO);
2031
2032 struct vk_compute_pipeline *pipeline =
2033 vk_pipeline_zalloc(device, &vk_compute_pipeline_ops,
2034 VK_PIPELINE_BIND_POINT_COMPUTE,
2035 pipeline_flags, pAllocator, sizeof(*pipeline));
2036 if (pipeline == NULL)
2037 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2038
2039 struct vk_pipeline_stage stage = {
2040 .stage = MESA_SHADER_COMPUTE,
2041 };
2042 result = vk_pipeline_precompile_shader(device, cache, pipeline_flags,
2043 pCreateInfo->pNext,
2044 &pCreateInfo->stage,
2045 &stage.precomp);
2046 if (result != VK_SUCCESS)
2047 goto fail_pipeline;
2048
2049 bool cache_hit;
2050 result = vk_pipeline_compile_compute_stage(device, cache, pipeline,
2051 pipeline_layout, &stage,
2052 &cache_hit);
2053 if (result != VK_SUCCESS)
2054 goto fail_stage;
2055
2056 if (stage.precomp != NULL)
2057 vk_pipeline_precomp_shader_unref(device, stage.precomp);
2058 pipeline->shader = stage.shader;
2059
2060 const int64_t pipeline_end = os_time_get_nano();
2061 if (feedback_info != NULL) {
2062 VkPipelineCreationFeedback pipeline_feedback = {
2063 .flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT,
2064 .duration = pipeline_end - pipeline_start,
2065 };
2066 if (cache_hit) {
2067 pipeline_feedback.flags |=
2068 VK_PIPELINE_CREATION_FEEDBACK_APPLICATION_PIPELINE_CACHE_HIT_BIT;
2069 }
2070
2071 *feedback_info->pPipelineCreationFeedback = pipeline_feedback;
2072 if (feedback_info->pipelineStageCreationFeedbackCount > 0) {
2073 feedback_info->pPipelineStageCreationFeedbacks[0] =
2074 pipeline_feedback;
2075 }
2076 }
2077
2078 *pPipeline = vk_pipeline_to_handle(&pipeline->base);
2079
2080 return VK_SUCCESS;
2081
2082 fail_stage:
2083 vk_pipeline_stage_finish(device, &stage);
2084 fail_pipeline:
2085 vk_pipeline_free(device, pAllocator, &pipeline->base);
2086
2087 return result;
2088 }
2089
2090 VKAPI_ATTR VkResult VKAPI_CALL
vk_common_CreateComputePipelines(VkDevice _device,VkPipelineCache pipelineCache,uint32_t createInfoCount,const VkComputePipelineCreateInfo * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkPipeline * pPipelines)2091 vk_common_CreateComputePipelines(VkDevice _device,
2092 VkPipelineCache pipelineCache,
2093 uint32_t createInfoCount,
2094 const VkComputePipelineCreateInfo *pCreateInfos,
2095 const VkAllocationCallbacks *pAllocator,
2096 VkPipeline *pPipelines)
2097 {
2098 VK_FROM_HANDLE(vk_device, device, _device);
2099 VK_FROM_HANDLE(vk_pipeline_cache, cache, pipelineCache);
2100 VkResult first_error_or_success = VK_SUCCESS;
2101
2102 /* From the Vulkan 1.3.274 spec:
2103 *
2104 * "When attempting to create many pipelines in a single command, it is
2105 * possible that creation may fail for a subset of them. In this case,
2106 * the corresponding elements of pPipelines will be set to
2107 * VK_NULL_HANDLE.
2108 */
2109 memset(pPipelines, 0, createInfoCount * sizeof(*pPipelines));
2110
2111 unsigned i = 0;
2112 for (; i < createInfoCount; i++) {
2113 VkResult result = vk_create_compute_pipeline(device, cache,
2114 &pCreateInfos[i],
2115 pAllocator,
2116 &pPipelines[i]);
2117 if (result == VK_SUCCESS)
2118 continue;
2119
2120 if (first_error_or_success == VK_SUCCESS)
2121 first_error_or_success = result;
2122
2123 /* Bail out on the first error != VK_PIPELINE_COMPILE_REQUIRED as it
2124 * is not obvious what error should be report upon 2 different failures.
2125 */
2126 if (result != VK_PIPELINE_COMPILE_REQUIRED)
2127 return result;
2128
2129 const VkPipelineCreateFlags2KHR flags =
2130 vk_compute_pipeline_create_flags(&pCreateInfos[i]);
2131 if (flags & VK_PIPELINE_CREATE_2_EARLY_RETURN_ON_FAILURE_BIT_KHR)
2132 return result;
2133 }
2134
2135 return first_error_or_success;
2136 }
2137
2138 void
vk_cmd_unbind_pipelines_for_stages(struct vk_command_buffer * cmd_buffer,VkShaderStageFlags stages)2139 vk_cmd_unbind_pipelines_for_stages(struct vk_command_buffer *cmd_buffer,
2140 VkShaderStageFlags stages)
2141 {
2142 stages &= cmd_buffer->pipeline_shader_stages;
2143
2144 if (stages & ~VK_SHADER_STAGE_COMPUTE_BIT)
2145 vk_graphics_pipeline_cmd_bind(cmd_buffer, NULL);
2146
2147 if (stages & VK_SHADER_STAGE_COMPUTE_BIT)
2148 vk_compute_pipeline_cmd_bind(cmd_buffer, NULL);
2149 }
2150