Vulkan: Move SpecializationInfo to own file.
This will also be used by the pipelines for dynamic recompilation.
Bug: b/154158882
Change-Id: I0fe16dbc3bc4eed8ffdd90afcd62f255ca8e4505
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/43848
Kokoro-Result: kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Tested-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Vulkan/BUILD.gn b/src/Vulkan/BUILD.gn
index 19b7e79..830a39c 100644
--- a/src/Vulkan/BUILD.gn
+++ b/src/Vulkan/BUILD.gn
@@ -91,6 +91,7 @@
"VkSampler.hpp",
"VkSemaphore.hpp",
"VkShaderModule.hpp",
+ "VkSpecializationInfo.hpp",
"VkStringify.hpp",
"VulkanPlatform.h",
]
@@ -133,6 +134,7 @@
"VkSampler.cpp",
"VkSemaphore.cpp",
"VkShaderModule.cpp",
+ "VkSpecializationInfo.cpp",
"VkStringify.cpp",
"Vulkan.rc",
"libVulkan.cpp",
diff --git a/src/Vulkan/CMakeLists.txt b/src/Vulkan/CMakeLists.txt
index bc334b0..65e29ad 100644
--- a/src/Vulkan/CMakeLists.txt
+++ b/src/Vulkan/CMakeLists.txt
@@ -68,6 +68,8 @@
VkPipeline.hpp
VkPipelineCache.cpp
VkPipelineCache.hpp
+ VkSpecializationInfo.cpp
+ VkSpecializationInfo.hpp
VkPipelineLayout.cpp
VkPipelineLayout.hpp
VkPromotedExtensions.cpp
diff --git a/src/Vulkan/VkPipelineCache.cpp b/src/Vulkan/VkPipelineCache.cpp
index c725b3f..8c4c894 100644
--- a/src/Vulkan/VkPipelineCache.cpp
+++ b/src/Vulkan/VkPipelineCache.cpp
@@ -17,100 +17,12 @@
namespace vk {
-PipelineCache::SpirvShaderKey::SpecializationInfo::SpecializationInfo(const VkSpecializationInfo *specializationInfo)
-{
- if(specializationInfo)
- {
- auto ptr = reinterpret_cast<VkSpecializationInfo *>(
- allocate(sizeof(VkSpecializationInfo), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
-
- info = std::shared_ptr<VkSpecializationInfo>(ptr, Deleter());
-
- info->mapEntryCount = specializationInfo->mapEntryCount;
- if(specializationInfo->mapEntryCount > 0)
- {
- size_t entriesSize = specializationInfo->mapEntryCount * sizeof(VkSpecializationMapEntry);
- VkSpecializationMapEntry *mapEntries = reinterpret_cast<VkSpecializationMapEntry *>(
- allocate(entriesSize, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
- memcpy(mapEntries, specializationInfo->pMapEntries, entriesSize);
- info->pMapEntries = mapEntries;
- }
-
- info->dataSize = specializationInfo->dataSize;
- if(specializationInfo->dataSize > 0)
- {
- void *data = allocate(specializationInfo->dataSize, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY);
- memcpy(data, specializationInfo->pData, specializationInfo->dataSize);
- info->pData = data;
- }
- else
- {
- info->pData = nullptr;
- }
- }
-}
-
-void PipelineCache::SpirvShaderKey::SpecializationInfo::Deleter::operator()(VkSpecializationInfo *info) const
-{
- if(info)
- {
- deallocate(const_cast<VkSpecializationMapEntry *>(info->pMapEntries), DEVICE_MEMORY);
- deallocate(const_cast<void *>(info->pData), DEVICE_MEMORY);
- deallocate(info, DEVICE_MEMORY);
- }
-}
-
-bool PipelineCache::SpirvShaderKey::SpecializationInfo::operator<(const SpecializationInfo &specializationInfo) const
-{
- // Check that either both or neither keys have specialization info.
- if((info.get() == nullptr) != (specializationInfo.info.get() == nullptr))
- {
- return info.get() == nullptr;
- }
-
- if(!info)
- {
- ASSERT(!specializationInfo.info);
- return false;
- }
-
- if(info->mapEntryCount != specializationInfo.info->mapEntryCount)
- {
- return info->mapEntryCount < specializationInfo.info->mapEntryCount;
- }
-
- if(info->dataSize != specializationInfo.info->dataSize)
- {
- return info->dataSize < specializationInfo.info->dataSize;
- }
-
- if(info->mapEntryCount > 0)
- {
- int cmp = memcmp(info->pMapEntries, specializationInfo.info->pMapEntries, info->mapEntryCount * sizeof(VkSpecializationMapEntry));
- if(cmp != 0)
- {
- return cmp < 0;
- }
- }
-
- if(info->dataSize > 0)
- {
- int cmp = memcmp(info->pData, specializationInfo.info->pData, info->dataSize);
- if(cmp != 0)
- {
- return cmp < 0;
- }
- }
-
- return false;
-}
-
PipelineCache::SpirvShaderKey::SpirvShaderKey(const VkShaderStageFlagBits pipelineStage,
const std::string &entryPointName,
const std::vector<uint32_t> &insns,
const vk::RenderPass *renderPass,
const uint32_t subpassIndex,
- const VkSpecializationInfo *specializationInfo)
+ const vk::SpecializationInfo &specializationInfo)
: pipelineStage(pipelineStage)
, entryPointName(entryPointName)
, insns(insns)
diff --git a/src/Vulkan/VkPipelineCache.hpp b/src/Vulkan/VkPipelineCache.hpp
index 85c5836..5e89e60 100644
--- a/src/Vulkan/VkPipelineCache.hpp
+++ b/src/Vulkan/VkPipelineCache.hpp
@@ -16,6 +16,7 @@
#define VK_PIPELINE_CACHE_HPP_
#include "VkObject.hpp"
+#include "VkSpecializationInfo.hpp"
#include <cstring>
#include <functional>
@@ -51,29 +52,12 @@
struct SpirvShaderKey
{
- struct SpecializationInfo
- {
- SpecializationInfo(const VkSpecializationInfo *specializationInfo);
-
- bool operator<(const SpecializationInfo &specializationInfo) const;
-
- const VkSpecializationInfo *get() const { return info.get(); }
-
- private:
- struct Deleter
- {
- void operator()(VkSpecializationInfo *) const;
- };
-
- std::shared_ptr<VkSpecializationInfo> info;
- };
-
SpirvShaderKey(const VkShaderStageFlagBits pipelineStage,
const std::string &entryPointName,
const std::vector<uint32_t> &insns,
const vk::RenderPass *renderPass,
const uint32_t subpassIndex,
- const VkSpecializationInfo *specializationInfo);
+ const vk::SpecializationInfo &specializationInfo);
bool operator<(const SpirvShaderKey &other) const;
@@ -90,7 +74,7 @@
const std::vector<uint32_t> insns;
const vk::RenderPass *renderPass;
const uint32_t subpassIndex;
- const SpecializationInfo specializationInfo;
+ const vk::SpecializationInfo specializationInfo;
};
// getOrCreateShader() queries the cache for a shader with the given key.
diff --git a/src/Vulkan/VkSpecializationInfo.cpp b/src/Vulkan/VkSpecializationInfo.cpp
new file mode 100644
index 0000000..bda5f43
--- /dev/null
+++ b/src/Vulkan/VkSpecializationInfo.cpp
@@ -0,0 +1,108 @@
+// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "VkPipelineCache.hpp"
+#include <cstring>
+
+namespace vk {
+
+SpecializationInfo::SpecializationInfo(const VkSpecializationInfo *specializationInfo)
+{
+ if(specializationInfo)
+ {
+ auto ptr = reinterpret_cast<VkSpecializationInfo *>(
+ allocate(sizeof(VkSpecializationInfo), REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
+
+ info = std::shared_ptr<VkSpecializationInfo>(ptr, Deleter());
+
+ info->mapEntryCount = specializationInfo->mapEntryCount;
+ if(specializationInfo->mapEntryCount > 0)
+ {
+ size_t entriesSize = specializationInfo->mapEntryCount * sizeof(VkSpecializationMapEntry);
+ VkSpecializationMapEntry *mapEntries = reinterpret_cast<VkSpecializationMapEntry *>(
+ allocate(entriesSize, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY));
+ memcpy(mapEntries, specializationInfo->pMapEntries, entriesSize);
+ info->pMapEntries = mapEntries;
+ }
+
+ info->dataSize = specializationInfo->dataSize;
+ if(specializationInfo->dataSize > 0)
+ {
+ void *data = allocate(specializationInfo->dataSize, REQUIRED_MEMORY_ALIGNMENT, DEVICE_MEMORY);
+ memcpy(data, specializationInfo->pData, specializationInfo->dataSize);
+ info->pData = data;
+ }
+ else
+ {
+ info->pData = nullptr;
+ }
+ }
+}
+
+void SpecializationInfo::Deleter::operator()(VkSpecializationInfo *info) const
+{
+ if(info)
+ {
+ deallocate(const_cast<VkSpecializationMapEntry *>(info->pMapEntries), DEVICE_MEMORY);
+ deallocate(const_cast<void *>(info->pData), DEVICE_MEMORY);
+ deallocate(info, DEVICE_MEMORY);
+ }
+}
+
+bool SpecializationInfo::operator<(const SpecializationInfo &specializationInfo) const
+{
+ // Check that either both or neither keys have specialization info.
+ if((info.get() == nullptr) != (specializationInfo.info.get() == nullptr))
+ {
+ return info.get() == nullptr;
+ }
+
+ if(!info)
+ {
+ ASSERT(!specializationInfo.info);
+ return false;
+ }
+
+ if(info->mapEntryCount != specializationInfo.info->mapEntryCount)
+ {
+ return info->mapEntryCount < specializationInfo.info->mapEntryCount;
+ }
+
+ if(info->dataSize != specializationInfo.info->dataSize)
+ {
+ return info->dataSize < specializationInfo.info->dataSize;
+ }
+
+ if(info->mapEntryCount > 0)
+ {
+ int cmp = memcmp(info->pMapEntries, specializationInfo.info->pMapEntries, info->mapEntryCount * sizeof(VkSpecializationMapEntry));
+ if(cmp != 0)
+ {
+ return cmp < 0;
+ }
+ }
+
+ if(info->dataSize > 0)
+ {
+ int cmp = memcmp(info->pData, specializationInfo.info->pData, info->dataSize);
+ if(cmp != 0)
+ {
+ return cmp < 0;
+ }
+ }
+
+ return false;
+}
+
+} // namespace vk
diff --git a/src/Vulkan/VkSpecializationInfo.hpp b/src/Vulkan/VkSpecializationInfo.hpp
new file mode 100644
index 0000000..0fdd43d
--- /dev/null
+++ b/src/Vulkan/VkSpecializationInfo.hpp
@@ -0,0 +1,43 @@
+// Copyright 2020 The SwiftShader Authors. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef VK_SPECIALIZATION_INFO_HPP_
+#define VK_SPECIALIZATION_INFO_HPP_
+
+#include "VkObject.hpp"
+
+#include <memory>
+
+namespace vk {
+
+struct SpecializationInfo
+{
+ SpecializationInfo(const VkSpecializationInfo *specializationInfo);
+
+ bool operator<(const SpecializationInfo &specializationInfo) const;
+
+ const VkSpecializationInfo *get() const { return info.get(); }
+
+private:
+ struct Deleter
+ {
+ void operator()(VkSpecializationInfo *) const;
+ };
+
+ std::shared_ptr<VkSpecializationInfo> info;
+};
+
+} // namespace vk
+
+#endif // VK_SPECIALIZATION_INFO_HPP_