예제 #1
0
    //-----------------------------------------------------------------------
    void CgProgram::buildConstantDefinitions() const
    {
        // Derive parameter names from Cg
		createParameterMappingStructures(true);

		if (!mCgProgram)
			return;

		recurseParams(cgGetFirstParameter(mCgProgram, CG_PROGRAM));
        recurseParams(cgGetFirstParameter(mCgProgram, CG_GLOBAL));
	}
예제 #2
0
    //-----------------------------------------------------------------------
    void CgProgram::buildConstantDefinitions() const
    {
        // Derive parameter names from Cg

		mFloatLogicalToPhysical.bufferSize = 0;
		mIntLogicalToPhysical.bufferSize = 0;
		mConstantDefs.floatBufferSize = 0;
		mConstantDefs.intBufferSize = 0;

		if (!mCgProgram)
			return;

		recurseParams(cgGetFirstParameter(mCgProgram, CG_PROGRAM));
        recurseParams(cgGetFirstParameter(mCgProgram, CG_GLOBAL));
	}
예제 #3
0
	//---------------------------------------------------------------------
	void CgProgram::recurseParams(CGparameter parameter, size_t contextArraySize)
	{
		while (parameter != 0)
		{
			// Look for uniform parameters only
			// Don't bother enumerating unused parameters, especially since they will
			// be optimised out and therefore not in the indexed versions
			CGtype paramType = cgGetParameterType(parameter);

			if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
				paramType != CG_SAMPLER1D &&
				paramType != CG_SAMPLER2D &&
				paramType != CG_SAMPLER3D &&
				paramType != CG_SAMPLERCUBE &&
				paramType != CG_SAMPLERRECT &&
				cgGetParameterDirection(parameter) != CG_OUT && 
				cgIsParameterReferenced(parameter))
			{
				int arraySize;

				switch(paramType)
				{
				case CG_STRUCT:
					recurseParams(cgGetFirstStructParameter(parameter));
					break;
				case CG_ARRAY:
					// Support only 1-dimensional arrays
					arraySize = cgGetArraySize(parameter, 0);
					recurseParams(cgGetArrayParameter(parameter, 0), (size_t)arraySize);
					break;
				default:
					// Normal path (leaf)
					String paramName = cgGetParameterName(parameter);
					size_t logicalIndex = cgGetParameterResourceIndex(parameter);

					// Get the parameter resource, to calculate the physical index
					CGresource res = cgGetParameterResource(parameter);
					bool isRegisterCombiner = false;
					size_t regCombinerPhysicalIndex = 0;
					switch (res)
					{
					case CG_COMBINER_STAGE_CONST0:
						// register combiner, const 0
						// the index relates to the texture stage; store this as (stage * 2) + 0
						regCombinerPhysicalIndex = logicalIndex * 2;
						isRegisterCombiner = true;
						break;
					case CG_COMBINER_STAGE_CONST1:
						// register combiner, const 1
						// the index relates to the texture stage; store this as (stage * 2) + 1
						regCombinerPhysicalIndex = (logicalIndex * 2) + 1;
						isRegisterCombiner = true;
						break;
					default:
						// normal constant
						break;
					}

					// Trim the '[0]' suffix if it exists, we will add our own indexing later
					if (StringUtil::endsWith(paramName, "[0]", false))
					{
						paramName.erase(paramName.size() - 3);
					}


					GpuConstantDefinition def;
					def.arraySize = contextArraySize;
					mapTypeAndElementSize(paramType, isRegisterCombiner, def);

					if (def.constType == GCT_UNKNOWN)
					{
						LogManager::getSingleton().logMessage(
							"Problem parsing the following Cg Uniform: '"
							+ paramName + "' in file " + mName);
						// next uniform
						parameter = cgGetNextParameter(parameter);
						continue;
					}
					if (isRegisterCombiner)
					{
						def.physicalIndex = regCombinerPhysicalIndex;
					}
					else
					{
						// base position on existing buffer contents
						if (def.isFloat())
						{
							def.physicalIndex = mFloatLogicalToPhysical->bufferSize;
						}
						else
						{
							def.physicalIndex = mIntLogicalToPhysical->bufferSize;
						}
					}

					def.logicalIndex = logicalIndex;
					if( mParametersMap.find(paramName) == mParametersMap.end())
					{
						mParametersMap.insert(GpuConstantDefinitionMap::value_type(paramName, def));
						mParametersMapSizeAsBuffer += sizeof(size_t);
						mParametersMapSizeAsBuffer += paramName.size();
						mParametersMapSizeAsBuffer += sizeof(GpuConstantDefinition);
					}

					// Record logical / physical mapping
					if (def.isFloat())
					{
											OGRE_LOCK_MUTEX(mFloatLogicalToPhysical->mutex);
						mFloatLogicalToPhysical->map.insert(
							GpuLogicalIndexUseMap::value_type(def.logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
						mFloatLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
					}
					else
					{
											OGRE_LOCK_MUTEX(mIntLogicalToPhysical->mutex);
						mIntLogicalToPhysical->map.insert(
							GpuLogicalIndexUseMap::value_type(def.logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize, GPV_GLOBAL)));
						mIntLogicalToPhysical->bufferSize += def.arraySize * def.elementSize;
					}

					break;
				}                   
			}

			// now handle uniform samplers. This is needed to fix their register positions
			// if delegating to a GLSL shader.
			if (mDelegate && cgGetParameterVariability(parameter) == CG_UNIFORM && (
				paramType == CG_SAMPLER1D ||
				paramType == CG_SAMPLER2D ||
				paramType == CG_SAMPLER3D ||
				paramType == CG_SAMPLERCUBE ||
				paramType == CG_SAMPLERRECT) &&
				cgGetParameterDirection(parameter) != CG_OUT && 
				cgIsParameterReferenced(parameter))
			{
				String paramName = cgGetParameterName(parameter);
				CGresource res = cgGetParameterResource(parameter);
				int pos = -1;
				switch (res)
				{
				case CG_TEXUNIT0: pos = 0; break;
				case CG_TEXUNIT1: pos = 1; break;
				case CG_TEXUNIT2: pos = 2; break;
				case CG_TEXUNIT3: pos = 3; break;
				case CG_TEXUNIT4: pos = 4; break;
				case CG_TEXUNIT5: pos = 5; break;
				case CG_TEXUNIT6: pos = 6; break;
				case CG_TEXUNIT7: pos = 7; break;
				case CG_TEXUNIT8: pos = 8; break;
				case CG_TEXUNIT9: pos = 9; break;
				case CG_TEXUNIT10: pos = 10; break;
				case CG_TEXUNIT11: pos = 11; break;
				case CG_TEXUNIT12: pos = 12; break;
				case CG_TEXUNIT13: pos = 13; break;
				case CG_TEXUNIT14: pos = 14; break;
				case CG_TEXUNIT15: pos = 15; break;
#if(CG_VERSION_NUM >= 3000)
				case CG_TEXUNIT16: pos = 16; break;
				case CG_TEXUNIT17: pos = 17; break;
				case CG_TEXUNIT18: pos = 18; break;
				case CG_TEXUNIT19: pos = 19; break;
				case CG_TEXUNIT20: pos = 20; break;
				case CG_TEXUNIT21: pos = 21; break;
				case CG_TEXUNIT22: pos = 22; break;
				case CG_TEXUNIT23: pos = 23; break;
				case CG_TEXUNIT24: pos = 24; break;
				case CG_TEXUNIT25: pos = 25; break;
				case CG_TEXUNIT26: pos = 26; break;
				case CG_TEXUNIT27: pos = 27; break;
				case CG_TEXUNIT28: pos = 28; break;
				case CG_TEXUNIT29: pos = 29; break;
				case CG_TEXUNIT30: pos = 30; break;
				case CG_TEXUNIT31: pos = 31; break;
#endif
				default:
					break;
				}
				if (pos != -1)
				{
					mSamplerRegisterMap.insert(std::make_pair(paramName, pos));
				}
			}

			// Get next
			parameter = cgGetNextParameter(parameter);
		}

		
	}
