示例#1
0
    void GLSLProgram::getMicrocodeFromCache(uint32 id)
    {
        GpuProgramManager::Microcode cacheMicrocode =
            GpuProgramManager::getSingleton().getMicrocodeFromCache(id);

        cacheMicrocode->seek(0);

        // Turns out we need this param when loading.
        GLenum binaryFormat = 0;
        cacheMicrocode->read(&binaryFormat, sizeof(GLenum));

        // Get size of binary.
        GLint binaryLength = static_cast<GLint>(cacheMicrocode->size() - sizeof(GLenum));

        // Load binary.
        OGRE_CHECK_GL_ERROR(glProgramBinary(mGLProgramHandle,
                                            binaryFormat,
                                            cacheMicrocode->getCurrentPtr(),
                                            binaryLength));

        GLint success = 0;
        OGRE_CHECK_GL_ERROR(glGetProgramiv(mGLProgramHandle, GL_LINK_STATUS, &success));

        if(success)
        {
            mLinked = true;
            return;
        }

        logObjectInfo("could not load from cache "+getCombinedName(), mGLProgramHandle);
        // Something must have changed since the program binaries
        // were cached away. Fallback to source shader loading path,
        // and then retrieve and cache new program binaries once again.
        compileAndLink();
    }
    //-----------------------------------------------------------------------
	void GLSLESProgramCommon::getMicrocodeFromCache(void)
	{
		GpuProgramManager::Microcode cacheMicrocode =
            GpuProgramManager::getSingleton().getMicrocodeFromCache(getCombinedName());

		// add to the microcode to the cache
		String name;
		name = getCombinedName();

		// turns out we need this param when loading
		GLenum binaryFormat = 0;

		cacheMicrocode->seek(0);

		// get size of binary
		cacheMicrocode->read(&binaryFormat, sizeof(GLenum));

        if(getGLES2SupportRef()->checkExtension("GL_OES_get_program_binary") || gleswIsSupported(3, 0))
        {
            GLint binaryLength = static_cast<GLint>(cacheMicrocode->size() - sizeof(GLenum));

            // load binary
            OGRE_CHECK_GL_ERROR(glProgramBinaryOES(mGLProgramHandle,
                               binaryFormat, 
                               cacheMicrocode->getPtr(),
                               binaryLength));
        }

		GLint success = 0;
		OGRE_CHECK_GL_ERROR(glGetProgramiv(mGLProgramHandle, GL_LINK_STATUS, &success));
		if (!success)
		{
			//
			// Something must have changed since the program binaries
			// were cached away.  Fallback to source shader loading path,
			// and then retrieve and cache new program binaries once again.
			//
			compileAndLink();
		}
	}
示例#3
0
	//-----------------------------------------------------------------------
	void CgProgram::addMicrocodeToCache()
	{
		String name = String("CG_") + mName;
		size_t programStringSize = mProgramString.size();
		uint32 sizeOfMicrocode = static_cast<uint32>(
													 sizeof(size_t) +   // size of mProgramString
													 programStringSize + // microcode - mProgramString
													 sizeof(size_t) + // size of param map
													 mParametersMapSizeAsBuffer);

		// create microcode
		GpuProgramManager::Microcode newMicrocode = 
			GpuProgramManager::getSingleton().createMicrocode(sizeOfMicrocode);

		newMicrocode->seek(0);

		// save size of string
		newMicrocode->write(&programStringSize, sizeof(size_t));

		// save microcode
		newMicrocode->write(&mProgramString[0], programStringSize);

		// save size of param map
		size_t parametersMapSize = mParametersMap.size();
		newMicrocode->write(&parametersMapSize, sizeof(size_t));

		// save params
		GpuConstantDefinitionMap::const_iterator iter = mParametersMap.begin();
		GpuConstantDefinitionMap::const_iterator iterE = mParametersMap.end();
		for (; iter != iterE ; iter++)
		{
			const String & paramName = iter->first;
			const GpuConstantDefinition & def = iter->second;

			// save string size
			size_t stringSize = paramName.size();
			newMicrocode->write(&stringSize, sizeof(size_t));

			// save string
			newMicrocode->write(&paramName[0], stringSize);

			// save def
			newMicrocode->write(&def, sizeof(GpuConstantDefinition));
		}

		if (mDelegate)
		{
			// save additional info required for delegating
			size_t samplerMapSize = mSamplerRegisterMap.size();
			newMicrocode->write(&samplerMapSize, sizeof(size_t));

			// save sampler register mapping
			map<String,int>::type::const_iterator sampRegister = mSamplerRegisterMap.begin();
			map<String,int>::type::const_iterator sampRegisterE = mSamplerRegisterMap.end();
			for (; sampRegister != sampRegisterE; ++sampRegister)
			{
				const String& paramName = sampRegister->first;
				int reg = sampRegister->second;

				size_t stringSize = paramName.size();
				newMicrocode->write(&stringSize, sizeof(size_t));
				newMicrocode->write(paramName.data(), stringSize);
				newMicrocode->write(&reg, sizeof(int));
			}

			// save input/output operations type
			newMicrocode->write(&mInputOp, sizeof(CGenum));
			newMicrocode->write(&mOutputOp, sizeof(CGenum));
		}

		// add to the microcode to the cache
		GpuProgramManager::getSingleton().addMicrocodeToCache(name, newMicrocode);
	}
