PipelineCache: Handle nullptr mismatch of specialization info.
It's valid in Vulkan for a shader to have specialization constants
and the pipeline to be lacking specialization constant data. This
could lead to a key match between the two even though there should
be a different shader payload. From the spec:
> It is legal for a SPIR-V module with specializations to be
> compiled into a pipeline where no specialization info was provided.
> SPIR-V specialization constants contain default values such that
> if a specialization is not provided.
Fix this by adding in the required checks. Should not affect perf.
Bug: b/150449637
Bug: angleproject:4426
Change-Id: I5f384420bdc1f03a36852db0b20393ae56452b62
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/41728
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: Jamie Madill <jmadill@chromium.org>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Vulkan/VkPipelineCache.cpp b/src/Vulkan/VkPipelineCache.cpp
index b9fb0d3..f54ac90 100644
--- a/src/Vulkan/VkPipelineCache.cpp
+++ b/src/Vulkan/VkPipelineCache.cpp
@@ -62,34 +62,43 @@
bool PipelineCache::SpirvShaderKey::SpecializationInfo::operator<(const SpecializationInfo &specializationInfo) const
{
- if(info && specializationInfo.info)
+ // Check that either both or neither keys have specialization info.
+ if((info.get() == nullptr) != (specializationInfo.info.get() == nullptr))
{
- if(info->mapEntryCount != specializationInfo.info->mapEntryCount)
- {
- return info->mapEntryCount < specializationInfo.info->mapEntryCount;
- }
+ return info.get() == nullptr;
+ }
- if(info->dataSize != specializationInfo.info->dataSize)
- {
- return info->dataSize < specializationInfo.info->dataSize;
- }
+ if(!info)
+ {
+ ASSERT(!specializationInfo.info);
+ return false;
+ }
- if(info->mapEntryCount > 0)
- {
- int cmp = memcmp(info->pMapEntries, specializationInfo.info->pMapEntries, info->mapEntryCount * sizeof(VkSpecializationMapEntry));
- if(cmp != 0)
- {
- return cmp < 0;
- }
- }
+ if(info->mapEntryCount != specializationInfo.info->mapEntryCount)
+ {
+ return info->mapEntryCount < specializationInfo.info->mapEntryCount;
+ }
- if(info->dataSize > 0)
+ if(info->dataSize != specializationInfo.info->dataSize)
+ {
+ return info->dataSize < specializationInfo.info->dataSize;
+ }
+
+ if(info->mapEntryCount > 0)
+ {
+ int cmp = memcmp(info->pMapEntries, specializationInfo.info->pMapEntries, info->mapEntryCount * sizeof(VkSpecializationMapEntry));
+ if(cmp != 0)
{
- int cmp = memcmp(info->pData, specializationInfo.info->pData, info->dataSize);
- if(cmp != 0)
- {
- return cmp < 0;
- }
+ return cmp < 0;
+ }
+ }
+
+ if(info->dataSize > 0)
+ {
+ int cmp = memcmp(info->pData, specializationInfo.info->pData, info->dataSize);
+ if(cmp != 0)
+ {
+ return cmp < 0;
}
}