mirror of
https://github.com/KhronosGroup/Vulkan-Hpp.git
synced 2024-10-14 16:32:17 +00:00
Make type conversions implicit for dispatchable handles
Vulkan handles are not typesafe on 32-bit platforms, but only for non-dispachable handles. Dispatchable handles are opaque struct pointers on all platforms, and thus typesafe. This commit makes all conversions for dispatchable handles implicit, regardless of VULKAN_HPP_TYPESAFE_CONVERSION setting.
This commit is contained in:
parent
25256d1d59
commit
9e95c0072d
@ -74,7 +74,7 @@ There is an additional header named vulkan_raii.hpp generated. That header holds
|
||||
|
||||
### C/C++ Interop for Handles
|
||||
|
||||
On 64-bit platforms Vulkan-Hpp supports implicit conversions between C++ Vulkan handles and C Vulkan handles. On 32-bit platforms all non-dispatchable handles are defined as `uint64_t`, thus preventing type-conversion checks at compile time which would catch assignments between incompatible handle types.. Due to that Vulkan-Hpp does not enable implicit conversion for 32-bit platforms by default and it is recommended to use a `static_cast` for the conversion like this: `VkDevice = static_cast<VkDevice>(cppDevice)` to prevent converting some arbitrary int to a handle or vice versa by accident. If you're developing your code on a 64-bit platform, but want compile your code for a 32-bit platform without adding the explicit casts you can define `VULKAN_HPP_TYPESAFE_CONVERSION` to 1 in your build system or before including `vulkan.hpp`. On 64-bit platforms this define is set to 1 by default and can be set to 0 to disable implicit conversions.
|
||||
On 64-bit platforms Vulkan-Hpp supports implicit conversions between C++ Vulkan handles and C Vulkan handles. On 32-bit platforms all non-dispatchable handles are defined as `uint64_t`, thus preventing type-conversion checks at compile time which would catch assignments between incompatible handle types. Due to that Vulkan-Hpp does not enable implicit conversion for 32-bit platforms by default and it is recommended to use a `static_cast` for the conversion like this: `VkImage = static_cast<VkImage>(cppImage)` to prevent converting some arbitrary int to a handle or vice versa by accident. If you're developing your code on a 64-bit platform, but want compile your code for a 32-bit platform without adding the explicit casts you can define `VULKAN_HPP_TYPESAFE_CONVERSION` to 1 in your build system or before including `vulkan.hpp`. On 64-bit platforms this define is set to 1 by default and can be set to 0 to disable implicit conversions.
|
||||
|
||||
### Flags
|
||||
|
||||
@ -641,7 +641,7 @@ With this define you can specify whether the ```DispatchLoaderDynamic``` is impo
|
||||
|
||||
#### VULKAN_HPP_TYPESAFE_CONVERSION
|
||||
|
||||
32-bit vulkan is not typesafe for handles, so we don't allow copy constructors on this platform by default. To enable this feature on 32-bit platforms define ```VULKAN_HPP_TYPESAFE_CONVERSION```.
|
||||
32-bit vulkan is not typesafe for non-dispatchable handles, so we don't allow copy constructors on this platform by default. To enable this feature on 32-bit platforms define ```VULKAN_HPP_TYPESAFE_CONVERSION```.
|
||||
|
||||
#### VULKAN_HPP_USE_REFLECT
|
||||
|
||||
|
@ -89,7 +89,7 @@ const std::set<std::string> specialPointerTypes = { "Display", "IDirectFB", "wl_
|
||||
VulkanHppGenerator::VulkanHppGenerator( tinyxml2::XMLDocument const & document )
|
||||
{
|
||||
// insert the default "handle" without class (for createInstance, and such)
|
||||
m_handles.insert( std::make_pair( "", HandleData( {}, "", 0 ) ) );
|
||||
m_handles.insert( std::make_pair( "", HandleData( {}, "", false, 0 ) ) );
|
||||
|
||||
// read the document and check its correctness
|
||||
int line = document.GetLineNum();
|
||||
@ -5503,6 +5503,10 @@ std::string VulkanHppGenerator::generateHandle( std::pair<std::string, HandleDat
|
||||
usingAlias += " using " + stripPrefix( handleData.second.alias, "Vk" ) + " = " + stripPrefix( handleData.first, "Vk" ) + ";\n";
|
||||
}
|
||||
|
||||
const std::string typesafeExplicitKeyword = handleData.second.isDispatchable ? "" : "VULKAN_HPP_TYPESAFE_EXPLICIT ";
|
||||
const std::string typesafeConversionConditional = handleData.second.isDispatchable ? "" : "#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)\n";
|
||||
const std::string typesafeConversionConditionalEnd = handleData.second.isDispatchable ? "" : "#endif\n";
|
||||
|
||||
static const std::string templateString = R"(
|
||||
${enter} class ${className}
|
||||
{
|
||||
@ -5517,18 +5521,16 @@ ${enter} class ${className}
|
||||
VULKAN_HPP_CONSTEXPR ${className}() = default;
|
||||
VULKAN_HPP_CONSTEXPR ${className}( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
|
||||
{}
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT ${className}( Vk${className} ${memberName} ) VULKAN_HPP_NOEXCEPT
|
||||
${typesafeExplicitKeyword}${className}( Vk${className} ${memberName} ) VULKAN_HPP_NOEXCEPT
|
||||
: m_${memberName}( ${memberName} )
|
||||
{}
|
||||
|
||||
#if defined(VULKAN_HPP_TYPESAFE_CONVERSION)
|
||||
${className} & operator=(Vk${className} ${memberName}) VULKAN_HPP_NOEXCEPT
|
||||
${typesafeConversionConditional} ${className} & operator=(Vk${className} ${memberName}) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
m_${memberName} = ${memberName};
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
${typesafeConversionConditionalEnd}
|
||||
${className} & operator=( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
m_${memberName} = {};
|
||||
@ -5554,7 +5556,7 @@ ${enter} class ${className}
|
||||
}
|
||||
#endif
|
||||
${commands}
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT operator Vk${className}() const VULKAN_HPP_NOEXCEPT
|
||||
${typesafeExplicitKeyword}operator Vk${className}() const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return m_${memberName};
|
||||
}
|
||||
@ -5599,7 +5601,10 @@ ${usingAlias}${leave})";
|
||||
{ "leave", leave },
|
||||
{ "memberName", startLowerCase( stripPrefix( handleData.first, "Vk" ) ) },
|
||||
{ "objTypeEnum", generateEnumValueName( enumIt->first, valueIt->name, false, m_tags ) },
|
||||
{ "usingAlias", usingAlias } } );
|
||||
{ "usingAlias", usingAlias },
|
||||
{ "typesafeExplicitKeyword", typesafeExplicitKeyword },
|
||||
{ "typesafeConversionConditional", typesafeConversionConditional },
|
||||
{ "typesafeConversionConditionalEnd", typesafeConversionConditionalEnd } } );
|
||||
}
|
||||
|
||||
listedHandles.insert( handleData.first );
|
||||
@ -13703,6 +13708,7 @@ void VulkanHppGenerator::readTypesTypeHandle( tinyxml2::XMLElement const * eleme
|
||||
NameData nameData;
|
||||
TypeInfo typeInfo;
|
||||
std::tie( nameData, typeInfo ) = readNameAndType( element );
|
||||
const bool isDispatchable = typeInfo.type == "VK_DEFINE_HANDLE";
|
||||
|
||||
check( beginsWith( nameData.name, "Vk" ), line, "name <" + nameData.name + "> does not begin with <Vk>" );
|
||||
check( nameData.arraySizes.empty(), line, "name <" + nameData.name + "> with unsupported arraySizes" );
|
||||
@ -13714,7 +13720,7 @@ void VulkanHppGenerator::readTypesTypeHandle( tinyxml2::XMLElement const * eleme
|
||||
check( !objTypeEnum.empty(), line, "handle <" + nameData.name + "> does not specify attribute \"objtypeenum\"" );
|
||||
|
||||
check( parent.find( ',' ) == std::string::npos, line, "mulitple parents specified for handle <" + nameData.name + ">" );
|
||||
check( m_handles.insert( std::make_pair( nameData.name, HandleData( parent, objTypeEnum, line ) ) ).second,
|
||||
check( m_handles.insert( std::make_pair( nameData.name, HandleData( parent, objTypeEnum, isDispatchable, line ) ) ).second,
|
||||
line,
|
||||
"handle <" + nameData.name + "> already specified" );
|
||||
check( m_types.insert( std::make_pair( nameData.name, TypeCategory::Handle ) ).second, line, "handle <" + nameData.name + "> already specified as a type" );
|
||||
@ -16900,7 +16906,7 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
" , \"Wrong VK_HEADER_VERSION!\" );\n"
|
||||
"\n";
|
||||
str +=
|
||||
"// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.\n"
|
||||
"// 32-bit vulkan is not typesafe for non-dispatchable handles, so don't allow copy constructors on this platform by default.\n"
|
||||
"// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION\n" +
|
||||
generator.getTypesafeCheck() +
|
||||
"\n"
|
||||
|
@ -272,7 +272,10 @@ private:
|
||||
|
||||
struct HandleData
|
||||
{
|
||||
HandleData( std::string const & p, std::string const & objType, int line ) : objTypeEnum( objType ), parent( p ), xmlLine( line ) {}
|
||||
HandleData( std::string const & p, std::string const & objType, bool isDispatchable, int line )
|
||||
: objTypeEnum( objType ), parent( p ), isDispatchable( isDispatchable ), xmlLine( line )
|
||||
{
|
||||
}
|
||||
|
||||
std::string alias;
|
||||
std::set<std::string> childrenHandles;
|
||||
@ -282,6 +285,7 @@ private:
|
||||
std::string objTypeEnum;
|
||||
std::string parent;
|
||||
std::set<std::string> secondLevelCommands;
|
||||
bool isDispatchable;
|
||||
int xmlLine;
|
||||
|
||||
// RAII data
|
||||
|
@ -121,7 +121,7 @@ extern "C" __declspec( dllimport ) FARPROC __stdcall GetProcAddress( HINSTANCE h
|
||||
|
||||
static_assert( VK_HEADER_VERSION == 211, "Wrong VK_HEADER_VERSION!" );
|
||||
|
||||
// 32-bit vulkan is not typesafe for handles, so don't allow copy constructors on this platform by default.
|
||||
// 32-bit vulkan is not typesafe for non-dispatchable handles, so don't allow copy constructors on this platform by default.
|
||||
// To enable this feature on 32-bit platforms please define VULKAN_HPP_TYPESAFE_CONVERSION
|
||||
#if ( VK_USE_64_BIT_PTR_DEFINES == 1 )
|
||||
# if !defined( VULKAN_HPP_TYPESAFE_CONVERSION )
|
||||
|
@ -3053,15 +3053,13 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
public:
|
||||
VULKAN_HPP_CONSTEXPR CommandBuffer() = default;
|
||||
VULKAN_HPP_CONSTEXPR CommandBuffer( std::nullptr_t ) VULKAN_HPP_NOEXCEPT {}
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT CommandBuffer( VkCommandBuffer commandBuffer ) VULKAN_HPP_NOEXCEPT : m_commandBuffer( commandBuffer ) {}
|
||||
CommandBuffer( VkCommandBuffer commandBuffer ) VULKAN_HPP_NOEXCEPT : m_commandBuffer( commandBuffer ) {}
|
||||
|
||||
#if defined( VULKAN_HPP_TYPESAFE_CONVERSION )
|
||||
CommandBuffer & operator=( VkCommandBuffer commandBuffer ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
m_commandBuffer = commandBuffer;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
CommandBuffer & operator=( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
@ -4822,7 +4820,7 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const VULKAN_HPP_NOEXCEPT;
|
||||
#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
|
||||
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT operator VkCommandBuffer() const VULKAN_HPP_NOEXCEPT
|
||||
operator VkCommandBuffer() const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return m_commandBuffer;
|
||||
}
|
||||
@ -6630,15 +6628,13 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
public:
|
||||
VULKAN_HPP_CONSTEXPR Queue() = default;
|
||||
VULKAN_HPP_CONSTEXPR Queue( std::nullptr_t ) VULKAN_HPP_NOEXCEPT {}
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT Queue( VkQueue queue ) VULKAN_HPP_NOEXCEPT : m_queue( queue ) {}
|
||||
Queue( VkQueue queue ) VULKAN_HPP_NOEXCEPT : m_queue( queue ) {}
|
||||
|
||||
#if defined( VULKAN_HPP_TYPESAFE_CONVERSION )
|
||||
Queue & operator=( VkQueue queue ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
m_queue = queue;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
Queue & operator=( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
@ -6812,7 +6808,7 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
getCheckpointData2NV( CheckpointData2NVAllocator & checkpointData2NVAllocator, Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const;
|
||||
#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
|
||||
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT operator VkQueue() const VULKAN_HPP_NOEXCEPT
|
||||
operator VkQueue() const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return m_queue;
|
||||
}
|
||||
@ -7122,15 +7118,13 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
public:
|
||||
VULKAN_HPP_CONSTEXPR Device() = default;
|
||||
VULKAN_HPP_CONSTEXPR Device( std::nullptr_t ) VULKAN_HPP_NOEXCEPT {}
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT Device( VkDevice device ) VULKAN_HPP_NOEXCEPT : m_device( device ) {}
|
||||
Device( VkDevice device ) VULKAN_HPP_NOEXCEPT : m_device( device ) {}
|
||||
|
||||
#if defined( VULKAN_HPP_TYPESAFE_CONVERSION )
|
||||
Device & operator=( VkDevice device ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
m_device = device;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
Device & operator=( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
@ -11224,7 +11218,7 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
Dispatch const & d VULKAN_HPP_DEFAULT_DISPATCHER_ASSIGNMENT ) const VULKAN_HPP_NOEXCEPT;
|
||||
#endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
|
||||
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT operator VkDevice() const VULKAN_HPP_NOEXCEPT
|
||||
operator VkDevice() const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
@ -11374,15 +11368,13 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
public:
|
||||
VULKAN_HPP_CONSTEXPR PhysicalDevice() = default;
|
||||
VULKAN_HPP_CONSTEXPR PhysicalDevice( std::nullptr_t ) VULKAN_HPP_NOEXCEPT {}
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT PhysicalDevice( VkPhysicalDevice physicalDevice ) VULKAN_HPP_NOEXCEPT : m_physicalDevice( physicalDevice ) {}
|
||||
PhysicalDevice( VkPhysicalDevice physicalDevice ) VULKAN_HPP_NOEXCEPT : m_physicalDevice( physicalDevice ) {}
|
||||
|
||||
#if defined( VULKAN_HPP_TYPESAFE_CONVERSION )
|
||||
PhysicalDevice & operator=( VkPhysicalDevice physicalDevice ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
m_physicalDevice = physicalDevice;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
PhysicalDevice & operator=( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
@ -12619,7 +12611,7 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
# endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
|
||||
#endif /*VK_USE_PLATFORM_SCREEN_QNX*/
|
||||
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT operator VkPhysicalDevice() const VULKAN_HPP_NOEXCEPT
|
||||
operator VkPhysicalDevice() const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return m_physicalDevice;
|
||||
}
|
||||
@ -12697,15 +12689,13 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
public:
|
||||
VULKAN_HPP_CONSTEXPR Instance() = default;
|
||||
VULKAN_HPP_CONSTEXPR Instance( std::nullptr_t ) VULKAN_HPP_NOEXCEPT {}
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT Instance( VkInstance instance ) VULKAN_HPP_NOEXCEPT : m_instance( instance ) {}
|
||||
Instance( VkInstance instance ) VULKAN_HPP_NOEXCEPT : m_instance( instance ) {}
|
||||
|
||||
#if defined( VULKAN_HPP_TYPESAFE_CONVERSION )
|
||||
Instance & operator=( VkInstance instance ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
m_instance = instance;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
Instance & operator=( std::nullptr_t ) VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
@ -13308,7 +13298,7 @@ namespace VULKAN_HPP_NAMESPACE
|
||||
# endif /*VULKAN_HPP_DISABLE_ENHANCED_MODE*/
|
||||
#endif /*VK_USE_PLATFORM_SCREEN_QNX*/
|
||||
|
||||
VULKAN_HPP_TYPESAFE_EXPLICIT operator VkInstance() const VULKAN_HPP_NOEXCEPT
|
||||
operator VkInstance() const VULKAN_HPP_NOEXCEPT
|
||||
{
|
||||
return m_instance;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user