//-----------------------------------------------------------------------
    void UnifiedHighLevelGpuProgram::chooseDelegate() const
    {
        OGRE_LOCK_AUTO_MUTEX;

        mChosenDelegate.setNull();

        HighLevelGpuProgramPtr tmpDelegate;
        tmpDelegate.setNull();
        int tmpPriority = -1;

        for (StringVector::const_iterator i = mDelegateNames.begin(); i != mDelegateNames.end(); ++i)
        {
            HighLevelGpuProgramPtr deleg = HighLevelGpuProgramManager::getSingleton().getByName(*i, mGroup);

            //recheck with auto resource group
            if (deleg.isNull())
              deleg = HighLevelGpuProgramManager::getSingleton().getByName(*i);

            // Silently ignore missing links
            if(!deleg.isNull() && deleg->isSupported())
            {
                int priority = getPriority(deleg->getLanguage());
                //Find the delegate with the highest prioriry
                if (priority >= tmpPriority)
                {
                    tmpDelegate = deleg;
                    tmpPriority = priority;
                }
            }

        }

        mChosenDelegate = tmpDelegate;
    }
Exemplo n.º 2
0
	//-----------------------------------------------------------------------------------
	GpuProgramPtr ShaderManager::createGpuProgram(const String& name, const String& code, HlmsDatablock* dataBlock)
	{
		HighLevelGpuProgramPtr gpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(name,
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, dataBlock->getLanguage(), dataBlock->getShaderType());

		gpuProgram->setParameter("entry_point", "main");

		gpuProgram->setSource(code);

		if (dataBlock->getLanguage() == "hlsl")
		{
			// HLSL program requires specific target profile settings - we have to split the profile string.
			const StringVector& profilesList = dataBlock->getProfileList();
			StringVector::const_iterator it = profilesList.begin();
			StringVector::const_iterator itEnd = profilesList.end();

			for (; it != itEnd; ++it)
			{
				if (GpuProgramManager::getSingleton().isSyntaxSupported(*it))
				{
					gpuProgram->setParameter("target", *it);
					break;
				}
			}
		}
		
		gpuProgram->load();

		// Case an error occurred.
		if (gpuProgram->hasCompileError())
		{
			gpuProgram.setNull();
			return GpuProgramPtr(gpuProgram);
		}

		return gpuProgram;
	}
