Пример #1
0
		protected void ProcessParamElement( D3D9.EffectHandle parent, string prefix, int index )
		{
			var constant = this.constTable.GetConstant( parent, index );

			// Since D3D HLSL doesn't deal with naming of array and struct parameters
			// automatically, we have to do it by hand
			var desc = this.constTable.GetConstantDescription( constant );

			var paramName = desc.Name;

			// trim the odd '$' which appears at the start of the names in HLSL
			if ( paramName.StartsWith( "$" ) )
			{
				paramName = paramName.Remove( 0, 1 );
			}

			// Also trim the '[0]' suffix if it exists, we will add our own indexing later
			if ( paramName.EndsWith( "[0]" ) )
			{
				paramName.Remove( paramName.Length - 3 );
			}

			if ( desc.Class == D3D9.ParameterClass.Struct )
			{
				// work out a new prefix for the nextest members if its an array, we need the index
				prefix += paramName + ".";
				// Cascade into struct
				for ( var i = 0; i < desc.StructMembers; ++i )
				{
					ProcessParamElement( constant, prefix, i );
				}
			}
			else
			{
				// process params
				if ( desc.Type == D3D9.ParameterType.Float || desc.Type == D3D9.ParameterType.Int ||
				     desc.Type == D3D9.ParameterType.Bool )
				{
					var paramIndex = desc.RegisterIndex;
					var name = prefix + paramName;

					var def = new GpuProgramParameters.GpuConstantDefinition();
					def.LogicalIndex = paramIndex;
					// populate type, array size & element size
					PopulateDef( desc, def );
					if ( def.IsFloat )
					{
						def.PhysicalIndex = floatLogicalToPhysical.BufferSize;
						lock ( floatLogicalToPhysical.Mutex )
						{
							floatLogicalToPhysical.Map.Add( paramIndex,
							                                new GpuProgramParameters.GpuLogicalIndexUse( def.PhysicalIndex,
							                                                                             def.ArraySize*def.ElementSize,
							                                                                             GpuProgramParameters.
							                                                                             	GpuParamVariability.Global ) );

							floatLogicalToPhysical.BufferSize += def.ArraySize*def.ElementSize;
							constantDefs.FloatBufferSize = floatLogicalToPhysical.BufferSize;
						}
					}
					else
					{
						def.PhysicalIndex = intLogicalToPhysical.BufferSize;
						lock ( intLogicalToPhysical.Mutex )
						{
							intLogicalToPhysical.Map.Add( paramIndex,
							                              new GpuProgramParameters.GpuLogicalIndexUse( def.PhysicalIndex,
							                                                                           def.ArraySize*def.ElementSize,
							                                                                           GpuProgramParameters.
							                                                                           	GpuParamVariability.Global ) );
							intLogicalToPhysical.BufferSize += def.ArraySize*def.ElementSize;
							constantDefs.IntBufferSize = intLogicalToPhysical.BufferSize;
						}
					}

					constantDefs.Map.Add( paramName.ToLower(), def );

					// Now deal with arrays
					constantDefs.GenerateConstantDefinitionArrayEntries( name, def );
				}
			}
		}
