aboutsummaryrefslogtreecommitdiff
path: root/layers/shader_validation.cpp
diff options
context:
space:
mode:
authorChris Forbes <chrisforbes@google.com>2017-07-24 15:35:29 -0700
committerChris Forbes <chrisf@ijw.co.nz>2017-11-28 16:27:21 -0800
commit0f36ac54143b3166c52952840ed71bf9ce041626 (patch)
tree7494b386c353497790b52975cac1b394ba163d90 /layers/shader_validation.cpp
parenta21af959330b04bf065369063c9f384a0391ab9f (diff)
downloadusermoji-0f36ac54143b3166c52952840ed71bf9ce041626.tar.xz
layers: Add VK_EXT_validation_cache implementation for shaders
Diffstat (limited to 'layers/shader_validation.cpp')
-rw-r--r--layers/shader_validation.cpp27
1 files changed, 27 insertions, 0 deletions
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);