• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2024 Valve Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #include "vk_log.h"
8 
9 #include "radv_device.h"
10 #include "radv_entrypoints.h"
11 #include "radv_physical_device.h"
12 #include "radv_pipeline_cache.h"
13 #include "radv_pipeline_compute.h"
14 #include "radv_pipeline_graphics.h"
15 #include "radv_shader_object.h"
16 
17 static void
radv_shader_object_destroy_variant(struct radv_device * device,VkShaderCodeTypeEXT code_type,struct radv_shader * shader,struct radv_shader_binary * binary)18 radv_shader_object_destroy_variant(struct radv_device *device, VkShaderCodeTypeEXT code_type,
19                                    struct radv_shader *shader, struct radv_shader_binary *binary)
20 {
21    if (shader)
22       radv_shader_unref(device, shader);
23 
24    if (code_type == VK_SHADER_CODE_TYPE_SPIRV_EXT)
25       free(binary);
26 }
27 
28 static void
radv_shader_object_destroy(struct radv_device * device,struct radv_shader_object * shader_obj,const VkAllocationCallbacks * pAllocator)29 radv_shader_object_destroy(struct radv_device *device, struct radv_shader_object *shader_obj,
30                            const VkAllocationCallbacks *pAllocator)
31 {
32    radv_shader_object_destroy_variant(device, shader_obj->code_type, shader_obj->as_ls.shader,
33                                       shader_obj->as_ls.binary);
34    radv_shader_object_destroy_variant(device, shader_obj->code_type, shader_obj->as_es.shader,
35                                       shader_obj->as_es.binary);
36    radv_shader_object_destroy_variant(device, shader_obj->code_type, shader_obj->gs.copy_shader,
37                                       shader_obj->gs.copy_binary);
38    radv_shader_object_destroy_variant(device, shader_obj->code_type, shader_obj->shader, shader_obj->binary);
39 
40    vk_object_base_finish(&shader_obj->base);
41    vk_free2(&device->vk.alloc, pAllocator, shader_obj);
42 }
43 
44 VKAPI_ATTR void VKAPI_CALL
radv_DestroyShaderEXT(VkDevice _device,VkShaderEXT shader,const VkAllocationCallbacks * pAllocator)45 radv_DestroyShaderEXT(VkDevice _device, VkShaderEXT shader, const VkAllocationCallbacks *pAllocator)
46 {
47    VK_FROM_HANDLE(radv_device, device, _device);
48    VK_FROM_HANDLE(radv_shader_object, shader_obj, shader);
49 
50    if (!shader)
51       return;
52 
53    radv_shader_object_destroy(device, shader_obj, pAllocator);
54 }
55 
56 static void
radv_shader_stage_init(const VkShaderCreateInfoEXT * sinfo,struct radv_shader_stage * out_stage)57 radv_shader_stage_init(const VkShaderCreateInfoEXT *sinfo, struct radv_shader_stage *out_stage)
58 {
59    uint16_t dynamic_shader_stages = 0;
60 
61    memset(out_stage, 0, sizeof(*out_stage));
62 
63    out_stage->stage = vk_to_mesa_shader_stage(sinfo->stage);
64    out_stage->next_stage = MESA_SHADER_NONE;
65    out_stage->entrypoint = sinfo->pName;
66    out_stage->spec_info = sinfo->pSpecializationInfo;
67    out_stage->feedback.flags = VK_PIPELINE_CREATION_FEEDBACK_VALID_BIT;
68    out_stage->spirv.data = (const char *)sinfo->pCode;
69    out_stage->spirv.size = sinfo->codeSize;
70 
71    for (uint32_t i = 0; i < sinfo->setLayoutCount; i++) {
72       VK_FROM_HANDLE(radv_descriptor_set_layout, set_layout, sinfo->pSetLayouts[i]);
73 
74       if (set_layout == NULL)
75          continue;
76 
77       out_stage->layout.num_sets = MAX2(i + 1, out_stage->layout.num_sets);
78       out_stage->layout.set[i].layout = set_layout;
79 
80       out_stage->layout.set[i].dynamic_offset_start = out_stage->layout.dynamic_offset_count;
81       out_stage->layout.dynamic_offset_count += set_layout->dynamic_offset_count;
82 
83       dynamic_shader_stages |= set_layout->dynamic_shader_stages;
84    }
85 
86    if (out_stage->layout.dynamic_offset_count && (dynamic_shader_stages & sinfo->stage)) {
87       out_stage->layout.use_dynamic_descriptors = true;
88    }
89 
90    for (unsigned i = 0; i < sinfo->pushConstantRangeCount; ++i) {
91       const VkPushConstantRange *range = sinfo->pPushConstantRanges + i;
92       out_stage->layout.push_constant_size = MAX2(out_stage->layout.push_constant_size, range->offset + range->size);
93    }
94 
95    out_stage->layout.push_constant_size = align(out_stage->layout.push_constant_size, 16);
96 
97    const VkShaderRequiredSubgroupSizeCreateInfoEXT *const subgroup_size =
98       vk_find_struct_const(sinfo->pNext, SHADER_REQUIRED_SUBGROUP_SIZE_CREATE_INFO_EXT);
99 
100    if (subgroup_size) {
101       if (subgroup_size->requiredSubgroupSize == 32)
102          out_stage->key.subgroup_required_size = RADV_REQUIRED_WAVE32;
103       else if (subgroup_size->requiredSubgroupSize == 64)
104          out_stage->key.subgroup_required_size = RADV_REQUIRED_WAVE64;
105       else
106          unreachable("Unsupported required subgroup size.");
107    }
108 
109    if (sinfo->flags & VK_SHADER_CREATE_REQUIRE_FULL_SUBGROUPS_BIT_EXT) {
110       out_stage->key.subgroup_require_full = 1;
111    }
112 
113    if (sinfo->flags & VK_SHADER_CREATE_INDIRECT_BINDABLE_BIT_EXT)
114       out_stage->key.indirect_bindable = 1;
115 
116    if (out_stage->stage == MESA_SHADER_MESH) {
117       out_stage->key.has_task_shader = !(sinfo->flags & VK_SHADER_CREATE_NO_TASK_SHADER_BIT_EXT);
118    }
119 }
120 
121 static VkResult
radv_shader_object_init_graphics(struct radv_shader_object * shader_obj,struct radv_device * device,const VkShaderCreateInfoEXT * pCreateInfo)122 radv_shader_object_init_graphics(struct radv_shader_object *shader_obj, struct radv_device *device,
123                                  const VkShaderCreateInfoEXT *pCreateInfo)
124 {
125    gl_shader_stage stage = vk_to_mesa_shader_stage(pCreateInfo->stage);
126    struct radv_shader_stage stages[MESA_VULKAN_SHADER_STAGES];
127 
128    for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
129       stages[i].entrypoint = NULL;
130       stages[i].nir = NULL;
131       stages[i].spirv.size = 0;
132       stages[i].next_stage = MESA_SHADER_NONE;
133    }
134 
135    radv_shader_stage_init(pCreateInfo, &stages[stage]);
136 
137    struct radv_graphics_state_key gfx_state = {0};
138 
139    gfx_state.vs.has_prolog = true;
140    gfx_state.ps.has_epilog = true;
141    gfx_state.dynamic_rasterization_samples = true;
142    gfx_state.unknown_rast_prim = true;
143    gfx_state.dynamic_provoking_vtx_mode = true;
144    gfx_state.dynamic_line_rast_mode = true;
145    gfx_state.ps.exports_mrtz_via_epilog = true;
146 
147    for (uint32_t i = 0; i < MAX_RTS; i++)
148       gfx_state.ps.epilog.color_map[i] = i;
149 
150    struct radv_shader *shader = NULL;
151    struct radv_shader_binary *binary = NULL;
152 
153    if (!pCreateInfo->nextStage) {
154       struct radv_shader *shaders[MESA_VULKAN_SHADER_STAGES] = {NULL};
155       struct radv_shader_binary *binaries[MESA_VULKAN_SHADER_STAGES] = {NULL};
156 
157       radv_graphics_shaders_compile(device, NULL, stages, &gfx_state, false, false, false, true, NULL, false, shaders,
158                                     binaries, &shader_obj->gs.copy_shader, &shader_obj->gs.copy_binary);
159 
160       shader = shaders[stage];
161       binary = binaries[stage];
162 
163       ralloc_free(stages[stage].nir);
164 
165       shader_obj->shader = shader;
166       shader_obj->binary = binary;
167    } else {
168       VkShaderStageFlags next_stages = pCreateInfo->nextStage;
169 
170       /* The last VGT stage can always be used with rasterization enabled and a null fragment shader
171        * (ie. depth-only rendering). Because we don't want to have two variants for NONE and
172        * FRAGMENT, let's compile only one variant that works for both.
173        */
174       if (stage == MESA_SHADER_VERTEX || stage == MESA_SHADER_TESS_EVAL || stage == MESA_SHADER_GEOMETRY)
175          next_stages |= VK_SHADER_STAGE_FRAGMENT_BIT;
176 
177       radv_foreach_stage(next_stage, next_stages)
178       {
179          struct radv_shader *shaders[MESA_VULKAN_SHADER_STAGES] = {NULL};
180          struct radv_shader_binary *binaries[MESA_VULKAN_SHADER_STAGES] = {NULL};
181 
182          radv_shader_stage_init(pCreateInfo, &stages[stage]);
183          stages[stage].next_stage = next_stage;
184 
185          radv_graphics_shaders_compile(device, NULL, stages, &gfx_state, false, false, false, true, NULL, false,
186                                        shaders, binaries, &shader_obj->gs.copy_shader, &shader_obj->gs.copy_binary);
187 
188          shader = shaders[stage];
189          binary = binaries[stage];
190 
191          ralloc_free(stages[stage].nir);
192 
193          if (stage == MESA_SHADER_VERTEX) {
194             if (next_stage == MESA_SHADER_TESS_CTRL) {
195                shader_obj->as_ls.shader = shader;
196                shader_obj->as_ls.binary = binary;
197             } else if (next_stage == MESA_SHADER_GEOMETRY) {
198                shader_obj->as_es.shader = shader;
199                shader_obj->as_es.binary = binary;
200             } else {
201                shader_obj->shader = shader;
202                shader_obj->binary = binary;
203             }
204          } else if (stage == MESA_SHADER_TESS_EVAL) {
205             if (next_stage == MESA_SHADER_GEOMETRY) {
206                shader_obj->as_es.shader = shader;
207                shader_obj->as_es.binary = binary;
208             } else {
209                shader_obj->shader = shader;
210                shader_obj->binary = binary;
211             }
212          } else {
213             shader_obj->shader = shader;
214             shader_obj->binary = binary;
215          }
216       }
217    }
218 
219    return VK_SUCCESS;
220 }
221 
222 static VkResult
radv_shader_object_init_compute(struct radv_shader_object * shader_obj,struct radv_device * device,const VkShaderCreateInfoEXT * pCreateInfo)223 radv_shader_object_init_compute(struct radv_shader_object *shader_obj, struct radv_device *device,
224                                 const VkShaderCreateInfoEXT *pCreateInfo)
225 {
226    struct radv_shader_binary *cs_binary;
227    struct radv_shader_stage stage = {0};
228 
229    radv_shader_stage_init(pCreateInfo, &stage);
230 
231    struct radv_shader *cs_shader = radv_compile_cs(device, NULL, &stage, false, false, false, true, &cs_binary);
232 
233    ralloc_free(stage.nir);
234 
235    shader_obj->shader = cs_shader;
236    shader_obj->binary = cs_binary;
237 
238    return VK_SUCCESS;
239 }
240 
241 static void
radv_get_shader_layout(const VkShaderCreateInfoEXT * pCreateInfo,struct radv_shader_layout * layout)242 radv_get_shader_layout(const VkShaderCreateInfoEXT *pCreateInfo, struct radv_shader_layout *layout)
243 {
244    uint16_t dynamic_shader_stages = 0;
245 
246    memset(layout, 0, sizeof(*layout));
247 
248    layout->dynamic_offset_count = 0;
249 
250    for (uint32_t i = 0; i < pCreateInfo->setLayoutCount; i++) {
251       VK_FROM_HANDLE(radv_descriptor_set_layout, set_layout, pCreateInfo->pSetLayouts[i]);
252 
253       if (set_layout == NULL)
254          continue;
255 
256       layout->num_sets = MAX2(i + 1, layout->num_sets);
257 
258       layout->set[i].layout = set_layout;
259       layout->set[i].dynamic_offset_start = layout->dynamic_offset_count;
260 
261       layout->dynamic_offset_count += set_layout->dynamic_offset_count;
262       dynamic_shader_stages |= set_layout->dynamic_shader_stages;
263    }
264 
265    if (layout->dynamic_offset_count && (dynamic_shader_stages & pCreateInfo->stage)) {
266       layout->use_dynamic_descriptors = true;
267    }
268 
269    layout->push_constant_size = 0;
270 
271    for (unsigned i = 0; i < pCreateInfo->pushConstantRangeCount; ++i) {
272       const VkPushConstantRange *range = pCreateInfo->pPushConstantRanges + i;
273       layout->push_constant_size = MAX2(layout->push_constant_size, range->offset + range->size);
274    }
275 
276    layout->push_constant_size = align(layout->push_constant_size, 16);
277 }
278 
279 static VkResult
radv_shader_object_init_binary(struct radv_device * device,struct blob_reader * blob,struct radv_shader ** shader_out,struct radv_shader_binary ** binary_out)280 radv_shader_object_init_binary(struct radv_device *device, struct blob_reader *blob, struct radv_shader **shader_out,
281                                struct radv_shader_binary **binary_out)
282 {
283    const char *binary_sha1 = blob_read_bytes(blob, SHA1_DIGEST_LENGTH);
284    const uint32_t binary_size = blob_read_uint32(blob);
285    const struct radv_shader_binary *binary = blob_read_bytes(blob, binary_size);
286    unsigned char sha1[SHA1_DIGEST_LENGTH];
287 
288    _mesa_sha1_compute(binary, binary->total_size, sha1);
289    if (memcmp(sha1, binary_sha1, SHA1_DIGEST_LENGTH))
290       return VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT;
291 
292    *shader_out = radv_shader_create(device, NULL, binary, true);
293    *binary_out = (struct radv_shader_binary *)binary;
294 
295    return VK_SUCCESS;
296 }
297 
298 static VkResult
radv_shader_object_init(struct radv_shader_object * shader_obj,struct radv_device * device,const VkShaderCreateInfoEXT * pCreateInfo)299 radv_shader_object_init(struct radv_shader_object *shader_obj, struct radv_device *device,
300                         const VkShaderCreateInfoEXT *pCreateInfo)
301 {
302    const struct radv_physical_device *pdev = radv_device_physical(device);
303    struct radv_shader_layout layout;
304    VkResult result;
305 
306    radv_get_shader_layout(pCreateInfo, &layout);
307 
308    shader_obj->stage = vk_to_mesa_shader_stage(pCreateInfo->stage);
309    shader_obj->code_type = pCreateInfo->codeType;
310    shader_obj->push_constant_size = layout.push_constant_size;
311    shader_obj->dynamic_offset_count = layout.dynamic_offset_count;
312 
313    if (pCreateInfo->codeType == VK_SHADER_CODE_TYPE_BINARY_EXT) {
314       if (pCreateInfo->codeSize < VK_UUID_SIZE + sizeof(uint32_t)) {
315          return VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT;
316       }
317 
318       struct blob_reader blob;
319       blob_reader_init(&blob, pCreateInfo->pCode, pCreateInfo->codeSize);
320 
321       const uint8_t *cache_uuid = blob_read_bytes(&blob, VK_UUID_SIZE);
322 
323       if (memcmp(cache_uuid, pdev->cache_uuid, VK_UUID_SIZE))
324          return VK_ERROR_INCOMPATIBLE_SHADER_BINARY_EXT;
325 
326       const bool has_main_binary = blob_read_uint32(&blob);
327 
328       if (has_main_binary) {
329          result = radv_shader_object_init_binary(device, &blob, &shader_obj->shader, &shader_obj->binary);
330          if (result != VK_SUCCESS)
331             return result;
332       }
333 
334       if (shader_obj->stage == MESA_SHADER_VERTEX) {
335          const bool has_es_binary = blob_read_uint32(&blob);
336          if (has_es_binary) {
337             result =
338                radv_shader_object_init_binary(device, &blob, &shader_obj->as_es.shader, &shader_obj->as_es.binary);
339             if (result != VK_SUCCESS)
340                return result;
341          }
342 
343          const bool has_ls_binary = blob_read_uint32(&blob);
344          if (has_ls_binary) {
345             result =
346                radv_shader_object_init_binary(device, &blob, &shader_obj->as_ls.shader, &shader_obj->as_ls.binary);
347             if (result != VK_SUCCESS)
348                return result;
349          }
350       } else if (shader_obj->stage == MESA_SHADER_TESS_EVAL) {
351          const bool has_es_binary = blob_read_uint32(&blob);
352          if (has_es_binary) {
353             result =
354                radv_shader_object_init_binary(device, &blob, &shader_obj->as_es.shader, &shader_obj->as_es.binary);
355             if (result != VK_SUCCESS)
356                return result;
357          }
358       } else if (shader_obj->stage == MESA_SHADER_GEOMETRY) {
359          const bool has_gs_copy_binary = blob_read_uint32(&blob);
360          if (has_gs_copy_binary) {
361             result =
362                radv_shader_object_init_binary(device, &blob, &shader_obj->gs.copy_shader, &shader_obj->gs.copy_binary);
363             if (result != VK_SUCCESS)
364                return result;
365          }
366       }
367    } else {
368       assert(pCreateInfo->codeType == VK_SHADER_CODE_TYPE_SPIRV_EXT);
369 
370       if (pCreateInfo->stage == VK_SHADER_STAGE_COMPUTE_BIT) {
371          result = radv_shader_object_init_compute(shader_obj, device, pCreateInfo);
372       } else {
373          result = radv_shader_object_init_graphics(shader_obj, device, pCreateInfo);
374       }
375 
376       if (result != VK_SUCCESS)
377          return result;
378    }
379 
380    return VK_SUCCESS;
381 }
382 
383 static VkResult
radv_shader_object_create(VkDevice _device,const VkShaderCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkShaderEXT * pShader)384 radv_shader_object_create(VkDevice _device, const VkShaderCreateInfoEXT *pCreateInfo,
385                           const VkAllocationCallbacks *pAllocator, VkShaderEXT *pShader)
386 {
387    VK_FROM_HANDLE(radv_device, device, _device);
388    struct radv_shader_object *shader_obj;
389    VkResult result;
390 
391    shader_obj = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*shader_obj), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
392    if (shader_obj == NULL)
393       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
394 
395    vk_object_base_init(&device->vk, &shader_obj->base, VK_OBJECT_TYPE_SHADER_EXT);
396 
397    result = radv_shader_object_init(shader_obj, device, pCreateInfo);
398    if (result != VK_SUCCESS) {
399       radv_shader_object_destroy(device, shader_obj, pAllocator);
400       return result;
401    }
402 
403    *pShader = radv_shader_object_to_handle(shader_obj);
404 
405    return VK_SUCCESS;
406 }
407 
408 static VkResult
radv_shader_object_create_linked(VkDevice _device,uint32_t createInfoCount,const VkShaderCreateInfoEXT * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkShaderEXT * pShaders)409 radv_shader_object_create_linked(VkDevice _device, uint32_t createInfoCount, const VkShaderCreateInfoEXT *pCreateInfos,
410                                  const VkAllocationCallbacks *pAllocator, VkShaderEXT *pShaders)
411 {
412    VK_FROM_HANDLE(radv_device, device, _device);
413    struct radv_shader_stage stages[MESA_VULKAN_SHADER_STAGES];
414 
415    for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
416       stages[i].entrypoint = NULL;
417       stages[i].nir = NULL;
418       stages[i].spirv.size = 0;
419       stages[i].next_stage = MESA_SHADER_NONE;
420    }
421 
422    struct radv_graphics_state_key gfx_state = {0};
423 
424    gfx_state.vs.has_prolog = true;
425    gfx_state.ps.has_epilog = true;
426    gfx_state.dynamic_rasterization_samples = true;
427    gfx_state.unknown_rast_prim = true;
428    gfx_state.dynamic_provoking_vtx_mode = true;
429    gfx_state.dynamic_line_rast_mode = true;
430    gfx_state.ps.exports_mrtz_via_epilog = true;
431 
432    for (uint32_t i = 0; i < MAX_RTS; i++)
433       gfx_state.ps.epilog.color_map[i] = i;
434 
435    for (unsigned i = 0; i < createInfoCount; i++) {
436       const VkShaderCreateInfoEXT *pCreateInfo = &pCreateInfos[i];
437       gl_shader_stage s = vk_to_mesa_shader_stage(pCreateInfo->stage);
438 
439       radv_shader_stage_init(pCreateInfo, &stages[s]);
440    }
441 
442    /* Determine next stage. */
443    for (unsigned i = 0; i < MESA_VULKAN_SHADER_STAGES; i++) {
444       if (!stages[i].entrypoint)
445          continue;
446 
447       switch (stages[i].stage) {
448       case MESA_SHADER_VERTEX:
449          if (stages[MESA_SHADER_TESS_CTRL].entrypoint) {
450             stages[i].next_stage = MESA_SHADER_TESS_CTRL;
451          } else if (stages[MESA_SHADER_GEOMETRY].entrypoint) {
452             stages[i].next_stage = MESA_SHADER_GEOMETRY;
453          } else if (stages[MESA_SHADER_FRAGMENT].entrypoint) {
454             stages[i].next_stage = MESA_SHADER_FRAGMENT;
455          }
456          break;
457       case MESA_SHADER_TESS_CTRL:
458          stages[i].next_stage = MESA_SHADER_TESS_EVAL;
459          break;
460       case MESA_SHADER_TESS_EVAL:
461          if (stages[MESA_SHADER_GEOMETRY].entrypoint) {
462             stages[i].next_stage = MESA_SHADER_GEOMETRY;
463          } else if (stages[MESA_SHADER_FRAGMENT].entrypoint) {
464             stages[i].next_stage = MESA_SHADER_FRAGMENT;
465          }
466          break;
467       case MESA_SHADER_GEOMETRY:
468       case MESA_SHADER_MESH:
469          if (stages[MESA_SHADER_FRAGMENT].entrypoint) {
470             stages[i].next_stage = MESA_SHADER_FRAGMENT;
471          }
472          break;
473       case MESA_SHADER_FRAGMENT:
474          stages[i].next_stage = MESA_SHADER_NONE;
475          break;
476       case MESA_SHADER_TASK:
477          stages[i].next_stage = MESA_SHADER_MESH;
478          break;
479       default:
480          assert(0);
481       }
482    }
483 
484    struct radv_shader *shaders[MESA_VULKAN_SHADER_STAGES] = {NULL};
485    struct radv_shader_binary *binaries[MESA_VULKAN_SHADER_STAGES] = {NULL};
486    struct radv_shader *gs_copy_shader = NULL;
487    struct radv_shader_binary *gs_copy_binary = NULL;
488 
489    radv_graphics_shaders_compile(device, NULL, stages, &gfx_state, false, false, false, true, NULL, false, shaders,
490                                  binaries, &gs_copy_shader, &gs_copy_binary);
491 
492    for (unsigned i = 0; i < createInfoCount; i++) {
493       const VkShaderCreateInfoEXT *pCreateInfo = &pCreateInfos[i];
494       gl_shader_stage s = vk_to_mesa_shader_stage(pCreateInfo->stage);
495       struct radv_shader_object *shader_obj;
496 
497       shader_obj = vk_zalloc2(&device->vk.alloc, pAllocator, sizeof(*shader_obj), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
498       if (shader_obj == NULL)
499          return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
500 
501       vk_object_base_init(&device->vk, &shader_obj->base, VK_OBJECT_TYPE_SHADER_EXT);
502 
503       shader_obj->stage = s;
504       shader_obj->code_type = pCreateInfo->codeType;
505       shader_obj->push_constant_size = stages[s].layout.push_constant_size;
506       shader_obj->dynamic_offset_count = stages[s].layout.dynamic_offset_count;
507 
508       if (s == MESA_SHADER_VERTEX) {
509          if (stages[s].next_stage == MESA_SHADER_TESS_CTRL) {
510             shader_obj->as_ls.shader = shaders[s];
511             shader_obj->as_ls.binary = binaries[s];
512          } else if (stages[s].next_stage == MESA_SHADER_GEOMETRY) {
513             shader_obj->as_es.shader = shaders[s];
514             shader_obj->as_es.binary = binaries[s];
515          } else {
516             shader_obj->shader = shaders[s];
517             shader_obj->binary = binaries[s];
518          }
519       } else if (s == MESA_SHADER_TESS_EVAL) {
520          if (stages[s].next_stage == MESA_SHADER_GEOMETRY) {
521             shader_obj->as_es.shader = shaders[s];
522             shader_obj->as_es.binary = binaries[s];
523          } else {
524             shader_obj->shader = shaders[s];
525             shader_obj->binary = binaries[s];
526          }
527       } else {
528          shader_obj->shader = shaders[s];
529          shader_obj->binary = binaries[s];
530       }
531 
532       if (s == MESA_SHADER_GEOMETRY) {
533          shader_obj->gs.copy_shader = gs_copy_shader;
534          shader_obj->gs.copy_binary = gs_copy_binary;
535       }
536 
537       ralloc_free(stages[s].nir);
538 
539       pShaders[i] = radv_shader_object_to_handle(shader_obj);
540    }
541 
542    return VK_SUCCESS;
543 }
544 
545 static bool
radv_shader_object_linking_enabled(uint32_t createInfoCount,const VkShaderCreateInfoEXT * pCreateInfos)546 radv_shader_object_linking_enabled(uint32_t createInfoCount, const VkShaderCreateInfoEXT *pCreateInfos)
547 {
548    const bool has_linked_spirv = createInfoCount > 1 &&
549                                  !!(pCreateInfos[0].flags & VK_SHADER_CREATE_LINK_STAGE_BIT_EXT) &&
550                                  pCreateInfos[0].codeType == VK_SHADER_CODE_TYPE_SPIRV_EXT;
551 
552    if (!has_linked_spirv)
553       return false;
554 
555    /* Gather the available shader stages. */
556    VkShaderStageFlagBits stages = 0;
557    for (unsigned i = 0; i < createInfoCount; i++) {
558       const VkShaderCreateInfoEXT *pCreateInfo = &pCreateInfos[i];
559       stages |= pCreateInfo->stage;
560    }
561 
562    for (unsigned i = 0; i < createInfoCount; i++) {
563       const VkShaderCreateInfoEXT *pCreateInfo = &pCreateInfos[i];
564 
565       /* Force disable shaders linking when the next stage of VS/TES isn't present because the
566        * driver would need to compile all shaders twice due to shader variants. This is probably
567        * less optimal than compiling unlinked shaders.
568        */
569       if ((pCreateInfo->stage & VK_SHADER_STAGE_VERTEX_BIT) &&
570           (pCreateInfo->nextStage & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_GEOMETRY_BIT)) &&
571           !(stages & (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | VK_SHADER_STAGE_GEOMETRY_BIT)))
572          return false;
573 
574       if ((pCreateInfo->stage & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) &&
575           (pCreateInfo->nextStage & VK_SHADER_STAGE_GEOMETRY_BIT) && !(stages & VK_SHADER_STAGE_GEOMETRY_BIT))
576          return false;
577 
578       assert(pCreateInfo->flags & VK_SHADER_CREATE_LINK_STAGE_BIT_EXT);
579    }
580 
581    return true;
582 }
583 
584 VKAPI_ATTR VkResult VKAPI_CALL
radv_CreateShadersEXT(VkDevice _device,uint32_t createInfoCount,const VkShaderCreateInfoEXT * pCreateInfos,const VkAllocationCallbacks * pAllocator,VkShaderEXT * pShaders)585 radv_CreateShadersEXT(VkDevice _device, uint32_t createInfoCount, const VkShaderCreateInfoEXT *pCreateInfos,
586                       const VkAllocationCallbacks *pAllocator, VkShaderEXT *pShaders)
587 {
588    VkResult result = VK_SUCCESS;
589    unsigned i = 0;
590 
591    if (radv_shader_object_linking_enabled(createInfoCount, pCreateInfos))
592       return radv_shader_object_create_linked(_device, createInfoCount, pCreateInfos, pAllocator, pShaders);
593 
594    for (; i < createInfoCount; i++) {
595       VkResult r;
596 
597       r = radv_shader_object_create(_device, &pCreateInfos[i], pAllocator, &pShaders[i]);
598       if (r != VK_SUCCESS) {
599          result = r;
600          pShaders[i] = VK_NULL_HANDLE;
601       }
602    }
603 
604    for (; i < createInfoCount; ++i)
605       pShaders[i] = VK_NULL_HANDLE;
606 
607    return result;
608 }
609 
610 static size_t
radv_get_shader_binary_size(const struct radv_shader_binary * binary)611 radv_get_shader_binary_size(const struct radv_shader_binary *binary)
612 {
613    size_t size = sizeof(uint32_t); /* has_binary */
614 
615    if (binary)
616       size += SHA1_DIGEST_LENGTH + 4 + ALIGN(binary->total_size, 4);
617 
618    return size;
619 }
620 
621 static size_t
radv_get_shader_object_size(const struct radv_shader_object * shader_obj)622 radv_get_shader_object_size(const struct radv_shader_object *shader_obj)
623 {
624    size_t size = VK_UUID_SIZE;
625 
626    size += radv_get_shader_binary_size(shader_obj->binary);
627 
628    if (shader_obj->stage == MESA_SHADER_VERTEX) {
629       size += radv_get_shader_binary_size(shader_obj->as_es.binary);
630       size += radv_get_shader_binary_size(shader_obj->as_ls.binary);
631    } else if (shader_obj->stage == MESA_SHADER_TESS_EVAL) {
632       size += radv_get_shader_binary_size(shader_obj->as_es.binary);
633    } else if (shader_obj->stage == MESA_SHADER_GEOMETRY) {
634       size += radv_get_shader_binary_size(shader_obj->gs.copy_binary);
635    }
636 
637    return size;
638 }
639 
640 static void
radv_write_shader_binary(struct blob * blob,const struct radv_shader_binary * binary)641 radv_write_shader_binary(struct blob *blob, const struct radv_shader_binary *binary)
642 {
643    unsigned char binary_sha1[SHA1_DIGEST_LENGTH];
644 
645    blob_write_uint32(blob, !!binary);
646 
647    if (binary) {
648       _mesa_sha1_compute(binary, binary->total_size, binary_sha1);
649 
650       blob_write_bytes(blob, binary_sha1, sizeof(binary_sha1));
651       blob_write_uint32(blob, binary->total_size);
652       blob_write_bytes(blob, binary, binary->total_size);
653    }
654 }
655 
656 VKAPI_ATTR VkResult VKAPI_CALL
radv_GetShaderBinaryDataEXT(VkDevice _device,VkShaderEXT shader,size_t * pDataSize,void * pData)657 radv_GetShaderBinaryDataEXT(VkDevice _device, VkShaderEXT shader, size_t *pDataSize, void *pData)
658 {
659    VK_FROM_HANDLE(radv_device, device, _device);
660    VK_FROM_HANDLE(radv_shader_object, shader_obj, shader);
661    const struct radv_physical_device *pdev = radv_device_physical(device);
662    const size_t size = radv_get_shader_object_size(shader_obj);
663 
664    if (!pData) {
665       *pDataSize = size;
666       return VK_SUCCESS;
667    }
668 
669    if (*pDataSize < size) {
670       *pDataSize = 0;
671       return VK_INCOMPLETE;
672    }
673 
674    struct blob blob;
675    blob_init_fixed(&blob, pData, *pDataSize);
676    blob_write_bytes(&blob, pdev->cache_uuid, VK_UUID_SIZE);
677 
678    radv_write_shader_binary(&blob, shader_obj->binary);
679 
680    if (shader_obj->stage == MESA_SHADER_VERTEX) {
681       radv_write_shader_binary(&blob, shader_obj->as_es.binary);
682       radv_write_shader_binary(&blob, shader_obj->as_ls.binary);
683    } else if (shader_obj->stage == MESA_SHADER_TESS_EVAL) {
684       radv_write_shader_binary(&blob, shader_obj->as_es.binary);
685    } else if (shader_obj->stage == MESA_SHADER_GEOMETRY) {
686       radv_write_shader_binary(&blob, shader_obj->gs.copy_binary);
687    }
688 
689    assert(!blob.out_of_memory);
690 
691    return VK_SUCCESS;
692 }
693