/// <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 (ReferenceCompiler.Locate() == 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 = ReferenceCompiler.GetHumanReadableSPIRV(shaderFile.fileName, out validatorOutput); 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> /// Compile the shader file using the given compilation function /// </summary> public void CompileShaders(List <ShaderFile> shaderFiles, CompileFunc compileFunc) { string title = name; string msg; if (ReferenceCompiler.Locate() == 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; } ErrorList.Clear(); bool success = true; msg = ""; foreach (var shaderFile in shaderFiles) { List <string> validatorOutput; bool compiled = compileFunc(shaderFile.fileName, out validatorOutput); if (compiled) { OutputWindow.Add(string.Join("\n", validatorOutput)); } else { msg += string.Format(CultureInfo.CurrentCulture, "Shader \"{0}\" could not be compiled to SPIR-V!", shaderFile.fileName) + "\n"; Debug.Write(msg); ParseErrors(validatorOutput, shaderFile); OutputWindow.Add(shaderFile.fileName + "\n" + string.Join("\n", validatorOutput)); success = false; } } if (success) { if (shaderFiles.Count == 1) { msg = string.Format(CultureInfo.CurrentCulture, "Shader successfully compiled to \"{0}\"", shaderFiles[0].fileName + ".spv"); } else { msg = "All shaders successfully compiled to SPIR-V"; } VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } else { VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST); } if (ErrorList.ErrorCount() > 0) { ErrorList.Show(); } }
/// <summary> /// Returns a list of valid shader files from the current file selection /// </summary> /// <param name="shaderFileNames">List to be filled with all valid shader files from the current selection</param> /// <returns>True if at least one shader has been selected</returns> public bool GetSelectedShaderFiles(List <ShaderFile> shaderFiles) { IVsHierarchy hierarchy = null; uint itemid = VSConstants.VSITEMID_NIL; int hr = VSConstants.S_OK; var monitorSelection = Package.GetGlobalService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection; var solution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution; if (monitorSelection == null || solution == null) { return(false); } IVsMultiItemSelect multiItemSelect = null; IntPtr hierarchyPtr = IntPtr.Zero; IntPtr selectionContainerPtr = IntPtr.Zero; try { hr = monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr); if (ErrorHandler.Failed(hr) || hierarchyPtr == IntPtr.Zero || itemid == VSConstants.VSITEMID_NIL) { return(false); } hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy; if (hierarchy == null) { return(false); } List <uint> itemids = new List <uint>(); if (multiItemSelect == null) { ReadItemHierarchy(itemid, hierarchy, itemids); } else { // todo: Read hierarchy for multi selects uint itemCount = 0; int fSingleHierarchy = 0; hr = multiItemSelect.GetSelectionInfo(out itemCount, out fSingleHierarchy); VSITEMSELECTION[] items = new VSITEMSELECTION[itemCount]; hr = multiItemSelect.GetSelectedItems(0, itemCount, items); foreach (var item in items) { itemids.Add(item.itemid); } } foreach (var id in itemids) { string filepath = null; ((IVsProject)hierarchy).GetMkDocument(id, out filepath); if (filepath != null && ReferenceCompiler.IsShaderFile(filepath)) { var transformFileInfo = new FileInfo(filepath); shaderFiles.Add(new ShaderFile(id, hierarchy, filepath)); } } // todo: hierarchy node if (itemid == VSConstants.VSITEMID_ROOT) { return(false); } Guid guidProjectID = Guid.Empty; if (ErrorHandler.Failed(solution.GetGuidOfProject(hierarchy, out guidProjectID))) { return(false); } return(shaderFiles.Count > 0); } finally { if (selectionContainerPtr != IntPtr.Zero) { Marshal.Release(selectionContainerPtr); } if (hierarchyPtr != IntPtr.Zero) { Marshal.Release(hierarchyPtr); } } }