//-----------------------------------------------------------------------------
GpuProgramPtr ProgramManager::createGpuProgram(Program* shaderProgram, 
											   ProgramWriter* programWriter,
											   const String& language,
											   const String& profiles,
											   const StringVector& profilesList,
											   const String& cachePath)
{

	
#if OGRE_PLATFORM == OGRE_PLATFORM_ANDROID
	Ogre::StringSerialiser sourceCodeStringStream;
#else
	std::stringstream sourceCodeStringStream;
#endif
	_StringHash stringHash;
	uint32 programHashCode;
	String programName;

	// Generate source code.
	programWriter->writeSourceCode(sourceCodeStringStream, shaderProgram);

	// Generate program hash code.
	programHashCode = static_cast<uint32>(stringHash(sourceCodeStringStream.str()));

	// Generate program name.
	programName = StringConverter::toString(programHashCode);
	
	if (shaderProgram->getType() == GPT_VERTEX_PROGRAM)
	{
		programName += "_VS";
	}
	else if (shaderProgram->getType() == GPT_FRAGMENT_PROGRAM)
	{
		programName += "_FS";
	}

	HighLevelGpuProgramPtr pGpuProgram;

	// Try to get program by name.
	pGpuProgram = HighLevelGpuProgramManager::getSingleton().getByName(programName);

	// Case the program doesn't exist yet.
	if (pGpuProgram.isNull())
	{
		// Create new GPU program.
		pGpuProgram = HighLevelGpuProgramManager::getSingleton().createProgram(programName,
			ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, language, shaderProgram->getType());

		// Case cache directory specified -> create program from file.
		if (cachePath.empty() == false)
		{
			const String  programFullName = programName + "." + language;
			const String  programFileName = cachePath + programFullName;	
			std::ifstream programFile;
			bool		  writeFile = true;


			// Check if program file already exist.
			programFile.open(programFileName.c_str());

			// Case no matching file found -> we have to write it.
			if (!programFile)
			{			
				writeFile = true;
			}
			else
			{
				writeFile = false;
				programFile.close();
			}

			// Case we have to write the program to a file.
			if (writeFile)
			{
				std::ofstream outFile(programFileName.c_str());

				if (!outFile)
					return GpuProgramPtr();

				outFile << sourceCodeStringStream.str();
				outFile.close();
			}

			pGpuProgram->setSourceFile(programFullName);
		}

		// No cache directory specified -> create program from system memory.
		else
		{
			pGpuProgram->setSource(sourceCodeStringStream.str());
		}
		
		
		pGpuProgram->setParameter("entry_point", shaderProgram->getEntryPointFunction()->getName());

		// HLSL program requires specific target profile settings - we have to split the profile string.
		if (language == "hlsl")
		{
			StringVector::const_iterator it = profilesList.begin();
			StringVector::const_iterator itEnd = profilesList.end();
			
			for (; it != itEnd; ++it)
			{
				if (GpuProgramManager::getSingleton().isSyntaxSupported(*it))
				{
					pGpuProgram->setParameter("target", *it);
					break;
				}
			}
		}
		
		pGpuProgram->setParameter("profiles", profiles);
		pGpuProgram->load();
	
		// Case an error occurred.
		if (pGpuProgram->hasCompileError())
		{
			pGpuProgram.setNull();
			return GpuProgramPtr(pGpuProgram);
		}

		// Add the created GPU program to local cache.
		if (pGpuProgram->getType() == GPT_VERTEX_PROGRAM)
		{
			mVertexShaderMap[programName] = pGpuProgram;			
		}
		else if (pGpuProgram->getType() == GPT_FRAGMENT_PROGRAM)
		{
			mFragmentShaderMap[programName] = pGpuProgram;	
		}				
	}
	
	return GpuProgramPtr(pGpuProgram);
}
Exemplo n.º 4
0
	//-----------------------------------------------------------------------------------
	Ogre::GpuProgramPtr ShaderManager::getGpuProgram(HlmsDatablock* dataBlock)
	{
		Ogre::uint32 hash = dataBlock->getHash();

		std::map<Ogre::uint32, Ogre::GpuProgramPtr>::iterator it = mShaderCache.find(hash);
		if (it != mShaderCache.end())
		{
			return (*it).second;
		}
		else
		{
			Ogre::String typeStr = FilePatterns[dataBlock->getShaderType()];

			std::stringstream sstream;
			sstream << std::hex << hash;
			std::string hashString = sstream.str();

			Ogre::String name = hashString + typeStr;

			// generate the shader code
			Ogre::String code = dataBlock->getTemplate()->getTemplate();
			code = ShaderGenerator::parse(code, *(dataBlock->getPropertyMap()), mShaderPiecesManager->getPieces(dataBlock->getLanguarge(), dataBlock->getShaderType()));

			HighLevelGpuProgramPtr gpuProgram = Ogre::HighLevelGpuProgramManager::getSingleton().createProgram(name,
				Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, dataBlock->getLanguarge(), dataBlock->getShaderType());

			gpuProgram->setSource(code);
			gpuProgram->setParameter("entry_point", "main");

			if (dataBlock->getLanguarge() == "hlsl")
			{
				// HLSL program requires specific target profile settings - we have to split the profile string.
				const Ogre::StringVector& profilesList = dataBlock->getProfileList();
				Ogre::StringVector::const_iterator it = profilesList.begin();
				Ogre::StringVector::const_iterator itEnd = profilesList.end();

				for (; it != itEnd; ++it)
				{
					if (Ogre::GpuProgramManager::getSingleton().isSyntaxSupported(*it))
					{
						gpuProgram->setParameter("target", *it);
						break;
					}
				}

				//gpuProgram->setParameter("enable_backwards_compatibility", "false");
				//gpuProgram->setParameter("column_major_matrices", Ogre::StringConverter::toString(shaderProgram->getUseColumnMajorMatrices()));
			}

			//gpuProgram->setParameter("profiles", profiles);
			gpuProgram->load();

			// Case an error occurred.
			if (gpuProgram->hasCompileError())
			{
				gpuProgram.setNull();
				return Ogre::GpuProgramPtr(gpuProgram);
			}

			mShaderCache[hash] = gpuProgram;

			return gpuProgram;
		}

	}