예제 #4
0
	//-----------------------------------------------------------------------
	void CgProgram::compileMicrocode(void)
	{
		// Create Cg Program
  
		/// Program handle
		CGprogram cgProgram;

		if (mSelectedCgProfile == CG_PROFILE_UNKNOWN)
		{
			LogManager::getSingleton().logMessage(
				"Attempted to load Cg program '" + mName + "', but no supported "
				"profile was found. ");
			return;
		}
		buildArgs();
		// deal with includes
		String sourceToUse = resolveCgIncludes(mSource, this, mFilename);

		cgProgram = cgCreateProgram(mCgContext, CG_SOURCE, sourceToUse.c_str(), 
			mSelectedCgProfile, mEntryPoint.c_str(), const_cast<const char**>(mCgArguments));

		// Test
		//LogManager::getSingleton().logMessage(cgGetProgramString(mCgProgram, CG_COMPILED_PROGRAM));

		// Check for errors
		checkForCgError("CgProgram::compileMicrocode", 
			"Unable to compile Cg program " + mName + ": ", mCgContext);

		CGerror error = cgGetError();
		if (error == CG_NO_ERROR)
		{
			// get program string (result of cg compile)
			mProgramString = cgGetProgramString(cgProgram, CG_COMPILED_PROGRAM);
			checkForCgError("CgProgram::compileMicrocode",
				"Unable to retrieve program code for Cg program " + mName + ": ", mCgContext);

			// get params
			mParametersMap.clear();
			mParametersMapSizeAsBuffer = 0;
			mSamplerRegisterMap.clear();
			recurseParams(cgGetFirstParameter(cgProgram, CG_PROGRAM));
			recurseParams(cgGetFirstParameter(cgProgram, CG_GLOBAL));

			if (mDelegate)
			{
				// Delegating to HLSL or GLSL, need to clean up Cg's output
				fixHighLevelOutput(mProgramString);
				if (mSelectedCgProfile == CG_PROFILE_GLSLG)
				{
					// need to determine input and output operations
					mInputOp = cgGetProgramInput(cgProgram);
					mOutputOp = cgGetProgramOutput(cgProgram);
				}
			}

			// Unload Cg Program - we don't need it anymore
			cgDestroyProgram(cgProgram);
			//checkForCgError("CgProgram::unloadImpl", 
			//  "Error while unloading Cg program " + mName + ": ", 
			//  mCgContext);
			cgProgram = 0;

			if ( GpuProgramManager::getSingleton().getSaveMicrocodesToCache())
			{
				addMicrocodeToCache();
			}
		}


	}
