Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreCgProgram.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2003 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreCgProgram.h"
00026 #include "OgreGpuProgramManager.h"
00027 #include "OgreStringConverter.h"
00028 
00029 namespace Ogre {
00030     //-----------------------------------------------------------------------
00031     CgProgram::CmdEntryPoint CgProgram::msCmdEntryPoint;
00032     CgProgram::CmdProfiles CgProgram::msCmdProfiles;
00033     CgProgram::CmdArgs CgProgram::msCmdArgs;
00034     //-----------------------------------------------------------------------
00035     void CgProgram::selectProfile(void)
00036     {
00037         mSelectedProfile = "";
00038         mSelectedCgProfile = CG_PROFILE_UNKNOWN;
00039 
00040         StringVector::iterator i, iend;
00041         iend = mProfiles.end();
00042         GpuProgramManager& gpuMgr = GpuProgramManager::getSingleton();
00043         for (i = mProfiles.begin(); i != iend; ++i)
00044         {
00045             if (gpuMgr.isSyntaxSupported(*i))
00046             {
00047                 mSelectedProfile = *i;
00048                 mSelectedCgProfile = cgGetProfile(mSelectedProfile);
00049                 // Check for errors
00050                 checkForCgError("CgProgram::selectProfile", 
00051                     "Unable to find CG profile enum for program " + mName + ": ", mCgContext);
00052                 break;
00053             }
00054         }
00055     }
00056     //-----------------------------------------------------------------------
00057     void CgProgram::buildArgs(void)
00058     {
00059         StringVector args;
00060         if (!mCompileArgs.empty())
00061             args = mCompileArgs.split();
00062 
00063         StringVector::const_iterator i;
00064         if (mSelectedCgProfile == CG_PROFILE_VS_1_1)
00065         {
00066             // Need the 'dcls' argument whenever we use this profile
00067             // otherwise compilation of the assembler will fail
00068             bool dclsFound = false;
00069             for (i = args.begin(); i != args.end(); ++i)
00070             {
00071                 if (*i == "dcls")
00072                 {
00073                     dclsFound = true;
00074                     break;
00075                 }
00076             }
00077             if (!dclsFound)
00078             {
00079                 args.push_back("-profileopts dcls");
00080             }
00081         }
00082         // Now split args into that god-awful char** that Cg insists on
00083         freeCgArgs();
00084         mCgArguments = new char*[args.size() + 1];
00085         int index = 0;
00086         for (i = args.begin(); i != args.end(); ++i, ++index)
00087         {
00088             mCgArguments[index] = new char[i->length() + 1];
00089             strcpy(mCgArguments[index], i->c_str());
00090         }
00091         // Null terminate list
00092         mCgArguments[index] = 0;
00093 
00094 
00095     }
00096     //-----------------------------------------------------------------------
00097     void CgProgram::freeCgArgs(void)
00098     {
00099         if (mCgArguments)
00100         {
00101             size_t index = 0;
00102             char* current = mCgArguments[index];
00103             while (current)
00104             {
00105                 delete [] current;
00106                 current = mCgArguments[++index];
00107             }
00108             delete [] mCgArguments;
00109             mCgArguments = 0;
00110         }
00111     }
00112     //-----------------------------------------------------------------------
00113     void CgProgram::loadFromSource(void)
00114     {
00115         // Create Cg Program
00116         selectProfile();
00117         buildArgs();
00118         mCgProgram = cgCreateProgram(mCgContext, CG_SOURCE, mSource.c_str(), 
00119             mSelectedCgProfile, mEntryPoint.c_str(), const_cast<const char**>(mCgArguments));
00120 
00121         // Test
00122         //LogManager::getSingleton().logMessage(cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM));
00123 
00124         // Check for errors
00125         checkForCgError("CgProgram::loadFromSource", 
00126             "Unable to compile Cg program " + mName + ": ", mCgContext);
00127 
00128     }
00129     //-----------------------------------------------------------------------
00130     void CgProgram::createLowLevelImpl(void)
00131     {
00132         // Create a low-level program, give it the same name as us
00133         mAssemblerProgram = 
00134             GpuProgramManager::getSingleton().createProgramFromString(
00135                 mName, 
00136                 cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM),
00137                 mType, 
00138                 mSelectedProfile);
00139 
00140     }
00141     //-----------------------------------------------------------------------
00142     void CgProgram::unloadImpl(void)
00143     {
00144         // Unload Cg Program
00145         // Lowlevel program will get unloaded elsewhere
00146         if (mCgProgram)
00147         {
00148             cgDestroyProgram(mCgProgram);
00149             checkForCgError("CgProgram::unloadImpl", 
00150                 "Error while unloading Cg program " + mName + ": ", 
00151                 mCgContext);
00152             mCgProgram = 0;
00153         }
00154     }
00155     //-----------------------------------------------------------------------
00156     void CgProgram::populateParameterNames(GpuProgramParametersSharedPtr params)
00157     {
00158         // Derive parameter names from Cg
00159         assert(mCgProgram && "Cg program not loaded!");
00160         // Note use of 'leaf' format so we only get bottom-level params, not structs
00161         CGparameter parameter = cgGetFirstLeafParameter(mCgProgram, CG_PROGRAM);
00162         while (parameter != 0) 
00163         {
00164             // Look for uniform (non-sampler) parameters only
00165             // Don't bother enumerating unused parameters, especially since they will
00166             // be optimised out and therefore not in the indexed versions
00167             CGtype paramType = cgGetParameterType(parameter);
00168             
00169             // *** test
00170             //String tempName = cgGetParameterName(parameter);
00171             //size_t tempindex = cgGetParameterResourceIndex(parameter);
00172             //LogManager::getSingleton().logMessage(
00173             //    tempName + " -> " + StringConverter::toString(tempindex));
00174 
00175             // *** end test
00176 
00177             if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
00178                 paramType != CG_SAMPLER1D &&
00179                 paramType != CG_SAMPLER2D &&
00180                 paramType != CG_SAMPLER3D &&
00181                 paramType != CG_SAMPLERCUBE &&
00182                 paramType != CG_SAMPLERRECT &&
00183                 cgGetParameterDirection(parameter) != CG_OUT && 
00184                 cgIsParameterReferenced(parameter))
00185             {
00186                 String paramName = cgGetParameterName(parameter);
00187                 size_t index = cgGetParameterResourceIndex(parameter);
00188 
00189                 // Get the parameter resource, so we know what type we're dealing with
00190                 CGresource res = cgGetParameterResource(parameter);
00191                 switch (res)
00192                 {
00193                 case CG_COMBINER_STAGE_CONST0:
00194                     // register combiner, const 0
00195                     // the index relates to the texture stage; store this as (stage * 2) + 0
00196                     index = index * 2;
00197                     break;
00198                 case CG_COMBINER_STAGE_CONST1:
00199                     // register combiner, const 1
00200                     // the index relates to the texture stage; store this as (stage * 2) + 1
00201                     index = (index * 2) + 1;
00202                     break;
00203                 default:
00204                     // do nothing, normal constant
00205                     break;
00206                 };
00207                 params->_mapParameterNameToIndex(paramName, index);
00208             }
00209             // Get next
00210             parameter = cgGetNextLeafParameter(parameter);
00211         }
00212 
00213         
00214     }
00215     //-----------------------------------------------------------------------
00216     CgProgram::CgProgram(const String& name, GpuProgramType gpType, 
00217         const String& language, CGcontext context)
00218         : HighLevelGpuProgram(name, gpType, language), mCgContext(context), 
00219         mCgProgram(0), mSelectedCgProfile(CG_PROFILE_UNKNOWN), mCgArguments(0)
00220     {
00221         if (createParamDictionary("CgProgram"))
00222         {
00223             ParamDictionary* dict = getParamDictionary();
00224 
00225             dict->addParameter(ParameterDef("entry_point", 
00226                 "The entry point for the Cg program.",
00227                 PT_STRING),&msCmdEntryPoint);
00228             dict->addParameter(ParameterDef("profiles", 
00229                 "Space-separated list of Cg profiles supported by this profile.",
00230                 PT_STRING),&msCmdProfiles);
00231             dict->addParameter(ParameterDef("compile_arguments", 
00232                 "A string of compilation arguments to pass to the Cg compiler.",
00233                 PT_STRING),&msCmdArgs);
00234         }
00235         
00236     }
00237     //-----------------------------------------------------------------------
00238     CgProgram::~CgProgram()
00239     {
00240         freeCgArgs();
00241         // unload will be called by superclass
00242     }
00243     //-----------------------------------------------------------------------
00244     bool CgProgram::isSupported(void) const
00245     {
00246         StringVector::const_iterator i, iend;
00247         iend = mProfiles.end();
00248         // Check to see if any of the profiles are supported
00249         for (i = mProfiles.begin(); i != iend; ++i)
00250         {
00251             if (GpuProgramManager::getSingleton().isSyntaxSupported(*i))
00252             {
00253                 return true;
00254             }
00255         }
00256         return false;
00257 
00258     }
00259     //-----------------------------------------------------------------------
00260     void CgProgram::setProfiles(const StringVector& profiles)
00261     {
00262         mProfiles.clear();
00263         StringVector::const_iterator i, iend;
00264         iend = profiles.end();
00265         for (i = profiles.begin(); i != iend; ++i)
00266         {
00267             mProfiles.push_back(*i);
00268         }
00269     }
00270     //-----------------------------------------------------------------------
00271     //-----------------------------------------------------------------------
00272     String CgProgram::CmdEntryPoint::doGet(const void *target) const
00273     {
00274         return static_cast<const CgProgram*>(target)->getEntryPoint();
00275     }
00276     void CgProgram::CmdEntryPoint::doSet(void *target, const String& val)
00277     {
00278         static_cast<CgProgram*>(target)->setEntryPoint(val);
00279     }
00280     //-----------------------------------------------------------------------
00281     String CgProgram::CmdProfiles::doGet(const void *target) const
00282     {
00283         return StringConverter::toString(
00284             static_cast<const CgProgram*>(target)->getProfiles() );
00285     }
00286     void CgProgram::CmdProfiles::doSet(void *target, const String& val)
00287     {
00288         static_cast<CgProgram*>(target)->setProfiles(val.split());
00289     }
00290     //-----------------------------------------------------------------------
00291     String CgProgram::CmdArgs::doGet(const void *target) const
00292     {
00293         return static_cast<const CgProgram*>(target)->getCompileArguments();
00294     }
00295     void CgProgram::CmdArgs::doSet(void *target, const String& val)
00296     {
00297         static_cast<CgProgram*>(target)->setCompileArguments(val);
00298     }
00299 
00300 }

Copyright © 2002-2003 by The OGRE Team
Last modified Wed Jan 21 00:10:04 2004