/// <summary> /// Returns the human readble SPIR-V representation of the shader /// </summary> public bool GetReadableSPIRV(ShaderFile shaderFile, out List <string> spirvOutput) { List <string> output = new List <string>(); spirvOutput = output; string title = name; string msg; if (GlslangCompiler.Locate(package as SPIRVExtensionPackage) == null) { msg = "Could not locate the glslang reference compiler (glslangvalidator.exe) in system path!"; VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); OutputWindow.Add(msg); return(false); } List <string> validatorOutput; bool res = GlslangCompiler.GetHumanReadableSPIRV(shaderFile.fileName, out validatorOutput, package as SPIRVExtensionPackage); if (res) { spirvOutput = validatorOutput; } else { msg = string.Format(CultureInfo.CurrentCulture, "Could not get human readable SPIR-V for shader \"{0}\" ", shaderFile.fileName) + "\n"; Debug.Write(msg); VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); ParseErrors(validatorOutput, shaderFile); msg += string.Join("\n", validatorOutput); OutputWindow.Add(msg); } return(res); }
/// <summary> /// Parse error output from the reference compiler and add it to the error list /// </summary> /// <param name="validatorOutput">Output of the reference compiler</param> /// <param name="shaderFile">Shader file info for which the validator output has been generated</param> public void ParseErrors(List <string> validatorOutput, ShaderFile shaderFile) { foreach (string line in validatorOutput) { // Examples: // ERROR: 0:26: 'aaa' : undeclared identifier // ERROR: E:\Vulkan\public\Vulkan\data\shaders\indirectdraw\ground.frag:16: '' : function does not return a value: test MatchCollection matches = Regex.Matches(line, @":\d+:\s", RegexOptions.IgnoreCase | RegexOptions.RightToLeft); if (matches.Count > 0) { // Line int errorLine = Convert.ToInt32(matches[0].Value.Replace(":", "")); // Error message string msg = line; Match match = Regex.Match(line, @"ERROR:\s.*\d+:(.*)", RegexOptions.IgnoreCase); if (match.Success) { msg = match.Groups[1].Value; } ErrorList.Add(msg, shaderFile.fileName, errorLine, 0, shaderFile.hierarchy); } } }