@@ -101,6 +101,8 @@ public class HlslToGlslConvertor : ShaderRewriter
101101
102102 private int breakIndex = 0 ;
103103
104+ private int structedBufferCounter = 0 ;
105+
104106 #endregion
105107
106108 #region Constructors and Destructors
@@ -243,7 +245,7 @@ public HlslToGlslConvertor(GlslShaderPlatform shaderPlatform, int shaderVersion,
243245 { "GroupMemoryBarrier" , "groupMemoryBarrier" } ,
244246 //{ "D3DCOLORtoUBYTE4", "ivec4" },
245247 } ;
246- }
248+ }
247249
248250 #endregion
249251
@@ -1093,7 +1095,7 @@ protected Statement VisitStatementAsMemberInvocation(Statement statement, Method
10931095 if ( memberReferenceExpression . Member == "GetDimensions" )
10941096 {
10951097 var textureRef = memberReferenceExpression . Target as VariableReferenceExpression ;
1096- var variableTexture = this . FindGlobalVariableFromExpression ( textureRef ) ;
1098+ var variableTexture = FindParameterOrGlobalVariableFromExpression ( textureRef ) ;
10971099
10981100 if ( variableTexture == null )
10991101 {
@@ -1233,6 +1235,7 @@ protected Statement VisitStatementAsAssignExpression(Statement statement, Assign
12331235 "RWBuffer" => ScalarType . Int ,
12341236 "RWTexture2D" => VectorType . Int2 ,
12351237 "RWTexture3D" => VectorType . Int3 ,
1238+ "RWTexture2DArray" => VectorType . Int3 ,
12361239 _ => throw new NotSupportedException ( $ "imageStore not supported for { variable . Name . Text } ")
12371240 } ;
12381241
@@ -1307,6 +1310,24 @@ public override Node Visit(MethodInvocationExpression methodInvocationExpression
13071310 return new ParenthesizedExpression ( new BinaryExpression ( BinaryOperator . Multiply , leftParameter , rightParameter ) ) ;
13081311 }
13091312
1313+ if ( methodName == "rcp" )
1314+ {
1315+ var rightParameter = ConvertToSafeExpressionForBinary ( methodInvocationExpression . Arguments [ 0 ] ) ;
1316+ return new ParenthesizedExpression ( new BinaryExpression ( BinaryOperator . Divide , new LiteralExpression ( 1.0f ) , rightParameter ) ) ;
1317+ }
1318+
1319+ if ( methodName == "mad" )
1320+ {
1321+ var firstParameter = ConvertToSafeExpressionForBinary ( methodInvocationExpression . Arguments [ 0 ] ) ;
1322+ var secondParameter = ConvertToSafeExpressionForBinary ( methodInvocationExpression . Arguments [ 1 ] ) ;
1323+ var thirdParameter = ConvertToSafeExpressionForBinary ( methodInvocationExpression . Arguments [ 2 ] ) ;
1324+
1325+ var multiply = new BinaryExpression ( BinaryOperator . Multiply , firstParameter , secondParameter ) ;
1326+ var add = new BinaryExpression ( BinaryOperator . Plus , multiply , thirdParameter ) ;
1327+
1328+ return new ParenthesizedExpression ( add ) ;
1329+ }
1330+
13101331 if ( methodName == "lit" )
13111332 {
13121333 // http://msdn.microsoft.com/en-us/library/bb509619%28v=vs.85%29.aspx
@@ -1389,7 +1410,7 @@ public override Node Visit(MethodInvocationExpression methodInvocationExpression
13891410 var memberReferenceExpression = methodInvocationExpression . Target as MemberReferenceExpression ;
13901411 if ( memberReferenceExpression != null )
13911412 {
1392- var targetVariable = FindGlobalVariableFromExpression ( memberReferenceExpression . Target ) ;
1413+ var targetVariable = FindParameterOrGlobalVariableFromExpression ( memberReferenceExpression . Target ) ;
13931414 if ( targetVariable == null )
13941415 {
13951416 parserResult . Error ( "Unable to find target variable for expression [{0}]" , methodInvocationExpression . Span , methodInvocationExpression ) ;
@@ -1428,7 +1449,7 @@ public override Node Visit(MethodInvocationExpression methodInvocationExpression
14281449 // texture.Load() doesn't require a sampler
14291450 if ( ! isLoad )
14301451 {
1431- sampler = this . FindGlobalVariableFromExpression ( methodInvocationExpression . Arguments [ 0 ] ) ;
1452+ sampler = FindParameterOrGlobalVariableFromExpression ( methodInvocationExpression . Arguments [ 0 ] ) ;
14321453 }
14331454 var glslSampler = GetGLSampler ( sampler , targetVariable , true ) ;
14341455
@@ -2477,6 +2498,7 @@ public override Node Visit(IndexerExpression indexerExpression)
24772498 "RWBuffer" => ScalarType . Int ,
24782499 "RWTexture2D" => VectorType . Int2 ,
24792500 "RWTexture3D" => VectorType . Int3 ,
2501+ "RWTexture2DArray" => VectorType . Int3 ,
24802502 _ => throw new NotSupportedException ( $ "imageLoad not supported for { variable . Name . Text } ")
24812503 } ;
24822504
@@ -2485,6 +2507,16 @@ public override Node Visit(IndexerExpression indexerExpression)
24852507
24862508 return new MethodInvocationExpression ( "imageLoad" , indexerExpression . Target , new MethodInvocationExpression ( new TypeReferenceExpression ( indexerType ) , indexerExpression . Index ) ) ;
24872509 }
2510+ else if ( classType != null && ( classType . Name . Text . StartsWith ( "StructuredBuffer" ) || classType . Name . Text . StartsWith ( "RWStructuredBuffer" ) ) )
2511+ {
2512+ // Convert to TargetName.Buffer[index]
2513+ indexerExpression . Target = ( Expression ) VisitDynamic ( indexerExpression . Target ) ;
2514+ indexerExpression . Index = ( Expression ) VisitDynamic ( indexerExpression . Index ) ;
2515+
2516+ indexerExpression . Target = new MemberReferenceExpression ( indexerExpression . Target , "Buffer" ) ;
2517+
2518+ return indexerExpression ;
2519+ }
24882520 }
24892521
24902522 base . Visit ( indexerExpression ) ;
@@ -3683,6 +3715,24 @@ private void FlattenArrayCreationExpression(ArrayInitializerExpression from, Lis
36833715 }
36843716 }
36853717
3718+ private Variable FindParameterOrGlobalVariableFromExpression ( Expression expression )
3719+ {
3720+ var variableRef = expression as VariableReferenceExpression ;
3721+ if ( variableRef != null )
3722+ {
3723+ // Check if present in parameter list first.
3724+ var parameter = CurrentFunction . Parameters . FirstOrDefault ( x => x is Stride . Core . Shaders . Ast . Parameter param && param . Name == variableRef . Name ) ;
3725+ if ( parameter != null )
3726+ {
3727+ return parameter ;
3728+ }
3729+
3730+ return FindGlobalVariableFromExpression ( expression ) ;
3731+ }
3732+
3733+ return null ;
3734+ }
3735+
36863736 private Variable FindGlobalVariableFromExpression ( Expression expression )
36873737 {
36883738 var variableRef = expression as VariableReferenceExpression ;
@@ -3695,7 +3745,7 @@ private Variable FindGlobalVariableFromExpression(Expression expression)
36953745 // If a variable has an initial value, find the global variable
36963746 if ( ! shader . Declarations . Contains ( variable ) && variable . InitialValue != null )
36973747 {
3698- return this . FindGlobalVariableFromExpression ( variable . InitialValue ) ;
3748+ return FindGlobalVariableFromExpression ( variable . InitialValue ) ;
36993749 }
37003750
37013751 // Is this a global variable?
@@ -4290,6 +4340,29 @@ private TypeBase ConvertType(TypeBase targetType)
42904340 {
42914341 var targetTypeName = targetType . Name . Text ;
42924342
4343+ if ( ( targetTypeName . Equals ( "StructuredBuffer" , StringComparison . Ordinal ) || targetTypeName . Equals ( "RWStructuredBuffer" , StringComparison . Ordinal ) )
4344+ && targetType is IGenerics structuredBufferGenericType )
4345+ {
4346+ // Convert to "readonly buffer Name { GenericType Buffer; };
4347+ var structuredBufferType = structuredBufferGenericType . GenericArguments [ 0 ] ;
4348+
4349+ var name = $ "Stride_Internal_{ structuredBufferType . Name . Text } _{ ++ structedBufferCounter } ";
4350+ var bufferType = new Ast . Glsl . InterfaceType ( name )
4351+ {
4352+ Qualifiers = Qualifier . None , // Assign buffer qualifier later as we want the ordering to be correct (readonly should come first)
4353+ Fields = [ new Variable ( new ArrayType ( structuredBufferType , new EmptyExpression ( ) ) , "Buffer" ) ]
4354+ } ;
4355+
4356+ if ( targetTypeName . Equals ( "StructuredBuffer" , StringComparison . Ordinal ) )
4357+ {
4358+ bufferType . Qualifiers |= StorageQualifier . ReadOnly ;
4359+ }
4360+
4361+ bufferType . Qualifiers |= StorageQualifier . Buffer ;
4362+
4363+ return bufferType ;
4364+ }
4365+
42934366 if ( targetTypeName . StartsWith ( "Texture" , StringComparison . Ordinal ) )
42944367 targetTypeName = "texture" + targetTypeName [ "Texture" . Length ..] ;
42954368 else if ( targetTypeName . StartsWith ( "RWTexture" , StringComparison . Ordinal ) )
@@ -4584,18 +4657,32 @@ private void ReorderVariableQualifiers()
45844657 }
45854658 }
45864659
4660+ /// <summary>
4661+ /// Apply std140 layout to all constant and storage buffers.
4662+ /// </summary>
45874663 private void ApplyStd140Layout ( )
45884664 {
45894665 foreach ( var constantBuffer in shader . Declarations . OfType < ConstantBuffer > ( ) )
45904666 {
4591- var layoutQualifier = constantBuffer . Qualifiers . OfType < Stride . Core . Shaders . Ast . Glsl . LayoutQualifier > ( ) . FirstOrDefault ( ) ;
4667+ var layoutQualifier = constantBuffer . Qualifiers . OfType < LayoutQualifier > ( ) . FirstOrDefault ( ) ;
45924668 if ( layoutQualifier == null )
45934669 {
4594- layoutQualifier = new Stride . Core . Shaders . Ast . Glsl . LayoutQualifier ( ) ;
4670+ layoutQualifier = new LayoutQualifier ( ) ;
45954671 constantBuffer . Qualifiers |= layoutQualifier ;
45964672 }
45974673 layoutQualifier . Layouts . Add ( new LayoutKeyValue ( "std140" ) ) ;
45984674 }
4675+
4676+ foreach ( var variable in shader . Declarations . OfType < Variable > ( ) . Where ( x => x . Type . Qualifiers . Contains ( StorageQualifier . Buffer ) ) )
4677+ {
4678+ var layoutQualifier = variable . Qualifiers . OfType < LayoutQualifier > ( ) . FirstOrDefault ( ) ;
4679+ if ( layoutQualifier == null )
4680+ {
4681+ layoutQualifier = new LayoutQualifier ( ) ;
4682+ variable . Qualifiers |= layoutQualifier ;
4683+ }
4684+ layoutQualifier . Layouts . Add ( new LayoutKeyValue ( "std430" ) ) ; // But this is not std140? You are very much correct.
4685+ }
45994686 }
46004687
46014688 private class StructMemberReference
0 commit comments