├── images
├── vs2015.png
├── errorlist.png
├── contextmenu.png
├── humanreadable.png
└── contextmenufolder.png
├── SPIRV-VSExtension
├── Key.snk
├── Resources
│ ├── SPIRVCommands.psd
│ ├── SPIRVExtension.ico
│ └── SPIRVExtension.png
├── Shared
│ ├── ShaderFile.cs
│ ├── OutputWindow.cs
│ ├── Utils.cs
│ ├── ErrorList.cs
│ ├── DocumentHelper.cs
│ ├── GlslangCompiler.cs
│ └── DxcCompiler.cs
├── LICENSE
├── Properties
│ └── AssemblyInfo.cs
├── source.extension.vsixmanifest
├── packages.config
├── CommandCompileHLSL.cs
├── CommandCompileOpenGL.cs
├── CommandCompileVulkan.cs
├── CommandPrintSPIRV.cs
├── SPIRVExtensionPackage.cs
├── VSPackage.resx
├── SPIRVExtensionPackage.vsct
├── ShaderCommandBase.cs
└── SPIRV-VSExtension.csproj
├── SPIRV-VSExtension.sln
├── LICENSE
├── README.md
└── .gitignore
/images/vs2015.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/images/vs2015.png
--------------------------------------------------------------------------------
/images/errorlist.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/images/errorlist.png
--------------------------------------------------------------------------------
/images/contextmenu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/images/contextmenu.png
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Key.snk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/SPIRV-VSExtension/Key.snk
--------------------------------------------------------------------------------
/images/humanreadable.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/images/humanreadable.png
--------------------------------------------------------------------------------
/images/contextmenufolder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/images/contextmenufolder.png
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Resources/SPIRVCommands.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/SPIRV-VSExtension/Resources/SPIRVCommands.psd
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Resources/SPIRVExtension.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/SPIRV-VSExtension/Resources/SPIRVExtension.ico
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Resources/SPIRVExtension.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SaschaWillems/SPIRV-VSExtension/HEAD/SPIRV-VSExtension/Resources/SPIRVExtension.png
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Shared/ShaderFile.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using Microsoft.VisualStudio.Shell.Interop;
10 | using System.IO;
11 |
12 | namespace SPIRVExtension
13 | {
14 | ///
15 | /// Encaspulates details of a shader file
16 | ///
17 | public class ShaderFile
18 | {
19 | public uint itemid;
20 | public IVsHierarchy hierarchy;
21 | public string fileName;
22 | public string fileExt;
23 |
24 | public ShaderFile(uint id, IVsHierarchy hr, string file)
25 | {
26 | itemid = id;
27 | hierarchy = hr;
28 | fileName = file;
29 | fileExt = Path.GetExtension(file);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.26228.10
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SPIRV-VSExtension", "SPIRV-VSExtension\SPIRV-VSExtension.csproj", "{914B9574-655F-435E-9928-FE245DABB221}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {914B9574-655F-435E-9928-FE245DABB221}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {914B9574-655F-435E-9928-FE245DABB221}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {914B9574-655F-435E-9928-FE245DABB221}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {914B9574-655F-435E-9928-FE245DABB221}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Sascha Willems
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Sascha Willems
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("SPIRVExtension")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("SPIRVExtension")]
13 | [assembly: AssemblyCopyright("")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // Version information for an assembly consists of the following four values:
23 | //
24 | // Major Version
25 | // Minor Version
26 | // Build Number
27 | // Revision
28 | //
29 | // You can specify all the values or you can default the Build and Revision Numbers
30 | // by using the '*' as shown below:
31 | // [assembly: AssemblyVersion("1.0.*")]
32 | [assembly: AssemblyVersion("1.0.0.0")]
33 | [assembly: AssemblyFileVersion("1.0.0.0")]
34 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Shared/OutputWindow.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using System;
10 | using Microsoft.VisualStudio.Shell;
11 | using Microsoft.VisualStudio.Shell.Interop;
12 |
13 | namespace SPIRVExtension
14 | {
15 | ///
16 | /// Helper class for displaying messages in a custom output window pane
17 | ///
18 | public static class OutputWindow
19 | {
20 | static private IVsOutputWindowPane customPane()
21 | {
22 | IVsOutputWindow outputWindow = Package.GetGlobalService(typeof(SVsOutputWindow)) as IVsOutputWindow;
23 | Guid customGuid = new Guid("6AFC25E1-1622-4589-82D7-136503A69B2F");
24 | string customTitle = "SPIRV Commands Extension";
25 | outputWindow.CreatePane(ref customGuid, customTitle, 1, 1);
26 | IVsOutputWindowPane pane;
27 | outputWindow.GetPane(ref customGuid, out pane);
28 | return pane;
29 | }
30 |
31 | static public void Add(string text)
32 | {
33 | customPane().OutputString(text);
34 | }
35 |
36 | public static void Clear()
37 | {
38 | customPane().Clear();
39 | }
40 |
41 | public static void Show()
42 | {
43 | customPane().Activate();
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Shared/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace SPIRVExtension.Shared
9 | {
10 | class Utils
11 | {
12 | ///
13 | /// Returns true if the file has a valid shader extension that can be used as an input for the reference compiler
14 | ///
15 | public static bool IsShaderFile(string fileName)
16 | {
17 | var shaderExtensions = new[] { ".vert", ".tesc", ".tese", ".geom", ".frag", ".comp", ".mesh", ".task", ".rgen", ".rint", ".rahit", ".rchit", ".rmiss", ".rcall" };
18 | foreach (string ext in shaderExtensions)
19 | {
20 | if (string.Compare(ext, Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase) == 0)
21 | {
22 | return true;
23 | }
24 | }
25 | return false;
26 | }
27 |
28 | ///
29 | /// Returns true if the file has a ray tracing related file extension
30 | ///
31 | public static bool IsRayTracingShaderFile(string fileName)
32 | {
33 | var shaderExtensions = new[] { ".rgen", ".rint", ".rahit", ".rchit", ".rmiss", ".rcall" };
34 | foreach (string ext in shaderExtensions)
35 | {
36 | if (string.Compare(ext, Path.GetExtension(fileName), StringComparison.OrdinalIgnoreCase) == 0)
37 | {
38 | return true;
39 | }
40 | }
41 | return false;
42 | }
43 |
44 |
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Shared/ErrorList.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using System;
10 | using Microsoft.VisualStudio.Shell;
11 | using Microsoft.VisualStudio.Shell.Interop;
12 |
13 | namespace SPIRVExtension
14 | {
15 | ///
16 | /// Helper class for the adding items to the Visual Studio error list
17 | ///
18 | public static class ErrorList
19 | {
20 | private static ErrorListProvider errorListProvider;
21 |
22 | public static void Initialize(IServiceProvider serviceProvider)
23 | {
24 | errorListProvider = new ErrorListProvider(serviceProvider);
25 | }
26 |
27 | public static void Add(string text, string fileName, int line, int column, IVsHierarchy hierarchy)
28 | {
29 | ErrorTask errorTask = new ErrorTask();
30 | errorTask.Text = text;
31 | errorTask.Line = line - 1;
32 | errorTask.Column = column;
33 | errorTask.Category = TaskCategory.User;
34 | errorTask.ErrorCategory = TaskErrorCategory.Error;
35 | errorTask.Document = fileName;
36 | errorTask.HierarchyItem = hierarchy;
37 | errorTask.Navigate += DocumentHelper.NavigateDocument;
38 | errorListProvider.Tasks.Add(errorTask);
39 | }
40 |
41 | public static void Clear()
42 | {
43 | errorListProvider.Tasks.Clear();
44 | }
45 |
46 | public static void Show()
47 | {
48 | errorListProvider.Show();
49 | }
50 |
51 | public static int ErrorCount()
52 | {
53 | return errorListProvider.Tasks.Count;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/source.extension.vsixmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SPIRV-VSExtension
6 | Adds SPIR-V commands to the context menu of GLSL/HLSL shader files and folders. Generate SPIR-V binaries for Vulkan or OpenGL and display human readable SPIR-V directly inside Visual Studio.
7 | LICENSE
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/CommandCompileHLSL.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extensiondeleted
3 | *
4 | * Copyright (C) 2016-2022 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using System;
10 | using System.ComponentModel.Design;
11 | using System.Collections.Generic;
12 | using Microsoft.VisualStudio.Shell;
13 |
14 | namespace SPIRVExtension
15 | {
16 | internal sealed class CommandCompileHLSL : ShaderCommandBase
17 | {
18 | public const int CommandId = 0x0140;
19 | public static readonly Guid CommandSet = new Guid("c25a4989-8e55-4457-822d-1e690eb23169");
20 | private readonly Package package;
21 |
22 | private CommandCompileHLSL(Package package) : base(package, "Compile HLSL to SPIR-V (Vulkan only)")
23 | {
24 | if (package == null)
25 | {
26 | throw new ArgumentNullException("package");
27 | }
28 |
29 | this.package = package;
30 |
31 | OleMenuCommandService mcs = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
32 | if (null != mcs)
33 | {
34 | CommandID menuCommandID = new CommandID(CommandSet, (int)CommandId);
35 | OleMenuCommand oleMenuItem = new OleMenuCommand(new EventHandler(MenuItemCallback), menuCommandID);
36 | oleMenuItem.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus);
37 | mcs.AddCommand(oleMenuItem);
38 | }
39 | }
40 |
41 | public static CommandCompileHLSL Instance
42 | {
43 | get;
44 | private set;
45 | }
46 |
47 | public static void Initialize(Package package)
48 | {
49 | Instance = new CommandCompileHLSL(package);
50 | }
51 |
52 | private void MenuItemCallback(object sender, EventArgs e)
53 | {
54 | List selectedShaderFiles = new List();
55 | if (GetSelectedShaderFiles(selectedShaderFiles))
56 | {
57 | CompileShaders(selectedShaderFiles, DxcCompiler.CompileToVulkan);
58 | }
59 | }
60 |
61 | void OnBeforeQueryStatus(object sender, EventArgs e)
62 | {
63 | var item = (OleMenuCommand)sender;
64 | if (item != null)
65 | {
66 | int count = GetSelectedShaderFileCount();
67 | item.Visible = (count > 0);
68 | item.Text = (count == 1) ? "Compile HLSL to SPIR-V (DXC)" : "Compile HLSL shaders to SPIR-V (DXC)";
69 | }
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/CommandCompileOpenGL.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using System;
10 | using System.ComponentModel.Design;
11 | using System.Collections.Generic;
12 | using Microsoft.VisualStudio.Shell;
13 |
14 | namespace SPIRVExtension
15 | {
16 | internal sealed class CommandCompileOpenGL : ShaderCommandBase
17 | {
18 | public const int CommandId = 0x0110;
19 | public static readonly Guid CommandSet = new Guid("c25a4989-8e55-4457-822d-1e690eb23169");
20 | private readonly Package package;
21 |
22 | private CommandCompileOpenGL(Package package) : base(package, "Compile to SPIR-V (OpenGL semantics)")
23 | {
24 | if (package == null)
25 | {
26 | throw new ArgumentNullException("package");
27 | }
28 |
29 | this.package = package;
30 |
31 | OleMenuCommandService mcs = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
32 | if (null != mcs)
33 | {
34 | CommandID menuCommandID = new CommandID(CommandSet, (int)CommandId);
35 | OleMenuCommand oleMenuItem = new OleMenuCommand(new EventHandler(MenuItemCallback), menuCommandID);
36 | oleMenuItem.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus);
37 | mcs.AddCommand(oleMenuItem);
38 | }
39 | }
40 |
41 | public static CommandCompileOpenGL Instance
42 | {
43 | get;
44 | private set;
45 | }
46 |
47 | public static void Initialize(Package package)
48 | {
49 | Instance = new CommandCompileOpenGL(package);
50 | }
51 |
52 | private void MenuItemCallback(object sender, EventArgs e)
53 | {
54 | List selectedShaderFiles = new List();
55 | if (GetSelectedShaderFiles(selectedShaderFiles))
56 | {
57 | CompileShaders(selectedShaderFiles, GlslangCompiler.CompileToOpenGL);
58 | }
59 | }
60 |
61 | void OnBeforeQueryStatus(object sender, EventArgs e)
62 | {
63 | var item = (OleMenuCommand)sender;
64 | if (item != null)
65 | {
66 | int count = GetSelectedShaderFileCount();
67 | item.Visible = (count > 0);
68 | item.Text = (count == 1) ? "Compile to SPIR-V (OpenGL)" : "Compile shaders to SPIR-V (OpenGL)";
69 | }
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/CommandCompileVulkan.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using System;
10 | using System.ComponentModel.Design;
11 | using System.Collections.Generic;
12 | using Microsoft.VisualStudio.Shell;
13 |
14 | namespace SPIRVExtension
15 | {
16 | internal sealed class CommandCompileVulkan : ShaderCommandBase
17 | {
18 | public const int CommandId = 0x0100;
19 | public static readonly Guid CommandSet = new Guid("c25a4989-8e55-4457-822d-1e690eb23169");
20 | private readonly Package package;
21 |
22 | private CommandCompileVulkan(Package package) : base(package, "Compile GLSL to SPIR-V (Vulkan semantics)")
23 | {
24 | if (package == null)
25 | {
26 | throw new ArgumentNullException("package");
27 | }
28 |
29 | this.package = package;
30 |
31 | OleMenuCommandService mcs = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
32 | if (null != mcs)
33 | {
34 | CommandID menuCommandID = new CommandID(CommandSet, (int)CommandId);
35 | OleMenuCommand oleMenuItem = new OleMenuCommand(new EventHandler(MenuItemCallback), menuCommandID);
36 | oleMenuItem.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus);
37 | mcs.AddCommand(oleMenuItem);
38 | }
39 | }
40 |
41 | public static CommandCompileVulkan Instance
42 | {
43 | get;
44 | private set;
45 | }
46 |
47 | public static void Initialize(Package package)
48 | {
49 | Instance = new CommandCompileVulkan(package);
50 | }
51 |
52 | private void MenuItemCallback(object sender, EventArgs e)
53 | {
54 | List selectedShaderFiles = new List();
55 | if (GetSelectedShaderFiles(selectedShaderFiles))
56 | {
57 | CompileShaders(selectedShaderFiles, GlslangCompiler.CompileToVulkan);
58 | }
59 | }
60 |
61 | void OnBeforeQueryStatus(object sender, EventArgs e)
62 | {
63 | var item = (OleMenuCommand)sender;
64 | if (item != null)
65 | {
66 | int count = GetSelectedShaderFileCount();
67 | item.Visible = (count > 0);
68 | item.Text = (count == 1) ? "Compile GLSL to SPIR-V (Vulkan)" : "Compile GLSL shaders to SPIR-V (Vulkan)";
69 | }
70 | }
71 |
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Shared/DocumentHelper.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using System;
10 | using Microsoft.VisualStudio;
11 | using Microsoft.VisualStudio.Shell;
12 | using Microsoft.VisualStudio.Shell.Interop;
13 | using Microsoft.VisualStudio.TextManager.Interop;
14 |
15 | namespace SPIRVExtension
16 | {
17 | ///
18 | /// Helper class for displaying documents and navigating inside of them
19 | ///
20 | public static class DocumentHelper
21 | {
22 | ///
23 | /// Open the file and jump to a line (and optional column)
24 | ///
25 | public static void OpenAndNavigateTo(string fileName, int line, int column = 0)
26 | {
27 | IVsUIShellOpenDocument uishellOpenDocument = Package.GetGlobalService(typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument;
28 | if (uishellOpenDocument != null)
29 | {
30 | Microsoft.VisualStudio.OLE.Interop.IServiceProvider serviceProvider;
31 | IVsWindowFrame frame;
32 | IVsUIHierarchy hierarchy;
33 | uint itemId;
34 | Guid logicalView = VSConstants.LOGVIEWID_Code;
35 | if (ErrorHandler.Succeeded(uishellOpenDocument.OpenDocumentViaProject(fileName, ref logicalView, out serviceProvider, out hierarchy, out itemId, out frame)))
36 | {
37 | object document;
38 | frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out document);
39 | VsTextBuffer buffer = document as VsTextBuffer;
40 | if (buffer == null)
41 | {
42 | IVsTextBufferProvider bufferProvider = document as IVsTextBufferProvider;
43 | if (bufferProvider != null)
44 | {
45 | IVsTextLines lines;
46 | ErrorHandler.ThrowOnFailure(bufferProvider.GetTextBuffer(out lines));
47 | buffer = lines as VsTextBuffer;
48 | }
49 | }
50 | if (buffer != null)
51 | {
52 | IVsTextManager textManager = Package.GetGlobalService(typeof(VsTextManagerClass)) as IVsTextManager;
53 | textManager.NavigateToLineAndColumn(buffer, ref logicalView, line, column, line, column);
54 | }
55 | }
56 | }
57 | }
58 |
59 | ///
60 | /// Callback to be assigned to a task
61 | ///
62 | public static void NavigateDocument(object sender, EventArgs e)
63 | {
64 | Task task = sender as Task;
65 | OpenAndNavigateTo(task.Document, task.Line, task.Column);
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/CommandPrintSPIRV.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using Microsoft.VisualStudio.Shell;
10 | using System;
11 | using System.Collections.Generic;
12 | using System.ComponentModel.Design;
13 | using System.IO;
14 |
15 | namespace SPIRVExtension
16 | {
17 | internal sealed class CommandPrintSPIRV : ShaderCommandBase
18 | {
19 | public const int CommandId = 0x0130;
20 | public static readonly Guid CommandSet = new Guid("c25a4989-8e55-4457-822d-1e690eb23169");
21 | private readonly Package package;
22 |
23 | private CommandPrintSPIRV(Package package) : base(package, "Print human readable SPIR-V")
24 | {
25 | if (package == null)
26 | {
27 | throw new ArgumentNullException("package");
28 | }
29 |
30 | this.package = package;
31 |
32 | OleMenuCommandService mcs = this.ServiceProvider.GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
33 | if (null != mcs)
34 | {
35 | CommandID menuCommandID = new CommandID(CommandSet, (int)CommandId);
36 | OleMenuCommand oleMenuItem = new OleMenuCommand(new EventHandler(MenuItemCallback), menuCommandID);
37 | oleMenuItem.BeforeQueryStatus += new EventHandler(OnBeforeQueryStatus);
38 | mcs.AddCommand(oleMenuItem);
39 | }
40 | }
41 |
42 | public static CommandPrintSPIRV Instance
43 | {
44 | get;
45 | private set;
46 | }
47 |
48 | public static void Initialize(Package package)
49 | {
50 | Instance = new CommandPrintSPIRV(package);
51 | }
52 |
53 | private void MenuItemCallback(object sender, EventArgs e)
54 | {
55 | List selectedShaderFiles = new List();
56 | if (GetSelectedShaderFiles(selectedShaderFiles))
57 | {
58 | ErrorList.Clear();
59 | foreach (var shaderFile in selectedShaderFiles)
60 | {
61 | List spirvOutput = new List();
62 | if (GetReadableSPIRV(shaderFile, out spirvOutput))
63 | {
64 | string fileName = Path.GetTempPath() + Path.GetFileName(shaderFile.fileName) + ".spirv.readable";
65 | File.WriteAllLines(fileName, spirvOutput);
66 | VsShellUtilities.OpenDocument(ServiceProvider, fileName);
67 | }
68 | }
69 | if (ErrorList.ErrorCount() > 0)
70 | {
71 | ErrorList.Show();
72 | }
73 | }
74 | }
75 |
76 | void OnBeforeQueryStatus(object sender, EventArgs e)
77 | {
78 | var item = (OleMenuCommand)sender;
79 | if (item != null)
80 | {
81 | int count = GetSelectedShaderFileCount();
82 | item.Visible = (count > 0);
83 | item.Text = "Print human-readable SPIR-V";
84 | }
85 | }
86 |
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SPIR-V extension for Visual Studio (VSIX)
2 |
3 | ## About
4 |
5 |
6 |
7 | This VSIX extension adds commands to the context menu of shader files (and folders containing shaders) that let's you quickly compile to them to SPIR-V and supports both GLSL and HLSL as source.
8 |
9 | ## Requirements
10 |
11 | ### GLSL standalone reference compiler
12 | The extension requires a version of the glslang reference compiler to be in your path that supports SPIR-V:
13 |
14 | - Install the [LunartG Vulkan SDK](https://vulkan.lunarg.com/) (comes with a pre-built version)
15 | - Built from the sources at [https://github.com/KhronosGroup/glslang](https://github.com/KhronosGroup/glslang)
16 |
17 | The extension will search for the ```glslangvalidator.exe``` using the paths from the following environment variables: ```PATH```, ```VK_SDK_PATH``` and ```VULKAN_SDK``` (set by the LunarG SDK). Alternatively you can override this with an explicit location in the extensions' settings page.
18 |
19 | ### DXC standalone compiler
20 | For compiling from HLSL, the extension requires a version of the DirectX shader compiler to be in your path that supports SPIR-V:
21 |
22 | - Install the [LunartG Vulkan SDK](https://vulkan.lunarg.com/) (comes with a pre-built version)
23 | - Built from the sources at [https://github.com/microsoft/DirectXShaderCompiler/](https://github.com/microsoft/DirectXShaderCompiler/)
24 |
25 | The extension will search for the ```dxc.exe``` using the paths from the following environment variables: ```PATH```, ```VK_SDK_PATH``` and ```VULKAN_SDK``` (set by the LunarG SDK). Alternatively you can override this with an explicit location in the extensions' settings page.
26 |
27 | ### Supported Visual Studio versions
28 | The extension supports all editions of **Visual Studio 2015, 2017 and 2019**.
29 |
30 | ## Installation
31 |
32 | The extension is available at the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=SaschaWillems.SPIRV-VSExtension) and can be installed directly from the IDE.
33 |
34 | ## New context menu entries
35 |
36 |
37 |
38 | The context menu entries will be displayed if the current file selection or folder includes at least one shader file with a file extension supported by the GLSL reference compiler:
39 | - ```.vert``` (Vertex shader)
40 | - ```.tesc``` (Tessellation control shader)
41 | - ```.tese``` (Tessellation evaluation shader)
42 | - ```.geom``` (Geometry shader)
43 | - ```.frag``` (Fragment shader)
44 | - ```.comp``` (Compute shader)
45 | - ```.mesh``` (Mesh shader)
46 | - ```.task``` (Task shader)
47 | - ```.rgen``` (Ray generation shader)
48 | - ```.rint``` (Ray intersection shader)
49 | - ```.rahit``` (Ray any hit shader)
50 | - ```.rchit``` (Ray closest hit shader)
51 | - ```.rmiss``` (Ray miss shader)
52 | - ```.rcall``` (Ray callable shader)
53 |
54 | These are currently fixed, but future versions may add an options pane to adjust file extensions and how they are treated.
55 |
56 | ## Features
57 |
58 | ### SPIR-V functions
59 |
60 | #### Compile GLSL to SPIR-V (Vulkan semantics)
61 | Compile all selected GLSL shader files to SPIR-V binary using Vulkan semantics (-V).
62 |
63 | #### Compile HLSL to SPIR-V (DXC)
64 | Compile all selected HLSL shader files to SPIR-V binary format using the SPIR-V back-end of the DirectX shader compiler.
65 |
66 | #### Compile to SPIR-V (OpenGL semantics)
67 | Compile all selected shader files to SPIR-V binary using OpenGL semantics (-G).
68 |
69 | **Note:** SPIR-V for OpenGL is supported with the [```GL_ARB_gl_spirv```](https://www.opengl.org/registry/specs/ARB/gl_spirv.txt) extension and implemented as a binary shader format.
70 |
71 | A C++ example for loading a binary SPIR-V shader with OpenGL [can be found here](https://github.com/SaschaWillems/openglcpp/tree/master/SPIRVShader).
72 |
73 | #### Print human-readable SPIR-V
74 |
75 | This will output human readable SPIR-V (-H) using Vulkan semantics and displays it in a new document window.
76 |
77 | ### Error list
78 |
79 |
80 |
81 | Compile errors are added to the error list of Visual Studio and work like regular compile errors. Double clicking on an error will open that shader and jump to the line that the error has occured.
82 |
83 | ## Todo
84 | This is a very early version of this extension, some of the planned features are:
85 | - Extension settings pane
86 | - Add file extension mappings
87 | - Custom binary SPIR-V output file name scheme (instead of a fixed output file scheme)
88 | - Option to disable dialog boxes after compile
89 | - Option to use a remapper (SPIR-V remap etc.)
90 | - Save to text as hexadecimal numbers (-x)
91 | - Generate include headers
92 | - Language features (as soon as their support by the reference compiler is finished)
93 | - Multiple main entry points
94 | - Compile from HLSL
95 |
96 | Issues and pull request for additional features are welcome :)
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | project.fragment.lock.json
46 | artifacts/
47 |
48 | *_i.c
49 | *_p.c
50 | *_i.h
51 | *.ilk
52 | *.meta
53 | *.obj
54 | *.pch
55 | *.pdb
56 | *.pgc
57 | *.pgd
58 | *.rsp
59 | *.sbr
60 | *.tlb
61 | *.tli
62 | *.tlh
63 | *.tmp
64 | *.tmp_proj
65 | *.log
66 | *.vspscc
67 | *.vssscc
68 | .builds
69 | *.pidb
70 | *.svclog
71 | *.scc
72 |
73 | # Chutzpah Test files
74 | _Chutzpah*
75 |
76 | # Visual C++ cache files
77 | ipch/
78 | *.aps
79 | *.ncb
80 | *.opendb
81 | *.opensdf
82 | *.sdf
83 | *.cachefile
84 | *.VC.db
85 | *.VC.VC.opendb
86 |
87 | # Visual Studio profiler
88 | *.psess
89 | *.vsp
90 | *.vspx
91 | *.sap
92 |
93 | # TFS 2012 Local Workspace
94 | $tf/
95 |
96 | # Guidance Automation Toolkit
97 | *.gpState
98 |
99 | # ReSharper is a .NET coding add-in
100 | _ReSharper*/
101 | *.[Rr]e[Ss]harper
102 | *.DotSettings.user
103 |
104 | # JustCode is a .NET coding add-in
105 | .JustCode
106 |
107 | # TeamCity is a build add-in
108 | _TeamCity*
109 |
110 | # DotCover is a Code Coverage Tool
111 | *.dotCover
112 |
113 | # NCrunch
114 | _NCrunch_*
115 | .*crunch*.local.xml
116 | nCrunchTemp_*
117 |
118 | # MightyMoose
119 | *.mm.*
120 | AutoTest.Net/
121 |
122 | # Web workbench (sass)
123 | .sass-cache/
124 |
125 | # Installshield output folder
126 | [Ee]xpress/
127 |
128 | # DocProject is a documentation generator add-in
129 | DocProject/buildhelp/
130 | DocProject/Help/*.HxT
131 | DocProject/Help/*.HxC
132 | DocProject/Help/*.hhc
133 | DocProject/Help/*.hhk
134 | DocProject/Help/*.hhp
135 | DocProject/Help/Html2
136 | DocProject/Help/html
137 |
138 | # Click-Once directory
139 | publish/
140 |
141 | # Publish Web Output
142 | *.[Pp]ublish.xml
143 | *.azurePubxml
144 | # TODO: Comment the next line if you want to checkin your web deploy settings
145 | # but database connection strings (with potential passwords) will be unencrypted
146 | *.pubxml
147 | *.publishproj
148 |
149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
150 | # checkin your Azure Web App publish settings, but sensitive information contained
151 | # in these scripts will be unencrypted
152 | PublishScripts/
153 |
154 | # NuGet Packages
155 | *.nupkg
156 | # The packages folder can be ignored because of Package Restore
157 | **/packages/*
158 | # except build/, which is used as an MSBuild target.
159 | !**/packages/build/
160 | # Uncomment if necessary however generally it will be regenerated when needed
161 | #!**/packages/repositories.config
162 | # NuGet v3's project.json files produces more ignoreable files
163 | *.nuget.props
164 | *.nuget.targets
165 |
166 | # Microsoft Azure Build Output
167 | csx/
168 | *.build.csdef
169 |
170 | # Microsoft Azure Emulator
171 | ecf/
172 | rcf/
173 |
174 | # Windows Store app package directories and files
175 | AppPackages/
176 | BundleArtifacts/
177 | Package.StoreAssociation.xml
178 | _pkginfo.txt
179 |
180 | # Visual Studio cache files
181 | # files ending in .cache can be ignored
182 | *.[Cc]ache
183 | # but keep track of directories ending in .cache
184 | !*.[Cc]ache/
185 |
186 | # Others
187 | ClientBin/
188 | ~$*
189 | *~
190 | *.dbmdl
191 | *.dbproj.schemaview
192 | *.pfx
193 | *.publishsettings
194 | node_modules/
195 | orleans.codegen.cs
196 |
197 | # Since there are multiple workflows, uncomment next line to ignore bower_components
198 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
199 | #bower_components/
200 |
201 | # RIA/Silverlight projects
202 | Generated_Code/
203 |
204 | # Backup & report files from converting an old project file
205 | # to a newer Visual Studio version. Backup files are not needed,
206 | # because we have git ;-)
207 | _UpgradeReport_Files/
208 | Backup*/
209 | UpgradeLog*.XML
210 | UpgradeLog*.htm
211 |
212 | # SQL Server files
213 | *.mdf
214 | *.ldf
215 |
216 | # Business Intelligence projects
217 | *.rdl.data
218 | *.bim.layout
219 | *.bim_*.settings
220 |
221 | # Microsoft Fakes
222 | FakesAssemblies/
223 |
224 | # GhostDoc plugin setting file
225 | *.GhostDoc.xml
226 |
227 | # Node.js Tools for Visual Studio
228 | .ntvs_analysis.dat
229 |
230 | # Visual Studio 6 build log
231 | *.plg
232 |
233 | # Visual Studio 6 workspace options file
234 | *.opt
235 |
236 | # Visual Studio LightSwitch build output
237 | **/*.HTMLClient/GeneratedArtifacts
238 | **/*.DesktopClient/GeneratedArtifacts
239 | **/*.DesktopClient/ModelManifest.xml
240 | **/*.Server/GeneratedArtifacts
241 | **/*.Server/ModelManifest.xml
242 | _Pvt_Extensions
243 |
244 | # Paket dependency manager
245 | .paket/paket.exe
246 | paket-files/
247 |
248 | # FAKE - F# Make
249 | .fake/
250 |
251 | # JetBrains Rider
252 | .idea/
253 | *.sln.iml
254 |
255 | # CodeRush
256 | .cr/
257 |
258 | # Python Tools for Visual Studio (PTVS)
259 | __pycache__/
260 | *.pyc
261 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Shared/GlslangCompiler.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using Microsoft.VisualStudio.Shell;
10 | using SPIRVExtension.Shared;
11 | using System;
12 | using System.Collections.Generic;
13 | using System.Diagnostics;
14 | using System.Globalization;
15 | using System.IO;
16 |
17 | namespace SPIRVExtension
18 | {
19 | ///
20 | /// Helper class for locating and invocating the glslang reference compiler
21 | ///
22 | public class GlslangCompiler
23 | {
24 | ///
25 | /// Searches the PATH environment and common SDK path environment variables for the glslangvalidator
26 | ///
27 | public static string Locate(SPIRVExtensionPackage package)
28 | {
29 | if (package.OptionGlslangValidatorBinaryPath != "")
30 | {
31 | OutputWindow.Add("Using glslangvalidator from options path: " + Path.Combine(package.OptionGlslangValidatorBinaryPath, "glslangvalidator.exe"));
32 | return Path.Combine(package.OptionGlslangValidatorBinaryPath, "glslangvalidator.exe");
33 | }
34 |
35 | var pathEnv = Environment.GetEnvironmentVariable("PATH");
36 | List paths = new List(pathEnv.Split(';'));
37 | var additionalPaths = new[] { "VK_SDK_PATH", "VULKAN_SDK" };
38 | foreach (string path in additionalPaths)
39 | {
40 | if (Environment.GetEnvironmentVariable(path) != null)
41 | {
42 | paths.Add(Environment.GetEnvironmentVariable(path));
43 | }
44 | }
45 |
46 | foreach (var path in paths)
47 | {
48 | var filePath = Path.Combine(path, "glslangvalidator.exe");
49 | if (File.Exists(filePath))
50 | {
51 | return filePath;
52 | }
53 | }
54 | return null;
55 | }
56 |
57 | private static bool Run(string fileName, string commandLine, out List validatorOutput, SPIRVExtensionPackage package)
58 | {
59 | var startInfo = new ProcessStartInfo();
60 | startInfo.FileName = Locate(package);
61 | startInfo.Arguments = commandLine;
62 | startInfo.UseShellExecute = false;
63 | startInfo.RedirectStandardOutput = true;
64 | startInfo.CreateNoWindow = true;
65 |
66 | var process = new Process();
67 | process.StartInfo = startInfo;
68 |
69 | try
70 | {
71 | process.Start();
72 | }
73 | catch (Exception e)
74 | {
75 | //todo: Display error message
76 | OutputWindow.Add("Exception while running: " + e.Message);
77 | throw;
78 | }
79 |
80 | OutputWindow.Add(Locate(package));
81 | OutputWindow.Add(commandLine);
82 |
83 | List output = new List();
84 | while (!process.StandardOutput.EndOfStream)
85 | {
86 | output.Add(process.StandardOutput.ReadLine());
87 | }
88 |
89 | validatorOutput = output;
90 |
91 | return (process.ExitCode == 0);
92 | }
93 |
94 | ///
95 | /// Compile the shader using Vulkan semantics and output to a binary file (.spv)
96 | ///
97 | public static bool CompileToVulkan(string fileName, out List validatorOutput, SPIRVExtensionPackage package)
98 | {
99 | string commandLine = string.Format(CultureInfo.CurrentCulture, "-V \"{0}\" -o \"{1}\"", fileName, fileName + ".spv");
100 | if (package.OptionTargetEnv != "")
101 | {
102 | commandLine += " --target-env " + package.OptionTargetEnv;
103 | } else
104 | {
105 | // Ray tracing shaders require at least SPIR-V 1.4
106 | if (Utils.IsRayTracingShaderFile(fileName)) {
107 | commandLine += " --target-env spirv1.4";
108 | }
109 | }
110 | return Run(fileName, commandLine, out validatorOutput, package);
111 | }
112 |
113 | ///
114 | /// Compile the shader using OpenGL semantics and output to a binary file (.spv)
115 | ///
116 | public static bool CompileToOpenGL(string fileName, out List validatorOutput, SPIRVExtensionPackage package)
117 | {
118 | string commandLine = string.Format(CultureInfo.CurrentCulture, "-G \"{0}\" -o \"{1}\"", fileName, fileName + ".spv");
119 | return Run(fileName, commandLine, out validatorOutput, package);
120 | }
121 |
122 | ///
123 | /// Converts the shader to human readable SPIR-V and returns the reference compiler output
124 | ///
125 | public static bool GetHumanReadableSPIRV(string fileName, out List validatorOutput, SPIRVExtensionPackage package)
126 | {
127 | string commandLine = string.Format(CultureInfo.CurrentCulture, "-H \"{0}\"", fileName);
128 | if (package.OptionTargetEnv != "")
129 | {
130 | commandLine += " --target-env " + package.OptionTargetEnv;
131 | }
132 | return Run(fileName, commandLine, out validatorOutput, package);
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/SPIRVExtensionPackage.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using System;
10 | using System.ComponentModel.Design;
11 | using System.Diagnostics;
12 | using System.Diagnostics.CodeAnalysis;
13 | using System.Globalization;
14 | using System.Runtime.InteropServices;
15 | using System.ComponentModel;
16 | using Microsoft.VisualStudio;
17 | using Microsoft.VisualStudio.OLE.Interop;
18 | using Microsoft.VisualStudio.Shell;
19 | using Microsoft.VisualStudio.Shell.Interop;
20 | using Microsoft.Win32;
21 |
22 | public class OptionPageGrid : DialogPage
23 | {
24 | [Category("GLSL")]
25 | [DisplayName("Target Environment")]
26 | [Description("Select the target environment for Vulkan shader compilation")]
27 | public string OptionTargetEnv { get; set; } = "";
28 |
29 | [Category("GLSL")]
30 | [DisplayName("glslangvalidator path")]
31 | [Description("Manually specify a path to the glslangvalidator binary to override the default one from PATH")]
32 | public string OptionGlslangValidatorBinaryPath { get; set; } = "";
33 |
34 | [Category("HLSL")]
35 | [DisplayName("dxc path")]
36 | [Description("Manually specify a path to the dxc binary to override the default one from PATH")]
37 | public string OptionDxcBinaryPath { get; set; } = "";
38 | }
39 |
40 | namespace SPIRVExtension
41 | {
42 | ///
43 | /// This is the class that implements the package exposed by this assembly.
44 | ///
45 | ///
46 | ///
47 | /// The minimum requirement for a class to be considered a valid package for Visual Studio
48 | /// is to implement the IVsPackage interface and register itself with the shell.
49 | /// This package uses the helper classes defined inside the Managed Package Framework (MPF)
50 | /// to do it: it derives from the Package class that provides the implementation of the
51 | /// IVsPackage interface and uses the registration attributes defined in the framework to
52 | /// register itself and its components with the shell. These attributes tell the pkgdef creation
53 | /// utility what data to put into .pkgdef file.
54 | ///
55 | ///
56 | /// To get loaded into VS, the package must be referred by <Asset Type="Microsoft.VisualStudio.VsPackage" ...> in .vsixmanifest file.
57 | ///
58 | ///
59 | [PackageRegistration(UseManagedResourcesOnly = true)]
60 | [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] // Info on this package for Help/About
61 | [ProvideMenuResource("Menus.ctmenu", 1)]
62 | [Guid(SPIRVExtensionPackage.PackageGuidString)]
63 | [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "pkgdef, VS and vsixmanifest are valid VS terms")]
64 | [ProvideAutoLoad("f1536ef8-92ec-443c-9ed7-fdadf150da82")]
65 | [ProvideOptionPage(typeof(OptionPageGrid),
66 | "SPIRV Extension", "General", 0, 0, true)]
67 | public sealed class SPIRVExtensionPackage : Package
68 | {
69 | ///
70 | /// SPIRVExtension GUID string.
71 | ///
72 | public const string PackageGuidString = "1ec0f76d-4687-49ea-a037-76a4ab592f51";
73 |
74 | ///
75 | /// Initializes a new instance of the class.
76 | ///
77 | public SPIRVExtensionPackage()
78 | {
79 | // Inside this method you can place any initialization code that does not require
80 | // any Visual Studio service because at this point the package object is created but
81 | // not sited yet inside Visual Studio environment. The place to do all the other
82 | // initialization is the Initialize method.
83 | }
84 |
85 | #region Package Members
86 |
87 | ///
88 | /// Initialization of the package; this method is called right after the package is sited, so this is the place
89 | /// where you can put all the initialization code that rely on services provided by VisualStudio.
90 | ///
91 | protected override void Initialize()
92 | {
93 | CommandCompileVulkan.Initialize(this);
94 | CommandCompileHLSL.Initialize(this);
95 | CommandCompileOpenGL.Initialize(this);
96 | CommandPrintSPIRV.Initialize(this);
97 |
98 | base.Initialize();
99 | ErrorList.Initialize(this);
100 | }
101 |
102 | public string OptionTargetEnv
103 | {
104 | get
105 | {
106 | OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
107 | return page.OptionTargetEnv;
108 | }
109 | }
110 |
111 | public string OptionGlslangValidatorBinaryPath
112 | {
113 | get
114 | {
115 | OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
116 | return page.OptionGlslangValidatorBinaryPath;
117 | }
118 | }
119 |
120 | public string OptionDxcBinaryPath
121 | {
122 | get
123 | {
124 | OptionPageGrid page = (OptionPageGrid)GetDialogPage(typeof(OptionPageGrid));
125 | return page.OptionDxcBinaryPath;
126 | }
127 | }
128 | #endregion
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/Shared/DxcCompiler.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * SPIR-V Visual Studio Extension
3 | *
4 | * Copyright (C) 2016-2022 by Sascha Willems - www.saschawillems.de
5 | *
6 | * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7 | */
8 |
9 | using Microsoft.VisualStudio.Shell;
10 | using SPIRVExtension.Shared;
11 | using System;
12 | using System.Collections.Generic;
13 | using System.Diagnostics;
14 | using System.Globalization;
15 | using System.IO;
16 |
17 | namespace SPIRVExtension
18 | {
19 | ///
20 | /// Helper class for locating and invocating the DXC compiler
21 | ///
22 | public class DxcCompiler
23 | {
24 | ///
25 | /// Searches the PATH environment and common SDK path environment variables for the glslangvalidator
26 | ///
27 | public static string Locate(SPIRVExtensionPackage package)
28 | {
29 | if (package.OptionGlslangValidatorBinaryPath != "")
30 | {
31 | OutputWindow.Add("Using glslangvalidator from options path: " + Path.Combine(package.OptionGlslangValidatorBinaryPath, "glslangvalidator.exe"));
32 | return Path.Combine(package.OptionGlslangValidatorBinaryPath, "glslangvalidator.exe");
33 | }
34 |
35 | var pathEnv = Environment.GetEnvironmentVariable("PATH");
36 | List paths = new List(pathEnv.Split(';'));
37 | var additionalPaths = new[] { "VK_SDK_PATH", "VULKAN_SDK" };
38 | foreach (string path in additionalPaths)
39 | {
40 | if (Environment.GetEnvironmentVariable(path) != null)
41 | {
42 | paths.Add(Environment.GetEnvironmentVariable(path));
43 | }
44 | }
45 |
46 | foreach (var path in paths)
47 | {
48 | var filePath = Path.Combine(path, "dxc.exe");
49 | if (File.Exists(filePath))
50 | {
51 | return filePath;
52 | }
53 | }
54 | return null;
55 | }
56 |
57 | private static bool Run(string fileName, string commandLine, out List validatorOutput, SPIRVExtensionPackage package)
58 | {
59 | var startInfo = new ProcessStartInfo();
60 | startInfo.FileName = Locate(package);
61 | startInfo.Arguments = commandLine;
62 | startInfo.UseShellExecute = false;
63 | startInfo.RedirectStandardOutput = true;
64 | startInfo.CreateNoWindow = true;
65 |
66 | var process = new Process();
67 | process.StartInfo = startInfo;
68 |
69 | try
70 | {
71 | process.Start();
72 | }
73 | catch (Exception e)
74 | {
75 | //todo: Display error message
76 | OutputWindow.Add("Exception while running: " + e.Message);
77 | throw;
78 | }
79 |
80 | OutputWindow.Add(Locate(package));
81 | OutputWindow.Add(commandLine);
82 |
83 | List output = new List();
84 | while (!process.StandardOutput.EndOfStream)
85 | {
86 | output.Add(process.StandardOutput.ReadLine());
87 | }
88 |
89 | validatorOutput = output;
90 |
91 | return (process.ExitCode == 0);
92 | }
93 |
94 | ///
95 | /// Compile the shader using Vulkan semantics and output to a binary file (.spv)
96 | ///
97 | public static bool CompileToVulkan(string fileName, out List validatorOutput, SPIRVExtensionPackage package)
98 | {
99 | // Get profile and additional options based on file extension
100 | var profileDictionary = new Dictionary
101 | {
102 | { ".vert", "vs_6_1" },
103 | { ".frag", "ps_6_1" },
104 | { ".comp", "cs_6_1" },
105 | { ".geom", "gs_6_1" },
106 | { ".tesc", "hs_6_1" },
107 | { ".tese", "ds_6_1" },
108 | { ".rgen", "lib_6_3" },
109 | { ".rchit", "lib_6_3" },
110 | { ".rmiss", "lib_6_3" },
111 | };
112 | string fileExt = Path.GetExtension(fileName).ToLower();
113 | if (!profileDictionary.ContainsKey(fileExt))
114 | {
115 | // @todo: add message
116 | List output = new List();
117 | output.Add("Could not match file extension to HLSL shader profile");
118 | validatorOutput = output;
119 | return false;
120 | }
121 | string profile = profileDictionary[fileExt];
122 |
123 | List commandLineArgs = new List();
124 | commandLineArgs.Add("-spirv");
125 | commandLineArgs.Add("-T " + profile);
126 | commandLineArgs.Add("-E main");
127 | if (package.OptionTargetEnv != "")
128 | {
129 | commandLineArgs.Add("-fspv-target-env=" + package.OptionTargetEnv);
130 | }
131 | else
132 | {
133 | // Ray tracing shaders require at least SPIR-V 1.4
134 | if (Utils.IsRayTracingShaderFile(fileName))
135 | {
136 | commandLineArgs.Add("-fspv-target-env=vulkan1.2");
137 | }
138 | }
139 | commandLineArgs.Add(fileName);
140 | commandLineArgs.Add("-Fo");
141 | commandLineArgs.Add(fileName + ".spv");
142 |
143 | string commandLine = string.Join(" ", commandLineArgs);
144 | return Run(fileName, commandLine, out validatorOutput, package);
145 | }
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/VSPackage.resx:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | text/microsoft-resx
120 |
121 |
122 | 2.0
123 |
124 |
125 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
126 |
127 |
128 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
129 |
130 |
131 |
132 | SPIRV Extension
133 |
134 |
135 | SPIRV Visual Studio Extension Detailed Info
136 |
137 |
138 | Resources\SPIRVExtension.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
139 |
140 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/SPIRVExtensionPackage.vsct:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
25 |
26 |
33 |
34 |
38 |
39 |
42 |
43 |
44 |
45 |
47 |
48 |
49 |
50 |
60 |
61 |
62 |
72 |
73 |
74 |
84 |
85 |
86 |
96 |
97 |
98 |
99 |
100 |
101 |
106 |
107 |
108 |
109 |
110 |
111 |
114 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/ShaderCommandBase.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio;
2 | using Microsoft.VisualStudio.Shell;
3 | using Microsoft.VisualStudio.Shell.Interop;
4 | using SPIRVExtension.Shared;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Diagnostics;
8 | using System.Globalization;
9 | using System.IO;
10 | using System.Runtime.InteropServices;
11 | using System.Text.RegularExpressions;
12 |
13 | namespace SPIRVExtension
14 | {
15 | public delegate bool CompileFunc(string a, out List b, SPIRVExtensionPackage p);
16 |
17 | ///
18 | /// Base class for commands that compile to SPIR-V
19 | ///
20 | public class ShaderCommandBase
21 | {
22 | private readonly Package package;
23 | public string name;
24 |
25 | public ShaderCommandBase(Package package, string name)
26 | {
27 | this.package = package;
28 | this.name = name;
29 | }
30 |
31 | ///
32 | /// Gets the service provider from the owner package.
33 | ///
34 | public IServiceProvider ServiceProvider
35 | {
36 | get
37 | {
38 | return this.package;
39 | }
40 | }
41 |
42 | ///
43 | /// Read hierarchy of an item recursively to also include files in folders
44 | ///
45 | public void ReadItemHierarchy(uint itemid, IVsHierarchy hierarchy, List itemids)
46 | {
47 | itemids.Add(itemid);
48 |
49 | object value = null;
50 | int res = hierarchy.GetProperty(itemid, (int)__VSHPROPID.VSHPROPID_FirstVisibleChild, out value);
51 |
52 | if (res != VSConstants.S_OK || value == null)
53 | {
54 | // Single item, add and return
55 | if (value is int)
56 | {
57 | itemids.Add(Convert.ToUInt32(value));
58 | return;
59 | }
60 | }
61 | else
62 | {
63 | // Item has siblings (e.g. folder)
64 | while (res == VSConstants.S_OK && value != null)
65 | {
66 | if (value is int && (uint)(int)value == VSConstants.VSITEMID_NIL)
67 | {
68 | break;
69 | }
70 | uint childNode = Convert.ToUInt32(value);
71 | ReadItemHierarchy(childNode, hierarchy, itemids);
72 | res = hierarchy.GetProperty(childNode, (int)__VSHPROPID.VSHPROPID_NextVisibleSibling, out value);
73 | }
74 | }
75 | }
76 |
77 | ///
78 | /// Returns a list of valid shader files from the current file selection
79 | ///
80 | /// List to be filled with all valid shader files from the current selection
81 | /// True if at least one shader has been selected
82 | public bool GetSelectedShaderFiles(List shaderFiles)
83 | {
84 | IVsHierarchy hierarchy = null;
85 | uint itemid = VSConstants.VSITEMID_NIL;
86 | int hr = VSConstants.S_OK;
87 |
88 | var monitorSelection = Package.GetGlobalService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
89 | var solution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution;
90 | if (monitorSelection == null || solution == null)
91 | {
92 | return false;
93 | }
94 |
95 | IVsMultiItemSelect multiItemSelect = null;
96 | IntPtr hierarchyPtr = IntPtr.Zero;
97 | IntPtr selectionContainerPtr = IntPtr.Zero;
98 |
99 | try
100 | {
101 | hr = monitorSelection.GetCurrentSelection(out hierarchyPtr, out itemid, out multiItemSelect, out selectionContainerPtr);
102 |
103 | if (ErrorHandler.Failed(hr) || hierarchyPtr == IntPtr.Zero || itemid == VSConstants.VSITEMID_NIL)
104 | {
105 | return false;
106 | }
107 |
108 | hierarchy = Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy;
109 | if (hierarchy == null)
110 | {
111 | return false;
112 | }
113 |
114 | List itemids = new List();
115 |
116 | if (multiItemSelect == null)
117 | {
118 | ReadItemHierarchy(itemid, hierarchy, itemids);
119 | }
120 | else
121 | {
122 | // todo: Read hierarchy for multi selects
123 | uint itemCount = 0;
124 | int fSingleHierarchy = 0;
125 | hr = multiItemSelect.GetSelectionInfo(out itemCount, out fSingleHierarchy);
126 |
127 | VSITEMSELECTION[] items = new VSITEMSELECTION[itemCount];
128 | hr = multiItemSelect.GetSelectedItems(0, itemCount, items);
129 |
130 | foreach (var item in items)
131 | {
132 | itemids.Add(item.itemid);
133 | }
134 |
135 | }
136 |
137 | foreach (var id in itemids)
138 | {
139 | string filepath = null;
140 | ((IVsProject)hierarchy).GetMkDocument(id, out filepath);
141 | if (filepath != null && Utils.IsShaderFile(filepath))
142 | {
143 | var transformFileInfo = new FileInfo(filepath);
144 | shaderFiles.Add(new ShaderFile(id, hierarchy, filepath));
145 | }
146 | }
147 |
148 | // todo: hierarchy node
149 | if (itemid == VSConstants.VSITEMID_ROOT)
150 | {
151 | return false;
152 | }
153 |
154 | Guid guidProjectID = Guid.Empty;
155 |
156 | if (ErrorHandler.Failed(solution.GetGuidOfProject(hierarchy, out guidProjectID)))
157 | {
158 | return false;
159 | }
160 |
161 | return (shaderFiles.Count > 0);
162 | }
163 | finally
164 | {
165 | if (selectionContainerPtr != IntPtr.Zero)
166 | Marshal.Release(selectionContainerPtr);
167 | if (hierarchyPtr != IntPtr.Zero)
168 | Marshal.Release(hierarchyPtr);
169 | }
170 | }
171 |
172 | ///
173 | /// Gets the selected shader file count
174 | ///
175 | /// Count of valid selected shader files
176 | public int GetSelectedShaderFileCount()
177 | {
178 | List selectedShaderFiles = new List();
179 | if (GetSelectedShaderFiles(selectedShaderFiles))
180 | {
181 | return selectedShaderFiles.Count;
182 | }
183 | return 0;
184 | }
185 |
186 | ///
187 | /// Parse error output from the reference compiler and add it to the error list
188 | ///
189 | /// Output of the reference compiler
190 | /// Shader file info for which the validator output has been generated
191 | public void ParseErrors(List validatorOutput, ShaderFile shaderFile)
192 | {
193 | foreach (string line in validatorOutput)
194 | {
195 | // Examples:
196 | // ERROR: 0:26: 'aaa' : undeclared identifier
197 | // ERROR: E:\Vulkan\public\Vulkan\data\shaders\indirectdraw\ground.frag:16: '' : function does not return a value: test
198 | MatchCollection matches = Regex.Matches(line, @":\d+:\s", RegexOptions.IgnoreCase | RegexOptions.RightToLeft);
199 | if (matches.Count > 0)
200 | {
201 | // Line
202 | int errorLine = Convert.ToInt32(matches[0].Value.Replace(":", ""));
203 | // Error message
204 | string msg = line;
205 | Match match = Regex.Match(line, @"ERROR:\s.*\d+:(.*)", RegexOptions.IgnoreCase);
206 | if (match.Success)
207 | {
208 | msg = match.Groups[1].Value;
209 | }
210 | ErrorList.Add(msg, shaderFile.fileName, errorLine, 0, shaderFile.hierarchy);
211 | }
212 | }
213 | }
214 |
215 | ///
216 | /// Compile the shader file using the given compilation function
217 | ///
218 | public void CompileShaders(List shaderFiles, CompileFunc compileFunc)
219 | {
220 | string title = name;
221 | string msg;
222 |
223 | // @todo
224 | //if (GlslangCompiler.Locate(package as SPIRVExtensionPackage) == null)
225 | //{
226 | // msg = "Could not locate the glslang reference compiler (glslangvalidator.exe) in system path!";
227 | // VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
228 | // OutputWindow.Add(msg);
229 | // return;
230 | //}
231 |
232 | ErrorList.Clear();
233 |
234 | bool success = true;
235 | msg = "";
236 | foreach (var shaderFile in shaderFiles)
237 | {
238 | string targetEnv = (package as SPIRVExtensionPackage).OptionTargetEnv;
239 |
240 | List validatorOutput;
241 | bool compiled = compileFunc(shaderFile.fileName, out validatorOutput, package as SPIRVExtensionPackage);
242 | if (compiled)
243 | {
244 | OutputWindow.Add(string.Join("\n", validatorOutput));
245 | }
246 | else
247 | {
248 | msg += string.Format(CultureInfo.CurrentCulture, "Shader \"{0}\" could not be compiled to SPIR-V!", shaderFile.fileName) + "\n";
249 | Debug.Write(msg);
250 | ParseErrors(validatorOutput, shaderFile);
251 | OutputWindow.Add(shaderFile.fileName + "\n" + string.Join("\n", validatorOutput));
252 | success = false;
253 | }
254 | }
255 |
256 | if (success)
257 | {
258 | if (shaderFiles.Count == 1)
259 | {
260 | msg = string.Format(CultureInfo.CurrentCulture, "Shader successfully compiled to \"{0}\"", shaderFiles[0].fileName + ".spv");
261 | }
262 | else
263 | {
264 | msg = "All shaders successfully compiled to SPIR-V";
265 | }
266 | VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_INFO, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
267 | }
268 | else
269 | {
270 | VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
271 | }
272 |
273 | if (ErrorList.ErrorCount() > 0)
274 | {
275 | ErrorList.Show();
276 | }
277 | }
278 |
279 | ///
280 | /// Returns the human readble SPIR-V representation of the shader
281 | ///
282 | public bool GetReadableSPIRV(ShaderFile shaderFile, out List spirvOutput)
283 | {
284 | List output = new List();
285 | spirvOutput = output;
286 | string title = name;
287 | string msg;
288 |
289 | if (GlslangCompiler.Locate(package as SPIRVExtensionPackage) == null)
290 | {
291 | msg = "Could not locate the glslang reference compiler (glslangvalidator.exe) in system path!";
292 | VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
293 | OutputWindow.Add(msg);
294 | return false;
295 | }
296 |
297 | List validatorOutput;
298 | bool res = GlslangCompiler.GetHumanReadableSPIRV(shaderFile.fileName, out validatorOutput, package as SPIRVExtensionPackage);
299 | if (res)
300 | {
301 | spirvOutput = validatorOutput;
302 | }
303 | else
304 | {
305 | msg = string.Format(CultureInfo.CurrentCulture, "Could not get human readable SPIR-V for shader \"{0}\" ", shaderFile.fileName) + "\n";
306 | Debug.Write(msg);
307 | VsShellUtilities.ShowMessageBox(ServiceProvider, msg, title, OLEMSGICON.OLEMSGICON_CRITICAL, OLEMSGBUTTON.OLEMSGBUTTON_OK, OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST);
308 | ParseErrors(validatorOutput, shaderFile);
309 | msg += string.Join("\n", validatorOutput);
310 | OutputWindow.Add(msg);
311 | }
312 |
313 | return res;
314 | }
315 | }
316 | }
317 |
--------------------------------------------------------------------------------
/SPIRV-VSExtension/SPIRV-VSExtension.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 15.0
6 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
7 |
8 |
9 | true
10 |
11 |
12 |
13 |
14 |
15 | 14.0
16 | false
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | 0
28 | 1.0.0.%2a
29 | false
30 | false
31 | true
32 |
33 |
34 | true
35 |
36 |
37 | Key.snk
38 |
39 |
40 |
41 | Debug
42 | AnyCPU
43 | 2.0
44 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
45 | {914B9574-655F-435E-9928-FE245DABB221}
46 | Library
47 | Properties
48 | SPIRVExtension
49 | SPIRVExtension
50 | v4.5
51 | true
52 | true
53 | true
54 | true
55 | true
56 | true
57 |
58 |
59 | true
60 | full
61 | false
62 | bin\Debug\
63 | DEBUG;TRACE
64 | prompt
65 | 4
66 | True
67 |
68 |
69 | pdbonly
70 | true
71 | bin\Release\
72 | TRACE
73 | prompt
74 | 4
75 | True
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | Component
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | Always
99 | true
100 |
101 |
102 |
103 | Designer
104 |
105 |
106 |
107 |
108 | Menus.ctmenu
109 |
110 |
111 |
112 |
113 |
114 |
115 | False
116 |
117 |
118 | False
119 |
120 |
121 | False
122 |
123 |
124 | False
125 |
126 |
127 |
128 |
129 | False
130 |
131 |
132 | ..\packages\Microsoft.VisualStudio.Imaging.14.3.25407\lib\net45\Microsoft.VisualStudio.Imaging.dll
133 | True
134 |
135 |
136 | ..\packages\Microsoft.VisualStudio.OLE.Interop.7.10.6070\lib\Microsoft.VisualStudio.OLE.Interop.dll
137 | True
138 |
139 |
140 | ..\packages\Microsoft.VisualStudio.Shell.14.0.14.3.25407\lib\Microsoft.VisualStudio.Shell.14.0.dll
141 | True
142 |
143 |
144 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.10.0.10.0.30319\lib\net40\Microsoft.VisualStudio.Shell.Immutable.10.0.dll
145 | True
146 |
147 |
148 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.11.0.11.0.50727\lib\net45\Microsoft.VisualStudio.Shell.Immutable.11.0.dll
149 | True
150 |
151 |
152 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.12.0.12.0.21003\lib\net45\Microsoft.VisualStudio.Shell.Immutable.12.0.dll
153 | True
154 |
155 |
156 | ..\packages\Microsoft.VisualStudio.Shell.Immutable.14.0.14.3.25407\lib\net45\Microsoft.VisualStudio.Shell.Immutable.14.0.dll
157 | True
158 |
159 |
160 | ..\packages\Microsoft.VisualStudio.Shell.Interop.7.10.6071\lib\Microsoft.VisualStudio.Shell.Interop.dll
161 | True
162 |
163 |
164 | True
165 | ..\packages\Microsoft.VisualStudio.Shell.Interop.10.0.10.0.30319\lib\Microsoft.VisualStudio.Shell.Interop.10.0.dll
166 | True
167 |
168 |
169 | True
170 | ..\packages\Microsoft.VisualStudio.Shell.Interop.11.0.11.0.61030\lib\Microsoft.VisualStudio.Shell.Interop.11.0.dll
171 | True
172 |
173 |
174 | True
175 | ..\packages\Microsoft.VisualStudio.Shell.Interop.12.0.12.0.30110\lib\Microsoft.VisualStudio.Shell.Interop.12.0.dll
176 | True
177 |
178 |
179 | ..\packages\Microsoft.VisualStudio.Shell.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.Shell.Interop.8.0.dll
180 | True
181 |
182 |
183 | ..\packages\Microsoft.VisualStudio.Shell.Interop.9.0.9.0.30729\lib\Microsoft.VisualStudio.Shell.Interop.9.0.dll
184 | True
185 |
186 |
187 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.7.10.6070\lib\Microsoft.VisualStudio.TextManager.Interop.dll
188 | True
189 |
190 |
191 | ..\packages\Microsoft.VisualStudio.TextManager.Interop.8.0.8.0.50727\lib\Microsoft.VisualStudio.TextManager.Interop.8.0.dll
192 | True
193 |
194 |
195 | ..\packages\Microsoft.VisualStudio.Threading.14.1.111\lib\net45\Microsoft.VisualStudio.Threading.dll
196 | True
197 |
198 |
199 | ..\packages\Microsoft.VisualStudio.Utilities.14.3.25407\lib\net45\Microsoft.VisualStudio.Utilities.dll
200 | True
201 |
202 |
203 | ..\packages\Microsoft.VisualStudio.Validation.14.1.111\lib\net45\Microsoft.VisualStudio.Validation.dll
204 | True
205 |
206 |
207 | False
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 | true
219 | VSPackage
220 | Designer
221 |
222 |
223 |
224 |
225 | False
226 | .NET Framework 3.5 SP1
227 | false
228 |
229 |
230 |
231 |
232 |
233 |
234 | Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".
235 |
236 |
237 |
238 |
239 |
240 |
247 |
--------------------------------------------------------------------------------