From 0f36ac54143b3166c52952840ed71bf9ce041626 Mon Sep 17 00:00:00 2001 From: Chris Forbes Date: Mon, 24 Jul 2017 15:35:29 -0700 Subject: layers: Add VK_EXT_validation_cache implementation for shaders --- layers/shader_validation.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'layers/shader_validation.cpp') diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp index 11fcbdcb..aa215fa4 100644 --- a/layers/shader_validation.cpp +++ b/layers/shader_validation.cpp @@ -35,6 +35,7 @@ #include "core_validation_types.h" #include "shader_validation.h" #include "spirv-tools/libspirv.h" +#include "xxhash.h" enum FORMAT_TYPE { FORMAT_TYPE_FLOAT = 1, // UNORM, SNORM, FLOAT, USCALED, SSCALED, SRGB -- anything we consider float in the shader @@ -1517,6 +1518,20 @@ bool validate_compute_pipeline(layer_data *dev_data, PIPELINE_STATE *pipeline) { return validate_pipeline_shader_stage(dev_data, &pCreateInfo->stage, pipeline, &module, &entrypoint); } +uint32_t ValidationCache::MakeShaderHash(VkShaderModuleCreateInfo const *smci) { + return XXH32(smci->pCode, smci->codeSize * sizeof(uint32_t), 0); +} + +static ValidationCache *GetValidationCacheInfo( + VkShaderModuleCreateInfo const *pCreateInfo) { + while ((pCreateInfo = (VkShaderModuleCreateInfo const *)pCreateInfo->pNext) != nullptr) { + if (pCreateInfo->sType == VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT) + return (ValidationCache *)((VkShaderModuleValidationCacheCreateInfoEXT const *)pCreateInfo)->validationCache; + } + + return nullptr; +} + bool PreCallValidateCreateShaderModule(layer_data *dev_data, VkShaderModuleCreateInfo const *pCreateInfo, bool *spirv_valid) { bool skip = false; spv_result_t spv_valid = SPV_SUCCESS; @@ -1534,6 +1549,14 @@ bool PreCallValidateCreateShaderModule(layer_data *dev_data, VkShaderModuleCreat "SPIR-V module not valid: Codesize must be a multiple of 4 but is " PRINTF_SIZE_T_SPECIFIER ". %s", pCreateInfo->codeSize, validation_error_map[VALIDATION_ERROR_12a00ac0]); } else { + auto cache = GetValidationCacheInfo(pCreateInfo); + uint32_t hash = 0; + if (cache) { + hash = ValidationCache::MakeShaderHash(pCreateInfo); + if (cache->Contains(hash)) + return false; + } + // Use SPIRV-Tools validator to try and catch any issues with the module itself spv_context ctx = spvContextCreate(SPV_ENV_VULKAN_1_0); spv_const_binary_t binary{ pCreateInfo->pCode, pCreateInfo->codeSize / sizeof(uint32_t) }; @@ -1547,6 +1570,10 @@ bool PreCallValidateCreateShaderModule(layer_data *dev_data, VkShaderModuleCreat VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, __LINE__, SHADER_CHECKER_INCONSISTENT_SPIRV, "SC", "SPIR-V module not valid: %s", diag && diag->error ? diag->error : "(no error text)"); } + } else { + if (cache) { + cache->Insert(hash); + } } spvDiagnosticDestroy(diag); -- cgit v1.2.3