Avoid SPIR-V binary identifier clashes

If we ever use both unoptimized and optimized SPIR-V binaries (e.g. as
part of tiered JIT compilation), we need them to have different
identifiers. This is accomplished by using the bitwise inverse of the
unoptimized binary's identifier as the one for the optimized binary.

Note this only affects cases where no pipeline cache is being used. If
one is used, we use the identifier that got assigned when creating the
cache entry.

Bug: b/172839674
Change-Id: I894a01f21518b046845cd56dcbb0d13cea1ff94b
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/58270
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
diff --git a/src/Pipeline/SpirvBinary.cpp b/src/Pipeline/SpirvBinary.cpp
index 88ade4d..fa769ce 100644
--- a/src/Pipeline/SpirvBinary.cpp
+++ b/src/Pipeline/SpirvBinary.cpp
@@ -28,9 +28,11 @@
 {
 }
 
-void SpirvBinary::inheritIdentifier(const SpirvBinary &binary)
+void SpirvBinary::mapOptimizedIdentifier(const SpirvBinary &unoptimized)
 {
-	identifier = binary.identifier;
+	// The bitwise NOT accomplishes a 1-to-1 mapping of the identifiers,
+	// while avoiding clashes with previous or future serial IDs.
+	identifier = ~unoptimized.identifier;
 }
 
 }  // namespace sw
\ No newline at end of file
diff --git a/src/Pipeline/SpirvBinary.hpp b/src/Pipeline/SpirvBinary.hpp
index 9ff4536..50c9f97 100644
--- a/src/Pipeline/SpirvBinary.hpp
+++ b/src/Pipeline/SpirvBinary.hpp
@@ -29,7 +29,8 @@
 
 	inline uint32_t getIdentifier() const { return identifier; };
 
-	void inheritIdentifier(const SpirvBinary &binary);
+	// Assigns an identifier derived from the unoptimized SPIR-V binary, to avoid recompiles.
+	void mapOptimizedIdentifier(const SpirvBinary &unoptimized);
 
 private:
 	static std::atomic<uint32_t> serialCounter;
diff --git a/src/Vulkan/VkPipeline.cpp b/src/Vulkan/VkPipeline.cpp
index 9c06350..497e0e2 100644
--- a/src/Vulkan/VkPipeline.cpp
+++ b/src/Vulkan/VkPipeline.cpp
@@ -237,7 +237,7 @@
 			// so we should use a 1-to-1 mapping of the identifiers to avoid JIT routine recompiles.
 			if(!key.getSpecializationInfo())
 			{
-				spirv.inheritIdentifier(key.getBinary());
+				spirv.mapOptimizedIdentifier(key.getBinary());
 			}
 		}
 
@@ -297,7 +297,7 @@
 		// so we should use a 1-to-1 mapping of the identifiers to avoid JIT routine recompiles.
 		if(!shaderKey.getSpecializationInfo())
 		{
-			spirv.inheritIdentifier(shaderKey.getBinary());
+			spirv.mapOptimizedIdentifier(shaderKey.getBinary());
 		}
 	}