namespace UnityEngine.ScriptableRenderLoop
{
public enum PackingRules
{
Exact ,
Aggressive
} ;
public enum PackingRules
{
Exact ,
Aggressive
} ;
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Enum)]
public class GenerateHLSL : System . Attribute
{
public PackingRules packingRules ;
public bool simple ;
public int debugCounterStart ;
public GenerateHLSL ( PackingRules rules = PackingRules . Exact , bool simple = false , int debugCounterStart = 1 )
{
packingRules = rules ;
this . simple = simple ;
this . debugCounterStart = debugCounterStart ;
}
}
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Enum)]
public class GenerateHLSL : System . Attribute
{
public PackingRules packingRules ;
public bool simple ;
public int debugCounterStart ;
public GenerateHLSL ( PackingRules rules = PackingRules . Exact , bool simple = false , int debugCounterStart = 1 )
{
packingRules = rules ;
this . simple = simple ;
this . debugCounterStart = debugCounterStart ;
}
}
[AttributeUsage(AttributeTargets.Field)]
public class SurfaceDataAttributes : System . Attribute
{
public string displayName ;
public SurfaceDataAttributes ( string displayName = "" )
{
this . displayName = displayName ;
}
}
[AttributeUsage(AttributeTargets.Field)]
public class SurfaceDataAttributes : System . Attribute
{
public string displayName ;
public SurfaceDataAttributes ( string displayName = "" )
{
this . displayName = displayName ;
}
}
internal class ShaderTypeGenerator
{
public ShaderTypeGenerator ( Type type , GenerateHLSL attr )
{
this . type = type ;
this . attr = attr ;
debugCounter = 0 ;
}
internal class ShaderTypeGenerator
{
public ShaderTypeGenerator ( Type type , GenerateHLSL attr )
{
this . type = type ;
this . attr = attr ;
debugCounter = 0 ;
}
enum PrimitiveType
{
Float , Int , UInt
} ;
enum PrimitiveType
{
Float , Int , UInt
} ;
static string PrimitiveToString ( PrimitiveType type , int rows , int cols )
{
string text = "" ;
switch ( type )
{
case PrimitiveType . Float :
text = "float" ;
break ;
case PrimitiveType . Int :
text = "int" ;
break ;
case PrimitiveType . UInt :
text = "uint" ;
break ;
}
static string PrimitiveToString ( PrimitiveType type , int rows , int cols )
{
string text = "" ;
switch ( type )
{
case PrimitiveType . Float :
text = "float" ;
break ;
case PrimitiveType . Int :
text = "int" ;
break ;
case PrimitiveType . UInt :
text = "uint" ;
break ;
}
if ( rows > 1 )
{
text + = rows . ToString ( ) ;
if ( cols > 1 )
{
text + = "x" + cols . ToString ( ) ;
}
}
if ( rows > 1 )
{
text + = rows . ToString ( ) ;
if ( cols > 1 )
{
text + = "x" + cols . ToString ( ) ;
}
}
return text ;
}
return text ;
}
class Accessor
{
public Accessor ( PrimitiveType type , string name , int rows , int cols )
{
this . name = name ;
this . fullType = PrimitiveToString ( type , rows , cols ) ;
field = name ;
}
class Accessor
{
public Accessor ( PrimitiveType type , string name , int rows , int cols )
{
this . name = name ;
this . fullType = PrimitiveToString ( type , rows , cols ) ;
field = name ;
}
Accessor ( string name , string swizzle , string field , string fullType )
{
this . name = name ;
this . field = field ;
this . fullType = fullType ;
}
Accessor ( string name , string swizzle , string field , string fullType )
{
this . name = name ;
this . field = field ;
this . fullType = fullType ;
}
public string name ;
public string field ;
public string fullType ;
} ;
public string name ;
public string field ;
public string fullType ;
} ;
class ShaderFieldInfo : ICloneable
{
public ShaderFieldInfo ( PrimitiveType type , string name , int rows , int cols )
{
this . type = type ;
this . name = originalName = name ;
this . rows = rows ;
this . cols = cols ;
this . comment = "" ;
swizzleOffset = 0 ;
packed = false ;
accessor = new Accessor ( type , name , rows , cols ) ;
}
public ShaderFieldInfo ( PrimitiveType type , string name , int rows , int cols , string comment )
{
this . type = type ;
this . name = originalName = name ;
this . rows = rows ;
this . cols = cols ;
this . comment = comment ;
swizzleOffset = 0 ;
packed = false ;
accessor = new Accessor ( type , name , rows , cols ) ;
}
class ShaderFieldInfo : ICloneable
{
public ShaderFieldInfo ( PrimitiveType type , string name , int rows , int cols )
{
this . type = type ;
this . name = originalName = name ;
this . rows = rows ;
this . cols = cols ;
this . comment = "" ;
swizzleOffset = 0 ;
packed = false ;
accessor = new Accessor ( type , name , rows , cols ) ;
}
public ShaderFieldInfo ( PrimitiveType type , string name , int rows , int cols , string comment )
{
this . type = type ;
this . name = originalName = name ;
this . rows = rows ;
this . cols = cols ;
this . comment = comment ;
swizzleOffset = 0 ;
packed = false ;
accessor = new Accessor ( type , name , rows , cols ) ;
}
public string typeString
{
get { return PrimitiveToString ( type , rows , cols ) ; }
}
public string typeString
{
get { return PrimitiveToString ( type , rows , cols ) ; }
}
public string DeclString ( )
{
return PrimitiveToString ( type , rows , cols ) + " " + name ;
}
public string DeclString ( )
{
return PrimitiveToString ( type , rows , cols ) + " " + name ;
}
public override string ToString ( )
{
string text = DeclString ( ) + ";" ;
if ( comment . Length > 0 )
{
text + = " // " + comment ;
}
return text ;
}
public override string ToString ( )
{
string text = DeclString ( ) + ";" ;
if ( comment . Length > 0 )
{
text + = " // " + comment ;
}
return text ;
}
public int elementCount
{
get { return rows * cols ; }
}
public int elementCount
{
get { return rows * cols ; }
}
public object Clone ( )
{
ShaderFieldInfo info = new ShaderFieldInfo ( type , name , rows , cols , comment ) ;
info . swizzleOffset = swizzleOffset ;
info . packed = packed ;
info . accessor = accessor ;
return info ;
}
public object Clone ( )
{
ShaderFieldInfo info = new ShaderFieldInfo ( type , name , rows , cols , comment ) ;
info . swizzleOffset = swizzleOffset ;
info . packed = packed ;
info . accessor = accessor ;
return info ;
}
public PrimitiveType type ;
public string name ;
public string originalName ;
public string comment ;
public int rows ;
public int cols ;
public int swizzleOffset ;
public bool packed ;
public Accessor accessor ;
} ;
public PrimitiveType type ;
public string name ;
public string originalName ;
public string comment ;
public int rows ;
public int cols ;
public int swizzleOffset ;
public bool packed ;
public Accessor accessor ;
} ;
void Error ( string error )
{
if ( errors = = null )
{
errors = new List < string > ( ) ;
}
errors . Add ( "Failed to generate shader type for " + type . ToString ( ) + ": " + error ) ;
}
void Error ( string error )
{
if ( errors = = null )
{
errors = new List < string > ( ) ;
}
errors . Add ( "Failed to generate shader type for " + type . ToString ( ) + ": " + error ) ;
}
public void PrintErrors ( )
{
if ( errors ! = null )
{
foreach ( var e in errors )
{
Debug . LogError ( e ) ;
}
}
}
public void PrintErrors ( )
{
if ( errors ! = null )
{
foreach ( var e in errors )
{
Debug . LogError ( e ) ;
}
}
}
void EmitPrimitiveType ( PrimitiveType type , int elements , string name , string comment , List < ShaderFieldInfo > fields )
{
fields . Add ( new ShaderFieldInfo ( type , name , elements , 1 , comment ) ) ;
}
void EmitPrimitiveType ( PrimitiveType type , int elements , string name , string comment , List < ShaderFieldInfo > fields )
{
fields . Add ( new ShaderFieldInfo ( type , name , elements , 1 , comment ) ) ;
}
void EmitMatrixType ( PrimitiveType type , int rows , int cols , string name , string comment , List < ShaderFieldInfo > fields )
{
fields . Add ( new ShaderFieldInfo ( type , name , rows , cols , comment ) ) ;
}
void EmitMatrixType ( PrimitiveType type , int rows , int cols , string name , string comment , List < ShaderFieldInfo > fields )
{
fields . Add ( new ShaderFieldInfo ( type , name , rows , cols , comment ) ) ;
}
bool ExtractComplex ( FieldInfo field , List < ShaderFieldInfo > shaderFields )
{
List < FieldInfo > floatFields = new List < FieldInfo > ( ) ;
List < FieldInfo > intFields = new List < FieldInfo > ( ) ;
List < FieldInfo > uintFields = new List < FieldInfo > ( ) ;
string [ ] descs = new string [ 4 ] { "x: " , "y: " , "z: " , "w: " } ;
int numFields = 0 ;
bool ExtractComplex ( FieldInfo field , List < ShaderFieldInfo > shaderFields )
{
List < FieldInfo > floatFields = new List < FieldInfo > ( ) ;
List < FieldInfo > intFields = new List < FieldInfo > ( ) ;
List < FieldInfo > uintFields = new List < FieldInfo > ( ) ;
string [ ] descs = new string [ 4 ] { "x: " , "y: " , "z: " , "w: " } ;
int numFields = 0 ;
string fieldName = "'" + field . FieldType . Name + " " + field . Name + "'" ;
string fieldName = "'" + field . FieldType . Name + " " + field . Name + "'" ;
foreach ( FieldInfo subField in field . FieldType . GetFields ( ) )
{
if ( subField . IsStatic )
continue ;
foreach ( FieldInfo subField in field . FieldType . GetFields ( ) )
{
if ( subField . IsStatic )
continue ;
if ( ! subField . FieldType . IsPrimitive )
{
Error ( "'" + fieldName + "' can not be packed into a register, since it contains a non-primitive field type '" + subField . FieldType + "'" ) ;
return false ;
}
if ( subField . FieldType = = typeof ( float ) )
floatFields . Add ( subField ) ;
else if ( subField . FieldType = = typeof ( int ) )
intFields . Add ( subField ) ;
else if ( subField . FieldType = = typeof ( uint ) )
uintFields . Add ( subField ) ;
else
{
Error ( "'" + fieldName + "' can not be packed into a register, since it contains an unsupported field type '" + subField . FieldType + "'" ) ;
return false ;
}
if ( ! subField . FieldType . IsPrimitive )
{
Error ( "'" + fieldName + "' can not be packed into a register, since it contains a non-primitive field type '" + subField . FieldType + "'" ) ;
return false ;
}
if ( subField . FieldType = = typeof ( float ) )
floatFields . Add ( subField ) ;
else if ( subField . FieldType = = typeof ( int ) )
intFields . Add ( subField ) ;
else if ( subField . FieldType = = typeof ( uint ) )
uintFields . Add ( subField ) ;
else
{
Error ( "'" + fieldName + "' can not be packed into a register, since it contains an unsupported field type '" + subField . FieldType + "'" ) ;
return false ;
}
if ( numFields = = 4 )
{
Error ( "'" + fieldName + "' can not be packed into a register because it contains more than 4 fields." ) ;
return false ;
}
if ( numFields = = 4 )
{
Error ( "'" + fieldName + "' can not be packed into a register because it contains more than 4 fields." ) ;
return false ;
}
descs [ numFields ] + = subField . Name + " " ;
numFields + + ;
}
Array . Resize ( ref descs , numFields ) ;
descs [ numFields ] + = subField . Name + " " ;
numFields + + ;
}
Array . Resize ( ref descs , numFields ) ;
string comment = string . Concat ( descs ) ;
string mismatchErrorMsg = "'" + fieldName + "' can not be packed into a single register because it contains mixed basic types." ;
string comment = string . Concat ( descs ) ;
string mismatchErrorMsg = "'" + fieldName + "' can not be packed into a single register because it contains mixed basic types." ;
if ( floatFields . Count > 0 )
{
if ( intFields . Count + uintFields . Count > 0 )
{
Error ( mismatchErrorMsg ) ;
return false ;
}
EmitPrimitiveType ( PrimitiveType . Float , floatFields . Count , field . Name , comment , shaderFields ) ;
}
else if ( intFields . Count > 0 )
{
if ( floatFields . Count + uintFields . Count > 0 )
{
Error ( mismatchErrorMsg ) ;
return false ;
}
EmitPrimitiveType ( PrimitiveType . Int , intFields . Count , field . Name , "" , shaderFields ) ;
}
else if ( uintFields . Count > 0 )
{
if ( floatFields . Count + intFields . Count > 0 )
{
Error ( mismatchErrorMsg ) ;
return false ;
}
EmitPrimitiveType ( PrimitiveType . UInt , uintFields . Count , field . Name , "" , shaderFields ) ;
}
else
{
// Empty struct.
}
if ( floatFields . Count > 0 )
{
if ( intFields . Count + uintFields . Count > 0 )
{
Error ( mismatchErrorMsg ) ;
return false ;
}
EmitPrimitiveType ( PrimitiveType . Float , floatFields . Count , field . Name , comment , shaderFields ) ;
}
else if ( intFields . Count > 0 )
{
if ( floatFields . Count + uintFields . Count > 0 )
{
Error ( mismatchErrorMsg ) ;
return false ;
}
EmitPrimitiveType ( PrimitiveType . Int , intFields . Count , field . Name , "" , shaderFields ) ;
}
else if ( uintFields . Count > 0 )
{
if ( floatFields . Count + intFields . Count > 0 )
{
Error ( mismatchErrorMsg ) ;
return false ;
}
EmitPrimitiveType ( PrimitiveType . UInt , uintFields . Count , field . Name , "" , shaderFields ) ;
}
else
{
// Empty struct.
}
return true ;
}
return true ;
}
enum MergeResult
{
Merged ,
Full ,
Failed
} ;
enum MergeResult
{
Merged ,
Full ,
Failed
} ;
MergeResult PackFields ( ShaderFieldInfo info , ref ShaderFieldInfo merged )
{
if ( merged . elementCount % 4 = = 0 )
{
return MergeResult . Full ;
}
MergeResult PackFields ( ShaderFieldInfo info , ref ShaderFieldInfo merged )
{
if ( merged . elementCount % 4 = = 0 )
{
return MergeResult . Full ;
}
if ( info . type ! = merged . type )
{
Error ( "can't merge '" + merged . DeclString ( ) + "' and '" + info . DeclString ( ) + "' into the same register because they have incompatible types. Consider reordering the fields so that adjacent fields have the same primitive type." ) ;
return MergeResult . Failed ; // incompatible types
}
if ( info . type ! = merged . type )
{
Error ( "can't merge '" + merged . DeclString ( ) + "' and '" + info . DeclString ( ) + "' into the same register because they have incompatible types. Consider reordering the fields so that adjacent fields have the same primitive type." ) ;
return MergeResult . Failed ; // incompatible types
}
if ( info . cols > 1 | | merged . cols > 1 )
{
Error ( "merging matrix types not yet supported ('" + merged . DeclString ( ) + "' and '" + info . DeclString ( ) + "'). Consider reordering the fields to place matrix-typed variables on four-component vector boundaries." ) ;
return MergeResult . Failed ; // don't merge matrix types
}
if ( info . cols > 1 | | merged . cols > 1 )
{
Error ( "merging matrix types not yet supported ('" + merged . DeclString ( ) + "' and '" + info . DeclString ( ) + "'). Consider reordering the fields to place matrix-typed variables on four-component vector boundaries." ) ;
return MergeResult . Failed ; // don't merge matrix types
}
if ( info . rows + merged . rows > 4 )
{
// @TODO: lift the restriction
Error ( "can't merge '" + merged . DeclString ( ) + "' and '" + info . DeclString ( ) + "' because then " + info . name + " would cross register boundary. Consider reordering the fields so that none of them cross four-component vector boundaries when packed." ) ;
return MergeResult . Failed ; // out of space
}
if ( info . rows + merged . rows > 4 )
{
// @TODO: lift the restriction
Error ( "can't merge '" + merged . DeclString ( ) + "' and '" + info . DeclString ( ) + "' because then " + info . name + " would cross register boundary. Consider reordering the fields so that none of them cross four-component vector boundaries when packed." ) ;
return MergeResult . Failed ; // out of space
}
merged . rows + = info . rows ;
merged . name + = "_" + info . name ;
return MergeResult . Merged ;
}
merged . rows + = info . rows ;
merged . name + = "_" + info . name ;
return MergeResult . Merged ;
}
List < ShaderFieldInfo > Pack ( List < ShaderFieldInfo > shaderFields )
{
List < ShaderFieldInfo > mergedFields = new List < ShaderFieldInfo > ( ) ;
List < ShaderFieldInfo > Pack ( List < ShaderFieldInfo > shaderFields )
{
List < ShaderFieldInfo > mergedFields = new List < ShaderFieldInfo > ( ) ;
List < ShaderFieldInfo > . Enumerator e = shaderFields . GetEnumerator ( ) ;
List < ShaderFieldInfo > . Enumerator e = shaderFields . GetEnumerator ( ) ;
if ( ! e . MoveNext ( ) )
{
// Empty shader struct definition.
return shaderFields ;
}
if ( ! e . MoveNext ( ) )
{
// Empty shader struct definition.
return shaderFields ;
}
ShaderFieldInfo current = e . Current . Clone ( ) as ShaderFieldInfo ;
ShaderFieldInfo current = e . Current . Clone ( ) as ShaderFieldInfo ;
while ( e . MoveNext ( ) )
{
while ( true )
{
int offset = current . elementCount ;
MergeResult result = PackFields ( e . Current , ref current ) ;
while ( e . MoveNext ( ) )
{
while ( true )
{
int offset = current . elementCount ;
MergeResult result = PackFields ( e . Current , ref current ) ;
if ( result = = MergeResult . Failed )
{
return null ;
}
else if ( result = = MergeResult . Full )
{
break ;
}
if ( result = = MergeResult . Failed )
{
return null ;
}
else if ( result = = MergeResult . Full )
{
break ;
}
// merge accessors
Accessor acc = current . accessor ;
// merge accessors
Accessor acc = current . accessor ;
acc . name = current . name ;
e . Current . accessor = acc ;
e . Current . swizzleOffset + = offset ;
acc . name = current . name ;
e . Current . accessor = acc ;
e . Current . swizzleOffset + = offset ;
current . packed = e . Current . packed = true ;
current . packed = e . Current . packed = true ;
if ( ! e . MoveNext ( ) )
{
mergedFields . Add ( current ) ;
return mergedFields ;
}
}
mergedFields . Add ( current ) ;
current = e . Current . Clone ( ) as ShaderFieldInfo ;
}
if ( ! e . MoveNext ( ) )
{
mergedFields . Add ( current ) ;
return mergedFields ;
}
}
mergedFields . Add ( current ) ;
current = e . Current . Clone ( ) as ShaderFieldInfo ;
}
return mergedFields ;
}
return mergedFields ;
}
public string EmitTypeDecl ( )
{
string shaderText = string . Empty ;
public string EmitTypeDecl ( )
{
string shaderText = string . Empty ;
shaderText + = "// Generated from " + type . FullName + "\n" ;
shaderText + = "// PackingRules = " + attr . packingRules . ToString ( ) + "\n" ;
shaderText + = "struct " + type . Name + "\n" ;
shaderText + = "{\n" ;
foreach ( ShaderFieldInfo shaderFieldInfo in packedFields )
{
shaderText + = "\t" + shaderFieldInfo . ToString ( ) + "\n" ;
}
shaderText + = "};\n" ;
shaderText + = "// Generated from " + type . FullName + "\n" ;
shaderText + = "// PackingRules = " + attr . packingRules . ToString ( ) + "\n" ;
shaderText + = "struct " + type . Name + "\n" ;
shaderText + = "{\n" ;
foreach ( ShaderFieldInfo shaderFieldInfo in packedFields )
{
shaderText + = "\t" + shaderFieldInfo . ToString ( ) + "\n" ;
}
shaderText + = "};\n" ;
return shaderText ;
}
return shaderText ;
}
public string EmitAccessors ( )
{
string shaderText = string . Empty ;
public string EmitAccessors ( )
{
string shaderText = string . Empty ;
shaderText + = "//\n" ;
shaderText + = "// Accessors for " + type . FullName + "\n" ;
shaderText + = "//\n" ;
foreach ( var shaderField in shaderFields )
{
Accessor acc = shaderField . accessor ;
string accessorName = shaderField . originalName ;
accessorName = "Get" + char . ToUpper ( accessorName [ 0 ] ) + accessorName . Substring ( 1 ) ;
shaderText + = "//\n" ;
shaderText + = "// Accessors for " + type . FullName + "\n" ;
shaderText + = "//\n" ;
foreach ( var shaderField in shaderFields )
{
Accessor acc = shaderField . accessor ;
string accessorName = shaderField . originalName ;
accessorName = "Get" + char . ToUpper ( accessorName [ 0 ] ) + accessorName . Substring ( 1 ) ;
shaderText + = shaderField . typeString + " " + accessorName + "(" + type . Name + " value)\n" ;
shaderText + = "{\n" ;
shaderText + = shaderField . typeString + " " + accessorName + "(" + type . Name + " value)\n" ;
shaderText + = "{\n" ;
string swizzle = "" ;
string swizzle = "" ;
// @TODO: support matrix type packing?
if ( shaderField . cols = = 1 ) // @TEMP
{
// don't emit redundant swizzles
if ( shaderField . originalName ! = acc . name )
{
swizzle = "." + "xyzw" . Substring ( shaderField . swizzleOffset , shaderField . elementCount ) ;
}
}
// @TODO: support matrix type packing?
if ( shaderField . cols = = 1 ) // @TEMP
{
// don't emit redundant swizzles
if ( shaderField . originalName ! = acc . name )
{
swizzle = "." + "xyzw" . Substring ( shaderField . swizzleOffset , shaderField . elementCount ) ;
}
}
shaderText + = "\treturn value." + acc . name + swizzle + ";\n" ;
shaderText + = "}\n" ;
}
shaderText + = "\treturn value." + acc . name + swizzle + ";\n" ;
shaderText + = "}\n" ;
}
return shaderText ;
}
return shaderText ;
}
public string EmitDefines ( )
{
string shaderText = string . Empty ;
public string EmitDefines ( )
{
string shaderText = string . Empty ;
shaderText + = "//\n" ;
shaderText + = "// " + type . FullName + ": static fields\n" ;
shaderText + = "//\n" ;
foreach ( var def in statics )
{
shaderText + = "#define " + def . Key + " (" + def . Value + ")\n" ;
}
shaderText + = "//\n" ;
shaderText + = "// " + type . FullName + ": static fields\n" ;
shaderText + = "//\n" ;
foreach ( var def in statics )
{
shaderText + = "#define " + def . Key + " (" + def . Value + ")\n" ;
}
return shaderText ;
}
return shaderText ;
}
public string Emit ( )
{
return EmitDefines ( ) + EmitTypeDecl ( ) + EmitAccessors ( ) ;
}
public string Emit ( )
{
return EmitDefines ( ) + EmitTypeDecl ( ) + EmitAccessors ( ) ;
}
public bool Generate ( )
{
statics = new Dictionary < string , string > ( ) ;
public bool Generate ( )
{
statics = new Dictionary < string , string > ( ) ;
FieldInfo [ ] fields = type . GetFields ( ) ;
shaderFields = new List < ShaderFieldInfo > ( ) ;
FieldInfo [ ] fields = type . GetFields ( ) ;
shaderFields = new List < ShaderFieldInfo > ( ) ;
if ( type . IsEnum )
{
foreach ( var field in fields )
{
if ( ! field . IsSpecialName )
{
string name = field . Name ;
for ( int i = 1 ; i < name . Length ; i + + )
{
if ( char . IsLower ( name [ i - 1 ] ) & & char . IsUpper ( name [ i ] ) )
{
// case switch, insert underscore
name = name . Insert ( i , "_" ) ;
}
}
statics [ ( type . Name + "_" + name ) . ToUpper ( ) ] = field . GetRawConstantValue ( ) . ToString ( ) ;
}
}
errors = null ;
return true ;
}
if ( type . IsEnum )
{
foreach ( var field in fields )
{
if ( ! field . IsSpecialName )
{
string name = field . Name ;
for ( int i = 1 ; i < name . Length ; i + + )
{
if ( char . IsLower ( name [ i - 1 ] ) & & char . IsUpper ( name [ i ] ) )
{
// case switch, insert underscore
name = name . Insert ( i , "_" ) ;
}
}
statics [ ( type . Name + "_" + name ) . ToUpper ( ) ] = field . GetRawConstantValue ( ) . ToString ( ) ;
}
}
errors = null ;
return true ;
}
foreach ( var field in fields )
{
if ( field . IsStatic )
{
if ( field . FieldType . IsPrimitive )
{
statics [ field . Name ] = field . GetValue ( null ) . ToString ( ) ;
}
continue ;
}
foreach ( var field in fields )
{
if ( field . IsStatic )
{
if ( field . FieldType . IsPrimitive )
{
statics [ field . Name ] = field . GetValue ( null ) . ToString ( ) ;
}
continue ;
}
if ( attr . simple )
{
string subNamespace = type . Namespace . Substring ( type . Namespace . LastIndexOf ( ( "." ) ) + 1 ) ;
statics [ "DEBUGVIEW_" + subNamespace . ToUpper ( ) + "_" + type . Name . ToUpper ( ) + "_" + field . Name . ToUpper ( ) ] = Convert . ToString ( attr . debugCounterStart + debugCounter + + ) ;
}
if ( attr . simple )
{
string subNamespace = type . Namespace . Substring ( type . Namespace . LastIndexOf ( ( "." ) ) + 1 ) ;
statics [ "DEBUGVIEW_" + subNamespace . ToUpper ( ) + "_" + type . Name . ToUpper ( ) + "_" + field . Name . ToUpper ( ) ] = Convert . ToString ( attr . debugCounterStart + debugCounter + + ) ;
}
if ( field . FieldType . IsPrimitive )
{
if ( field . FieldType = = typeof ( float ) )
EmitPrimitiveType ( PrimitiveType . Float , 1 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( int ) )
EmitPrimitiveType ( PrimitiveType . Int , 1 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( uint ) )
EmitPrimitiveType ( PrimitiveType . UInt , 1 , field . Name , "" , shaderFields ) ;
else
{
Error ( "unsupported field type '" + field . FieldType + "'" ) ;
return false ;
}
}
else
{
// handle special types, otherwise try parsing the struct
if ( field . FieldType = = typeof ( Vector2 ) )
EmitPrimitiveType ( PrimitiveType . Float , 2 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( Vector3 ) )
EmitPrimitiveType ( PrimitiveType . Float , 3 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( Vector4 ) )
EmitPrimitiveType ( PrimitiveType . Float , 4 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( Matrix4x4 ) )
EmitMatrixType ( PrimitiveType . Float , 4 , 4 , field . Name , "" , shaderFields ) ;
else if ( ! ExtractComplex ( field , shaderFields ) )
{
// Error reporting done in ExtractComplex()
return false ;
}
}
}
if ( field . FieldType . IsPrimitive )
{
if ( field . FieldType = = typeof ( float ) )
EmitPrimitiveType ( PrimitiveType . Float , 1 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( int ) )
EmitPrimitiveType ( PrimitiveType . Int , 1 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( uint ) )
EmitPrimitiveType ( PrimitiveType . UInt , 1 , field . Name , "" , shaderFields ) ;
else
{
Error ( "unsupported field type '" + field . FieldType + "'" ) ;
return false ;
}
}
else
{
// handle special types, otherwise try parsing the struct
if ( field . FieldType = = typeof ( Vector2 ) )
EmitPrimitiveType ( PrimitiveType . Float , 2 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( Vector3 ) )
EmitPrimitiveType ( PrimitiveType . Float , 3 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( Vector4 ) )
EmitPrimitiveType ( PrimitiveType . Float , 4 , field . Name , "" , shaderFields ) ;
else if ( field . FieldType = = typeof ( Matrix4x4 ) )
EmitMatrixType ( PrimitiveType . Float , 4 , 4 , field . Name , "" , shaderFields ) ;
else if ( ! ExtractComplex ( field , shaderFields ) )
{
// Error reporting done in ExtractComplex()
return false ;
}
}
}
packedFields = shaderFields ;
if ( attr . packingRules = = PackingRules . Aggressive )
{
packedFields = Pack ( shaderFields ) ;
packedFields = shaderFields ;
if ( attr . packingRules = = PackingRules . Aggressive )
{
packedFields = Pack ( shaderFields ) ;
if ( packedFields = = null )
{
return false ;
}
}
if ( packedFields = = null )
{
return false ;
}
}
errors = null ;
return true ;
}
errors = null ;
return true ;
}
public bool hasFields
{
get { return shaderFields . Count > 0 ; }
}
public bool hasFields
{
get { return shaderFields . Count > 0 ; }
}
public bool hasStatics
{
get { return statics . Count > 0 ; }
}
public bool hasStatics
{
get { return statics . Count > 0 ; }
}
public bool IsSimple ( )
{
return attr . simple ;
}
public bool IsSimple ( )
{
return attr . simple ;
}
public Type type ;
public GenerateHLSL attr ;
public int debugCounter ;
public List < string > errors = null ;
public Type type ;
public GenerateHLSL attr ;
public int debugCounter ;
public List < string > errors = null ;
Dictionary < string , string > statics ;
List < ShaderFieldInfo > shaderFields ;
List < ShaderFieldInfo > packedFields ;
}
Dictionary < string , string > statics ;
List < ShaderFieldInfo > shaderFields ;
List < ShaderFieldInfo > packedFields ;
}
}