示例#4
0
	//-----------------------------------------------------------------------
	void CgProgram::getMicrocodeFromCache(void)
	{
		GpuProgramManager::Microcode cacheMicrocode = 
			GpuProgramManager::getSingleton().getMicrocodeFromCache(String("CG_") + mName);
		
		cacheMicrocode->seek(0);

		// get size of string
		size_t programStringSize = 0;
		cacheMicrocode->read(&programStringSize, sizeof(size_t));

		// get microcode
		mProgramString.resize(programStringSize);
		cacheMicrocode->read(&mProgramString[0], programStringSize);

		// get size of param map
		size_t parametersMapSize = 0;
		cacheMicrocode->read(&parametersMapSize, sizeof(size_t));
				
		// get params
		for(size_t i = 0 ; i < parametersMapSize ; i++)
		{
			String paramName;
			size_t stringSize = 0;
			GpuConstantDefinition def;
			
			// get string size
			cacheMicrocode->read(&stringSize, sizeof(size_t));

			// get string
			paramName.resize(stringSize);
			cacheMicrocode->read(&paramName[0], stringSize);
		
			// get def
			cacheMicrocode->read( &def, sizeof(GpuConstantDefinition));

			mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def));
		}

		if (mDelegate)
		{
			// get sampler register mapping
			size_t samplerMapSize = 0;
			cacheMicrocode->read(&samplerMapSize, sizeof(size_t));
			for (size_t i = 0; i < samplerMapSize; ++i)
			{
				String paramName;
				size_t stringSize = 0;
				int reg = -1;

				cacheMicrocode->read(&stringSize, sizeof(size_t));
				paramName.resize(stringSize);
				cacheMicrocode->read(&paramName[0], stringSize);
				cacheMicrocode->read(&reg, sizeof(int));
			}

			// get input/output operations type
			cacheMicrocode->read(&mInputOp, sizeof(CGenum));
			cacheMicrocode->read(&mOutputOp, sizeof(CGenum));
		}

	}
    void GLSLSeparableProgram::loadIndividualProgram(GLSLShader *program)
    {
        if (program && !program->isLinked())
        {
            GLint linkStatus = 0;

            String programName = program->getName();

            GLuint programHandle = program->getGLProgramHandle();

            OGRE_CHECK_GL_ERROR(glProgramParameteri(programHandle, GL_PROGRAM_SEPARABLE, GL_TRUE));
            //if (GpuProgramManager::getSingleton().getSaveMicrocodesToCache())
            OGRE_CHECK_GL_ERROR(glProgramParameteri(programHandle, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE));

            // Use precompiled program if possible.
            bool microcodeAvailableInCache = GpuProgramManager::getSingleton().isMicrocodeAvailableInCache(programName);
            if (microcodeAvailableInCache)
            {
                GpuProgramManager::Microcode cacheMicrocode =
                    GpuProgramManager::getSingleton().getMicrocodeFromCache(programName);
                cacheMicrocode->seek(0);

                GLenum binaryFormat = 0;
                cacheMicrocode->read(&binaryFormat, sizeof(GLenum));

                GLint binaryLength = cacheMicrocode->size() - sizeof(GLenum);

                OGRE_CHECK_GL_ERROR(glProgramBinary(programHandle,
                                                    binaryFormat,
                                                    cacheMicrocode->getPtr() + sizeof(GLenum),
                                                    binaryLength));

                OGRE_CHECK_GL_ERROR(glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus));
                if (!linkStatus)
                    logObjectInfo("Could not use cached binary " + programName, programHandle);
            }

            // Compilation needed if precompiled program is
            // unavailable or failed to link.
            if (!linkStatus)
            {
                try
                {
                    program->compile(true);
                }
                catch (Exception& e)
                {
                    LogManager::getSingleton().stream() << e.getDescription();
                    mTriedToLinkAndFailed = true;
                    return;
                }

                program->attachToProgramObject(programHandle);
                OGRE_CHECK_GL_ERROR(glLinkProgram(programHandle));
                OGRE_CHECK_GL_ERROR(glGetProgramiv(programHandle, GL_LINK_STATUS, &linkStatus));

                // Binary cache needs an update.
                microcodeAvailableInCache = false;
            }

            program->setLinked(linkStatus);
            mLinked = linkStatus;

            mTriedToLinkAndFailed = !linkStatus;

            logObjectInfo( getCombinedName() + String("GLSL program result : "), programHandle );

            if (program->getType() == GPT_VERTEX_PROGRAM)
                setSkeletalAnimationIncluded(program->isSkeletalAnimationIncluded());

            // Add the microcode to the cache.
            if (!microcodeAvailableInCache && mLinked &&
                GpuProgramManager::getSingleton().getSaveMicrocodesToCache() )
            {
                // Get buffer size.
                GLint binaryLength = 0;

                OGRE_CHECK_GL_ERROR(glGetProgramiv(programHandle, GL_PROGRAM_BINARY_LENGTH, &binaryLength));

                // Create microcode.
                GpuProgramManager::Microcode newMicrocode =
                    GpuProgramManager::getSingleton().createMicrocode((unsigned long)binaryLength + sizeof(GLenum));

                // Get binary.
                OGRE_CHECK_GL_ERROR(glGetProgramBinary(programHandle, binaryLength, NULL, (GLenum *)newMicrocode->getPtr(), newMicrocode->getPtr() + sizeof(GLenum)));

                // std::vector<uchar> buffer(binaryLength);
                // GLenum format(0);
                // OGRE_CHECK_GL_ERROR(glGetProgramBinary(programHandle, binaryLength, NULL, &format, &buffer[0]));

                // GLenum binaryFormat = 0;
                // std::vector<uchar> binaryData(binaryLength);
                // newMicrocode->read(&binaryFormat, sizeof(GLenum));
                // newMicrocode->read(&binaryData[0], binaryLength);

                GpuProgramManager::getSingleton().addMicrocodeToCache(programName, newMicrocode);
            }
        }
    }