Add optimization state to the optimized SPIR-V binary cache key
The SpirvShaderKey should uniquely identify each of the pipeline cache's
optimized SPIR-V binary entries. The Boolean which indicates whether
the binary is even optimized in the first place wasn't yet part of it.
Bug: b/197982536
Change-Id: I3c4c8f41fedc8baffe0822853a894bc1c65a583c
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/57148
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/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 0fb6f9d..ef2da43 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -105,16 +105,9 @@
return optimized;
}
-sw::SpirvBinary optimizeSpirv(
- const vk::PipelineCache::SpirvShaderKey &key,
- const std::shared_ptr<vk::dbg::Context> &dbgctx)
+sw::SpirvBinary optimizeSpirv(const vk::PipelineCache::SpirvShaderKey &key)
{
- // Do not optimize the shader if we have a debugger context.
- // Optimization passes are likely to damage debug information, and reorder
- // instructions.
- const bool optimize = !dbgctx;
-
- auto code = preprocessSpirv(key.getInsns(), key.getSpecializationInfo(), optimize);
+ auto code = preprocessSpirv(key.getInsns(), key.getSpecializationInfo(), key.getOptimization());
ASSERT(code.size() > 0);
return code;
@@ -241,24 +234,29 @@
UNSUPPORTED("pStage->flags %d", int(pStage->flags));
}
+ auto dbgctx = device->getDebuggerContext();
+ // Do not optimize the shader if we have a debugger context.
+ // Optimization passes are likely to damage debug information, and reorder
+ // instructions.
+ const bool optimize = !dbgctx;
+
const ShaderModule *module = vk::Cast(pStage->module);
const PipelineCache::SpirvShaderKey key(pStage->stage, pStage->pName, module->getCode(),
vk::Cast(pCreateInfo->renderPass), pCreateInfo->subpass,
- pStage->pSpecializationInfo);
+ pStage->pSpecializationInfo, optimize);
auto pipelineStage = key.getPipelineStage();
- auto dbgctx = device->getDebuggerContext();
sw::SpirvBinary spirv;
if(pPipelineCache)
{
spirv = pPipelineCache->getOrOptimizeSpirv(key, [&] {
- return optimizeSpirv(key, dbgctx);
+ return optimizeSpirv(key);
});
}
else
{
- spirv = optimizeSpirv(key, dbgctx);
+ spirv = optimizeSpirv(key);
}
auto shader = createShader(key, module, spirv, robustBufferAccess, dbgctx);
@@ -291,21 +289,26 @@
ASSERT(shader.get() == nullptr);
ASSERT(program.get() == nullptr);
- const PipelineCache::SpirvShaderKey shaderKey(
- stage.stage, stage.pName, module->getCode(), nullptr, 0, stage.pSpecializationInfo);
auto dbgctx = device->getDebuggerContext();
+ // Do not optimize the shader if we have a debugger context.
+ // Optimization passes are likely to damage debug information, and reorder
+ // instructions.
+ const bool optimize = !dbgctx;
+
+ const PipelineCache::SpirvShaderKey shaderKey(
+ stage.stage, stage.pName, module->getCode(), nullptr, 0, stage.pSpecializationInfo, optimize);
sw::SpirvBinary spirv;
if(pPipelineCache)
{
spirv = pPipelineCache->getOrOptimizeSpirv(shaderKey, [&] {
- return optimizeSpirv(shaderKey, dbgctx);
+ return optimizeSpirv(shaderKey);
});
}
else
{
- spirv = optimizeSpirv(shaderKey, dbgctx);
+ spirv = optimizeSpirv(shaderKey);
}
shader = createShader(shaderKey, module, spirv, robustBufferAccess, dbgctx);
diff --git a/src/Vulkan/VkPipelineCache.cpp b/src/Vulkan/VkPipelineCache.cpp
index dc4afe3..87b4c89 100644
--- a/src/Vulkan/VkPipelineCache.cpp
+++ b/src/Vulkan/VkPipelineCache.cpp
@@ -23,13 +23,15 @@
const sw::SpirvBinary &insns,
const vk::RenderPass *renderPass,
const uint32_t subpassIndex,
- const vk::SpecializationInfo &specializationInfo)
+ const vk::SpecializationInfo &specializationInfo,
+ bool optimize)
: pipelineStage(pipelineStage)
, entryPointName(entryPointName)
, insns(insns)
, renderPass(renderPass)
, subpassIndex(subpassIndex)
, specializationInfo(specializationInfo)
+ , optimize(optimize)
{
}
@@ -72,6 +74,11 @@
return cmp < 0;
}
+ if(optimize != other.optimize)
+ {
+ return !optimize && other.optimize;
+ }
+
return (specializationInfo < other.specializationInfo);
}
diff --git a/src/Vulkan/VkPipelineCache.hpp b/src/Vulkan/VkPipelineCache.hpp
index c959e0d..9e950c6 100644
--- a/src/Vulkan/VkPipelineCache.hpp
+++ b/src/Vulkan/VkPipelineCache.hpp
@@ -60,7 +60,8 @@
const sw::SpirvBinary &insns,
const vk::RenderPass *renderPass,
const uint32_t subpassIndex,
- const vk::SpecializationInfo &specializationInfo);
+ const vk::SpecializationInfo &specializationInfo,
+ bool optimize);
bool operator<(const SpirvShaderKey &other) const;
@@ -70,6 +71,7 @@
const vk::RenderPass *getRenderPass() const { return renderPass; }
uint32_t getSubpassIndex() const { return subpassIndex; }
const VkSpecializationInfo *getSpecializationInfo() const { return specializationInfo.get(); }
+ bool getOptimization() const { return optimize; }
private:
const VkShaderStageFlagBits pipelineStage;
@@ -78,6 +80,7 @@
const vk::RenderPass *renderPass;
const uint32_t subpassIndex;
const vk::SpecializationInfo specializationInfo;
+ const bool optimize;
};
// getOrOptimizeSpirv() queries the cache for a shader with the given key.