Пример #2
0
        protected void RecurseParams(IntPtr parameter, int contextArraySize = 1)
		{
			// loop through the rest of the params
			while ( parameter != IntPtr.Zero )
			{

				// get the type of this param up front
                var paramType = Cg.cgGetParameterType(parameter);

				// Look for uniform parameters only
				// Don't bother enumerating unused parameters, especially since they will
				// be optimized out and therefore not in the indexed versions
                if (Cg.cgIsParameterReferenced(parameter) != 0
                    && Cg.cgGetParameterVariability(parameter) == Cg.CG_UNIFORM
                    && Cg.cgGetParameterDirection(parameter) != Cg.CG_OUT
					&& paramType != Cg.CG_SAMPLER1D
					&& paramType != Cg.CG_SAMPLER2D
					&& paramType != Cg.CG_SAMPLER3D
					&& paramType != Cg.CG_SAMPLERCUBE
					&& paramType != Cg.CG_SAMPLERRECT )
                {

                    int arraySize;

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

                            // Get the parameter resource, to calculate the physical index
                            var res = Cg.cgGetParameterResource( parameter );
                            var isRegisterCombiner = false;
                            var regCombinerPhysicalIndex = 0;
                            switch ( res )
                            {
                                case Cg.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.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 ( paramName.EndsWith( "[0]" ) )
                            {
                                paramName.Remove( paramName.Length - 3 );
                            }


                            var def = new GpuProgramParameters.GpuConstantDefinition();
                            def.ArraySize = contextArraySize;
                            MapTypeAndElementSize( paramType, isRegisterCombiner, def );

                            if ( def.ConstantType == GpuProgramParameters.GpuConstantType.Unknown)
                            {
                                LogManager.Instance.Write(
                                    "Problem parsing the following Cg Uniform: '"
                                    + paramName + "' in file " + _name );
                                // next uniform
                                parameter = Cg.cgGetNextParameter( parameter );
                                continue;
                            }
                            if ( isRegisterCombiner )
                            {
                                def.PhysicalIndex = regCombinerPhysicalIndex;
                            }
                            else
                            {
                                // base position on existing buffer contents
                                if ( def.IsFloat )
                                {
                                    def.PhysicalIndex = floatLogicalToPhysical.BufferSize;
                                }
                                else
                                {
                                    def.PhysicalIndex = intLogicalToPhysical.BufferSize;
                                }
                            }

                            def.LogicalIndex = logicalIndex;

                            if ( !parametersMap.ContainsKey( paramName ) )
                            {
                                parametersMap.Add( paramName, def);
                                /*
                                mParametersMapSizeAsBuffer += sizeof ( size_t );
                                mParametersMapSizeAsBuffer += paramName.size();
                                mParametersMapSizeAsBuffer += sizeof ( GpuConstantDefinition );
                                 */
                            }

                            // Record logical / physical mapping
                            if ( def.IsFloat )
                            {
                                lock(floatLogicalToPhysical.Mutex)
                                {
                                    floatLogicalToPhysical.Map.Add( def.LogicalIndex,
                                                                    new GpuProgramParameters.GpuLogicalIndexUse(
                                                                        def.PhysicalIndex, def.ArraySize*def.ElementSize,
                                                                        GpuProgramParameters.GpuParamVariability.Global ) );

                                    floatLogicalToPhysical.BufferSize += def.ArraySize*def.ElementSize;
                                }
                            }
                            else
                            {
                                lock( intLogicalToPhysical.Mutex )
                                {
                                    intLogicalToPhysical.Map.Add(def.LogicalIndex,
                                                                    new GpuProgramParameters.GpuLogicalIndexUse(
                                                                        def.PhysicalIndex, def.ArraySize * def.ElementSize,
                                                                        GpuProgramParameters.GpuParamVariability.Global));

                                    intLogicalToPhysical.BufferSize += def.ArraySize * def.ElementSize;
                                }
                            }

                            break;
                    }
                }

			    // get the next param
				parameter = Cg.cgGetNextLeafParameter( parameter );
			}
		}
		/// <summary>
		///   Populate a list of uniforms based on GLSL ES source.
		/// </summary>
		/// <param name="src"> Reference to the source code </param>
		/// <param name="constantDefs"> The defs to populate (will not be cleared before adding, clear it yourself before calling this if that's what you want). </param>
		/// <param name="fileName"> The file name this came from, for logging errors </param>
		public void ExtractConstantDefs( string src, Axiom.Graphics.GpuProgramParameters.GpuNamedConstants constantDefs, string fileName )
		{
			// Parse the output string and collect all uniforms
			// NOTE this relies on the source already having been preprocessed
			// which is done in GLSLESProgram::loadFromSource
			string line;
			int currPos = src.IndexOf( "uniform" );
			while ( currPos != -1 )
			{
				var def = new GpuProgramParameters.GpuConstantDefinition();
				string paramName = string.Empty;

				//Now check for using the word 'uniform' in a larger string & ignore
				bool inLargerString = false;
				if ( currPos != 0 )
				{
					char prev = src[ currPos - 1 ];
					if ( prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n' && prev != ';' )
					{
						inLargerString = true;
					}
				}
				if ( !inLargerString && currPos + 7 < src.Length )
				{
					char next = src[ currPos + 7 ];
					if ( next != ' ' && next != '\t' && next != '\r' && next != '\n' )
					{
						inLargerString = true;
					}
				}

				//skip uniform 
				currPos += 7;

				if ( !inLargerString )
				{
					//find terminatiing semicolon
					int endPos = -1;
					for ( int i = 0; i < src.Length; i++ )
					{
						if ( src[ i ] == ';' )
						{
							endPos = i;
							break;
						}
					}
					if ( endPos == -1 )
					{
						//problem, missing semicolon, abort
						break;
					}
					line = src.Substring( currPos, endPos - currPos );

					//remove spaces before opening square braces, otherwise the following split() can split the line at inapppropriate
					//places (e.g. "vec3 sometihng [3]" won't work).

					for ( int sqp = line.IndexOf( "[" ); sqp != -1; sqp = line.IndexOf( " [" ) )
					{
						line.Remove( sqp, 1 );
					}
					string[] parts = line.Split( '\t', '\r', '\n' );

					foreach ( string i in parts )
					{
						//Is this a type
						if ( this.typeEnumMap.ContainsKey( i ) )
						{
							this.CompleteDefInfo( this.typeEnumMap[ i ], def );
						}
						else
						{
							//If this is not a type, and not empty, it should be a name
							string trim = i.Trim();
							if ( trim.Length == 0 )
							{
								continue;
							}

							//Skip over precision keywords
							if ( trim == "lowp" || trim == "mediump" || trim == "highp" )
							{
								continue;
							}

							int arrayStart = -1;
							for ( int j = 0; j < trim.Length; j++ )
							{
								if ( trim[ j ] == '[' )
								{
									arrayStart = j;
									break;
								}
							}
							if ( arrayStart != -1 )
							{
								//potential name (if butted up to array)
								string name = trim.Substring( 0, arrayStart );
								name = name.Trim();
								if ( name.Length > 0 )
								{
									paramName = name;
								}

								int arrayEnd = -1;
								for ( int k = 0; k < trim.Length; k++ )
								{
									if ( trim[ k ] == ']' )
									{
										arrayEnd = k;
										break;
									}
								}
								string arrayDimTerm = trim.Substring( arrayStart + 1, arrayEnd - arrayStart - 1 );
								arrayDimTerm = arrayDimTerm.Trim();
								// the array term might be a simple number or it might be
								// an expression (e.g. 24*3) or refer to a constant expression
								// we'd have to evaluate the expression which could get nasty
								// Ogre TODO
								def.ArraySize = int.Parse( arrayDimTerm );
							}
							else
							{
								paramName = trim;
								def.ArraySize = 1;
							}

							//Name should be after the type, so complete def and add
							//We do this now so that comma-seperated params will do
							//this part once for each name mentioned
							if ( def.ConstantType == GpuProgramParameters.GpuConstantType.Unknown )
							{
								Axiom.Core.LogManager.Instance.Write( "Problem parsing the following GLSL Uniform: " + line + " in file " + fileName );
								//next uniform
								break;
							}

							//Complete def and add
							//increment physical buffer location
							def.LogicalIndex = 0; // not valid in GLSL
							if ( def.IsFloat )
							{
								def.PhysicalIndex = constantDefs.FloatBufferSize;
								constantDefs.FloatBufferSize += def.ArraySize * def.ElementSize;
							}
							else
							{
								def.PhysicalIndex = constantDefs.IntBufferSize;
								constantDefs.IntBufferSize += def.ArraySize * def.ElementSize;
							}
							constantDefs.Map.Add( paramName, def );
						}
					}
				}
				//Find next one
				currPos = src.IndexOf( "uniform" );
			}
		}
Пример #4
0
        ///<summary>
        /// Populate a list of uniforms based on GLSL source.
        ///</summary>
        ///<param name="src">Reference to the source code</param>
        ///<param name="defs">The defs to populate (will not be cleared before adding, clear
        /// it yourself before calling this if that's what you want).</param>
        ///<param name="filename">The file name this came from, for logging errors.</param>
        public void ExtractConstantDefs(String src, GpuProgramParameters.GpuNamedConstants defs, String filename)
        {
            // Parse the output string and collect all uniforms
            // NOTE this relies on the source already having been preprocessed
            // which is done in GLSLProgram::loadFromSource

            string line;

            var currPos = src.IndexOf( "uniform" );
            while (currPos != -1)
            {
                var def = new GpuProgramParameters.GpuConstantDefinition();
                var paramName = "";

                // Now check for using the word 'uniform' in a larger string & ignore
                bool inLargerString = false;
                if (currPos != 0)
                {
                    var prev = src[currPos - 1];
                    if (prev != ' ' && prev != '\t' && prev != '\r' && prev != '\n'
                                       && prev != ';')
                        inLargerString = true;
                }
                if (!inLargerString && currPos + 7 < src.Length)
                {
                    var next = src[currPos + 7];
                    if (next != ' ' && next != '\t' && next != '\r' && next != '\n')
                        inLargerString = true;
                }

                // skip 'uniform'
                currPos += 7;

                if (!inLargerString)
                {
                    // find terminating semicolon
                    var endPos = src.IndexOf(';', currPos);
                    if (endPos == -1)
                    {
                        // problem, missing semicolon, abort
                        break;
                    }
                    line = src.Substring(currPos, endPos - currPos);

                    // Remove spaces before opening square braces, otherwise
                    // the following split() can split the line at inappropriate
                    // places (e.g. "vec3 something [3]" won't work).
                    for (var sqp = line.IndexOf(" ["); sqp != -1;
                        sqp = line.IndexOf(" ["))
                        line.Remove( sqp, 1 );

                    // Split into tokens
                    var parts = line.Split( ", \t\r\n".ToCharArray() );
                    foreach (var _i in parts)
                    {
                        var i = _i;
                        int typei;
                        if (typeEnumMap.TryGetValue( i, out typei ))
                        {
                            CompleteDefInfo(typei, def);
                        }
                        else
                        {
                            // if this is not a type, and not empty, it should be a name
                            i = i.Trim();
                            if (i == string.Empty)
                                continue;

                            var arrayStart = i.IndexOf('[');
                            if (arrayStart != -1)
                            {
                                // potential name (if butted up to array)
                                var name = i.Substring(0, arrayStart);
                                name = name.Trim();
                                if (name != string.Empty)
                                    paramName = name;

                                var arrayEnd = i.IndexOf(']', arrayStart);
                                var arrayDimTerm = i.Substring(arrayStart + 1, arrayEnd - arrayStart - 1);
                                arrayDimTerm = arrayDimTerm.Trim();
                                // the array term might be a simple number or it might be
                                // an expression (e.g. 24*3) or refer to a constant expression
                                // we'd have to evaluate the expression which could get nasty
                                // TODO
                                def.ArraySize = int.Parse( arrayDimTerm );
                            }
                            else
                            {
                                paramName = i;
                                def.ArraySize = 1;
                            }

                            // Name should be after the type, so complete def and add
                            // We do this now so that comma-separated params will do
                            // this part once for each name mentioned 
                            if (def.ConstantType == GpuProgramParameters.GpuConstantType.Unknown)
                            {
                                LogManager.Instance.Write(
                                    "Problem parsing the following GLSL Uniform: '"
                                    + line + "' in file " + filename );
                                // next uniform
                                break;
                            }

                            // Complete def and add
                            // increment physical buffer location
                            def.LogicalIndex = 0; // not valid in GLSL
                            if (def.IsFloat)
                            {
                                def.PhysicalIndex = defs.FloatBufferSize;
                                defs.FloatBufferSize += /*def.ArraySize * def.ElementSize*/ 1;
                            }
                            else
                            {
                                def.PhysicalIndex = defs.IntBufferSize;
                                defs.IntBufferSize += /*def.ArraySize * def.ElementSize*/ 1;
                            }

                            defs.Map.Add(paramName, def);
                            
                            // Axiom: This is not stable yet
                            //defs.GenerateConstantDefinitionArrayEntries(paramName, def);
                        }
                    }
                }
                // Find next one
                currPos = src.IndexOf("uniform", currPos);
            }
        }