1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 #include "OgreStableHeaders.h" 29 #include "OgreUnifiedHighLevelGpuProgram.h" 30 #include "OgreGpuProgramManager.h" 31 32 namespace Ogre 33 { 34 //----------------------------------------------------------------------- 35 UnifiedHighLevelGpuProgram::CmdDelegate UnifiedHighLevelGpuProgram::msCmdDelegate; 36 static const String sLanguage = "unified"; 37 std::map<String,int> UnifiedHighLevelGpuProgram::mLanguagePriorities; 38 getPriority(String shaderLanguage)39 int UnifiedHighLevelGpuProgram::getPriority(String shaderLanguage) 40 { 41 std::map<String,int>::iterator it = mLanguagePriorities.find(shaderLanguage); 42 if (it == mLanguagePriorities.end()) 43 return -1; 44 else 45 return (*it).second; 46 } 47 setPriority(String shaderLanguage,int priority)48 void UnifiedHighLevelGpuProgram::setPriority(String shaderLanguage,int priority) 49 { 50 mLanguagePriorities[shaderLanguage] = priority; 51 } 52 //----------------------------------------------------------------------- 53 //----------------------------------------------------------------------- UnifiedHighLevelGpuProgram(ResourceManager * creator,const String & name,ResourceHandle handle,const String & group,bool isManual,ManualResourceLoader * loader)54 UnifiedHighLevelGpuProgram::UnifiedHighLevelGpuProgram( 55 ResourceManager* creator, const String& name, ResourceHandle handle, 56 const String& group, bool isManual, ManualResourceLoader* loader) 57 :HighLevelGpuProgram(creator, name, handle, group, isManual, loader) 58 { 59 if (createParamDictionary("UnifiedHighLevelGpuProgram")) 60 { 61 setupBaseParamDictionary(); 62 63 ParamDictionary* dict = getParamDictionary(); 64 65 dict->addParameter(ParameterDef("delegate", 66 "Additional delegate programs containing implementations.", 67 PT_STRING),&msCmdDelegate); 68 } 69 70 } 71 //----------------------------------------------------------------------- ~UnifiedHighLevelGpuProgram()72 UnifiedHighLevelGpuProgram::~UnifiedHighLevelGpuProgram() 73 { 74 75 } 76 //----------------------------------------------------------------------- chooseDelegate() const77 void UnifiedHighLevelGpuProgram::chooseDelegate() const 78 { 79 OGRE_LOCK_AUTO_MUTEX; 80 81 mChosenDelegate.reset(); 82 83 HighLevelGpuProgramPtr tmpDelegate; 84 tmpDelegate.reset(); 85 int tmpPriority = -1; 86 87 for (StringVector::const_iterator i = mDelegateNames.begin(); i != mDelegateNames.end(); ++i) 88 { 89 HighLevelGpuProgramPtr deleg = HighLevelGpuProgramManager::getSingleton().getByName(*i, mGroup); 90 91 //recheck with auto resource group 92 if (!deleg) 93 deleg = HighLevelGpuProgramManager::getSingleton().getByName( 94 *i, ResourceGroupManager::AUTODETECT_RESOURCE_GROUP_NAME); 95 96 // Silently ignore missing links 97 if(!deleg || !deleg->isSupported()) 98 continue; 99 100 if (deleg->getType() != getType()) 101 { 102 LogManager::getSingleton().logError( 103 "unified program '" + getName() + 104 "' delegating to program with different type '" + *i + "'"); 105 continue; 106 } 107 108 int priority = getPriority(deleg->getLanguage()); 109 //Find the delegate with the highest prioriry 110 if (priority >= tmpPriority) 111 { 112 tmpDelegate = deleg; 113 tmpPriority = priority; 114 } 115 } 116 117 mChosenDelegate = tmpDelegate; 118 } 119 //----------------------------------------------------------------------- _getDelegate() const120 const HighLevelGpuProgramPtr& UnifiedHighLevelGpuProgram::_getDelegate() const 121 { 122 if (!mChosenDelegate) 123 { 124 chooseDelegate(); 125 } 126 return mChosenDelegate; 127 } 128 //----------------------------------------------------------------------- addDelegateProgram(const String & name)129 void UnifiedHighLevelGpuProgram::addDelegateProgram(const String& name) 130 { 131 OGRE_LOCK_AUTO_MUTEX; 132 133 mDelegateNames.push_back(name); 134 135 // reset chosen delegate 136 mChosenDelegate.reset(); 137 138 } 139 //----------------------------------------------------------------------- clearDelegatePrograms()140 void UnifiedHighLevelGpuProgram::clearDelegatePrograms() 141 { 142 OGRE_LOCK_AUTO_MUTEX; 143 144 mDelegateNames.clear(); 145 mChosenDelegate.reset(); 146 147 } 148 //----------------------------------------------------------------------------- calculateSize(void) const149 size_t UnifiedHighLevelGpuProgram::calculateSize(void) const 150 { 151 size_t memSize = 0; 152 153 memSize += HighLevelGpuProgram::calculateSize(); 154 155 // Delegate Names 156 for (StringVector::const_iterator i = mDelegateNames.begin(); i != mDelegateNames.end(); ++i) 157 memSize += (*i).size() * sizeof(char); 158 159 return memSize; 160 } 161 //----------------------------------------------------------------------- getLanguage(void) const162 const String& UnifiedHighLevelGpuProgram::getLanguage(void) const 163 { 164 return sLanguage; 165 } 166 //----------------------------------------------------------------------- createParameters(void)167 GpuProgramParametersSharedPtr UnifiedHighLevelGpuProgram::createParameters(void) 168 { 169 if (isSupported()) 170 { 171 return _getDelegate()->createParameters(); 172 } 173 else 174 { 175 // return a default set 176 GpuProgramParametersSharedPtr params = GpuProgramManager::getSingleton().createParameters(); 177 // avoid any errors on parameter names that don't exist 178 params->setIgnoreMissingParams(true); 179 return params; 180 } 181 } 182 //----------------------------------------------------------------------- _getBindingDelegate(void)183 GpuProgram* UnifiedHighLevelGpuProgram::_getBindingDelegate(void) 184 { 185 if (_getDelegate()) 186 return _getDelegate()->_getBindingDelegate(); 187 else 188 return 0; 189 } 190 //----------------------------------------------------------------------- isSupported(void) const191 bool UnifiedHighLevelGpuProgram::isSupported(void) const 192 { 193 // Supported if one of the delegates is 194 return _getDelegate().get() != 0; 195 } 196 //----------------------------------------------------------------------- isSkeletalAnimationIncluded(void) const197 bool UnifiedHighLevelGpuProgram::isSkeletalAnimationIncluded(void) const 198 { 199 if (_getDelegate()) 200 return _getDelegate()->isSkeletalAnimationIncluded(); 201 else 202 return false; 203 } 204 //----------------------------------------------------------------------- isMorphAnimationIncluded(void) const205 bool UnifiedHighLevelGpuProgram::isMorphAnimationIncluded(void) const 206 { 207 if (_getDelegate()) 208 return _getDelegate()->isMorphAnimationIncluded(); 209 else 210 return false; 211 } 212 //----------------------------------------------------------------------- isPoseAnimationIncluded(void) const213 bool UnifiedHighLevelGpuProgram::isPoseAnimationIncluded(void) const 214 { 215 if (_getDelegate()) 216 return _getDelegate()->isPoseAnimationIncluded(); 217 else 218 return false; 219 } 220 //----------------------------------------------------------------------- getNumberOfPosesIncluded(void) const221 ushort UnifiedHighLevelGpuProgram::getNumberOfPosesIncluded(void) const 222 { 223 if (_getDelegate()) 224 return _getDelegate()->getNumberOfPosesIncluded(); 225 else 226 return 0; 227 } 228 //----------------------------------------------------------------------- isVertexTextureFetchRequired(void) const229 bool UnifiedHighLevelGpuProgram::isVertexTextureFetchRequired(void) const 230 { 231 if (_getDelegate()) 232 return _getDelegate()->isVertexTextureFetchRequired(); 233 else 234 return false; 235 } 236 //----------------------------------------------------------------------- getDefaultParameters(void)237 GpuProgramParametersSharedPtr UnifiedHighLevelGpuProgram::getDefaultParameters(void) 238 { 239 if (_getDelegate()) 240 return _getDelegate()->getDefaultParameters(); 241 else 242 return GpuProgramParametersSharedPtr(); 243 } 244 //----------------------------------------------------------------------- hasDefaultParameters(void) const245 bool UnifiedHighLevelGpuProgram::hasDefaultParameters(void) const 246 { 247 if (_getDelegate()) 248 return _getDelegate()->hasDefaultParameters(); 249 else 250 return false; 251 } 252 //----------------------------------------------------------------------- getPassSurfaceAndLightStates(void) const253 bool UnifiedHighLevelGpuProgram::getPassSurfaceAndLightStates(void) const 254 { 255 if (_getDelegate()) 256 return _getDelegate()->getPassSurfaceAndLightStates(); 257 else 258 return HighLevelGpuProgram::getPassSurfaceAndLightStates(); 259 } 260 //--------------------------------------------------------------------- getPassFogStates(void) const261 bool UnifiedHighLevelGpuProgram::getPassFogStates(void) const 262 { 263 if (_getDelegate()) 264 return _getDelegate()->getPassFogStates(); 265 else 266 return HighLevelGpuProgram::getPassFogStates(); 267 } 268 //--------------------------------------------------------------------- getPassTransformStates(void) const269 bool UnifiedHighLevelGpuProgram::getPassTransformStates(void) const 270 { 271 if (_getDelegate()) 272 return _getDelegate()->getPassTransformStates(); 273 else 274 return HighLevelGpuProgram::getPassTransformStates(); 275 276 } 277 //----------------------------------------------------------------------- hasCompileError(void) const278 bool UnifiedHighLevelGpuProgram::hasCompileError(void) const 279 { 280 if (!_getDelegate()) 281 { 282 return false; 283 } 284 else 285 { 286 return _getDelegate()->hasCompileError(); 287 } 288 } 289 //----------------------------------------------------------------------- resetCompileError(void)290 void UnifiedHighLevelGpuProgram::resetCompileError(void) 291 { 292 if (_getDelegate()) 293 _getDelegate()->resetCompileError(); 294 } 295 //----------------------------------------------------------------------- load(bool backgroundThread)296 void UnifiedHighLevelGpuProgram::load(bool backgroundThread) 297 { 298 if (_getDelegate()) 299 _getDelegate()->load(backgroundThread); 300 } 301 //----------------------------------------------------------------------- reload(LoadingFlags flags)302 void UnifiedHighLevelGpuProgram::reload(LoadingFlags flags) 303 { 304 if (_getDelegate()) 305 _getDelegate()->reload(flags); 306 } 307 //----------------------------------------------------------------------- isReloadable(void) const308 bool UnifiedHighLevelGpuProgram::isReloadable(void) const 309 { 310 if (_getDelegate()) 311 return _getDelegate()->isReloadable(); 312 else 313 return true; 314 } 315 //----------------------------------------------------------------------- unload(void)316 void UnifiedHighLevelGpuProgram::unload(void) 317 { 318 if (_getDelegate()) 319 _getDelegate()->unload(); 320 } 321 //----------------------------------------------------------------------- isLoaded(void) const322 bool UnifiedHighLevelGpuProgram::isLoaded(void) const 323 { 324 if (_getDelegate()) 325 return _getDelegate()->isLoaded(); 326 else 327 return false; 328 } 329 //----------------------------------------------------------------------- isLoading() const330 bool UnifiedHighLevelGpuProgram::isLoading() const 331 { 332 if (_getDelegate()) 333 return _getDelegate()->isLoading(); 334 else 335 return false; 336 } 337 //----------------------------------------------------------------------- getLoadingState() const338 Resource::LoadingState UnifiedHighLevelGpuProgram::getLoadingState() const 339 { 340 if (_getDelegate()) 341 return _getDelegate()->getLoadingState(); 342 else 343 return Resource::LOADSTATE_UNLOADED; 344 } 345 //----------------------------------------------------------------------- getSize(void) const346 size_t UnifiedHighLevelGpuProgram::getSize(void) const 347 { 348 if (_getDelegate()) 349 return _getDelegate()->getSize(); 350 else 351 return 0; 352 } 353 //----------------------------------------------------------------------- touch(void)354 void UnifiedHighLevelGpuProgram::touch(void) 355 { 356 if (_getDelegate()) 357 _getDelegate()->touch(); 358 } 359 //----------------------------------------------------------------------- isBackgroundLoaded(void) const360 bool UnifiedHighLevelGpuProgram::isBackgroundLoaded(void) const 361 { 362 if (_getDelegate()) 363 return _getDelegate()->isBackgroundLoaded(); 364 else 365 return false; 366 } 367 //----------------------------------------------------------------------- setBackgroundLoaded(bool bl)368 void UnifiedHighLevelGpuProgram::setBackgroundLoaded(bool bl) 369 { 370 if (_getDelegate()) 371 _getDelegate()->setBackgroundLoaded(bl); 372 } 373 //----------------------------------------------------------------------- escalateLoading()374 void UnifiedHighLevelGpuProgram::escalateLoading() 375 { 376 if (_getDelegate()) 377 _getDelegate()->escalateLoading(); 378 } 379 //----------------------------------------------------------------------- addListener(Resource::Listener * lis)380 void UnifiedHighLevelGpuProgram::addListener(Resource::Listener* lis) 381 { 382 if (_getDelegate()) 383 _getDelegate()->addListener(lis); 384 } 385 //----------------------------------------------------------------------- removeListener(Resource::Listener * lis)386 void UnifiedHighLevelGpuProgram::removeListener(Resource::Listener* lis) 387 { 388 if (_getDelegate()) 389 _getDelegate()->removeListener(lis); 390 } 391 //----------------------------------------------------------------------- createLowLevelImpl(void)392 void UnifiedHighLevelGpuProgram::createLowLevelImpl(void) 393 { 394 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 395 "This method should never get called!", 396 "UnifiedHighLevelGpuProgram::createLowLevelImpl"); 397 } 398 //----------------------------------------------------------------------- unloadHighLevelImpl(void)399 void UnifiedHighLevelGpuProgram::unloadHighLevelImpl(void) 400 { 401 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 402 "This method should never get called!", 403 "UnifiedHighLevelGpuProgram::unloadHighLevelImpl"); 404 } 405 //----------------------------------------------------------------------- buildConstantDefinitions() const406 void UnifiedHighLevelGpuProgram::buildConstantDefinitions() const 407 { 408 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 409 "This method should never get called!", 410 "UnifiedHighLevelGpuProgram::buildConstantDefinitions"); 411 } 412 //----------------------------------------------------------------------- loadFromSource(void)413 void UnifiedHighLevelGpuProgram::loadFromSource(void) 414 { 415 OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED, 416 "This method should never get called!", 417 "UnifiedHighLevelGpuProgram::loadFromSource"); 418 } 419 //----------------------------------------------------------------------- 420 //----------------------------------------------------------------------- doGet(const void * target) const421 String UnifiedHighLevelGpuProgram::CmdDelegate::doGet(const void* target) const 422 { 423 // Can't do this (not one delegate), shouldn't matter 424 return BLANKSTRING; 425 } 426 //----------------------------------------------------------------------- doSet(void * target,const String & val)427 void UnifiedHighLevelGpuProgram::CmdDelegate::doSet(void* target, const String& val) 428 { 429 static_cast<UnifiedHighLevelGpuProgram*>(target)->addDelegateProgram(val); 430 } 431 //----------------------------------------------------------------------- 432 //----------------------------------------------------------------------- UnifiedHighLevelGpuProgramFactory()433 UnifiedHighLevelGpuProgramFactory::UnifiedHighLevelGpuProgramFactory() 434 { 435 } 436 //----------------------------------------------------------------------- ~UnifiedHighLevelGpuProgramFactory()437 UnifiedHighLevelGpuProgramFactory::~UnifiedHighLevelGpuProgramFactory() 438 { 439 } 440 //----------------------------------------------------------------------- getLanguage(void) const441 const String& UnifiedHighLevelGpuProgramFactory::getLanguage(void) const 442 { 443 return sLanguage; 444 } 445 //----------------------------------------------------------------------- create(ResourceManager * creator,const String & name,ResourceHandle handle,const String & group,bool isManual,ManualResourceLoader * loader)446 HighLevelGpuProgram* UnifiedHighLevelGpuProgramFactory::create(ResourceManager* creator, 447 const String& name, ResourceHandle handle, 448 const String& group, bool isManual, ManualResourceLoader* loader) 449 { 450 return OGRE_NEW UnifiedHighLevelGpuProgram(creator, name, handle, group, isManual, loader); 451 } 452 //----------------------------------------------------------------------- destroy(HighLevelGpuProgram * prog)453 void UnifiedHighLevelGpuProgramFactory::destroy(HighLevelGpuProgram* prog) 454 { 455 OGRE_DELETE prog; 456 } 457 //----------------------------------------------------------------------- 458 459 } 460 461