protected override void init() { m_FolderMap = new Dictionary <AnalyzedBase, bool>(); for (int i = 0; i < m_AnalyzedData.Subshaders.Count; i++) { AnalyzedSubshaderData subshader = m_AnalyzedData.Subshaders[i]; m_FolderMap.Add(subshader, true); for (int j = 0; j < subshader.Passes.Count; j++) { AnalyzedPassData pass = subshader.Passes[j]; m_FolderMap.Add(pass, true); for (int k = 0; k < pass.Variants.Count; k++) { AnalyzedVariantData variant = pass.Variants[k]; m_FolderMap.Add(variant, true); for (int l = 0; l < variant.Shaders.Count; l++) { AnalyzedShaderDataBase shader = variant.Shaders[l]; m_FolderMap.Add(shader, true); } } } } }
protected override int init(AnalyzeWrap wrap, ShaderAnalyzeParams param) { createFolder(Constant.SAWorkSpace); for (int i = 0; i < wrap.Subshaders.Count; i++) { AnalyzedSubshaderData subshader = wrap.Subshaders[i]; string subshaderFolder = Constant.SAWorkSpace + "/Subshader_" + i.ToString(); createFolder(subshaderFolder); for (int j = 0; j < subshader.Passes.Count; j++) { AnalyzedPassData pass = subshader.Passes[j]; string passFolder = subshaderFolder + "/Pass_" + j.ToString(); createFolder(passFolder); for (int k = 0; k < pass.Variants.Count; k++) { AnalyzedVariantData variant = pass.Variants[k]; string variantFolder = passFolder + "/" + ShaderAnalyzerUtil.ReplaceBadCharOfFileName(variant.VariantName); createFolder(variantFolder); wrap.VariantDirectory.Add(variant, variantFolder); } } } return(wrap.Variants.Count); }
protected override void init() { m_List = new List <AnalyzedShaderDataBase>(); m_ParamMap = new Dictionary <AnalyzedShaderDataBase, ShaderParem>(); for (int i = 0; i < m_AnalyzedData.Subshaders.Count; i++) { AnalyzedSubshaderData subshader = m_AnalyzedData.Subshaders[i]; for (int j = 0; j < subshader.Passes.Count; j++) { AnalyzedPassData pass = subshader.Passes[j]; for (int k = 0; k < pass.Variants.Count; k++) { AnalyzedVariantData variant = pass.Variants[k]; for (int l = 0; l < variant.Shaders.Count; l++) { AnalyzedShaderDataBase shader = variant.Shaders[l]; if (m_FieldInfoMap == null) { m_FieldInfoMap = new Dictionary <FieldInfo, ShaderAnalyzedDataTooltipAttribute>(); Type type = shader.GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); for (int n = 0; n < fields.Length; n++) { FieldInfo field = fields[n]; ShaderAnalyzedDataTooltipAttribute attribute = field.GetCustomAttribute <ShaderAnalyzedDataTooltipAttribute>(); m_FieldInfoMap.Add(field, attribute); } } m_List.Add(shader); m_ParamMap.Add(shader, new ShaderParem() { Subshader = subshader, SubshaderIndex = i, Pass = pass, PassIndex = j, Variant = variant, VariantIndex = k }); } } } } }
protected override EAnalyzeStageStatus execute(int index) { AnalyzedVariantData variant = m_AnalyzeWrap.Variants[index]; foreach (var item in variant.ShaderSourceCodes) { string path; if (m_AnalyzeWrap.VariantDirectory.TryGetValue(variant, out path)) { File.WriteAllText(path + "/shader" + ShaderAnalyzerUtil.GetFileExtensionByShaderType(item.Key), item.Value); } } //TODO 这里要处理IO异常 return(EAnalyzeStageStatus.Success); }
protected override EAnalyzeStageStatus execute(int index) { AnalyzedVariantData avd = m_AnalyzeWrap.Variants[index]; foreach (var item in avd.ShaderSourceCodes) { string path; if (m_AnalyzeWrap.VariantDirectory.TryGetValue(avd, out path)) { List <string> lines = new List <string>(32); ProcessStartInfo psi = new ProcessStartInfo(UnityEngine.Application.dataPath + "/../Tools/mali_offline_compiler/malioc.exe", "\"" + path + "/shader" + ShaderAnalyzerUtil.GetFileExtensionByShaderType(item.Key) + "\""); psi.RedirectStandardOutput = true; psi.CreateNoWindow = true; psi.UseShellExecute = false; Process process = Process.Start(psi); process.EnableRaisingEvents = true; process.OutputDataReceived += new DataReceivedEventHandler( (object o, DataReceivedEventArgs e) => { lines.Add(e.Data); } ); process.BeginOutputReadLine(); process.Exited += new EventHandler( (object o, EventArgs args) => { avd.CompileResult.Add(item.Key, lines.ToArray()); } ); process.WaitForExit(); process.Dispose(); } } //TODO 这里要处理进程异常 return(EAnalyzeStageStatus.Success); }
protected override int init(AnalyzeWrap wrap, ShaderAnalyzeParams param) { int count = 0; bool shaderDisassembly = false; AnalyzedSubshaderData currentSubshader = null; AnalyzedPassData currentPass = null; AnalyzedVariantData currentVariant = null; using (StreamReader sr = new StreamReader(wrap.CompiledShaderFilePath)) { string line = string.Empty; int lineCount = 0; while ((line = sr.ReadLine()) != null) { lineCount++; //wrap.SourceCode.Add(line); if (Regex.IsMatch(line, "^Shader \"\\S+\" {$")) { m_BraceStack.AddLast(EBraceRegionType.ShaderMain); currentSubshader = new AnalyzedSubshaderData(); wrap.Subshaders.Add(currentSubshader); wrap.AnalyzedData.Subshaders.Add(currentSubshader); } else if (line == "Properties {") { m_BraceStack.AddLast(EBraceRegionType.Properties); } else if (line == "SubShader { ") { m_BraceStack.AddLast(EBraceRegionType.SubShader); } else if (line == " Pass {") { m_BraceStack.AddLast(EBraceRegionType.Pass); currentPass = new AnalyzedPassData(); currentSubshader.Passes.Add(currentPass); wrap.Passes.Add(currentPass); } else if (line.StartsWith("Global Keywords: ")) { m_BraceStack.AddLast(EBraceRegionType.Variant); currentVariant = new AnalyzedVariantData(); currentPass.Variants.Add(currentVariant); wrap.Variants.Add(currentVariant); count++; } else if (line.StartsWith("Constant Buffer ")) { m_BraceStack.AddLast(EBraceRegionType.Constant); } else if (line == "{") { m_BraceStack.AddLast(EBraceRegionType.Function); } else if (line == "}") { m_BraceStack.RemoveLast(); } else if (line == "Shader Disassembly:") { if (shaderDisassembly) { m_BraceStack.RemoveLast(); } shaderDisassembly = !shaderDisassembly; } if (m_BraceStack.Count > 0) { switch (m_BraceStack.Last.Value) { case EBraceRegionType.SubShader: currentSubshader.SourceCodeLines.Add(line); break; case EBraceRegionType.Pass: currentSubshader.SourceCodeLines.Add(line); currentPass.SourceCodeLines.Add(line); break; case EBraceRegionType.Variant: case EBraceRegionType.Constant: case EBraceRegionType.Function: currentSubshader.SourceCodeLines.Add(line); currentPass.SourceCodeLines.Add(line); currentVariant.SourceCodeLines.Add(line); break; } } } } //TODO 这里可以改为逐帧读取 return(InitFinish); }
public override void Draw() { for (int i = 0; i < m_AnalyzedData.Subshaders.Count; i++) { AnalyzedSubshaderData subshader = m_AnalyzedData.Subshaders[i]; if (drawHeader(subshader, EDataType.Subshader, i.ToString(), string.Empty)) { EditorGUILayout.BeginVertical(); GUITools.BeginContents(GUITools.Styles.HelpBoxStyle); EditorGUILayout.LabelField("LOD : ", subshader.LOD.ToString()); for (int j = 0; j < subshader.Passes.Count; j++) { AnalyzedPassData pass = subshader.Passes[j]; if (drawHeader(pass, EDataType.Pass, j.ToString(), pass.PassName)) { GUITools.BeginContents(GUITools.Styles.HelpBoxStyle); EditorGUILayout.LabelField("Name : ", pass.PassName); for (int k = 0; k < pass.Variants.Count; k++) { AnalyzedVariantData variant = pass.Variants[k]; //TODO 这里需要分页,避免变体过多导致GUI卡顿 if (drawHeader(variant, EDataType.Variant, k.ToString(), getShortVariantName(variant.VariantName))) { GUITools.BeginContents(GUITools.Styles.HelpBoxStyle); EditorGUILayout.LabelField("Name : ", variant.VariantName); ShaderDataDrawerBase drawer; if (!ShaderDrawer.TryGetValue(variant.GPUVendorType, out drawer)) { Debug.LogError("无法获取到" + variant.GPUVendorType.ToString() + "的绘制器"); } else { for (int l = 0; l < variant.Shaders.Count; l++) { AnalyzedShaderDataBase shader = variant.Shaders[l]; if (drawHeader(shader, EDataType.Shader, shader.ShaderType.ToString(), string.Empty)) { GUITools.BeginContents(GUITools.Styles.HelpBoxStyle); if (!string.IsNullOrEmpty(shader.ERROR)) { EditorGUILayout.HelpBox(shader.ERROR, MessageType.Error); } else { drawer.Draw(shader); } GUITools.EndContents(); } } } GUITools.EndContents(); } } GUITools.EndContents(); } } GUITools.EndContents(); EditorGUILayout.EndVertical(); } } }
protected override EAnalyzeStageStatus execute(int index) { AnalyzedVariantData variant = m_AnalyzeWrap.Variants[index]; int currentLine = 0; bool afterEmpty = false; EShaderType currentShaderType = EShaderType.None; while (currentLine < variant.SourceCodeLines.Count) { string line = variant.SourceCodeLines[currentLine++]; if (string.IsNullOrEmpty(line)) { afterEmpty = true; continue; } else { if (afterEmpty && line == "//////////////////////////////////////////////////////") { currentShaderType = EShaderType.None; break; } else if (string.IsNullOrEmpty(variant.VariantName)) { if (line.StartsWith("Global Keywords: ")) { variant.VariantName = line.Replace("Global Keywords: ", string.Empty); continue; } } else if (currentShaderType == EShaderType.None) { for (int i = 0; i < ShaderBeginFlag.Length; i++) { if (line == ShaderBeginFlag[i]) { currentShaderType = (EShaderType)i; break; } } } else if (currentShaderType != EShaderType.None) { if (afterEmpty && line == ShaderEndFlag) { variant.ShaderSourceCodes.Add(currentShaderType, m_TextContainer.ToString()); m_TextContainer.Clear(); currentShaderType = EShaderType.None; continue; } m_TextContainer.AppendLine(line); } afterEmpty = false; } } return(EAnalyzeStageStatus.Success); }
protected override EAnalyzeStageStatus execute(int index) { AnalyzedVariantData varint = m_AnalyzeWrap.Variants[index]; foreach (var item in varint.CompileResult) { MaliAnalyzedShaderData shaderData = new MaliAnalyzedShaderData(); shaderData.SourceCode = varint.ShaderSourceCodes[item.Key]; shaderData.ShaderType = item.Key; varint.Shaders.Add(shaderData); for (int i = 0; i < item.Value.Length; i++) { string line = item.Value[i]; if (string.IsNullOrEmpty(line)) { continue; } else if (string.IsNullOrEmpty(m_AnalyzeWrap.AnalyzedData.Hardware) && line.StartsWith("Hardware: ")) { int spaceIndex = line.LastIndexOf(' '); m_AnalyzeWrap.AnalyzedData.Hardware = line.Substring(spaceIndex + 1, line.Length - spaceIndex - 1); } else if (string.IsNullOrEmpty(m_AnalyzeWrap.AnalyzedData.Driver) && line.StartsWith("Driver: ")) { m_AnalyzeWrap.AnalyzedData.Driver = line.Replace("Driver: ", string.Empty); } else if (line.StartsWith("ERROR: ")) { shaderData.ERROR = line; break; } else if (line.StartsWith("Work registers: ")) { int.TryParse(line.Replace("Work registers: ", string.Empty), out shaderData.WorkRegisterUsed); } else if (line.StartsWith("Uniform registers: ")) { int.TryParse(line.Replace("Uniform registers: ", string.Empty), out shaderData.UniformRegistersUsed); } else if (line.StartsWith("Stack spilling: ")) { shaderData.StackSpilling = line != "Stack spilling: False"; } else if (line.StartsWith("Total instruction cycles:")) { getInstructionNormFormLine(line, "Total instruction cycles:", out shaderData.TotalArithmeticCycles, out shaderData.TotalLoad_StoreCycles, out shaderData.TotalVaryingCycles, out shaderData.TotalTextureCycles, out shaderData.TotalBound); } else if (line.StartsWith("Shortest path cycles:")) { getInstructionNormFormLine(line, "Shortest path cycles:", out shaderData.ShortestPathArithmeticCycles, out shaderData.ShortestPathLoad_StoreCycles, out shaderData.ShortestPathVaryingCycles, out shaderData.ShortestPathTextureCycles, out shaderData.ShortestPathBound); } else if (line.StartsWith("Longest path cycles:")) { getInstructionNormFormLine(line, "Longest path cycles:", out shaderData.LongestPathArithmeticCycles, out shaderData.LongestPathLoad_StoreCycles, out shaderData.LongestPathVaryingCycles, out shaderData.LongestPathTextureCycles, out shaderData.LongestPathBound); } else if (line.StartsWith("Uniform computation: ")) { shaderData.UniformComputation = line != "Uniform computation: False"; } } } //TODO 这里处理各种异常 return(EAnalyzeStageStatus.Success); }