예제 #5
0
	//---------------------------------------------------------------------
	void CgProgram::recurseParams(CGparameter parameter, size_t contextArraySize) const
	{
		while (parameter != 0)
        {
            // Look for uniform (non-sampler) parameters only
            // Don't bother enumerating unused parameters, especially since they will
            // be optimised out and therefore not in the indexed versions
            CGtype paramType = cgGetParameterType(parameter);

            if (cgGetParameterVariability(parameter) == CG_UNIFORM &&
                paramType != CG_SAMPLER1D &&
                paramType != CG_SAMPLER2D &&
                paramType != CG_SAMPLER3D &&
                paramType != CG_SAMPLERCUBE &&
                paramType != CG_SAMPLERRECT &&
                cgGetParameterDirection(parameter) != CG_OUT && 
                cgIsParameterReferenced(parameter))
            {
				int arraySize;

				switch(paramType)
				{
				case CG_STRUCT:
					recurseParams(cgGetFirstStructParameter(parameter));
					break;
				case CG_ARRAY:
					// Support only 1-dimensional arrays
					arraySize = cgGetArraySize(parameter, 0);
					recurseParams(cgGetArrayParameter(parameter, 0), (size_t)arraySize);
					break;
				default:
					// Normal path (leaf)
					String paramName = cgGetParameterName(parameter);
					size_t logicalIndex = cgGetParameterResourceIndex(parameter);

					// Get the parameter resource, to calculate the physical index
					CGresource res = cgGetParameterResource(parameter);
					bool isRegisterCombiner = false;
					size_t regCombinerPhysicalIndex = 0;
					switch (res)
					{
					case CG_COMBINER_STAGE_CONST0:
						// register combiner, const 0
						// the index relates to the texture stage; store this as (stage * 2) + 0
						regCombinerPhysicalIndex = logicalIndex * 2;
						isRegisterCombiner = true;
						break;
					case CG_COMBINER_STAGE_CONST1:
						// register combiner, const 1
						// the index relates to the texture stage; store this as (stage * 2) + 1
						regCombinerPhysicalIndex = (logicalIndex * 2) + 1;
						isRegisterCombiner = true;
						break;
					default:
						// normal constant
						break;
					}

					// Trim the '[0]' suffix if it exists, we will add our own indexing later
					if (StringUtil::endsWith(paramName, "[0]", false))
					{
						paramName.erase(paramName.size() - 3);
					}


					GpuConstantDefinition def;
					def.arraySize = contextArraySize;
					mapTypeAndElementSize(paramType, isRegisterCombiner, def);

					if (def.constType == GCT_UNKNOWN)
					{
						LogManager::getSingleton().logMessage(
							"Problem parsing the following Cg Uniform: '"
							+ paramName + "' in file " + mName);
						// next uniform
						continue;
					}
					if (isRegisterCombiner)
					{
						def.physicalIndex = regCombinerPhysicalIndex;
					}
					else
					{
						// base position on existing buffer contents
						if (def.isFloat())
						{
							def.physicalIndex = mFloatLogicalToPhysical.bufferSize;
						}
						else
						{
							def.physicalIndex = mIntLogicalToPhysical.bufferSize;
						}
					}


					mConstantDefs.map.insert(GpuConstantDefinitionMap::value_type(paramName, def));

					// Record logical / physical mapping
					if (def.isFloat())
					{
						OGRE_LOCK_MUTEX(mFloatLogicalToPhysical.mutex)
						mFloatLogicalToPhysical.map.insert(
							GpuLogicalIndexUseMap::value_type(logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize)));
						mFloatLogicalToPhysical.bufferSize += def.arraySize * def.elementSize;
						mConstantDefs.floatBufferSize = mFloatLogicalToPhysical.bufferSize;
					}
					else
					{
						OGRE_LOCK_MUTEX(mIntLogicalToPhysical.mutex)
						mIntLogicalToPhysical.map.insert(
							GpuLogicalIndexUseMap::value_type(logicalIndex, 
								GpuLogicalIndexUse(def.physicalIndex, def.arraySize * def.elementSize)));
						mIntLogicalToPhysical.bufferSize += def.arraySize * def.elementSize;
						mConstantDefs.intBufferSize = mIntLogicalToPhysical.bufferSize;
					}

					// Deal with array indexing
					mConstantDefs.generateConstantDefinitionArrayEntries(paramName, def);

					break;
		
				}
					
            }
            // Get next
            parameter = cgGetNextParameter(parameter);
        }

        
    }