4 using System.Collections.Generic;
6 using SiliconStudio.Shaders.Ast;
7 using SiliconStudio.Shaders.Ast.Hlsl;
9 namespace SiliconStudio.Shaders.Visitor
17 private Dictionary<Node, HashSet<Node>> indirectReferences;
18 private readonly
string[] entryPoints;
24 public StripVisitor(params
string[] entryPoints) : base(true, true)
26 this.entryPoints = entryPoints;
27 this.StripUniforms =
true;
28 this.KeepConstantBuffers =
true;
31 public bool StripUniforms {
get; set; }
33 public bool KeepConstantBuffers {
get; set; }
38 Visit((
Node)methodInvocationExpression);
39 AddReference(GetDeclarationContainer(), (
Node)methodInvocationExpression.TypeInference.Declaration);
45 Visit((
Node)variableReferenceExpression);
46 AddReference(GetDeclarationContainer(), (
Node)variableReferenceExpression.TypeInference.Declaration);
54 currentConstantBuffer = constantBuffer;
55 Visit((
Node)constantBuffer);
56 currentConstantBuffer = null;
64 if (KeepConstantBuffers && currentConstantBuffer != null && node is
IDeclaration)
66 AddReference(node, currentConstantBuffer);
67 AddReference(currentConstantBuffer, node);
70 return base.PreVisitNode(node);
77 Visit((
Node)parameter);
78 var containers = GetDeclarationContainers();
79 var container = containers[containers.Count - 2];
80 AddReference((
Node)container, parameter);
86 Visit((
Node)typeReference);
87 AddReference(GetDeclarationContainer(), (
Node)typeReference.TypeInference.Declaration);
93 Visit((
Node)methodDefinition);
96 if (!ReferenceEquals(methodDefinition.Declaration, methodDefinition))
98 AddReference(methodDefinition.Declaration, methodDefinition);
105 Visit((
Node)variable);
106 var containers = GetDeclarationContainers();
107 if (containers.Count > 1)
109 var container = containers[containers.Count - 2];
110 AddReference((
Node)container, variable);
117 indirectReferences =
new Dictionary<Node, HashSet<Node>>();
120 Visit((
Node) shader);
124 var collectedReferences =
new List<Node>();
125 foreach (var entryPointName
in entryPoints)
128 var entryPoint = shader.Declarations.OfType<
MethodDefinition>().FirstOrDefault(x => x.Name == entryPointName);
130 if (entryPoint == null)
131 throw new ArgumentException(
string.Format(
"Could not find entry point named {0}", entryPointName));
133 CollectReferences(collectedReferences, entryPoint);
136 StripDeclarations(shader.Declarations, collectedReferences, StripUniforms);
144 private static void StripDeclarations(IList<Node> nodes,
ICollection<Node> collectedReferences,
bool stripUniforms)
147 for (
int i = 0; i < nodes.Count; i++)
149 var declaration = nodes[i];
152 var variableDeclaration = (Variable)declaration;
153 if ((!stripUniforms && variableDeclaration.Qualifiers.Contains(Ast.StorageQualifier.Uniform)) || variableDeclaration.Name.Text ==
"ParadoxFlipRendertarget")
156 if (variableDeclaration.IsGroup)
158 variableDeclaration.SubVariables.RemoveAll(x => !collectedReferences.Contains(x));
159 if (variableDeclaration.SubVariables.Count == 0)
165 else if (!collectedReferences.Contains(declaration))
171 else if (declaration is
IDeclaration && !collectedReferences.Contains(declaration))
182 StripDeclarations(constantBuffer.Members, collectedReferences, stripUniforms);
193 private void CollectReferences(List<Node> collectedReferences,
Node reference)
195 if (!collectedReferences.Contains(reference))
198 collectedReferences.Add(reference);
201 HashSet<Node> referencedFunctions;
202 if (indirectReferences.TryGetValue((
Node)reference, out referencedFunctions))
204 foreach (var referencedFunction
in referencedFunctions)
205 CollectReferences(collectedReferences, referencedFunction);
212 if (parent != null && declaration != null)
214 HashSet<Node> childReferences;
215 if (!indirectReferences.TryGetValue(parent, out childReferences))
217 childReferences =
new HashSet<Node>();
218 indirectReferences[parent] = childReferences;
220 if (!childReferences.Contains(declaration))
221 childReferences.Add(declaration);
226 private Node GetDeclarationContainer()
230 if (methodDefinition != null)
231 return methodDefinition;
237 private List<IDeclaration> GetDeclarationContainers()
SiliconStudio.Shaders.Ast.Hlsl.ConstantBuffer ConstantBuffer
StripVisitor(params string[] entryPoints)
Initializes a new instance of the StripVisitor class.
void Visit(Shader shader)
void Visit(MethodDefinition methodDefinition)
void Visit(Variable variable)
void Visit(MethodInvocationExpression methodInvocationExpression)
A method definition with a body of statements.
A single parameter declaration.
override bool PreVisitNode(Node node)
Called before visiting the node.
void Visit(Parameter parameter)
The strip visitor collects all function and declaration used by a set of entrypoints and remove any u...
Declaration of a constant buffer.
Toplevel container of a shader parsing result.
A reference to a variable.
void Visit(VariableReferenceExpression variableReferenceExpression)
void Visit(TypeBase typeReference)
Toplevel interface for a declaration.
IReferencable.AddReference() event.
void Visit(ConstantBuffer constantBuffer)