123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.VFX;
- namespace UnityEditor.VFX
- {
- class VFXUniformMapper
- {
- public VFXUniformMapper(VFXExpressionMapper mapper, bool filterOutConstants)
- {
- m_FilterOutConstants = filterOutConstants;
- Init(mapper);
- }
- private void CollectAndAddUniforms(VFXExpression exp, IEnumerable<string> names, HashSet<VFXExpression> processedExp)
- {
- if (!exp.IsAny(VFXExpression.Flags.NotCompilableOnCPU))
- {
- string prefix;
- Dictionary<VFXExpression, List<string>> expressions;
- if (VFXExpression.IsUniform(exp.valueType))
- {
- if (m_FilterOutConstants && exp.Is(VFXExpression.Flags.Constant)) // Filter out constant uniform that should be patched directly in shader
- return;
- prefix = "uniform_";
- expressions = m_UniformToName;
- }
- else if (VFXExpression.IsTexture(exp.valueType))
- {
- prefix = "texture_";
- expressions = m_TextureToName;
- }
- else if (VFXExpression.IsBufferOnGPU(exp.valueType))
- {
- prefix = "buffer_";
- expressions = m_BufferToName;
- }
- else
- {
- if (VFXExpression.IsTypeValidOnGPU(exp.valueType))
- {
- throw new InvalidOperationException(string.Format("Missing handling for type: {0}", exp.valueType));
- }
- return;
- }
- List<string> previousNames;
- expressions.TryGetValue(exp, out previousNames);
- if (previousNames == null)
- {
- previousNames = new List<string>();
- expressions[exp] = previousNames;
- }
- if (names == null)
- {
- if (previousNames.Count == 0) // No need to generate a name if one was already generated
- previousNames.Add(prefix + VFXCodeGeneratorHelper.GeneratePrefix(m_CurrentUniformIndex++));
- }
- else
- previousNames.AddRange(names);
- }
- else
- {
- foreach (var parent in exp.parents)
- {
- if (processedExp.Contains(parent))
- continue;
- processedExp.Add(parent);
- CollectAndAddUniforms(parent, null, processedExp);
- }
- }
- }
- private void Init(VFXExpressionMapper mapper)
- {
- m_UniformToName = new Dictionary<VFXExpression, List<string>>();
- m_TextureToName = new Dictionary<VFXExpression, List<string>>();
- m_BufferToName = new Dictionary<VFXExpression, List<string>>();
- m_CurrentUniformIndex = 0;
- var processedExp = new HashSet<VFXExpression>();
- foreach (var exp in mapper.expressions)
- {
- processedExp.Clear();
- var initialNames = mapper.GetData(exp).Select(d => d.fullName);
- CollectAndAddUniforms(exp, initialNames, processedExp);
- }
- }
- public IEnumerable<VFXExpression> uniforms { get { return m_UniformToName.Keys; } }
- public IEnumerable<VFXExpression> textures { get { return m_TextureToName.Keys; } }
- public IEnumerable<VFXExpression> buffers { get { return m_BufferToName.Keys; } }
- // Get only the first name of a uniform (For generated code, we collapse all uniforms using the same expression into a single one)
- public string GetName(VFXExpression exp)
- {
- return GetNames(exp).First();
- }
- public List<string> GetNames(VFXExpression exp)
- {
- if (VFXExpression.IsTexture(exp.valueType))
- return m_TextureToName[exp];
- if (VFXExpression.IsBufferOnGPU(exp.valueType))
- return m_BufferToName[exp];
- return m_UniformToName[exp];
- }
- // This retrieves expression to name with additional type conversion where suitable
- public Dictionary<VFXExpression, string> expressionToCode
- {
- get
- {
- return m_UniformToName.Select(s =>
- {
- string code = null;
- string firstName = s.Value.First();
- switch (s.Key.valueType)
- {
- case VFXValueType.Int32:
- code = "asint(" + firstName + ")";
- break;
- case VFXValueType.Uint32:
- code = "asuint(" + firstName + ")";
- break;
- case VFXValueType.Boolean:
- code = "(bool)asuint(" + firstName + ")";
- break;
- default:
- code = firstName;
- break;
- }
- return new KeyValuePair<VFXExpression, string>(s.Key, code);
- })
- .Union(m_TextureToName.Select(s => new KeyValuePair<VFXExpression, string>(s.Key, s.Value.First())))
- .Union(m_BufferToName.Select(s => new KeyValuePair<VFXExpression, string>(s.Key, s.Value.First())))
- .ToDictionary(s => s.Key, s => s.Value);
- }
- }
- private Dictionary<VFXExpression, List<string>> m_UniformToName;
- private Dictionary<VFXExpression, List<string>> m_TextureToName;
- private Dictionary<VFXExpression, List<string>> m_BufferToName;
- private uint m_CurrentUniformIndex;
- private bool m_FilterOutConstants;
- }
- }
|