@@ -101,6 +101,8 @@ public class HlslToGlslConvertor : ShaderRewriter
101
101
102
102
private int breakIndex = 0 ;
103
103
104
+ private int structedBufferCounter = 0 ;
105
+
104
106
#endregion
105
107
106
108
#region Constructors and Destructors
@@ -243,7 +245,7 @@ public HlslToGlslConvertor(GlslShaderPlatform shaderPlatform, int shaderVersion,
243
245
{ "GroupMemoryBarrier" , "groupMemoryBarrier" } ,
244
246
//{ "D3DCOLORtoUBYTE4", "ivec4" },
245
247
} ;
246
- }
248
+ }
247
249
248
250
#endregion
249
251
@@ -1093,7 +1095,7 @@ protected Statement VisitStatementAsMemberInvocation(Statement statement, Method
1093
1095
if ( memberReferenceExpression . Member == "GetDimensions" )
1094
1096
{
1095
1097
var textureRef = memberReferenceExpression . Target as VariableReferenceExpression ;
1096
- var variableTexture = this . FindGlobalVariableFromExpression ( textureRef ) ;
1098
+ var variableTexture = FindParameterOrGlobalVariableFromExpression ( textureRef ) ;
1097
1099
1098
1100
if ( variableTexture == null )
1099
1101
{
@@ -1233,6 +1235,7 @@ protected Statement VisitStatementAsAssignExpression(Statement statement, Assign
1233
1235
"RWBuffer" => ScalarType . Int ,
1234
1236
"RWTexture2D" => VectorType . Int2 ,
1235
1237
"RWTexture3D" => VectorType . Int3 ,
1238
+ "RWTexture2DArray" => VectorType . Int3 ,
1236
1239
_ => throw new NotSupportedException ( $ "imageStore not supported for { variable . Name . Text } ")
1237
1240
} ;
1238
1241
@@ -1307,6 +1310,24 @@ public override Node Visit(MethodInvocationExpression methodInvocationExpression
1307
1310
return new ParenthesizedExpression ( new BinaryExpression ( BinaryOperator . Multiply , leftParameter , rightParameter ) ) ;
1308
1311
}
1309
1312
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
+
1310
1331
if ( methodName == "lit" )
1311
1332
{
1312
1333
// http://msdn.microsoft.com/en-us/library/bb509619%28v=vs.85%29.aspx
@@ -1389,7 +1410,7 @@ public override Node Visit(MethodInvocationExpression methodInvocationExpression
1389
1410
var memberReferenceExpression = methodInvocationExpression . Target as MemberReferenceExpression ;
1390
1411
if ( memberReferenceExpression != null )
1391
1412
{
1392
- var targetVariable = FindGlobalVariableFromExpression ( memberReferenceExpression . Target ) ;
1413
+ var targetVariable = FindParameterOrGlobalVariableFromExpression ( memberReferenceExpression . Target ) ;
1393
1414
if ( targetVariable == null )
1394
1415
{
1395
1416
parserResult . Error ( "Unable to find target variable for expression [{0}]" , methodInvocationExpression . Span , methodInvocationExpression ) ;
@@ -1428,7 +1449,7 @@ public override Node Visit(MethodInvocationExpression methodInvocationExpression
1428
1449
// texture.Load() doesn't require a sampler
1429
1450
if ( ! isLoad )
1430
1451
{
1431
- sampler = this . FindGlobalVariableFromExpression ( methodInvocationExpression . Arguments [ 0 ] ) ;
1452
+ sampler = FindParameterOrGlobalVariableFromExpression ( methodInvocationExpression . Arguments [ 0 ] ) ;
1432
1453
}
1433
1454
var glslSampler = GetGLSampler ( sampler , targetVariable , true ) ;
1434
1455
@@ -2477,6 +2498,7 @@ public override Node Visit(IndexerExpression indexerExpression)
2477
2498
"RWBuffer" => ScalarType . Int ,
2478
2499
"RWTexture2D" => VectorType . Int2 ,
2479
2500
"RWTexture3D" => VectorType . Int3 ,
2501
+ "RWTexture2DArray" => VectorType . Int3 ,
2480
2502
_ => throw new NotSupportedException ( $ "imageLoad not supported for { variable . Name . Text } ")
2481
2503
} ;
2482
2504
@@ -2485,6 +2507,16 @@ public override Node Visit(IndexerExpression indexerExpression)
2485
2507
2486
2508
return new MethodInvocationExpression ( "imageLoad" , indexerExpression . Target , new MethodInvocationExpression ( new TypeReferenceExpression ( indexerType ) , indexerExpression . Index ) ) ;
2487
2509
}
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
+ }
2488
2520
}
2489
2521
2490
2522
base . Visit ( indexerExpression ) ;
@@ -3683,6 +3715,24 @@ private void FlattenArrayCreationExpression(ArrayInitializerExpression from, Lis
3683
3715
}
3684
3716
}
3685
3717
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
+
3686
3736
private Variable FindGlobalVariableFromExpression ( Expression expression )
3687
3737
{
3688
3738
var variableRef = expression as VariableReferenceExpression ;
@@ -3695,7 +3745,7 @@ private Variable FindGlobalVariableFromExpression(Expression expression)
3695
3745
// If a variable has an initial value, find the global variable
3696
3746
if ( ! shader . Declarations . Contains ( variable ) && variable . InitialValue != null )
3697
3747
{
3698
- return this . FindGlobalVariableFromExpression ( variable . InitialValue ) ;
3748
+ return FindGlobalVariableFromExpression ( variable . InitialValue ) ;
3699
3749
}
3700
3750
3701
3751
// Is this a global variable?
@@ -4290,6 +4340,29 @@ private TypeBase ConvertType(TypeBase targetType)
4290
4340
{
4291
4341
var targetTypeName = targetType . Name . Text ;
4292
4342
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
+
4293
4366
if ( targetTypeName . StartsWith ( "Texture" , StringComparison . Ordinal ) )
4294
4367
targetTypeName = "texture" + targetTypeName [ "Texture" . Length ..] ;
4295
4368
else if ( targetTypeName . StartsWith ( "RWTexture" , StringComparison . Ordinal ) )
@@ -4584,18 +4657,32 @@ private void ReorderVariableQualifiers()
4584
4657
}
4585
4658
}
4586
4659
4660
+ /// <summary>
4661
+ /// Apply std140 layout to all constant and storage buffers.
4662
+ /// </summary>
4587
4663
private void ApplyStd140Layout ( )
4588
4664
{
4589
4665
foreach ( var constantBuffer in shader . Declarations . OfType < ConstantBuffer > ( ) )
4590
4666
{
4591
- var layoutQualifier = constantBuffer . Qualifiers . OfType < Stride . Core . Shaders . Ast . Glsl . LayoutQualifier > ( ) . FirstOrDefault ( ) ;
4667
+ var layoutQualifier = constantBuffer . Qualifiers . OfType < LayoutQualifier > ( ) . FirstOrDefault ( ) ;
4592
4668
if ( layoutQualifier == null )
4593
4669
{
4594
- layoutQualifier = new Stride . Core . Shaders . Ast . Glsl . LayoutQualifier ( ) ;
4670
+ layoutQualifier = new LayoutQualifier ( ) ;
4595
4671
constantBuffer . Qualifiers |= layoutQualifier ;
4596
4672
}
4597
4673
layoutQualifier . Layouts . Add ( new LayoutKeyValue ( "std140" ) ) ;
4598
4674
}
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
+ }
4599
4686
}
4600
4687
4601
4688
private class StructMemberReference
0 commit comments