// This code contains NVIDIA Confidential Information and is disclosed to you // under a form of NVIDIA software license agreement provided separately to you. // // Notice // NVIDIA Corporation and its licensors retain all intellectual property and // proprietary rights in and to this software and related documentation and // any modifications thereto. Any use, reproduction, disclosure, or // distribution of this software and related documentation without an express // license agreement from NVIDIA Corporation is strictly prohibited. // // ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES // NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO // THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT, // MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE. // // Information and code furnished is believed to be accurate and reliable. // However, NVIDIA Corporation assumes no responsibility for the consequences of use of such // information or for any infringement of patents or other rights of third parties that may // result from its use. No license is granted by implication or otherwise under any patent // or patent rights of NVIDIA Corporation. Details are subject to change without notice. // This code supersedes and replaces all information previously supplied. // NVIDIA Corporation products are not authorized for use as critical // components in life support devices or systems without express written approval of // NVIDIA Corporation. // // Copyright (c) 2008-2020 NVIDIA Corporation. All rights reserved. #include #include #include #include #include "nvparameterized/NvParameterized.h" #include "nvparameterized/NvParameterizedTraits.h" #include "NvTraitsInternal.h" #include "SerializerCommon.h" namespace NvParameterized { class DefaultParamConversion: public Conversion { Traits *mTraits; RefConversionMode::Enum mRefMode; typedef physx::shdfnd::HashMap, Traits::Allocator> MapName2Ver; MapName2Ver mapName2Ver; bool copy(Handle &legacyHandle, Handle &handle) { const Definition *pdLegacy = legacyHandle.parameterDefinition(), *pd = handle.parameterDefinition(); if( pdLegacy->type() != pd->type() ) return true; switch( pdLegacy->type() ) { case TYPE_STRUCT: for(int32_t i = 0; i < pdLegacy->numChildren(); ++i) { legacyHandle.set(i); int32_t j = -1; if( pd->child(pdLegacy->child(i)->name(), j) ) { handle.set(j); if( !copy(legacyHandle, handle) ) { char longName[128]; legacyHandle.getLongName(longName, sizeof(longName)); NV_PARAM_TRAITS_WARNING( mTraits, "%s: failed to copy legacy data", longName ); return false; } handle.popIndex(); } legacyHandle.popIndex(); } break; case TYPE_ARRAY: { //FIXME: this is too harsh e.g. we can convert static to dynamic if( pdLegacy->arraySizeIsFixed() != pd->arraySizeIsFixed() ) return true; int32_t size; if( pdLegacy->arraySizeIsFixed() ) { //FIXME: this is too harsh e.g. we may just copy first elements if( pdLegacy->arraySize() != pd->arraySize() ) return true; size = pd->arraySize(); } else { if( ERROR_NONE != legacyHandle.getArraySize(size) ) return false; handle.resizeArray(size); } if( size > 100 && pdLegacy->isSimpleType(false, false) && pdLegacy->type() == pd->type() ) { // Large array of simple types, fast path switch( pdLegacy->type() ) { NV_PARAMETRIZED_NO_MATH_DATATYPE_LABELS NV_PARAMETRIZED_LEGACY_DATATYPE_LABELS default: // Fall to slow path break; #define NV_PARAMETERIZED_TYPES_ONLY_SIMPLE_TYPES #define NV_PARAMETERIZED_TYPES_NO_STRING_TYPES #define NV_PARAMETERIZED_TYPE(type_name, enum_name, c_type) \ case TYPE_ ## enum_name: { \ c_type *data = (c_type *)mTraits->alloc(sizeof(c_type) * size); \ if( ERROR_NONE != legacyHandle.getParam ## type_name ## Array(data, size) ) return false; \ if( ERROR_NONE != handle.setParam ## type_name ## Array(data, size) ) return false; \ mTraits->free(data); \ break; \ } #include "nvparameterized/NvParameterized_types.h" } } // Slow path for arrays of aggregates, including TYPE_MAT34 for(int32_t i = 0; i < size; ++i) { legacyHandle.set(i); handle.set(i); copy(legacyHandle, handle); handle.popIndex(); legacyHandle.popIndex(); } break; } case TYPE_REF: { Interface *legacyRefObj; legacyHandle.getParamRef(legacyRefObj); // Skip references which have unsupported classes (keep default version) if( legacyRefObj && -1 == handle.parameterDefinition()->refVariantValIndex(legacyRefObj->className()) ) return true; Interface *refObj; handle.getParamRef(refObj); switch( mRefMode ) { case RefConversionMode::REF_CONVERT_LAST: default: DEBUG_ALWAYS_ASSERT(); break; case RefConversionMode::REF_CONVERT_SKIP: break; case RefConversionMode::REF_CONVERT_COPY: { // TODO: check that this class is allowed in new version? // Update to preferred version if necessary if( legacyRefObj && pdLegacy->isIncludedRef() ) { const char *className = legacyRefObj->className(); const MapName2Ver::Entry *e = mapName2Ver.find(pd->longName()); if( e ) { uint32_t prefVer = e->second, curVer = legacyRefObj->version(); if( curVer > prefVer ) { NV_PARAM_TRAITS_WARNING( mTraits, "Unable to upgrade included reference of class %s, " "actual version (%u) is higher than preferred version (%u), " "your conversion may not work properly", className, (unsigned)curVer, (unsigned)prefVer ); DEBUG_ALWAYS_ASSERT(); return false; } else if( curVer < prefVer ) { Interface *newLegacyRefObj = mTraits->createNvParameterized(className, prefVer); if( !mTraits->updateLegacyNvParameterized(*legacyRefObj, *newLegacyRefObj) ) { NV_PARAM_TRAITS_WARNING( mTraits, "Failed to upgrade reference of class %s to version %u", className, (unsigned)prefVer ); DEBUG_ALWAYS_ASSERT(); newLegacyRefObj->destroy(); return false; } legacyRefObj->destroy(); legacyRefObj = newLegacyRefObj; legacyHandle.setParamRef(legacyRefObj); } else { // Object has preferred version => do not do anything } } } if( ERROR_NONE != handle.setParamRef(legacyRefObj) ) return true; if( ERROR_NONE != legacyHandle.setParamRef(0) ) { //Prevent destruction in legacyObj->destroy() handle.setParamRef(0); return false; } if( refObj ) refObj->destroy(); return true; } case RefConversionMode::REF_CONVERT_UPDATE: { DEBUG_ASSERT( 0 && "This was not used/tested for a long time" ); return false; /* if( !refObj ) { //TODO: do we need to create refObj here? return false; } if( 0 != strcmp(legacyRefObj->className(), refObj->className()) ) { if( NvParameterized::ERROR_NONE != handle.initParamRef(legacyRefObj->className(), true) ) return false; if( NvParameterized::ERROR_NONE != handle.getParamRef(refObj) ) return false; } if( legacyRefObj->version() != refObj->version() ) return mTraits->updateLegacyNvParameterized(*legacyRefObj, *refObj); //Same version => recursive copy Handle refHandle(*refObj, ""); DEBUG_ASSERT( refHandle.isValid() ); Handle legacyRefHandle(*legacyRefObj, ""); DEBUG_ASSERT( legacyRefHandle.isValid() ); return copy(legacyRefHandle, refHandle);*/ } } //switch( mRefMode ) break; } case TYPE_POINTER: // do nothing? break; case TYPE_ENUM: { const char *val; legacyHandle.getParamEnum(val); int32_t valIdx = handle.parameterDefinition()->enumValIndex(val); if(-1 != valIdx) { const char *canonicVal = handle.parameterDefinition()->enumVal(valIdx); if( ERROR_NONE != handle.setParamEnum(canonicVal) ) { NV_PARAM_TRAITS_WARNING( mTraits, "Internal error while setting enum value %s", canonicVal ? canonicVal : "" ); DEBUG_ALWAYS_ASSERT(); return false; } } break; } # define NV_PARAMETERIZED_TYPES_NO_STRING_TYPES # define NV_PARAMETERIZED_TYPES_ONLY_SIMPLE_TYPES # define NV_PARAMETERIZED_TYPE(type_name, enum_name, c_type) \ case TYPE_##enum_name: { c_type val; legacyHandle.getParam##type_name(val); handle.setParam##type_name(val); break; } NV_PARAMETERIZED_TYPE(String, STRING, const char *) # include "nvparameterized/NvParameterized_types.h" case TYPE_MAT34: { float val[12]; legacyHandle.getParamMat34Legacy(val); handle.setParamMat34Legacy(val); break; } NV_PARAMETRIZED_UNDEFINED_AND_LAST_DATATYPE_LABELS default: DEBUG_ALWAYS_ASSERT(); } return true; } public: DefaultParamConversion(Traits *traits, const PrefVer *prefVers, RefConversionMode::Enum refMode) : mTraits(traits), mRefMode(refMode), mapName2Ver(0, 0.75, Traits::Allocator(traits)) { for(; prefVers && prefVers->longName; ++prefVers) mapName2Ver[prefVers->longName] = prefVers->ver; } bool operator()(NvParameterized::Interface &legacyObj, NvParameterized::Interface &obj) { obj.initDefaults(); Handle legacyHandle(legacyObj, ""); DEBUG_ASSERT( legacyHandle.isValid() ); Handle handle(obj, ""); DEBUG_ASSERT( handle.isValid() ); return copy(legacyHandle, handle); } void release() { this->~DefaultParamConversion(); mTraits->free(this); } }; Conversion *internalCreateDefaultConversion(Traits *traits, const PrefVer *prefVers, RefConversionMode::Enum refMode) { void *buf = traits->alloc(sizeof(DefaultParamConversion)); return PX_PLACEMENT_NEW(buf, DefaultParamConversion)(traits, prefVers, refMode); } }; // end of namespace