Skip to content

Commit a8eb155

Browse files
committed
various tweaks to get vulkan to work with stride streaming terrain
1 parent c37f53c commit a8eb155

File tree

10 files changed

+178
-15
lines changed

10 files changed

+178
-15
lines changed

sources/engine/Stride.Graphics/Vulkan/Buffer.Vulkan.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,18 @@ public unsafe void Recreate(IntPtr dataPointer)
126126
NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader;
127127
}
128128

129+
if ((ViewFlags & BufferFlags.StructuredBuffer) != 0)
130+
{
131+
createInfo.usage |= VkBufferUsageFlags.StorageBuffer;
132+
NativeAccessMask |= VkAccessFlags.UniformRead;
133+
NativePipelineStageMask |= VkPipelineStageFlags.VertexShader | VkPipelineStageFlags.FragmentShader;
134+
135+
if ((ViewFlags & BufferFlags.UnorderedAccess) != 0)
136+
{
137+
NativeAccessMask |= VkAccessFlags.ShaderWrite;
138+
}
139+
}
140+
129141
if ((ViewFlags & BufferFlags.ShaderResource) != 0)
130142
{
131143
createInfo.usage |= VkBufferUsageFlags.UniformTexelBuffer;

sources/engine/Stride.Graphics/Vulkan/CommandList.Vulkan.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,12 @@ private unsafe void BindDescriptorSets()
373373
write->pTexelBufferView = &descriptorData->BufferView;
374374
break;
375375

376+
case VkDescriptorType.StorageBuffer:
377+
buffer = heapObject.Value as Buffer;
378+
descriptorData->BufferInfo = new VkDescriptorBufferInfo { buffer = buffer?.NativeBuffer ?? VkBuffer.Null, offset = (ulong)heapObject.Offset, range = (ulong)(buffer?.SizeInBytes ?? 0)};
379+
write->pBufferInfo = &descriptorData->BufferInfo;
380+
break;
381+
376382
default:
377383
throw new InvalidOperationException();
378384
}
@@ -1321,10 +1327,11 @@ public unsafe MappedResource MapSubresource(GraphicsResource resource, int subRe
13211327
throw new InvalidOperationException();
13221328
}
13231329

1324-
if (mapMode == MapMode.WriteDiscard)
1325-
{
1326-
throw new InvalidOperationException("Can't use WriteDiscard on Graphics API that doesn't support renaming");
1327-
}
1330+
// Maybe it just works if removed?
1331+
//if (mapMode == MapMode.WriteDiscard)
1332+
//{
1333+
// throw new InvalidOperationException("Can't use WriteDiscard on Graphics API that doesn't support renaming");
1334+
//}
13281335

13291336
if (mapMode != MapMode.WriteNoOverwrite && mapMode != MapMode.Write)
13301337
{

sources/engine/Stride.Graphics/Vulkan/GraphicsDevice.Vulkan.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public partial class GraphicsDevice
5757
64, // UniformTexelBuffer
5858
64, // StorageTexelBuffer
5959
512, // UniformBuffer
60-
0, // StorageBuffer
60+
64, // StorageBuffer
6161
0, // UniformBufferDynamic
6262
0, // StorageBufferDynamic
6363
0 // InputAttachment

sources/engine/Stride.Graphics/Vulkan/Texture.Vulkan.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ private unsafe VkImageView GetImageView(ViewType viewType, int arrayOrDepthSlice
487487
if (!IsShaderResource)
488488
return VkImageView.Null;
489489

490-
if (viewType == ViewType.MipBand)
490+
if (viewType == ViewType.MipBand && IsRenderTarget)
491491
throw new NotSupportedException("ViewSlice.MipBand is not supported for render targets");
492492

493493
GetViewSliceBounds(viewType, ref arrayOrDepthSlice, ref mipIndex, out var arrayOrDepthCount, out var mipCount);

sources/engine/Stride.Graphics/Vulkan/VulkanConvertExtensions.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,15 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form
276276
pixelSize = 4;
277277
break;
278278

279+
case PixelFormat.R10G10B10A2_UInt:
280+
format = VkFormat.A2R10G10B10UIntPack32;
281+
pixelSize = 4;
282+
break;
283+
case PixelFormat.R10G10B10A2_UNorm:
284+
format = VkFormat.A2R10G10B10UNormPack32;
285+
pixelSize = 4;
286+
break;
287+
279288
case PixelFormat.R16_Float:
280289
format = VkFormat.R16Sfloat;
281290
pixelSize = 2;
@@ -396,6 +405,10 @@ public static void ConvertPixelFormat(PixelFormat inputFormat, out VkFormat form
396405
format = VkFormat.D32Sfloat;
397406
pixelSize = 4;
398407
break;
408+
case PixelFormat.D32_Float_S8X24_UInt:
409+
format = VkFormat.D32SFloatS8UInt;
410+
pixelSize = 8;
411+
break;
399412

400413
case PixelFormat.ETC1:
401414
case PixelFormat.ETC2_RGB: // ETC1 upper compatible
@@ -554,6 +567,8 @@ public static VkDescriptorType ConvertDescriptorType(EffectParameterClass @class
554567

555568
case EffectParameterType.Buffer:
556569
return VkDescriptorType.UniformTexelBuffer;
570+
case EffectParameterType.StructuredBuffer:
571+
return VkDescriptorType.StorageBuffer;
557572

558573
default:
559574
throw new NotImplementedException();
@@ -578,6 +593,7 @@ public static VkDescriptorType ConvertDescriptorType(EffectParameterClass @class
578593
return VkDescriptorType.StorageImage;
579594

580595
case EffectParameterType.Buffer:
596+
case EffectParameterType.StructuredBuffer:
581597
return VkDescriptorType.StorageBuffer;
582598

583599
default:

sources/engine/Stride.Shaders.Compiler/OpenGL/ShaderCompiler.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ private string Compile(string shaderSource, string entryPoint, ShaderStage stage
344344
layoutQualifier.Layouts.Add(new LayoutKeyValue("binding", layoutBindingIndex + 1));
345345

346346
resourceBindings.Add(bindings[layoutBindingIndex].Key.KeyName, layoutBindingIndex + 1);
347+
348+
// Buffer should not be marked with uniform, this probably should not be here but it works and does not mess anything up.
349+
if (variable.Type.Qualifiers.Contains(StorageQualifier.Buffer))
350+
{
351+
variable.Qualifiers.Values.Remove(StorageQualifier.Uniform);
352+
}
347353
}
348354
}
349355
}

sources/shaders/Stride.Core.Shaders/Ast/StorageQualifier.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,11 @@ public partial class StorageQualifier
2121
/// </summary>
2222
public static readonly Qualifier Uniform = new Qualifier("uniform");
2323

24+
/// <summary>
25+
/// Uniform qualifier.
26+
/// </summary>
27+
public static readonly Qualifier Buffer = new Qualifier("buffer");
28+
2429
/// <summary>
2530
/// Shared qualifier.
2631
/// </summary>

sources/shaders/Stride.Core.Shaders/Convertor/HlslToGlslConvertor.cs

Lines changed: 94 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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

sources/shaders/Stride.Core.Shaders/Convertor/SamplerMappingVisitor.cs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,36 @@ public override void Run(MethodDefinition methodEntry)
6464
}
6565
}
6666

67+
private Variable FindParameterOrGlobalVariable(Expression expression)
68+
{
69+
var variableRef = expression as VariableReferenceExpression;
70+
if (variableRef != null)
71+
{
72+
// Check if present in parameter list first.
73+
MethodDeclaration currentFunction = null;
74+
for (var i = NodeStack.Count - 1; i >= 0; i--)
75+
{
76+
if (NodeStack[i] is MethodDeclaration function)
77+
{
78+
currentFunction = function;
79+
break;
80+
}
81+
}
82+
if (currentFunction != null)
83+
{
84+
var parameter = currentFunction.Parameters.FirstOrDefault(x => x is Stride.Core.Shaders.Ast.Parameter param && param.Name == variableRef.Name);
85+
if (parameter != null)
86+
{
87+
return parameter;
88+
}
89+
}
90+
91+
return FindGlobalVariable(expression);
92+
}
93+
94+
return null;
95+
}
96+
6797
private Variable FindGlobalVariable(Expression expression)
6898
{
6999
var variableRef = expression as VariableReferenceExpression;
@@ -108,7 +138,7 @@ public override Node Visit(MethodInvocationExpression methodInvocationExpression
108138
if (memberRef != null)
109139
{
110140
// TODO handle Texture2D<float>
111-
var textureVariable = this.FindGlobalVariable(memberRef.Target);
141+
var textureVariable = FindParameterOrGlobalVariable(memberRef.Target);
112142

113143
if (textureVariable != null)
114144
{

sources/shared/Stride.NuGetResolver.Targets/Stride.NuGetResolver.Targets.projitems

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
<NuGetResolverModuleInitializerFile>$(IntermediateOutputPath)$(MSBuildProjectName).NuGetResolverEntryPoint$(DefaultLanguageSourceExtension)</NuGetResolverModuleInitializerFile>
2323
<NuGetResolverTargetFramework>$(TargetFramework)</NuGetResolverTargetFramework>
2424
<NuGetResolverTargetFramework Condition="'$(TargetPlatformVersion)' != '' and !$(TargetFramework.EndsWith(TargetPlatformVersion))">$(TargetFramework)$(TargetPlatformVersion)</NuGetResolverTargetFramework>
25-
<DefineConstants Condition="'$(StrideNuGetResolverUI)' == 'true'">STRIDE_NUGET_RESOLVER_UI;$(DefineConstants)</DefineConstants>
25+
<DefineConstants Condition="'$(StrideNuGetResolverUI)' == 'true'">STRIDE_NUGET_RESOLVER_UI;$(DefineConstants)</DefineConstants>
2626
</PropertyGroup>
2727
<WriteLinesToFile File="$(NuGetResolverModuleInitializerFile)" Overwrite="true" Lines="$([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)NuGetResolverModuleInitializer.cs').Replace('STRIDE_NUGET_RESOLVER_TARGET_FRAMEWORK','&quot;$(NuGetResolverTargetFramework)&quot;').Replace('STRIDE_NUGET_RESOLVER_PACKAGE_NAME','&quot;$(PackageId)&quot;').Replace('STRIDE_NUGET_RESOLVER_PACKAGE_VERSION','&quot;$(PackageVersion)&quot;').Replace('STRIDE_NUGET_RESOLVER_UI_AVALONIA_VERSION','&quot;$(AvaloniaVersion)&quot;'))" />
2828
<ItemGroup>

0 commit comments

Comments
 (0)