Commit e6092f3b by Ben Clayton

Fix memory corruption SpirvShaderKey::SpecializationInfo

SpecializationInfo was default copy-constructed / assigned, and held a raw pointer to the copy of the VkSpecializationInfo. This struct was deleted in the destructor, trashing any other copies. Fixes undefined behavior and crashes of a few Vulkan samples. Bug b/123588002 Change-Id: I7adcec2d51bc357ef5bcee1ec6bdafe9ecd208a7 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/34454 Kokoro-Presubmit: kokoro <noreply+kokoro@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com>
parent 03c2aea0
...@@ -22,9 +22,11 @@ PipelineCache::SpirvShaderKey::SpecializationInfo::SpecializationInfo(const VkSp ...@@ -22,9 +22,11 @@ PipelineCache::SpirvShaderKey::SpecializationInfo::SpecializationInfo(const VkSp
{ {
if(specializationInfo) if(specializationInfo)
{ {
info = reinterpret_cast<VkSpecializationInfo*>( auto ptr = reinterpret_cast<VkSpecializationInfo*>(
allocate(sizeof(VkSpecializationInfo), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY)); allocate(sizeof(VkSpecializationInfo), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
info = std::shared_ptr<VkSpecializationInfo>(ptr, Deleter());
info->mapEntryCount = specializationInfo->mapEntryCount; info->mapEntryCount = specializationInfo->mapEntryCount;
if(specializationInfo->mapEntryCount > 0) if(specializationInfo->mapEntryCount > 0)
{ {
...@@ -42,10 +44,14 @@ PipelineCache::SpirvShaderKey::SpecializationInfo::SpecializationInfo(const VkSp ...@@ -42,10 +44,14 @@ PipelineCache::SpirvShaderKey::SpecializationInfo::SpecializationInfo(const VkSp
memcpy(data, specializationInfo->pData, specializationInfo->dataSize); memcpy(data, specializationInfo->pData, specializationInfo->dataSize);
info->pData = data; info->pData = data;
} }
else
{
info->pData = nullptr;
}
} }
} }
PipelineCache::SpirvShaderKey::SpecializationInfo::~SpecializationInfo() void PipelineCache::SpirvShaderKey::SpecializationInfo::Deleter::operator() (VkSpecializationInfo* info) const
{ {
if(info) if(info)
{ {
...@@ -57,34 +63,34 @@ PipelineCache::SpirvShaderKey::SpecializationInfo::~SpecializationInfo() ...@@ -57,34 +63,34 @@ PipelineCache::SpirvShaderKey::SpecializationInfo::~SpecializationInfo()
bool PipelineCache::SpirvShaderKey::SpecializationInfo::operator<(const SpecializationInfo& specializationInfo) const bool PipelineCache::SpirvShaderKey::SpecializationInfo::operator<(const SpecializationInfo& specializationInfo) const
{ {
if(info && specializationInfo.info) if(info && specializationInfo.info)
{ {
if(info->mapEntryCount != specializationInfo.info->mapEntryCount) if(info->mapEntryCount != specializationInfo.info->mapEntryCount)
{ {
return info->mapEntryCount < specializationInfo.info->mapEntryCount; return info->mapEntryCount < specializationInfo.info->mapEntryCount;
} }
if(info->dataSize != specializationInfo.info->dataSize) if(info->dataSize != specializationInfo.info->dataSize)
{ {
return info->dataSize < specializationInfo.info->dataSize; return info->dataSize < specializationInfo.info->dataSize;
} }
if(info->mapEntryCount > 0) if(info->mapEntryCount > 0)
{ {
int cmp = memcmp(info->pMapEntries, specializationInfo.info->pMapEntries, info->mapEntryCount * sizeof(VkSpecializationMapEntry)); int cmp = memcmp(info->pMapEntries, specializationInfo.info->pMapEntries, info->mapEntryCount * sizeof(VkSpecializationMapEntry));
if(cmp != 0) if(cmp != 0)
{ {
return cmp < 0; return cmp < 0;
} }
} }
if(info->dataSize > 0) if(info->dataSize > 0)
{ {
int cmp = memcmp(info->pData, specializationInfo.info->pData, info->dataSize); int cmp = memcmp(info->pData, specializationInfo.info->pData, info->dataSize);
if(cmp != 0) if(cmp != 0)
{ {
return cmp < 0; return cmp < 0;
} }
} }
} }
...@@ -106,46 +112,46 @@ PipelineCache::SpirvShaderKey::SpirvShaderKey(const VkShaderStageFlagBits pipeli ...@@ -106,46 +112,46 @@ PipelineCache::SpirvShaderKey::SpirvShaderKey(const VkShaderStageFlagBits pipeli
{ {
} }
bool PipelineCache::SpirvShaderKey::operator<(const SpirvShaderKey &other) const bool PipelineCache::SpirvShaderKey::operator<(const SpirvShaderKey &other) const
{ {
if(pipelineStage != other.pipelineStage) if(pipelineStage != other.pipelineStage)
{ {
return pipelineStage < other.pipelineStage; return pipelineStage < other.pipelineStage;
} }
if(renderPass != other.renderPass) if(renderPass != other.renderPass)
{ {
return renderPass < other.renderPass; return renderPass < other.renderPass;
} }
if(subpassIndex != other.subpassIndex) if(subpassIndex != other.subpassIndex)
{ {
return subpassIndex < other.subpassIndex; return subpassIndex < other.subpassIndex;
} }
if(insns.size() != other.insns.size()) if(insns.size() != other.insns.size())
{ {
return insns.size() < other.insns.size(); return insns.size() < other.insns.size();
} }
if(entryPointName.size() != other.entryPointName.size()) if(entryPointName.size() != other.entryPointName.size())
{ {
return entryPointName.size() < other.entryPointName.size(); return entryPointName.size() < other.entryPointName.size();
} }
int cmp = memcmp(entryPointName.c_str(), other.entryPointName.c_str(), entryPointName.size()); int cmp = memcmp(entryPointName.c_str(), other.entryPointName.c_str(), entryPointName.size());
if(cmp != 0) if(cmp != 0)
{ {
return cmp < 0; return cmp < 0;
} }
cmp = memcmp(insns.data(), other.insns.data(), insns.size() * sizeof(uint32_t)); cmp = memcmp(insns.data(), other.insns.data(), insns.size() * sizeof(uint32_t));
if(cmp != 0) if(cmp != 0)
{ {
return cmp < 0; return cmp < 0;
} }
return (specializationInfo < other.specializationInfo); return (specializationInfo < other.specializationInfo);
} }
PipelineCache::PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem) : PipelineCache::PipelineCache(const VkPipelineCacheCreateInfo* pCreateInfo, void* mem) :
......
...@@ -52,14 +52,18 @@ public: ...@@ -52,14 +52,18 @@ public:
struct SpecializationInfo struct SpecializationInfo
{ {
SpecializationInfo(const VkSpecializationInfo* specializationInfo); SpecializationInfo(const VkSpecializationInfo* specializationInfo);
~SpecializationInfo();
bool operator<(const SpecializationInfo& specializationInfo) const; bool operator<(const SpecializationInfo& specializationInfo) const;
VkSpecializationInfo* get() const { return info; } const VkSpecializationInfo* get() const { return info.get(); }
private: private:
VkSpecializationInfo* info = nullptr; struct Deleter
{
void operator()(VkSpecializationInfo*) const;
};
std::shared_ptr<VkSpecializationInfo> info;
}; };
SpirvShaderKey(const VkShaderStageFlagBits pipelineStage, SpirvShaderKey(const VkShaderStageFlagBits pipelineStage,
...@@ -97,9 +101,9 @@ public: ...@@ -97,9 +101,9 @@ public:
shader(shader), layout(layout) shader(shader), layout(layout)
{} {}
bool operator<(const ComputeProgramKey &other) const bool operator<(const ComputeProgramKey &other) const
{ {
return (shader < other.shader) || (layout < other.layout); return (shader < other.shader) || (layout < other.layout);
} }
const sw::SpirvShader* getShader() const { return shader; } const sw::SpirvShader* getShader() const { return shader; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment