diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index f779b68..08bd071 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -2679,6 +2679,36 @@ void VulkanHppGenerator::appendHandlesCommandDefintions(std::string & str) const str += "\n"; } +void VulkanHppGenerator::appendHashStructures(std::string& str) const +{ + str += "\n" + "namespace std\n" + "{\n"; + + const std::string hashTemplate = R"( template <> struct hash + { + std::size_t operator()(vk::${type} const& ${name}) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(${name})); + } + }; +)"; + for (auto handle : m_handles) + { + if (!handle.first.empty()) + { + str += "\n"; + appendPlatformEnter(str, !handle.second.alias.empty(), handle.second.platform); + std::string type = stripPrefix(handle.first, "Vk"); + std::string name = startLowerCase(type); + str += replaceWithMap(hashTemplate, { {"name", name}, {"type", type} }); + appendPlatformLeave(str, !handle.second.alias.empty(), handle.second.platform); + } + } + + str += "}\n"; +} + // Intended only for `enum class Result`! void VulkanHppGenerator::appendResultExceptions(std::string & str) const { @@ -6443,6 +6473,7 @@ int main(int argc, char **argv) #include #include #include +#include #include #include #include @@ -6756,8 +6787,9 @@ namespace std generator.appendHandlesCommandDefintions(str); generator.appendStructureChainValidation(str); generator.appendDispatchLoaderDynamic(str); - str += "} // namespace VULKAN_HPP_NAMESPACE\n" - "#endif\n"; + str += "} // namespace VULKAN_HPP_NAMESPACE\n"; + generator.appendHashStructures(str); + str += "#endif\n"; assert(str.length() < estimatedLength); cleanup(str); diff --git a/VulkanHppGenerator.hpp b/VulkanHppGenerator.hpp index 1b29bb3..e500ac4 100644 --- a/VulkanHppGenerator.hpp +++ b/VulkanHppGenerator.hpp @@ -34,6 +34,7 @@ class VulkanHppGenerator void appendForwardDeclarations(std::string & str) const; void appendHandles(std::string & str) const; void appendHandlesCommandDefintions(std::string & str) const; + void appendHashStructures(std::string& str) const; void appendResultExceptions(std::string & str) const; void appendStructs(std::string & str) const; void appendStructureChainValidation(std::string & str); diff --git a/tests/Hash/CMakeLists.txt b/tests/Hash/CMakeLists.txt new file mode 100644 index 0000000..37a7e7d --- /dev/null +++ b/tests/Hash/CMakeLists.txt @@ -0,0 +1,37 @@ +# Copyright(c) 2018, NVIDIA CORPORATION. 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. + +cmake_minimum_required(VERSION 3.2) + +if (NOT TESTS_BUILD_ONLY_DYNAMIC) + project(Hash) + + set(HEADERS + ) + + set(SOURCES + Hash.cpp + ) + + source_group(headers FILES ${HEADERS}) + source_group(sources FILES ${SOURCES}) + + add_executable(Hash + ${HEADERS} + ${SOURCES} + ) + + set_target_properties(Hash PROPERTIES FOLDER "Tests") + target_link_libraries(Hash "${Vulkan_LIBRARIES}") +endif() \ No newline at end of file diff --git a/tests/Hash/Hash.cpp b/tests/Hash/Hash.cpp new file mode 100644 index 0000000..41e1fcf --- /dev/null +++ b/tests/Hash/Hash.cpp @@ -0,0 +1,55 @@ +// Copyright(c) 2018, NVIDIA CORPORATION. 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. +// +// VulkanHpp Samples : Hash +// Compile test on using std::hash on handles + +#include "vulkan/vulkan.hpp" +#include +#include +#include + +static char const* AppName = "Hash"; +static char const* EngineName = "Vulkan.hpp"; + +int main(int /*argc*/, char ** /*argv*/) +{ + try + { + vk::ApplicationInfo appInfo(AppName, 1, EngineName, 1, VK_API_VERSION_1_1); + vk::UniqueInstance instance = vk::createInstanceUnique(vk::InstanceCreateInfo({}, &appInfo)); + + auto h1 = std::hash{}(*instance); + auto h2 = std::hash{}(*instance); + assert(h1 == h2); + + std::unordered_set uset; + uset.insert(*instance); + + std::unordered_map umap; + umap[*instance] = 1; + } + catch (vk::SystemError const& err) + { + std::cout << "vk::SystemError: " << err.what() << std::endl; + exit(-1); + } + catch (...) + { + std::cout << "unknown error\n"; + exit(-1); + } + + return 0; +} diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 316cd2a..dcbb928 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -77981,4 +77982,313 @@ namespace VULKAN_HPP_NAMESPACE }; } // namespace VULKAN_HPP_NAMESPACE + +namespace std +{ + template <> struct hash + { + std::size_t operator()(vk::AccelerationStructureKHR const& accelerationStructureKHR) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(accelerationStructureKHR)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Buffer const& buffer) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(buffer)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::BufferView const& bufferView) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(bufferView)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::CommandBuffer const& commandBuffer) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(commandBuffer)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::CommandPool const& commandPool) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(commandPool)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DebugReportCallbackEXT const& debugReportCallbackEXT) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(debugReportCallbackEXT)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DebugUtilsMessengerEXT const& debugUtilsMessengerEXT) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(debugUtilsMessengerEXT)); + } + }; + +#ifdef VK_ENABLE_BETA_EXTENSIONS + template <> struct hash + { + std::size_t operator()(vk::DeferredOperationKHR const& deferredOperationKHR) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(deferredOperationKHR)); + } + }; +#endif /*VK_ENABLE_BETA_EXTENSIONS*/ + + template <> struct hash + { + std::size_t operator()(vk::DescriptorPool const& descriptorPool) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(descriptorPool)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DescriptorSet const& descriptorSet) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(descriptorSet)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DescriptorSetLayout const& descriptorSetLayout) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(descriptorSetLayout)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DescriptorUpdateTemplate const& descriptorUpdateTemplate) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(descriptorUpdateTemplate)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Device const& device) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(device)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DeviceMemory const& deviceMemory) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(deviceMemory)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DisplayKHR const& displayKHR) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(displayKHR)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::DisplayModeKHR const& displayModeKHR) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(displayModeKHR)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Event const& event) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(event)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Fence const& fence) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(fence)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Framebuffer const& framebuffer) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(framebuffer)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Image const& image) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(image)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::ImageView const& imageView) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(imageView)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::IndirectCommandsLayoutNV const& indirectCommandsLayoutNV) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(indirectCommandsLayoutNV)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Instance const& instance) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(instance)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::PerformanceConfigurationINTEL const& performanceConfigurationINTEL) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(performanceConfigurationINTEL)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::PhysicalDevice const& physicalDevice) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(physicalDevice)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Pipeline const& pipeline) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(pipeline)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::PipelineCache const& pipelineCache) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(pipelineCache)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::PipelineLayout const& pipelineLayout) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(pipelineLayout)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::QueryPool const& queryPool) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(queryPool)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Queue const& queue) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(queue)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::RenderPass const& renderPass) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(renderPass)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Sampler const& sampler) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(sampler)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::SamplerYcbcrConversion const& samplerYcbcrConversion) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(samplerYcbcrConversion)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::Semaphore const& semaphore) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(semaphore)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::ShaderModule const& shaderModule) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(shaderModule)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::SurfaceKHR const& surfaceKHR) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(surfaceKHR)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::SwapchainKHR const& swapchainKHR) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(swapchainKHR)); + } + }; + + template <> struct hash + { + std::size_t operator()(vk::ValidationCacheEXT const& validationCacheEXT) const VULKAN_HPP_NOEXCEPT + { + return std::hash{}(static_cast(validationCacheEXT)); + } + }; +} #endif