Add specializations of std::hash for all the structs and handles in the vk-namespace. (#1994)

This commit is contained in:
Andreas Süßenbach 2024-11-26 11:08:49 +01:00 committed by GitHub
parent d433715af0
commit cdfa83ab79
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 4358 additions and 72 deletions

View File

@ -725,7 +725,7 @@ module;
#include <vulkan/vulkan_hpp_macros.hpp>
#if defined( __cpp_lib_modules )
#if defined( __cpp_lib_modules ) && !defined( VULKAN_HPP_ENABLE_STD_MODULE )
#define VULKAN_HPP_ENABLE_STD_MODULE
#endif
@ -749,10 +749,16 @@ export namespace VULKAN_HPP_NAMESPACE
} // namespace VULKAN_HPP_RAII_NAMESPACE
#endif
} // namespace VULKAN_HPP_NAMESPACE
export namespace std
{
${hashSpecializations}
}
)";
auto const str = replaceWithMap( vulkanCppmTemplate,
{ { "api", m_api },
{ "hashSpecializations", generateCppModuleHashSpecializations() },
{ "licenseHeader", m_vulkanLicenseHeader },
{ "raiiUsings", generateCppModuleRaiiUsings() },
{ "usings", generateCppModuleUsings() } } );
@ -6026,6 +6032,101 @@ std::string VulkanHppGenerator::generateCppModuleRaiiUsings() const
return usings;
}
std::string VulkanHppGenerator::generateCppModuleHandleHashSpecializations() const
{
const std::string hashesTemplate = R"(
//========================================
//=== HASH specializations for handles ===
//========================================
${specializations}
)";
auto const generateSpecializations = [this]( std::vector<RequireData> const & requireData, std::string const & title )
{
auto specializations = std::string{};
for ( auto const & require : requireData )
{
for ( auto const & type : require.types )
{
if ( auto const & handleIt = m_handles.find( type.name ); handleIt != m_handles.end() )
{
specializations += " template <> struct hash<VULKAN_HPP_NAMESPACE::" + stripPrefix( handleIt->first, "Vk" ) + ">;\n";
}
}
}
return addTitleAndProtection( title, specializations );
};
std::string specializations;
for ( auto const & feature : m_features )
{
specializations += generateSpecializations( feature.requireData, feature.name );
}
for ( auto const & extension : m_extensions )
{
specializations += generateSpecializations( extension.requireData, extension.name );
}
return replaceWithMap( hashesTemplate, { { "specializations", specializations } } );
}
std::string VulkanHppGenerator::generateCppModuleHashSpecializations() const
{
std::string const hasSpecializationsTemplate = R"(
//=======================================
//=== HASH specialization for Flags types ===
//=======================================
template <typename BitType>
struct hash<VULKAN_HPP_NAMESPACE::Flags<BitType>>;
${handleHashSpecializations}
${structHashSpecializations}
)";
return replaceWithMap( hasSpecializationsTemplate,
{ { "handleHashSpecializations", generateCppModuleHandleHashSpecializations() },
{ "structHashSpecializations", generateCppModuleStructHashSpecializations() } } );
}
std::string VulkanHppGenerator::generateCppModuleStructHashSpecializations() const
{
const std::string hashesTemplate = R"(
//========================================
//=== HASH specializations for structs ===
//========================================
${specializations}
)";
auto const generateSpecializations = [this]( std::vector<RequireData> const & requireData, std::string const & title )
{
auto specializations = std::string{};
for ( auto const & require : requireData )
{
for ( auto const & type : require.types )
{
if ( auto const & structIt = m_structs.find( type.name ); structIt != m_structs.end() )
{
specializations += " template <> struct hash<VULKAN_HPP_NAMESPACE::" + stripPrefix( structIt->first, "Vk" ) + ">;\n";
}
}
}
return addTitleAndProtection( title, specializations );
};
std::string specializations;
for ( auto const & feature : m_features )
{
specializations += generateSpecializations( feature.requireData, feature.name );
}
for ( auto const & extension : m_extensions )
{
specializations += generateSpecializations( extension.requireData, extension.name );
}
return replaceWithMap( hashesTemplate, { { "specializations", specializations } } );
}
std::string VulkanHppGenerator::generateDataDeclarations( CommandData const & commandData,
std::vector<size_t> const & returnParams,
std::map<size_t, VectorParamData> const & vectorParams,

View File

@ -753,6 +753,9 @@ private:
std::string generateCppModuleUsings() const;
std::string generateCppModuleRaiiUsings() const;
std::string generateCppModuleSharedHandleUsings() const;
std::string generateCppModuleHandleHashSpecializations() const;
std::string generateCppModuleHashSpecializations() const;
std::string generateCppModuleStructHashSpecializations() const;
std::string generateDataDeclarations( CommandData const & commandData,
std::vector<size_t> const & returnParams,
std::map<size_t, VectorParamData> const & vectorParams,

View File

@ -1,6 +1,22 @@
// Copyright(c) 2024, 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 Test : Cpp20Module
// Compile test on using c++20 modules
import vulkan_hpp;
#include <iostream>
#include <vulkan/vulkan_hpp_macros.hpp>
static std::string AppName = "Cpp20Modules";
@ -12,6 +28,8 @@ VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
int main( int /*argc*/, char ** /*argv*/ )
{
std::cout << "test Cpp20Module" << std::endl;
/* VULKAN_HPP_KEY_START */
try
{

View File

@ -1,59 +1,101 @@
// Copyright(c) 2024, 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 Test : CppStdModule
// Compile test on using c++20 modules
import std;
import vulkan_hpp;
#if defined( _MSC_VER )
# pragma warning( disable : 4189 ) // local variable is initialized but not referenced
#elif defined( __GNUC__ )
# pragma GCC diagnostic ignored "-Wunused-variable"
#else
// unknow compiler... just ignore the warnings for yourselves ;)
#endif
#include <assert.h>
#include <vulkan/vulkan_hpp_macros.hpp>
static std::string AppName = "CppStdModule";
static std::string AppName = "CppStdModule";
static std::string EngineName = "Vulkan.cppm";
#if VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE
#endif
int main(int /*argc*/, char** /*argv*/)
int main( int /*argc*/, char ** /*argv*/ )
{
/* VULKAN_HPP_KEY_START */
try
{
std::cout << "test CppStdModule" << std::endl;
/* VULKAN_HPP_KEY_START */
try
{
#if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
// initialize minimal set of function pointers
VULKAN_HPP_DEFAULT_DISPATCHER.init();
// initialize minimal set of function pointers
VULKAN_HPP_DEFAULT_DISPATCHER.init();
#endif
// initialize the vk::ApplicationInfo structure
vk::ApplicationInfo applicationInfo(AppName.c_str(), 1, EngineName.c_str(), 1, vk::makeApiVersion(1, 0, 0, 0));
// initialize the vk::ApplicationInfo structure
vk::ApplicationInfo applicationInfo( AppName.c_str(), 1, EngineName.c_str(), 1, vk::makeApiVersion( 1, 0, 0, 0 ) );
// initialize the vk::InstanceCreateInfo
vk::InstanceCreateInfo instanceCreateInfo({}, &applicationInfo);
// initialize the vk::InstanceCreateInfo
vk::InstanceCreateInfo instanceCreateInfo( {}, &applicationInfo );
// create an Instance
vk::Instance instance = vk::createInstance(instanceCreateInfo);
// create an Instance
vk::Instance instance = vk::createInstance( instanceCreateInfo );
#if ( VULKAN_HPP_DISPATCH_LOADER_DYNAMIC == 1 )
// initialize function pointers for instance
VULKAN_HPP_DEFAULT_DISPATCHER.init(instance);
// initialize function pointers for instance
VULKAN_HPP_DEFAULT_DISPATCHER.init( instance );
#endif
// destroy it again
instance.destroy();
}
catch (vk::SystemError& err)
{
std::cout << "vk::SystemError: " << err.what() << std::endl;
exit(-1);
}
catch (std::exception& err)
{
std::cout << "std::exception: " << err.what() << std::endl;
exit(-1);
}
catch (...)
{
std::cout << "unknown error\n";
exit(-1);
}
// some minimal check for std::hash on a vk-type
auto h1 = std::hash<vk::Instance>{}( instance );
auto h2 = std::hash<VkInstance>{}( static_cast<VkInstance>( instance ) );
assert( h1 == h2 );
/* VULKAN_HPP_KEY_END */
std::unordered_set<vk::Instance> uset;
uset.insert( instance );
return 0;
std::unordered_map<vk::Instance, size_t> umap;
umap[instance] = 1;
vk::FormatFeatureFlags fff;
auto hf = std::hash<vk::FormatFeatureFlags>{}( fff );
// destroy it again
instance.destroy();
}
catch ( vk::SystemError & err )
{
std::cout << "vk::SystemError: " << err.what() << std::endl;
exit( -1 );
}
catch ( std::exception & err )
{
std::cout << "std::exception: " << err.what() << std::endl;
exit( -1 );
}
catch ( ... )
{
std::cout << "unknown error\n";
exit( -1 );
}
/* VULKAN_HPP_KEY_END */
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -24,7 +24,7 @@ namespace VULKAN_HPP_NAMESPACE
//=== Extension inspection functions ===
//======================================
VULKAN_HPP_CONSTEXPR_20 std::set<std::string> const & getDeviceExtensions();
std::set<std::string> const & getDeviceExtensions();
std::set<std::string> const & getInstanceExtensions();
std::map<std::string, std::string> const & getDeprecatedExtensions();
std::map<std::string, std::vector<std::vector<std::string>>> const & getExtensionDepends( std::string const & extension );
@ -44,9 +44,9 @@ namespace VULKAN_HPP_NAMESPACE
//=== Extension inspection function implementations ===
//=====================================================
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20std::map<std::string, std::string> const & getDeprecatedExtensions()
VULKAN_HPP_INLINE std::map<std::string, std::string> const & getDeprecatedExtensions()
{
static std::map<std::string, std::string> deprecatedExtensions = {
static const std::map<std::string, std::string> deprecatedExtensions = {
{ "VK_EXT_validation_features", "VK_EXT_layer_settings" },
#if defined( VK_USE_PLATFORM_SCI )
{ "VK_NV_external_sci_sync", "VK_NV_external_sci_sync2" }
@ -55,7 +55,7 @@ namespace VULKAN_HPP_NAMESPACE
return deprecatedExtensions;
}
VULKAN_HPP_INLINE VULKAN_HPP_CONSTEXPR_20 std::set<std::string> const & getDeviceExtensions()
VULKAN_HPP_INLINE std::set<std::string> const & getDeviceExtensions()
{
static const std::set<std::string> deviceExtensions = {
"VK_KHR_swapchain",
@ -135,25 +135,25 @@ namespace VULKAN_HPP_NAMESPACE
VULKAN_HPP_INLINE std::set<std::string> const & getInstanceExtensions()
{
static std::set<std::string> instanceExtensions = { "VK_KHR_surface",
"VK_KHR_display",
"VK_EXT_direct_mode_display",
"VK_EXT_display_surface_counter",
"VK_EXT_swapchain_colorspace",
"VK_KHR_get_surface_capabilities2",
"VK_KHR_get_display_properties2",
"VK_EXT_debug_utils",
"VK_EXT_validation_features",
"VK_EXT_headless_surface",
"VK_EXT_application_parameters",
"VK_EXT_layer_settings" };
static const std::set<std::string> instanceExtensions = { "VK_KHR_surface",
"VK_KHR_display",
"VK_EXT_direct_mode_display",
"VK_EXT_display_surface_counter",
"VK_EXT_swapchain_colorspace",
"VK_KHR_get_surface_capabilities2",
"VK_KHR_get_display_properties2",
"VK_EXT_debug_utils",
"VK_EXT_validation_features",
"VK_EXT_headless_surface",
"VK_EXT_application_parameters",
"VK_EXT_layer_settings" };
return instanceExtensions;
}
VULKAN_HPP_INLINE std::map<std::string, std::vector<std::vector<std::string>>> const & getExtensionDepends( std::string const & extension )
{
static std::map<std::string, std::vector<std::vector<std::string>>> noDependencies;
static std::map<std::string, std::map<std::string, std::vector<std::vector<std::string>>>> dependencies = {
static const std::map<std::string, std::vector<std::vector<std::string>>> noDependencies;
static const std::map<std::string, std::map<std::string, std::vector<std::vector<std::string>>>> dependencies = {
{ "VK_KHR_swapchain",
{ { "VK_VERSION_1_0",
{ {
@ -552,26 +552,26 @@ namespace VULKAN_HPP_NAMESPACE
VULKAN_HPP_INLINE std::map<std::string, std::string> const & getObsoletedExtensions()
{
static std::map<std::string, std::string> obsoletedExtensions = {};
static const std::map<std::string, std::string> obsoletedExtensions = {};
return obsoletedExtensions;
}
VULKAN_HPP_INLINE std::map<std::string, std::string> const & getPromotedExtensions()
{
static std::map<std::string, std::string> promotedExtensions = { { "VK_EXT_texture_compression_astc_hdr", "VK_VERSION_1_3" },
{ "VK_KHR_shader_terminate_invocation", "VK_VERSION_1_3" },
{ "VK_EXT_subgroup_size_control", "VK_VERSION_1_3" },
{ "VK_EXT_line_rasterization", "VK_KHR_line_rasterization" },
{ "VK_EXT_index_type_uint8", "VK_KHR_index_type_uint8" },
{ "VK_EXT_extended_dynamic_state", "VK_VERSION_1_3" },
{ "VK_EXT_shader_demote_to_helper_invocation", "VK_VERSION_1_3" },
{ "VK_EXT_texel_buffer_alignment", "VK_VERSION_1_3" },
{ "VK_KHR_synchronization2", "VK_VERSION_1_3" },
{ "VK_EXT_ycbcr_2plane_444_formats", "VK_VERSION_1_3" },
{ "VK_EXT_image_robustness", "VK_VERSION_1_3" },
{ "VK_KHR_copy_commands2", "VK_VERSION_1_3" },
{ "VK_EXT_4444_formats", "VK_VERSION_1_3" },
{ "VK_EXT_extended_dynamic_state2", "VK_VERSION_1_3" } };
static const std::map<std::string, std::string> promotedExtensions = { { "VK_EXT_texture_compression_astc_hdr", "VK_VERSION_1_3" },
{ "VK_KHR_shader_terminate_invocation", "VK_VERSION_1_3" },
{ "VK_EXT_subgroup_size_control", "VK_VERSION_1_3" },
{ "VK_EXT_line_rasterization", "VK_KHR_line_rasterization" },
{ "VK_EXT_index_type_uint8", "VK_KHR_index_type_uint8" },
{ "VK_EXT_extended_dynamic_state", "VK_VERSION_1_3" },
{ "VK_EXT_shader_demote_to_helper_invocation", "VK_VERSION_1_3" },
{ "VK_EXT_texel_buffer_alignment", "VK_VERSION_1_3" },
{ "VK_KHR_synchronization2", "VK_VERSION_1_3" },
{ "VK_EXT_ycbcr_2plane_444_formats", "VK_VERSION_1_3" },
{ "VK_EXT_image_robustness", "VK_VERSION_1_3" },
{ "VK_KHR_copy_commands2", "VK_VERSION_1_3" },
{ "VK_EXT_4444_formats", "VK_VERSION_1_3" },
{ "VK_EXT_extended_dynamic_state2", "VK_VERSION_1_3" } };
return promotedExtensions;
}