VK_EXT_primitives_generated_query on RADV
VK_EXT_non_seamless_cube_map on RADV, ANV
VK_EXT_border_color_swizzle on lavapipe, ANV, turnip, RADV
+VK_EXT_shader_module_identifier on RADV
#endif
.EXT_shader_demote_to_helper_invocation = true,
.EXT_shader_image_atomic_int64 = true,
+ .EXT_shader_module_identifier = true,
.EXT_shader_stencil_export = true,
.EXT_shader_subgroup_ballot = true,
.EXT_shader_subgroup_vote = true,
features->borderColorSwizzleFromImage = true;
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_FEATURES_EXT: {
+ VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT *features =
+ (VkPhysicalDeviceShaderModuleIdentifierFeaturesEXT *)ext;
+ features->shaderModuleIdentifier = true;
+ break;
+ }
default:
break;
}
break;
}
+ case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_MODULE_IDENTIFIER_PROPERTIES_EXT: {
+ VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT *properties =
+ (VkPhysicalDeviceShaderModuleIdentifierPropertiesEXT *)ext;
+ STATIC_ASSERT(sizeof(vk_shaderModuleIdentifierAlgorithmUUID) ==
+ sizeof(properties->shaderModuleIdentifierAlgorithmUUID));
+ memcpy(properties->shaderModuleIdentifierAlgorithmUUID,
+ vk_shaderModuleIdentifierAlgorithmUUID,
+ sizeof(properties->shaderModuleIdentifierAlgorithmUUID));
+ break;
+ }
default:
break;
}
free(library_pipeline->groups);
for (uint32_t i = 0; i < library_pipeline->stage_count; i++) {
RADV_FROM_HANDLE(vk_shader_module, module, library_pipeline->stages[i].module);
- vk_object_base_finish(&module->base);
- ralloc_free(module);
+ if (module) {
+ vk_object_base_finish(&module->base);
+ ralloc_free(module);
+ }
}
free(library_pipeline->stages);
+ free(library_pipeline->identifiers);
+ free(library_pipeline->hashes);
}
if (pipeline->slab)
{
const VkShaderModuleCreateInfo *minfo =
vk_find_struct_const(sinfo->pNext, SHADER_MODULE_CREATE_INFO);
+ const VkPipelineShaderStageModuleIdentifierCreateInfoEXT *iinfo =
+ vk_find_struct_const(sinfo->pNext, PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT);
- if (sinfo->module == VK_NULL_HANDLE && !minfo)
+ if (sinfo->module == VK_NULL_HANDLE && !minfo && !iinfo)
return;
memset(out_stage, 0, sizeof(*out_stage));
if (module->nir)
out_stage->internal_nir = module->nir;
- } else {
+ } else if (minfo) {
out_stage->spirv.data = (const char *) minfo->pCode;
out_stage->spirv.size = minfo->codeSize;
}
RADV_FROM_HANDLE(vk_shader_module, module, pCreateInfo->pStages[i].module);
const VkSpecializationInfo *spec_info = pCreateInfo->pStages[i].pSpecializationInfo;
- _mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
+ const VkPipelineShaderStageModuleIdentifierCreateInfoEXT *iinfo =
+ vk_find_struct_const(pCreateInfo->pStages[i].pNext,
+ PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT);
+
+ if (module) {
+ _mesa_sha1_update(&ctx, module->sha1, sizeof(module->sha1));
+ } else {
+ assert(iinfo);
+ assert(iinfo->identifierSize <= VK_MAX_SHADER_MODULE_IDENTIFIER_SIZE_EXT);
+ _mesa_sha1_update(&ctx, iinfo->pIdentifier, iinfo->identifierSize);
+ }
+
_mesa_sha1_update(&ctx, pCreateInfo->pStages[i].pName, strlen(pCreateInfo->pStages[i].pName));
if (spec_info && spec_info->mapEntryCount) {
_mesa_sha1_update(&ctx, spec_info->pMapEntries,
memcpy(pipeline->stages, local_create_info.pStages, size);
+ pipeline->hashes = malloc(sizeof(*pipeline->hashes) * local_create_info.stageCount);
+ if (!pipeline->hashes)
+ goto fail;
+
+ pipeline->identifiers = malloc(sizeof(*pipeline->identifiers) * local_create_info.stageCount);
+ if (!pipeline->identifiers)
+ goto fail;
+
for (uint32_t i = 0; i < local_create_info.stageCount; i++) {
RADV_FROM_HANDLE(vk_shader_module, module, pipeline->stages[i].module);
- struct vk_shader_module *new_module = vk_shader_module_clone(NULL, module);
- pipeline->stages[i].module = vk_shader_module_to_handle(new_module);
+ const VkPipelineShaderStageModuleIdentifierCreateInfoEXT *iinfo =
+ vk_find_struct_const(pCreateInfo->pStages[i].pNext,
+ PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT);
+
+ if (module) {
+ struct vk_shader_module *new_module = vk_shader_module_clone(NULL, module);
+ pipeline->stages[i].module = vk_shader_module_to_handle(new_module);
+ pipeline->stages[i].pNext = NULL;
+ } else {
+ assert(iinfo);
+ pipeline->identifiers[i].identifierSize =
+ MIN2(iinfo->identifierSize, sizeof(pipeline->hashes[i].sha1));
+ memcpy(pipeline->hashes[i].sha1, iinfo->pIdentifier,
+ pipeline->identifiers[i].identifierSize);
+ pipeline->stages[i].module = VK_NULL_HANDLE;
+ pipeline->stages[i].pNext = &pipeline->identifiers[i];
+ pipeline->identifiers[i].sType =
+ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_MODULE_IDENTIFIER_CREATE_INFO_EXT;
+ pipeline->identifiers[i].pNext = NULL;
+ pipeline->identifiers[i].pIdentifier = pipeline->hashes[i].sha1;
+ }
}
}
fail:
free(pipeline->groups);
free(pipeline->stages);
+ free(pipeline->hashes);
+ free(pipeline->identifiers);
free((void *)local_create_info.pGroups);
free((void *)local_create_info.pStages);
return VK_ERROR_OUT_OF_HOST_MEMORY;
* generating the nir. */
result = radv_compute_pipeline_create(_device, _cache, &compute_info, pAllocator, hash,
stack_sizes, local_create_info.groupCount, pPipeline);
+
if (result == VK_PIPELINE_COMPILE_REQUIRED) {
+ if (pCreateInfo->flags & VK_PIPELINE_CREATE_FAIL_ON_PIPELINE_COMPILE_REQUIRED_BIT)
+ goto fail;
+
stack_sizes = calloc(sizeof(*stack_sizes), local_create_info.groupCount);
if (!stack_sizes) {
result = VK_ERROR_OUT_OF_HOST_MEMORY;
VkPipelineShaderStageCreateInfo *stages;
unsigned group_count;
VkRayTracingShaderGroupCreateInfoKHR *groups;
+ VkPipelineShaderStageModuleIdentifierCreateInfoEXT *identifiers;
+ struct {
+ uint8_t sha1[SHA1_DIGEST_LENGTH];
+ } *hashes;
};
#define RADV_DECL_PIPELINE_DOWNCAST(pipe_type, pipe_enum) \