layers: Add VK_EXT_validation_cache implementation for shaders
diff --git a/layers/shader_validation.cpp b/layers/shader_validation.cpp
index 11fcbdc..aa215fa 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 @@
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 @@
"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 @@
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);