Fix taking the sampling instruction type into account
Our lookup key for generated sampling functions was only using the
sampler and image view descriptors into account. The same descriptors
can be used in various different sampling instructions, so we need to
also make that part of the lookup key.
Bug: b/129523279
Change-Id: I325aa5571191e4ffc69214c2d13d431d21316fed
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/31949
Presubmit-Ready: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
diff --git a/src/Pipeline/SpirvShaderSampling.cpp b/src/Pipeline/SpirvShaderSampling.cpp
index e7b7848..9d3dc8a 100644
--- a/src/Pipeline/SpirvShaderSampling.cpp
+++ b/src/Pipeline/SpirvShaderSampling.cpp
@@ -31,6 +31,31 @@
#include <climits>
#include <mutex>
+namespace
+{
+
+struct SamplingRoutineKey
+{
+ uint32_t instruction;
+ uint32_t sampler;
+ uint32_t imageView;
+
+ bool operator==(const SamplingRoutineKey &rhs) const
+ {
+ return instruction == rhs.instruction && sampler == rhs.sampler && imageView == rhs.imageView;
+ }
+
+ struct Hash
+ {
+ std::size_t operator()(const SamplingRoutineKey &key) const noexcept
+ {
+ return (key.instruction << 16) ^ (key.sampler << 8) ^ key.imageView;
+ }
+ };
+};
+
+}
+
namespace sw {
SpirvShader::ImageSampler *SpirvShader::getImageSampler(uint32_t inst, vk::SampledImageDescriptor const *imageDescriptor, const vk::Sampler *sampler)
@@ -39,11 +64,10 @@
ASSERT(imageDescriptor->imageViewId != 0 && (sampler->id != 0 || instruction.samplerMethod == Fetch));
// TODO(b/129523279): Move somewhere sensible.
- static std::unordered_map<uint64_t, ImageSampler*> cache;
+ static std::unordered_map<SamplingRoutineKey, ImageSampler*, SamplingRoutineKey::Hash> cache;
static std::mutex mutex;
- // FIXME(b/129523279): Take instruction opcode and optional parameters into account (SamplerMethod / SamplerOption).
- auto key = (static_cast<uint64_t>(imageDescriptor->imageViewId) << 32) | static_cast<uint64_t>(sampler->id);
+ SamplingRoutineKey key = {inst, imageDescriptor->imageViewId, sampler->id};
std::unique_lock<std::mutex> lock(mutex);
auto it = cache.find(key);
diff --git a/src/Vulkan/VkConfig.h b/src/Vulkan/VkConfig.h
index 6e4ad11..157f34e 100644
--- a/src/Vulkan/VkConfig.h
+++ b/src/Vulkan/VkConfig.h
@@ -39,7 +39,7 @@
{
// Alignment of all Vulkan objects, pools, device memory, images, buffers, descriptors.
REQUIRED_MEMORY_ALIGNMENT = 16, // 16 bytes for 128-bit vector types.
-
+
MIN_TEXEL_BUFFER_OFFSET_ALIGNMENT = 256,
MIN_UNIFORM_BUFFER_OFFSET_ALIGNMENT = 256,
MIN_STORAGE_BUFFER_OFFSET_ALIGNMENT = 256,
diff --git a/src/Vulkan/VulkanPlatform.h b/src/Vulkan/VulkanPlatform.h
index fb71a7b..958c22d 100644
--- a/src/Vulkan/VulkanPlatform.h
+++ b/src/Vulkan/VulkanPlatform.h
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#ifndef VULKAN_PLATFORM
-#define VULKAN_PLATFORM
-
+#ifndef VULKAN_PLATFORM
+#define VULKAN_PLATFORM
+
#include <cstddef>
#include <cstdint>
@@ -112,4 +112,4 @@
#undef None
#endif
-#endif // VULKAN_PLATFORM
+#endif // VULKAN_PLATFORM