| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 |
- /*
- -----------------------------------------------------------------------------
- This source file is part of OGRE
- (Object-oriented Graphics Rendering Engine)
- For the latest info, see http://www.ogre3d.org/
- Copyright (c) 2000-2011 Torus Knot Software Ltd
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- -----------------------------------------------------------------------------
- */
- #include "OgreGpuProgram.h"
- #include "OgreHighLevelGpuProgram.h"
- #include "OgreVector3.h"
- #include "OgreVector4.h"
- #include "OgreRenderSystemCapabilities.h"
- #include "OgreStringConverter.h"
- #include "OgreException.h"
- #include "OgreRenderSystem.h"
- #include "CmRenderSystemManager.h"
- namespace Ogre
- {
- //-----------------------------------------------------------------------------
- GpuProgram::CmdType GpuProgram::msTypeCmd;
- GpuProgram::CmdSyntax GpuProgram::msSyntaxCmd;
- GpuProgram::CmdSkeletal GpuProgram::msSkeletalCmd;
- GpuProgram::CmdMorph GpuProgram::msMorphCmd;
- GpuProgram::CmdPose GpuProgram::msPoseCmd;
- GpuProgram::CmdVTF GpuProgram::msVTFCmd;
- GpuProgram::CmdManualNamedConstsFile GpuProgram::msManNamedConstsFileCmd;
- GpuProgram::CmdAdjacency GpuProgram::msAdjacencyCmd;
-
- //-----------------------------------------------------------------------------
- GpuProgram::GpuProgram()
- :mType(GPT_VERTEX_PROGRAM), mLoadFromFile(true), mSkeletalAnimation(false),
- mMorphAnimation(false), mPoseAnimation(0),
- mVertexTextureFetch(false), mNeedsAdjacencyInfo(false),
- mCompileError(false), mLoadedManualNamedConstants(false)
- {
- createParameterMappingStructures();
- }
- //-----------------------------------------------------------------------------
- void GpuProgram::setType(GpuProgramType t)
- {
- mType = t;
- }
- //-----------------------------------------------------------------------------
- void GpuProgram::setSyntaxCode(const String& syntax)
- {
- mSyntaxCode = syntax;
- }
- //-----------------------------------------------------------------------------
- void GpuProgram::setSourceFile(const String& filename)
- {
- mFilename = filename;
- mSource.clear();
- mLoadFromFile = true;
- mCompileError = false;
- }
- //-----------------------------------------------------------------------------
- void GpuProgram::setSource(const String& source)
- {
- mSource = source;
- mFilename.clear();
- mLoadFromFile = false;
- mCompileError = false;
- }
-
- //-----------------------------------------------------------------------------
- void GpuProgram::load(void)
- {
- // Call polymorphic load
- try
- {
- loadFromSource();
- assert(mDefaultParams.isNull());
- mDefaultParams = createParameters();
- }
- catch (const Exception&)
- {
- // will already have been logged
- //LogManager::getSingleton().stream()
- // << "Gpu program " << mName << " encountered an error "
- // << "during loading and is thus not supported.";
- mCompileError = true;
- }
- }
- //-----------------------------------------------------------------------------
- bool GpuProgram::isRequiredCapabilitiesSupported(void) const
- {
- // TODO PORT- I dont think I'll be using these capabilities
- return true;
- //const RenderSystemCapabilities* caps =
- // Root::getSingleton().getRenderSystem()->getCapabilities();
- // // If skeletal animation is being done, we need support for UBYTE4
- // if (isSkeletalAnimationIncluded() &&
- // !caps->hasCapability(RSC_VERTEX_FORMAT_UBYTE4))
- // {
- // return false;
- // }
- //// Vertex texture fetch required?
- //if (isVertexTextureFetchRequired() &&
- // !caps->hasCapability(RSC_VERTEX_TEXTURE_FETCH))
- //{
- // return false;
- //}
- // return true;
- }
- //-----------------------------------------------------------------------------
- bool GpuProgram::isSupported(void) const
- {
- if (mCompileError || !isRequiredCapabilitiesSupported())
- return false;
- RenderSystem* rs = CamelotEngine::RenderSystemManager::getActive();
- return rs->getCapabilities()->isShaderProfileSupported(mSyntaxCode);
- }
- //---------------------------------------------------------------------
- void GpuProgram::createParameterMappingStructures(bool recreateIfExists) const
- {
- createLogicalParameterMappingStructures(recreateIfExists);
- createNamedParameterMappingStructures(recreateIfExists);
- }
- //---------------------------------------------------------------------
- void GpuProgram::createLogicalParameterMappingStructures(bool recreateIfExists) const
- {
- if (recreateIfExists || mFloatLogicalToPhysical.isNull())
- mFloatLogicalToPhysical = GpuLogicalBufferStructPtr(OGRE_NEW GpuLogicalBufferStruct());
- if (recreateIfExists || mIntLogicalToPhysical.isNull())
- mIntLogicalToPhysical = GpuLogicalBufferStructPtr(OGRE_NEW GpuLogicalBufferStruct());
- }
- //---------------------------------------------------------------------
- void GpuProgram::createNamedParameterMappingStructures(bool recreateIfExists) const
- {
- if (recreateIfExists || mConstantDefs.isNull())
- mConstantDefs = GpuNamedConstantsPtr(OGRE_NEW GpuNamedConstants());
- }
- //---------------------------------------------------------------------
- void GpuProgram::setManualNamedConstantsFile(const String& paramDefFile)
- {
- mManualNamedConstantsFile = paramDefFile;
- mLoadedManualNamedConstants = false;
- }
- //---------------------------------------------------------------------
- void GpuProgram::setManualNamedConstants(const GpuNamedConstants& namedConstants)
- {
- createParameterMappingStructures();
- *mConstantDefs.get() = namedConstants;
- mFloatLogicalToPhysical->bufferSize = mConstantDefs->floatBufferSize;
- mIntLogicalToPhysical->bufferSize = mConstantDefs->intBufferSize;
- mFloatLogicalToPhysical->map.clear();
- mIntLogicalToPhysical->map.clear();
- // need to set up logical mappings too for some rendersystems
- for (GpuConstantDefinitionMap::const_iterator i = mConstantDefs->map.begin();
- i != mConstantDefs->map.end(); ++i)
- {
- const String& name = i->first;
- const GpuConstantDefinition& def = i->second;
- // only consider non-array entries
- if (name.find("[") == String::npos)
- {
- GpuLogicalIndexUseMap::value_type val(def.logicalIndex,
- GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, def.variability));
- if (def.isFloat())
- {
- mFloatLogicalToPhysical->map.insert(val);
- }
- else
- {
- mIntLogicalToPhysical->map.insert(val);
- }
- }
- }
- }
- //-----------------------------------------------------------------------------
- GpuProgramParametersSharedPtr GpuProgram::createParameters(void)
- {
- // Default implementation simply returns standard parameters.
- GpuProgramParametersSharedPtr ret = GpuProgramParametersSharedPtr(OGRE_NEW GpuProgramParameters());
-
- // set up named parameters, if any
- if (!mConstantDefs.isNull() && !mConstantDefs->map.empty())
- {
- ret->_setNamedConstants(mConstantDefs);
- }
- // link shared logical / physical map for low-level use
- ret->_setLogicalIndexes(mFloatLogicalToPhysical, mIntLogicalToPhysical);
- // Copy in default parameters if present
- if (!mDefaultParams.isNull())
- ret->copyConstantsFrom(*(mDefaultParams.get()));
-
- return ret;
- }
- //-----------------------------------------------------------------------------
- GpuProgramParametersSharedPtr GpuProgram::getDefaultParameters(void)
- {
- if (mDefaultParams.isNull())
- {
- mDefaultParams = createParameters();
- }
- return mDefaultParams;
- }
- //-----------------------------------------------------------------------------
- void GpuProgram::setupBaseParamDictionary(void)
- {
- // TODO PORT - I'm not really sure what this will do and will it be needed in my port, but its calling a method from Resource, and we don't inherit from it
- // ParamDictionary* dict = getParamDictionary();
- // dict->addParameter(
- // ParameterDef("type", "'vertex_program', 'geometry_program' or 'fragment_program'",
- // PT_STRING), &msTypeCmd);
- // dict->addParameter(
- // ParameterDef("syntax", "Syntax code, e.g. vs_1_1", PT_STRING), &msSyntaxCmd);
- // dict->addParameter(
- // ParameterDef("includes_skeletal_animation",
- // "Whether this vertex program includes skeletal animation", PT_BOOL),
- // &msSkeletalCmd);
- //dict->addParameter(
- // ParameterDef("includes_morph_animation",
- // "Whether this vertex program includes morph animation", PT_BOOL),
- // &msMorphCmd);
- //dict->addParameter(
- // ParameterDef("includes_pose_animation",
- // "The number of poses this vertex program supports for pose animation", PT_INT),
- // &msPoseCmd);
- //dict->addParameter(
- // ParameterDef("uses_vertex_texture_fetch",
- // "Whether this vertex program requires vertex texture fetch support.", PT_BOOL),
- // &msVTFCmd);
- //dict->addParameter(
- // ParameterDef("manual_named_constants",
- // "File containing named parameter mappings for low-level programs.", PT_BOOL),
- // &msManNamedConstsFileCmd);
- //dict->addParameter(
- // ParameterDef("uses_adjacency_information",
- // "Whether this geometry program requires adjacency information from the input primitives.", PT_BOOL),
- // &msAdjacencyCmd);
- }
- //-----------------------------------------------------------------------
- const String& GpuProgram::getLanguage(void) const
- {
- static const String language = "asm";
- return language;
- }
- //-----------------------------------------------------------------------
- //-----------------------------------------------------------------------
- String GpuProgram::CmdType::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- if (t->getType() == GPT_VERTEX_PROGRAM)
- {
- return "vertex_program";
- }
- else if (t->getType() == GPT_GEOMETRY_PROGRAM)
- {
- return "geometry_program";
- }
- else
- {
- return "fragment_program";
- }
- }
- void GpuProgram::CmdType::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- if (val == "vertex_program")
- {
- t->setType(GPT_VERTEX_PROGRAM);
- }
- else if (val == "geometry_program")
- {
- t->setType(GPT_GEOMETRY_PROGRAM);
- }
- else
- {
- t->setType(GPT_FRAGMENT_PROGRAM);
- }
- }
- //-----------------------------------------------------------------------
- String GpuProgram::CmdSyntax::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- return t->getSyntaxCode();
- }
- void GpuProgram::CmdSyntax::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- t->setSyntaxCode(val);
- }
- //-----------------------------------------------------------------------
- String GpuProgram::CmdSkeletal::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- return StringConverter::toString(t->isSkeletalAnimationIncluded());
- }
- void GpuProgram::CmdSkeletal::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- t->setSkeletalAnimationIncluded(StringConverter::parseBool(val));
- }
- //-----------------------------------------------------------------------
- String GpuProgram::CmdMorph::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- return StringConverter::toString(t->isMorphAnimationIncluded());
- }
- void GpuProgram::CmdMorph::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- t->setMorphAnimationIncluded(StringConverter::parseBool(val));
- }
- //-----------------------------------------------------------------------
- String GpuProgram::CmdPose::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- return StringConverter::toString(t->getNumberOfPosesIncluded());
- }
- void GpuProgram::CmdPose::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- t->setPoseAnimationIncluded((ushort)StringConverter::parseUnsignedInt(val));
- }
- //-----------------------------------------------------------------------
- String GpuProgram::CmdVTF::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- return StringConverter::toString(t->isVertexTextureFetchRequired());
- }
- void GpuProgram::CmdVTF::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- t->setVertexTextureFetchRequired(StringConverter::parseBool(val));
- }
- //-----------------------------------------------------------------------
- String GpuProgram::CmdManualNamedConstsFile::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- return t->getManualNamedConstantsFile();
- }
- void GpuProgram::CmdManualNamedConstsFile::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- t->setManualNamedConstantsFile(val);
- }
- //-----------------------------------------------------------------------
- String GpuProgram::CmdAdjacency::doGet(const void* target) const
- {
- const GpuProgram* t = static_cast<const GpuProgram*>(target);
- return StringConverter::toString(t->isAdjacencyInfoRequired());
- }
- void GpuProgram::CmdAdjacency::doSet(void* target, const String& val)
- {
- GpuProgram* t = static_cast<GpuProgram*>(target);
- t->setAdjacencyInfoRequired(StringConverter::parseBool(val));
- }
- //-----------------------------------------------------------------------
- GpuProgramPtr& GpuProgramPtr::operator=(const HighLevelGpuProgramPtr& r)
- {
- // Can assign direct
- if (pRep == r.getPointer())
- return *this;
- release();
- // lock & copy other mutex pointer
- OGRE_MUTEX_CONDITIONAL(r.OGRE_AUTO_MUTEX_NAME)
- {
- OGRE_LOCK_MUTEX(*r.OGRE_AUTO_MUTEX_NAME)
- OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
- pRep = r.getPointer();
- pUseCount = r.useCountPointer();
- if (pUseCount)
- {
- ++(*pUseCount);
- }
- }
- else
- {
- // RHS must be a null pointer
- assert(r.isNull() && "RHS must be null if it has no mutex!");
- setNull();
- }
- return *this;
- }
- }
|