public GpuLogicalIndexUse Clone()
            {
                var p = new GpuLogicalIndexUse();

                p.PhysicalIndex = this.PhysicalIndex;
                p.CurrentSize   = this.CurrentSize;
                p.Variability   = this.Variability;
                return(p);
            }
		protected GpuLogicalIndexUse GetFloatConstantLogicalIndexUse( int logicalIndex, int requestedSize,
																	  GpuParamVariability variability )
		{
			if ( this.floatLogicalToPhysical == null )
			{
				return null;
			}

			GpuLogicalIndexUse indexUse = null;
			lock ( this.floatLogicalToPhysical.Mutex )
			{
				GpuLogicalIndexUse logi;
				if ( !this.floatLogicalToPhysical.Map.TryGetValue( logicalIndex, out logi ) )
				{
					if ( requestedSize != 0 )
					{
						var physicalIndex = this.floatConstants.Count;

						// Expand at buffer end
						for ( var i = 0; i < requestedSize; i++ )
						{
							this.floatConstants.Add( 0.0f );
						}

						// Record extended size for future GPU params re-using this information
						this.floatLogicalToPhysical.BufferSize = this.floatConstants.Count;

						// low-level programs will not know about mapping ahead of time, so 
						// populate it. Other params objects will be able to just use this
						// accepted mapping since the constant structure will be the same

						// Set up a mapping for all items in the count
						var currPhys = physicalIndex;
						var count = requestedSize/4;

						GpuLogicalIndexUse insertedIterator = null;
						for ( var logicalNum = 0; logicalNum < count; ++logicalNum )
						{
							var it = new GpuLogicalIndexUse( currPhys, requestedSize, variability );
							this.floatLogicalToPhysical.Map.Add( logicalIndex + logicalNum, it );
							currPhys += 4;

							if ( logicalNum == 0 )
							{
								insertedIterator = it;
							}
						}

						indexUse = insertedIterator;
					}
					else
					{
						// no match & ignore
						return null;
					}
				}
				else
				{
					var physicalIndex = logi.PhysicalIndex;
					indexUse = logi;
					// check size
					if ( logi.CurrentSize < requestedSize )
					{
						// init buffer entry wasn't big enough; could be a mistake on the part
						// of the original use, or perhaps a variable length we can't predict
						// until first actual runtime use e.g. world matrix array
						var insertCount = requestedSize - logi.CurrentSize;
						var insertPos = 0;
						insertPos += physicalIndex;

						for ( var i = 0; i < insertCount; i++ )
						{
							this.floatConstants.Insert( insertPos, 0.0f );
						}

						// shift all physical positions after this one
						foreach ( var i in this.floatLogicalToPhysical.Map )
						{
							if ( i.Value.PhysicalIndex > physicalIndex )
							{
								i.Value.PhysicalIndex += insertCount;
							}
						}

						this.floatLogicalToPhysical.BufferSize += insertCount;
						foreach ( var i in this.autoConstants )
						{
							AutoConstantDefinition def;
							if ( i.PhysicalIndex > physicalIndex && GetAutoConstantDefinition( i.Type.ToString(), out def ) &&
								 def.ElementType == ElementType.Real )
							{
								i.PhysicalIndex += insertCount;
							}
						}
						if ( this._namedConstants != null )
						{
							foreach ( var i in this._namedConstants.Map )
							{
								if ( i.Value.IsFloat && i.Value.PhysicalIndex > physicalIndex )
								{
									i.Value.PhysicalIndex += insertCount;
								}
							}
							this._namedConstants.FloatBufferSize += insertCount;
						}

						logi.CurrentSize += insertCount;
					}
				}

				if ( indexUse != null )
				{
					indexUse.Variability = variability;
				}

				return indexUse;
			}
		}
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(GpuLogicalIndexUse obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }