Skip to content

Commit 9ccd98c

Browse files
PaulDemeulenaereEvergreen
authored andcommitted
[VFX] CustomHLSL Operator Includes
Correctly handle HLSL includes in vfx custom operator. It was simply discarded before this change. 🎁 Bonus: - Remove unexpected warnings about `in` missing in operators ![image](https://media.github.cds.internal.unity3d.com/user/42/files/293fe03b-8af0-48da-a291-3b07788511c0) - Add errors when include refers to missing files https://media.github.cds.internal.unity3d.com/user/42/files/76139d70-9a35-472d-95d2-fa3176dd6da8 - Factorize error feedback for CustomHLSL at https://github.cds.internal.unity3d.com/unity/unity/pull/46642/commits/5a25691885a828b0af6d42313ed042b8362b52bb
1 parent 0a12d40 commit 9ccd98c

File tree

16 files changed

+1592
-646
lines changed

16 files changed

+1592
-646
lines changed

Packages/com.unity.render-pipelines.high-definition/Editor/Water/WaterSurface/VFX/SampleWaterSurface.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ protected override sealed VFXExpression[] BuildExpression(VFXExpression[] inputE
7979
string EvaluateNormal = baseCode + "float3 EvaluateNormal(float3 positionWS) { " + FindVerticalDisplacements + " return normal; }";
8080
string EvaluateCurrent = baseCode + "float2 EvaluateCurrent(float3 positionWS) { " + FindVerticalDisplacements + " return current; }";
8181

82-
VFXExpression outputPosition = new VFXExpressionHLSL("ProjectPoint", ProjectPoint, typeof(Vector3), inputExpression);
83-
VFXExpression outputHeight = new VFXExpressionHLSL("EvaluateHeight", EvaluateHeight, typeof(float), inputExpression);
84-
VFXExpression outputNormal = new VFXExpressionHLSL("EvaluateNormal", EvaluateNormal, typeof(Vector3), inputExpression);
85-
VFXExpression outputCurrent = new VFXExpressionHLSL("EvaluateCurrent", EvaluateCurrent, typeof(Vector3), inputExpression);
82+
VFXExpression outputPosition = new VFXExpressionHLSL("ProjectPoint", ProjectPoint, typeof(Vector3), inputExpression, Array.Empty<string>());
83+
VFXExpression outputHeight = new VFXExpressionHLSL("EvaluateHeight", EvaluateHeight, typeof(float), inputExpression, Array.Empty<string>());
84+
VFXExpression outputNormal = new VFXExpressionHLSL("EvaluateNormal", EvaluateNormal, typeof(Vector3), inputExpression, Array.Empty<string>());
85+
VFXExpression outputCurrent = new VFXExpressionHLSL("EvaluateCurrent", EvaluateCurrent, typeof(Vector3), inputExpression, Array.Empty<string>());
8686
return new [] { outputPosition, outputHeight, outputNormal, outputCurrent };
8787
}
8888
}

Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXCodeGenerator.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -754,8 +754,10 @@ static private StringBuilder Build(
754754

755755
// Per-block includes
756756
var includes = Enumerable.Empty<string>();
757-
foreach (var block in context.activeFlattenedChildrenWithImplicit)
757+
foreach (var block in context.activeFlattenedChildrenWithImplicit.OfType<IHLSLCodeHolder>())
758758
includes = includes.Concat(block.includes);
759+
foreach (var hlslHolder in taskData.hlslCodeHolders)
760+
includes = includes.Concat(hlslHolder.includes);
759761
var uniqueIncludes = new HashSet<string>(includes);
760762
foreach (var includePath in uniqueIncludes)
761763
perPassIncludeContent.WriteLine(string.Format("#include \"{0}\"", includePath));

Packages/com.unity.visualeffectgraph/Editor/Compiler/VFXShaderWriter.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ public static string GeneratePrefix(uint index)
2929

3030
interface IHLSLCodeHolder : IEquatable<IHLSLCodeHolder>
3131
{
32+
IEnumerable<string> includes { get; }
3233
ShaderInclude shaderFile { get; }
3334
string sourceCode { get; set; }
3435
string customCode { get; }

Packages/com.unity.visualeffectgraph/Editor/Expressions/VFXExpressionHLSL.cs

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using System.Collections.Generic;
23
using UnityEngine.VFX;
34

@@ -11,32 +12,37 @@ class VFXExpressionHLSL : VFXExpression, IHLSLCodeHolder
1112
VFXValueType m_ValueType;
1213
string m_HlslCode;
1314
List<int> m_TextureParentExpressionIndex;
15+
string[] m_Includes;
1416

15-
public VFXExpressionHLSL() : this(string.Empty, string.Empty, VFXValueType.None, new [] { VFXValue<int>.Default })
17+
public VFXExpressionHLSL() : this(string.Empty, string.Empty, VFXValueType.None, new [] { VFXValue<int>.Default }, Array.Empty<string>())
1618
{
1719
}
1820

19-
public VFXExpressionHLSL(string functionName, string hlslCode, VFXValueType returnType, VFXExpression[] parents) : base(Flags.InvalidOnCPU, parents)
21+
public VFXExpressionHLSL(string functionName, string hlslCode, VFXValueType returnType, VFXExpression[] parents, string[] includes) : base(Flags.InvalidOnCPU, parents)
2022
{
2123
this.m_TextureParentExpressionIndex = new List<int>();
2224
this.m_FunctionName = functionName;
2325
this.m_ValueType = returnType;
2426
this.m_HlslCode = hlslCode;
27+
this.m_Includes = includes;
2528
}
2629

27-
public VFXExpressionHLSL(string functionName, string hlslCode, System.Type returnType, VFXExpression[] parents) : base(Flags.InvalidOnCPU, parents)
30+
public VFXExpressionHLSL(string functionName, string hlslCode, System.Type returnType, VFXExpression[] parents, string[] includes) : base(Flags.InvalidOnCPU, parents)
2831
{
2932
this.m_TextureParentExpressionIndex = new List<int>();
3033
this.m_FunctionName = functionName;
3134
this.m_ValueType = GetVFXValueTypeFromType(returnType);
3235
this.m_HlslCode = hlslCode;
36+
this.m_Includes = includes;
3337
}
3438

3539
public override VFXValueType valueType => m_ValueType;
3640
public override VFXExpressionOperation operation => VFXExpressionOperation.None;
3741
public ShaderInclude shaderFile => null;
3842
public string sourceCode { get; set; }
3943
public string customCode => m_HlslCode;
44+
public IEnumerable<string> includes => m_Includes;
45+
4046
public bool HasShaderFile() => false;
4147
public bool Equals(IHLSLCodeHolder other) => false;
4248

@@ -45,9 +51,23 @@ public override bool Equals(object obj)
4551
if (!base.Equals(obj))
4652
return false;
4753

54+
if (ReferenceEquals(this, obj))
55+
return true;
56+
4857
if (obj is VFXExpressionHLSL hlslExpression)
4958
{
50-
return hlslExpression.m_FunctionName == m_FunctionName && hlslExpression.valueType == valueType && hlslExpression.m_HlslCode == m_HlslCode;
59+
if (hlslExpression.m_Includes.Length == m_Includes.Length)
60+
return false;
61+
62+
for (var index = 0; index < m_Includes.Length; ++index)
63+
{
64+
if (hlslExpression.m_Includes[index] != m_Includes[index])
65+
return false;
66+
}
67+
68+
return hlslExpression.m_FunctionName == m_FunctionName
69+
&& hlslExpression.valueType == valueType
70+
&& hlslExpression.m_HlslCode == m_HlslCode;
5171
}
5272

5373
return false;
@@ -56,16 +76,15 @@ public override bool Equals(object obj)
5676
protected override int GetInnerHashCode()
5777
{
5878
var hash = base.GetInnerHashCode();
59-
hash = (hash * 397) ^ m_FunctionName.GetHashCode();
60-
hash = (hash * 397) ^ m_ValueType.GetHashCode();
61-
hash = (hash * 397) ^ m_HlslCode.GetHashCode();
79+
hash = HashCode.Combine(hash, m_FunctionName.GetHashCode(), m_ValueType.GetHashCode(), m_HlslCode.GetHashCode());
80+
foreach (var include in m_Includes)
81+
hash = HashCode.Combine(hash, include);
6282
return hash;
6383
}
6484

6585
protected override VFXExpression Reduce(VFXExpression[] reducedParents)
6686
{
6787
m_TextureParentExpressionIndex.Clear();
68-
6988
for (int i = 0; i < reducedParents.Length; i++)
7089
{
7190
if (IsTexture(reducedParents[i].valueType))
@@ -78,7 +97,8 @@ protected override VFXExpression Reduce(VFXExpression[] reducedParents)
7897
newExpression.m_FunctionName = m_FunctionName;
7998
newExpression.m_ValueType = m_ValueType;
8099
newExpression.m_HlslCode = m_HlslCode;
81-
newExpression.m_TextureParentExpressionIndex = m_TextureParentExpressionIndex;
100+
newExpression.m_TextureParentExpressionIndex = new List<int>(m_TextureParentExpressionIndex);
101+
newExpression.m_Includes = (string[])m_Includes.Clone();
82102
return newExpression;
83103
}
84104

Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/HLSL/CustomHLSL.cs

Lines changed: 4 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,10 @@
99

1010
namespace UnityEditor.VFX.Block
1111
{
12-
class CustomHLSLBlockFunctionValidator
12+
sealed class CustomHLSLBlockFunctionValidator : Operator.CustomHLSLFunctionValidator
1313
{
14-
public IEnumerable<IHLSMessage> Validate(IEnumerable<string> functions, HLSLFunction selectedFunction)
14+
protected override IEnumerable<IHLSMessage> ValidateImpl(IEnumerable<string> functions, HLSLFunction selectedFunction)
1515
{
16-
if (functions == null || selectedFunction == null)
17-
{
18-
yield return new HLSLMissingFunction();
19-
yield break;
20-
}
21-
22-
var functionsFound = new Dictionary<string, int>();
23-
foreach (var f in functions)
24-
{
25-
if (functionsFound.TryGetValue(f, out var count) && count == 1)
26-
{
27-
yield return new HLSLSameFunctionName(f);
28-
}
29-
else
30-
{
31-
count = 0;
32-
}
33-
34-
functionsFound[f] = count + 1;
35-
}
36-
3716
if (selectedFunction.returnType != typeof(void))
3817
{
3918
yield return new HLSLVoidReturnTypeOnlyIsSupported(selectedFunction.name);
@@ -46,15 +25,6 @@ public IEnumerable<IHLSMessage> Validate(IEnumerable<string> functions, HLSLFunc
4625
HLSLFunctionParameter attributesInput = null;
4726
foreach (var input in selectedFunction.inputs)
4827
{
49-
if (input.access is HLSLAccess.IN or HLSLAccess.INOUT &&
50-
input.rawType is "Texture2D" or "Texture3D" or "TextureCube" or "Texture2DArray")
51-
{
52-
yield return new HLSLWrongHLSLTextureType(input.rawType, input.name);
53-
}
54-
if (input.rawType is "TextureCubeArray" or "VFXSamplerCubeArray")
55-
{
56-
yield return new HLSLTextureCubeArrayNotSupported(input.name);
57-
}
5828
if (input.type == typeof(VFXAttribute))
5929
{
6030
attributesInput = input;
@@ -82,17 +52,6 @@ public IEnumerable<IHLSMessage> Validate(IEnumerable<string> functions, HLSLFunc
8252
}
8353
}
8454
}
85-
86-
foreach (var message in selectedFunction.inputs)
87-
{
88-
if (message.errors != null)
89-
{
90-
foreach (var error in message.errors)
91-
{
92-
yield return error;
93-
}
94-
}
95-
}
9655
}
9756
}
9857

@@ -207,7 +166,7 @@ public string sourceCode
207166
}
208167
}
209168
public string customCode => BuildCustomCode();
210-
public override IEnumerable<string> includes
169+
public IEnumerable<string> includes
211170
{
212171
get
213172
{
@@ -284,7 +243,7 @@ internal override void GenerateErrors(VFXErrorReporter report)
284243
base.GenerateErrors(report);
285244
var hlslValidator = new CustomHLSLBlockFunctionValidator();
286245
ParseCodeIfNeeded();
287-
foreach(var error in hlslValidator.Validate(m_AvailableFunction.values, m_Function))
246+
foreach(var error in hlslValidator.Validate(m_AvailableFunction.values, m_Function, includes))
288247
{
289248
report.RegisterError(string.Empty, error.type, error.message, this);
290249
}

Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/Implementations/HLSL/HLSLParser.cs

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -46,43 +46,7 @@ class HLSLVFXAttributeAccessError : IHLSMessage
4646
public string message => "Missing `inout` access modifier before the VFXAttributes type.\nNeeded because your code writes to at least one attribute.";
4747
public VFXErrorType type => VFXErrorType.Error;
4848
}
49-
50-
class HLSLMissingAccessError : IHLSMessage
51-
{
52-
string m_Name;
53-
HLSLAccess[] m_ExpectedAccess;
54-
HLSLAccess m_Fallback;
55-
56-
public HLSLMissingAccessError(string parameterName, HLSLAccess[] expectedAccess, HLSLAccess fallback = HLSLAccess.NONE)
57-
{
58-
m_Name = parameterName;
59-
m_ExpectedAccess = expectedAccess;
60-
m_Fallback = fallback;
61-
}
62-
63-
public string message
64-
{
65-
get
66-
{
67-
var sb = new StringBuilder();
68-
sb.Append($"Missing access modifier for parameter {m_Name}. Expected ");
69-
foreach (var access in m_ExpectedAccess)
70-
{
71-
sb.Append($" or '{access.ToString().ToLower()}'");
72-
}
73-
if (m_Fallback != HLSLAccess.NONE)
74-
{
75-
sb.AppendLine();
76-
sb.Append($"Fallback to '{m_Fallback.ToString().ToLower()}'.");
77-
}
78-
79-
return sb.ToString();
80-
}
81-
}
82-
83-
public VFXErrorType type => VFXErrorType.Warning;
84-
}
85-
49+
8650
class HLSLMissingVFXAttribute : IHLSMessage
8751
{
8852
public string message => "Missing `VFXAttributes attributes` as function's parameter";
@@ -188,6 +152,16 @@ public HLSLOutParameterNotAllowed(string parameterName)
188152
public VFXErrorType type => VFXErrorType.Error;
189153
}
190154

155+
class HLSLMissingIncludeFile : IHLSMessage
156+
{
157+
public HLSLMissingIncludeFile(string filePath)
158+
{
159+
message = $"Couldn't open include file '{filePath}'.";
160+
}
161+
public string message { get; }
162+
public VFXErrorType type => VFXErrorType.Error;
163+
}
164+
191165
class HLSLFunctionParameter
192166
{
193167
// Match inout/in/out accessor then any whitespace then the parameter type then optionally a template type any whitespace and then the parameter name

Packages/com.unity.visualeffectgraph/Editor/Models/Blocks/VFXBlock.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ public bool isActive
7070
public virtual IEnumerable<VFXAttributeInfo> attributes { get { return Enumerable.Empty<VFXAttributeInfo>(); } }
7171
public virtual IEnumerable<VFXNamedExpression> parameters { get { return GetExpressionsFromSlots(this); } }
7272
public VFXExpression activationExpression => m_ActivationSlot.GetExpression();
73-
public virtual IEnumerable<string> includes { get { return Enumerable.Empty<string>(); } }
7473
public virtual IEnumerable<string> defines { get { return Enumerable.Empty<string>(); } }
7574
public virtual string source => null;
7675

0 commit comments

Comments
 (0)