No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GraphValidation.cs 4.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Reflection;
  5. using UnityEditor.Graphing;
  6. using UnityEngine;
  7. namespace UnityEditor.ShaderGraph
  8. {
  9. sealed partial class GraphData : ISerializationCallbackReceiver
  10. {
  11. public static class GraphValidation
  12. {
  13. static Dictionary<Type, FieldInfo> s_ActiveSubTarget = new();
  14. static readonly PropertyInfo s_JsonData = typeof(Serialization.JsonData<SubTarget>).GetProperty("value");
  15. static SubTarget GetActiveSubTarget(Target target)
  16. {
  17. // All targets have an active subtarget but it's not accessible from ShaderGraph
  18. // so we use reflection to access it
  19. var type = target.GetType();
  20. if (!s_ActiveSubTarget.TryGetValue(type, out var activeSubTarget))
  21. {
  22. activeSubTarget = type.GetField("m_ActiveSubTarget", BindingFlags.Instance | BindingFlags.NonPublic);
  23. s_ActiveSubTarget.Add(type, activeSubTarget);
  24. }
  25. if (activeSubTarget != null)
  26. {
  27. var jsonData = activeSubTarget.GetValue(target);
  28. if (jsonData != null)
  29. {
  30. return s_JsonData.GetValue(jsonData) as SubTarget;
  31. }
  32. }
  33. return null;
  34. }
  35. public static void ValidateNode(AbstractMaterialNode node)
  36. {
  37. Type t = node.GetType();
  38. node.ValidateNode();
  39. if (!(node is BlockNode))
  40. {
  41. bool disallowedByAnyTargets = false;
  42. bool disallowedByAllTargets = true;
  43. bool disallowedByAnySubTarget = false;
  44. IEnumerable<Target> targets = node.owner.activeTargets;
  45. if (node.owner.isSubGraph)
  46. {
  47. targets = node.owner.allPotentialTargets;
  48. }
  49. foreach (var target in targets)
  50. {
  51. //if at least one target doesn't allow a node, it is considered invalid
  52. if (!target.IsNodeAllowedByTarget(t))
  53. {
  54. disallowedByAnyTargets = true;
  55. node.isValid = false;
  56. node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by {target.displayName} implementation", Rendering.ShaderCompilerMessageSeverity.Warning);
  57. node.owner.m_UnsupportedTargets.Add(target);
  58. }
  59. //at least one target does allow node, not going to be explicitly set inactive
  60. else
  61. {
  62. disallowedByAllTargets = false;
  63. }
  64. var subtarget = GetActiveSubTarget(target);
  65. if (subtarget != null && !subtarget.IsNodeAllowedBySubTarget(t))
  66. {
  67. disallowedByAnySubTarget = true;
  68. node.isValid = false;
  69. node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by {subtarget.displayName} implementation", Rendering.ShaderCompilerMessageSeverity.Error);
  70. }
  71. }
  72. if (!disallowedByAnyTargets && !disallowedByAnySubTarget)
  73. {
  74. node.isValid = true;
  75. }
  76. //Set ActiveState based on if all targets disallow this node
  77. if (disallowedByAllTargets)
  78. {
  79. node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.ExplicitInactive);
  80. node.owner.AddValidationError(node.objectId, $"{node.name} Node is not allowed by any active targets, and will not be used in generation", Rendering.ShaderCompilerMessageSeverity.Warning);
  81. }
  82. else
  83. {
  84. node.SetOverrideActiveState(AbstractMaterialNode.ActiveState.Implicit);
  85. }
  86. }
  87. }
  88. public static void ValidateGraph(GraphData graph)
  89. {
  90. graph.m_UnsupportedTargets.Clear();
  91. GraphDataUtils.ApplyActionLeafFirst(graph, ValidateNode);
  92. }
  93. }
  94. }
  95. }