Skip to content

Instantly share code, notes, and snippets.

@wotakuro
Created October 10, 2024 01:57
Show Gist options
  • Save wotakuro/f6132b9d4393d6af9c59893b07a21308 to your computer and use it in GitHub Desktop.
Save wotakuro/f6132b9d4393d6af9c59893b07a21308 to your computer and use it in GitHub Desktop.
GraphicStateCollectionのInspectorだと情報見にくかったので用意
using UnityEditor;
using UnityEngine;
using UnityEditor.UIElements;
using UnityEngine.UIElements;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
using UnityEngine.Rendering;
using System.Text;
namespace UTJ
{
public class GraphicStateCollectionViewer : EditorWindow
{
[MenuItem("Tools/GraphicStateCollectionViewer")]
public static void Create()
{
GraphicStateCollectionViewer.GetWindow<GraphicStateCollectionViewer>();
}
private GraphicsStateCollection stateCollection;
private VisualElement stateCollectionHeaderInfo;
private ScrollView scrollView;
private List<GraphicsStateCollection.ShaderVariant> variantsBuffer;
private List<Shader> shaders;
private Dictionary< Shader , List<GraphicsStateCollection.ShaderVariant> > variants;
private Dictionary<GraphicsStateCollection.ShaderVariant, List<GraphicsStateCollection.GraphicsState> > states;
private StringBuilder stringBuilder = new StringBuilder();
private void OnEnable()
{
this.variantsBuffer = new List<GraphicsStateCollection.ShaderVariant>();
this.shaders = new List<Shader>();
this.variants = new Dictionary<Shader, List<GraphicsStateCollection.ShaderVariant>>();
this.states = new Dictionary<GraphicsStateCollection.ShaderVariant, List<GraphicsStateCollection.GraphicsState> >();
var vi = new VisualElement();
var selectObj = new ObjectField("Select GraphicsStateCollection");
selectObj.objectType = typeof(GraphicsStateCollection);
vi.Add(selectObj);
this.stateCollectionHeaderInfo = new VisualElement();
vi.Add(this.stateCollectionHeaderInfo);
this.scrollView = new ScrollView();
vi.Add(this.scrollView);
selectObj.RegisterValueChangedCallback(OnChangeObject);
this.rootVisualElement.Add(vi);
}
private void OnChangeObject(ChangeEvent<UnityEngine.Object> changeEvent)
{
scrollView.Clear();
this.stateCollection = changeEvent.newValue as GraphicsStateCollection;
ConstructData();
stateCollectionHeaderInfo.style.marginLeft = 20;
stateCollectionHeaderInfo.style.height = 80;
stateCollectionHeaderInfo.Clear();
stateCollectionHeaderInfo.Add(new Label("Version:" + this.stateCollection.version.ToString()));
stateCollectionHeaderInfo.Add(new Label("Platform:"+this.stateCollection.runtimePlatform.ToString() + " GraphicsDeviceType:" + this.stateCollection.graphicsDeviceType.ToString()));
stateCollectionHeaderInfo.Add(new Label("QualityLevel:" + this.stateCollection.qualityLevelName));
stateCollectionHeaderInfo.Add(new Label("VariantCount:" + this.stateCollection.variantCount + " StateCount:" + this.stateCollection.totalGraphicsStateCount));
foreach (var shader in this.shaders)
{
ConstructShader(shader);
}
}
private void ConstructShader(Shader shader)
{
Foldout fold = new Foldout();
//visualElement.style.flexDirection = FlexDirection.Row;
var objField = new ObjectField();
objField.value = shader;
objField.SetEnabled(false);
objField.style.flexGrow = 0;
var foldHeader = fold.Q<VisualElement>("unity-checkmark").parent;
this.scrollView.Add(fold);
List<GraphicsStateCollection.ShaderVariant> currentVariants;
if (this.variants.TryGetValue(shader, out currentVariants))
{
foldHeader.Add(new Label("Shader("+currentVariants.Count+")"));
foldHeader.Add(objField);
foreach (var variant in currentVariants)
{
ConstructVaraintUI(fold, variant);
}
}
else
{
foldHeader.Add(new Label("Shader"));
foldHeader.Add(objField);
}
fold.value = false;
}
private void ConstructVaraintUI(Foldout fold,GraphicsStateCollection.ShaderVariant variant)
{
var variantStr = GetVariantDetail(stringBuilder, variant);
Foldout variantInfo = new Foldout();
fold.Add(variantInfo);
variantInfo.value = false;
List<GraphicsStateCollection.GraphicsState> currentStates;
if (this.states.TryGetValue(variant, out currentStates))
{
variantInfo.text = "(State:"+currentStates.Count+")"+ variantStr;
foreach (var state in currentStates)
{
var label = new Label(GetStateDetail(this.stringBuilder,state));
variantInfo.Add(label);
}
}
else
{
variantInfo.text = variantStr;
}
}
private static string GetStateDetail(StringBuilder sb,GraphicsStateCollection.GraphicsState state)
{
sb.Clear();
foreach(var attr in state.vertexAttributes)
{
sb.Append(attr.ToString()).Append(' ');
}
return sb.ToString();
}
private void ConstructData()
{
this.variantsBuffer.Clear();
this.shaders.Clear();
this.variants.Clear();
this.states.Clear();
this.stateCollection.GetVariants(variantsBuffer);
variantsBuffer.Sort((a, b) =>
{
if(a.shader == null && b.shader == null) { return 0; }
if (a.shader == null)
{
return 1;
}
else if (b.shader == null)
{
return -1;
}
int shaderNameCompare = a.shader.name.CompareTo(b.shader.name);
if(shaderNameCompare != 0)
{
return shaderNameCompare;
}
int subShaderCompare = (int)a.passId.SubshaderIndex - (int)b.passId.SubshaderIndex;
if(subShaderCompare != 0)
{
return subShaderCompare;
}
int passCompare = (int)a.passId.PassIndex - (int)b.passId.PassIndex;
return passCompare;
});
if(variantsBuffer.Count <= 0)
{
return;
}
Shader currentShader = variantsBuffer[0].shader;
var currentShaderVariants = new List<GraphicsStateCollection.ShaderVariant>();
this.shaders.Add(currentShader);
this.variants.Add(currentShader,currentShaderVariants);
foreach (var variant in variantsBuffer)
{
if(variant.shader == null)
{
continue;
}
if(currentShader != variant.shader)
{
currentShader = variant.shader;
currentShaderVariants = new List<GraphicsStateCollection.ShaderVariant>();
this.shaders.Add(currentShader);
this.variants.Add(currentShader, currentShaderVariants);
}
currentShaderVariants.Add(variant);
var currentStates = new List<GraphicsStateCollection.GraphicsState>();
this.stateCollection.GetGraphicsStatesForVariant(variant,currentStates);
this.states.Add(variant,currentStates);
}
}
private static string GetVariantDetail(StringBuilder sb , GraphicsStateCollection.ShaderVariant variant)
{
sb.Clear();
var passId = variant.passId;
sb.Append("Pass ").Append(passId.SubshaderIndex).Append("-").Append(passId.PassIndex).Append(" ");
LocalKeyword[] keywords = variant.keywords;
if (keywords == null || keywords.Length == 0)
{
sb.Append("<no keyword>");
return sb.ToString();
}
bool isFirst = true;
foreach(var keyword in keywords)
{
if (!isFirst)
{
sb.Append(' ');
}
sb.Append(keyword.name);
isFirst = false;
}
return sb.ToString();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment