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