Fix use of deleted shader during compute execution ComputeProgram::run() uses the `shader` member, which was previously a weak pointer to a SpirvShader object. If the corresponding shader module is destroyed, and there is no (more) pipeline cache to hold a shared_ptr reference to it, we'd access a deleted object. The `pipelineLayout` member is safe-ish because we explicitly reference count it in the vk::Pipeline class, since graphics pipelines also use it to (re)compile routines at draw execution time. The ComputeProgramKey was modified to use unique integer identifiers instead of pointers to the shader and pipeline layout. This prevents a false cache hit when these objects are destroyed and new ones get allocated at the same address. Note that this means we lose the nice property of constructing new cache entries only from cache key data, but this is a better compromise than the previous buggy code. Bug: b/197982536 Change-Id: Ie75bb0e8df21ad25c2a7fed29adbf086fab072e3 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/57168 Tested-by: Nicolas Capens <nicolascapens@google.com> Kokoro-Result: kokoro <noreply+kokoro@google.com> Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/ComputeProgram.hpp b/src/Pipeline/ComputeProgram.hpp index 839f494..79a0bcb 100644 --- a/src/Pipeline/ComputeProgram.hpp +++ b/src/Pipeline/ComputeProgram.hpp
@@ -46,7 +46,7 @@ int32_t subgroupCount)> { public: - ComputeProgram(vk::Device *device, SpirvShader const *spirvShader, vk::PipelineLayout const *pipelineLayout, const vk::DescriptorSet::Bindings &descriptorSets); + ComputeProgram(vk::Device *device, std::shared_ptr<SpirvShader> spirvShader, vk::PipelineLayout const *pipelineLayout, const vk::DescriptorSet::Bindings &descriptorSets); virtual ~ComputeProgram(); @@ -81,8 +81,8 @@ }; vk::Device *const device; - SpirvShader const *const shader; - vk::PipelineLayout const *const pipelineLayout; + const std::shared_ptr<SpirvShader> shader; + const vk::PipelineLayout *const pipelineLayout; // Reference held by vk::Pipeline const vk::DescriptorSet::Bindings &descriptorSets; };