diff --git a/VulkanHppGenerator.cpp b/VulkanHppGenerator.cpp index c47a887..cb5e12e 100644 --- a/VulkanHppGenerator.cpp +++ b/VulkanHppGenerator.cpp @@ -62,6 +62,57 @@ const std::string exceptionHeader( "\n" ); +std::string const exceptionClassesHeader = ( + "#if defined(_MSC_VER) && (_MSC_VER == 1800)\n" + "# define noexcept _NOEXCEPT\n" + "#endif\n" + "\n" + " class Error\n" + " {\n" + " public:\n" + " virtual ~Error() = default;\n" + "\n" + " virtual const char* what() const noexcept = 0;\n" + " };\n" + "\n" + " class LogicError : public Error, public std::logic_error\n" + " {\n" + " public:\n" + " explicit LogicError( const std::string& what )\n" + " : Error(), std::logic_error(what) {}\n" + " explicit LogicError( char const * what )\n" + " : Error(), std::logic_error(what) {}\n" + " virtual ~LogicError() = default;\n" + "\n" + " virtual const char* what() const noexcept { return std::logic_error::what(); }\n" + " };\n" + "\n" + " class SystemError : public Error, public std::system_error\n" + " {\n" + " public:\n" + " SystemError( std::error_code ec )\n" + " : Error(), std::system_error(ec) {}\n" + " SystemError( std::error_code ec, std::string const& what )\n" + " : Error(), std::system_error(ec, what) {}\n" + " SystemError( std::error_code ec, char const * what )\n" + " : Error(), std::system_error(ec, what) {}\n" + " SystemError( int ev, std::error_category const& ecat )\n" + " : Error(), std::system_error(ev, ecat) {}\n" + " SystemError( int ev, std::error_category const& ecat, std::string const& what)\n" + " : Error(), std::system_error(ev, ecat, what) {}\n" + " SystemError( int ev, std::error_category const& ecat, char const * what)\n" + " : Error(), std::system_error(ev, ecat, what) {}\n" + " virtual ~SystemError() = default;\n" + "\n" + " virtual const char* what() const noexcept { return std::system_error::what(); }\n" + " };\n" + "\n" + "#if defined(_MSC_VER) && (_MSC_VER == 1800)\n" + "# undef noexcept\n" + "#endif\n" + "\n" + ); + const std::string flagsHeader( " template struct FlagTraits\n" " {\n" @@ -396,7 +447,7 @@ std::string const createResultValueHeader = ( "#else\n" " if ( result != Result::eSuccess )\n" " {\n" - " throw std::system_error( result, message );\n" + " throwResultException( result, message );\n" " }\n" "#endif\n" " }\n" @@ -410,7 +461,7 @@ std::string const createResultValueHeader = ( "#else\n" " if ( result != Result::eSuccess )\n" " {\n" - " throw std::system_error( result, message );\n" + " throwResultException( result, message );\n" " }\n" " return data;\n" "#endif\n" @@ -423,7 +474,7 @@ std::string const createResultValueHeader = ( "#else\n" " if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() )\n" " {\n" - " throw std::system_error( result, message );\n" + " throwResultException( result, message );\n" " }\n" "#endif\n" " return result;\n" @@ -437,7 +488,7 @@ std::string const createResultValueHeader = ( "#else\n" " if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() )\n" " {\n" - " throw std::system_error( result, message );\n" + " throwResultException( result, message );\n" " }\n" "#endif\n" " return ResultValue( result, data );\n" @@ -789,6 +840,10 @@ void writeStructSetter( std::ofstream & ofs, std::string const& structureName, M void writeTypeCommand(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData); void writeTypeCommand(std::ofstream &ofs, std::string const& indentation, VkData const& vkData, CommandData const& commandData, bool definition); void writeTypeEnum(std::ofstream & ofs, EnumData const& enumData); +bool isErrorEnum(std::string const& enumName); +std::string stripErrorEnumPrefix(std::string const& enumName); +void writeExceptionsForEnum(std::ofstream & ofs, EnumData const& enumData); +void writeThrowExceptions(std::ofstream& ofs, EnumData const& enumData); void writeTypeFlags(std::ofstream & ofs, std::string const& flagsName, FlagData const& flagData, EnumData const& enumData); void writeTypeHandle(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, HandleData const& handle, std::list const& dependencies); void writeTypeScalar( std::ofstream & ofs, DependencyData const& dependencyData ); @@ -2052,7 +2107,7 @@ void writeCall(std::ostream & os, CommandData const& commandData, std::set with the pure return type + // if there is a return parameter at all, and there are multiple success codes, we return a ResultValue<...> with the pure return type assert(commandData.returnType == "Result"); os << "ResultValue<" << commandData.params[commandData.returnParam].pureType << "> "; } @@ -3206,6 +3261,67 @@ void writeTypeEnum( std::ofstream & ofs, EnumData const& enumData ) ofs << std::endl; } +bool isErrorEnum(std::string const& enumName) +{ + return (enumName.substr(0, 6) == "eError"); +} + +std::string stripErrorEnumPrefix(std::string const& enumName) +{ + assert(isErrorEnum(enumName)); + return strip(enumName, "eError"); +} + +// Intended only for `enum class Result`! +void writeExceptionsForEnum( std::ofstream & ofs, EnumData const& enumData) +{ + enterProtect(ofs, enumData.protect); + for ( size_t i=0 ; i(result) < 0 );" << std::endl + << " switch ( result )" << std::endl + << " {" << std::endl; + for ( size_t i=0 ; i> const& deleterTypes, std::map const& deleterData) { // A Deleter class for each of the Unique* classes... but only if smart handles are not switched off @@ -3981,8 +4097,11 @@ int main( int argc, char **argv ) assert(it != vkData.dependencies.end()); writeTypeEnum(ofs, vkData.enums.find(it->name)->second); writeEnumsToString(ofs, vkData.enums.find(it->name)->second); - vkData.dependencies.erase(it); ofs << exceptionHeader; + ofs << exceptionClassesHeader; + writeExceptionsForEnum(ofs, vkData.enums.find(it->name)->second); + writeThrowExceptions(ofs, vkData.enums.find(it->name)->second); + vkData.dependencies.erase(it); ofs << "} // namespace vk" << std::endl << std::endl diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 512a374..ed34366 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -531,6 +531,264 @@ namespace vk return std::error_condition(static_cast(e), errorCategory()); } +#if defined(_MSC_VER) && (_MSC_VER == 1800) +# define noexcept _NOEXCEPT +#endif + + class Error + { + public: + virtual ~Error() = default; + + virtual const char* what() const noexcept = 0; + }; + + class LogicError : public Error, public std::logic_error + { + public: + explicit LogicError( const std::string& what ) + : Error(), std::logic_error(what) {} + explicit LogicError( char const * what ) + : Error(), std::logic_error(what) {} + virtual ~LogicError() = default; + + virtual const char* what() const noexcept { return std::logic_error::what(); } + }; + + class SystemError : public Error, public std::system_error + { + public: + SystemError( std::error_code ec ) + : Error(), std::system_error(ec) {} + SystemError( std::error_code ec, std::string const& what ) + : Error(), std::system_error(ec, what) {} + SystemError( std::error_code ec, char const * what ) + : Error(), std::system_error(ec, what) {} + SystemError( int ev, std::error_category const& ecat ) + : Error(), std::system_error(ev, ecat) {} + SystemError( int ev, std::error_category const& ecat, std::string const& what) + : Error(), std::system_error(ev, ecat, what) {} + SystemError( int ev, std::error_category const& ecat, char const * what) + : Error(), std::system_error(ev, ecat, what) {} + virtual ~SystemError() = default; + + virtual const char* what() const noexcept { return std::system_error::what(); } + }; + +#if defined(_MSC_VER) && (_MSC_VER == 1800) +# undef noexcept +#endif + + class OutOfHostMemoryError : public SystemError + { + public: + OutOfHostMemoryError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorOutOfHostMemory), message) {} + OutOfHostMemoryError( char const * message ) + : SystemError(make_error_code(Result::eErrorOutOfHostMemory), message) {} + }; + + class OutOfDeviceMemoryError : public SystemError + { + public: + OutOfDeviceMemoryError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorOutOfDeviceMemory), message) {} + OutOfDeviceMemoryError( char const * message ) + : SystemError(make_error_code(Result::eErrorOutOfDeviceMemory), message) {} + }; + + class InitializationFailedError : public SystemError + { + public: + InitializationFailedError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorInitializationFailed), message) {} + InitializationFailedError( char const * message ) + : SystemError(make_error_code(Result::eErrorInitializationFailed), message) {} + }; + + class DeviceLostError : public SystemError + { + public: + DeviceLostError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorDeviceLost), message) {} + DeviceLostError( char const * message ) + : SystemError(make_error_code(Result::eErrorDeviceLost), message) {} + }; + + class MemoryMapFailedError : public SystemError + { + public: + MemoryMapFailedError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorMemoryMapFailed), message) {} + MemoryMapFailedError( char const * message ) + : SystemError(make_error_code(Result::eErrorMemoryMapFailed), message) {} + }; + + class LayerNotPresentError : public SystemError + { + public: + LayerNotPresentError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorLayerNotPresent), message) {} + LayerNotPresentError( char const * message ) + : SystemError(make_error_code(Result::eErrorLayerNotPresent), message) {} + }; + + class ExtensionNotPresentError : public SystemError + { + public: + ExtensionNotPresentError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorExtensionNotPresent), message) {} + ExtensionNotPresentError( char const * message ) + : SystemError(make_error_code(Result::eErrorExtensionNotPresent), message) {} + }; + + class FeatureNotPresentError : public SystemError + { + public: + FeatureNotPresentError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorFeatureNotPresent), message) {} + FeatureNotPresentError( char const * message ) + : SystemError(make_error_code(Result::eErrorFeatureNotPresent), message) {} + }; + + class IncompatibleDriverError : public SystemError + { + public: + IncompatibleDriverError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorIncompatibleDriver), message) {} + IncompatibleDriverError( char const * message ) + : SystemError(make_error_code(Result::eErrorIncompatibleDriver), message) {} + }; + + class TooManyObjectsError : public SystemError + { + public: + TooManyObjectsError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorTooManyObjects), message) {} + TooManyObjectsError( char const * message ) + : SystemError(make_error_code(Result::eErrorTooManyObjects), message) {} + }; + + class FormatNotSupportedError : public SystemError + { + public: + FormatNotSupportedError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorFormatNotSupported), message) {} + FormatNotSupportedError( char const * message ) + : SystemError(make_error_code(Result::eErrorFormatNotSupported), message) {} + }; + + class FragmentedPoolError : public SystemError + { + public: + FragmentedPoolError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorFragmentedPool), message) {} + FragmentedPoolError( char const * message ) + : SystemError(make_error_code(Result::eErrorFragmentedPool), message) {} + }; + + class SurfaceLostKHRError : public SystemError + { + public: + SurfaceLostKHRError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorSurfaceLostKHR), message) {} + SurfaceLostKHRError( char const * message ) + : SystemError(make_error_code(Result::eErrorSurfaceLostKHR), message) {} + }; + + class NativeWindowInUseKHRError : public SystemError + { + public: + NativeWindowInUseKHRError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorNativeWindowInUseKHR), message) {} + NativeWindowInUseKHRError( char const * message ) + : SystemError(make_error_code(Result::eErrorNativeWindowInUseKHR), message) {} + }; + + class OutOfDateKHRError : public SystemError + { + public: + OutOfDateKHRError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorOutOfDateKHR), message) {} + OutOfDateKHRError( char const * message ) + : SystemError(make_error_code(Result::eErrorOutOfDateKHR), message) {} + }; + + class IncompatibleDisplayKHRError : public SystemError + { + public: + IncompatibleDisplayKHRError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorIncompatibleDisplayKHR), message) {} + IncompatibleDisplayKHRError( char const * message ) + : SystemError(make_error_code(Result::eErrorIncompatibleDisplayKHR), message) {} + }; + + class ValidationFailedEXTError : public SystemError + { + public: + ValidationFailedEXTError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorValidationFailedEXT), message) {} + ValidationFailedEXTError( char const * message ) + : SystemError(make_error_code(Result::eErrorValidationFailedEXT), message) {} + }; + + class InvalidShaderNVError : public SystemError + { + public: + InvalidShaderNVError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorInvalidShaderNV), message) {} + InvalidShaderNVError( char const * message ) + : SystemError(make_error_code(Result::eErrorInvalidShaderNV), message) {} + }; + + class OutOfPoolMemoryKHRError : public SystemError + { + public: + OutOfPoolMemoryKHRError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorOutOfPoolMemoryKHR), message) {} + OutOfPoolMemoryKHRError( char const * message ) + : SystemError(make_error_code(Result::eErrorOutOfPoolMemoryKHR), message) {} + }; + + class InvalidExternalHandleKHXError : public SystemError + { + public: + InvalidExternalHandleKHXError( std::string const& message ) + : SystemError(make_error_code(Result::eErrorInvalidExternalHandleKHX), message) {} + InvalidExternalHandleKHXError( char const * message ) + : SystemError(make_error_code(Result::eErrorInvalidExternalHandleKHX), message) {} + }; + + + VULKAN_HPP_INLINE void throwResultException( Result result, char const * message ) + { + assert ( static_cast(result) < 0 ); + switch ( result ) + { + case Result::eErrorOutOfHostMemory: throw OutOfHostMemoryError ( message ); + case Result::eErrorOutOfDeviceMemory: throw OutOfDeviceMemoryError ( message ); + case Result::eErrorInitializationFailed: throw InitializationFailedError ( message ); + case Result::eErrorDeviceLost: throw DeviceLostError ( message ); + case Result::eErrorMemoryMapFailed: throw MemoryMapFailedError ( message ); + case Result::eErrorLayerNotPresent: throw LayerNotPresentError ( message ); + case Result::eErrorExtensionNotPresent: throw ExtensionNotPresentError ( message ); + case Result::eErrorFeatureNotPresent: throw FeatureNotPresentError ( message ); + case Result::eErrorIncompatibleDriver: throw IncompatibleDriverError ( message ); + case Result::eErrorTooManyObjects: throw TooManyObjectsError ( message ); + case Result::eErrorFormatNotSupported: throw FormatNotSupportedError ( message ); + case Result::eErrorFragmentedPool: throw FragmentedPoolError ( message ); + case Result::eErrorSurfaceLostKHR: throw SurfaceLostKHRError ( message ); + case Result::eErrorNativeWindowInUseKHR: throw NativeWindowInUseKHRError ( message ); + case Result::eErrorOutOfDateKHR: throw OutOfDateKHRError ( message ); + case Result::eErrorIncompatibleDisplayKHR: throw IncompatibleDisplayKHRError ( message ); + case Result::eErrorValidationFailedEXT: throw ValidationFailedEXTError ( message ); + case Result::eErrorInvalidShaderNV: throw InvalidShaderNVError ( message ); + case Result::eErrorOutOfPoolMemoryKHR: throw OutOfPoolMemoryKHRError ( message ); + case Result::eErrorInvalidExternalHandleKHX: throw InvalidExternalHandleKHXError ( message ); + default: throw SystemError( make_error_code( result ) ); + } + } + } // namespace vk namespace std @@ -583,7 +841,7 @@ namespace vk #else if ( result != Result::eSuccess ) { - throw std::system_error( result, message ); + throwResultException( result, message ); } #endif } @@ -597,7 +855,7 @@ namespace vk #else if ( result != Result::eSuccess ) { - throw std::system_error( result, message ); + throwResultException( result, message ); } return data; #endif @@ -610,7 +868,7 @@ namespace vk #else if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() ) { - throw std::system_error( result, message ); + throwResultException( result, message ); } #endif return result; @@ -624,7 +882,7 @@ namespace vk #else if ( std::find( successCodes.begin(), successCodes.end(), result ) == successCodes.end() ) { - throw std::system_error( result, message ); + throwResultException( result, message ); } #endif return ResultValue( result, data ); @@ -22020,7 +22278,7 @@ namespace vk #else if ( buffers.size() != offsets.size() ) { - throw std::logic_error( "vk::CommandBuffer::bindVertexBuffers: buffers.size() != offsets.size()" ); + throw LogicError( "vk::CommandBuffer::bindVertexBuffers: buffers.size() != offsets.size()" ); } #endif // VULKAN_HPP_NO_EXCEPTIONS vkCmdBindVertexBuffers( m_commandBuffer, firstBinding, buffers.size() , reinterpret_cast( buffers.data() ), offsets.data() ); @@ -25175,7 +25433,7 @@ namespace vk #else if ( pObjectTableEntries.size() != objectIndices.size() ) { - throw std::logic_error( "vk::Device::registerObjectsNVX: pObjectTableEntries.size() != objectIndices.size()" ); + throw LogicError( "vk::Device::registerObjectsNVX: pObjectTableEntries.size() != objectIndices.size()" ); } #endif // VULKAN_HPP_NO_EXCEPTIONS Result result = static_cast( vkRegisterObjectsNVX( m_device, static_cast( objectTable ), pObjectTableEntries.size() , reinterpret_cast( pObjectTableEntries.data() ), objectIndices.data() ) ); @@ -25195,7 +25453,7 @@ namespace vk #else if ( objectEntryTypes.size() != objectIndices.size() ) { - throw std::logic_error( "vk::Device::unregisterObjectsNVX: objectEntryTypes.size() != objectIndices.size()" ); + throw LogicError( "vk::Device::unregisterObjectsNVX: objectEntryTypes.size() != objectIndices.size()" ); } #endif // VULKAN_HPP_NO_EXCEPTIONS Result result = static_cast( vkUnregisterObjectsNVX( m_device, static_cast( objectTable ), objectEntryTypes.size() , reinterpret_cast( objectEntryTypes.data() ), objectIndices.data() ) ); @@ -25493,7 +25751,7 @@ namespace vk #else if ( swapchains.size() != metadata.size() ) { - throw std::logic_error( "vk::Device::setHdrMetadataEXT: swapchains.size() != metadata.size()" ); + throw LogicError( "vk::Device::setHdrMetadataEXT: swapchains.size() != metadata.size()" ); } #endif // VULKAN_HPP_NO_EXCEPTIONS vkSetHdrMetadataEXT( m_device, swapchains.size() , reinterpret_cast( swapchains.data() ), reinterpret_cast( metadata.data() ) ); @@ -27223,7 +27481,7 @@ namespace vk #else if ( layerPrefix.size() != message.size() ) { - throw std::logic_error( "vk::Instance::debugReportMessageEXT: layerPrefix.size() != message.size()" ); + throw LogicError( "vk::Instance::debugReportMessageEXT: layerPrefix.size() != message.size()" ); } #endif // VULKAN_HPP_NO_EXCEPTIONS vkDebugReportMessageEXT( m_instance, static_cast( flags ), static_cast( objectType ), object, location, messageCode, layerPrefix.c_str(), message.c_str() );