Skip to content

Commit

Permalink
Engine: Add new ShaderCompiler for build shader compiling (pretty har…
Browse files Browse the repository at this point in the history
…dcoded now)
  • Loading branch information
amerkoleci committed Jun 3, 2024
1 parent f38c8ab commit 4fffe65
Show file tree
Hide file tree
Showing 13 changed files with 190 additions and 11 deletions.
7 changes: 7 additions & 0 deletions Alimer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Alimer.Editor", "src\editor
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Alimer.ImGui", "src\Alimer.ImGui\Alimer.ImGui.csproj", "{B8CA8405-66BB-40FE-B5DD-527BF6821856}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Alimer.ShaderCompiler", "src\assets\Alimer.ShaderCompiler\Alimer.ShaderCompiler.csproj", "{40A434AE-8653-4F40-B096-3B620DD092A7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -153,6 +155,10 @@ Global
{B8CA8405-66BB-40FE-B5DD-527BF6821856}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8CA8405-66BB-40FE-B5DD-527BF6821856}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8CA8405-66BB-40FE-B5DD-527BF6821856}.Release|Any CPU.Build.0 = Release|Any CPU
{40A434AE-8653-4F40-B096-3B620DD092A7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{40A434AE-8653-4F40-B096-3B620DD092A7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{40A434AE-8653-4F40-B096-3B620DD092A7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{40A434AE-8653-4F40-B096-3B620DD092A7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -166,6 +172,7 @@ Global
{A80A537D-096C-4916-9222-0F65FBFD64A8} = {6E75A307-8EA0-441A-9882-967B5048E707}
{23D2739E-5B8A-406B-A6D7-B1DB939B12E7} = {922968E0-A70B-4E09-BF72-5DB37F5936AE}
{2696DBC8-C7A4-4AD2-AE5A-C7008AABF513} = {922968E0-A70B-4E09-BF72-5DB37F5936AE}
{40A434AE-8653-4F40-B096-3B620DD092A7} = {6E75A307-8EA0-441A-9882-967B5048E707}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {2F91C04E-B42E-4037-8FF3-A9C768E70094}
Expand Down
14 changes: 7 additions & 7 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<TerraFXWindowsVersion>10.0.22621.6</TerraFXWindowsVersion>
<ImGuiVersion>1.0.3</ImGuiVersion>
<SkiaSharpVersion>3.0.0-preview.2.1</SkiaSharpVersion>
<SkiaSharpVersion>3.0.0-preview.3.1</SkiaSharpVersion>
</PropertyGroup>

<ItemGroup>
Expand Down Expand Up @@ -33,19 +33,19 @@
<!-- Asset Pipeline -->
<PackageVersion Include="SkiaSharp" Version="$(SkiaSharpVersion)" />
<PackageVersion Include="SkiaSharp.HarfBuzz" Version="$(SkiaSharpVersion)" />
<PackageVersion Include="SharpGLTF.Core" Version="1.0.0-alpha0031" />
<PackageVersion Include="Silk.NET.Assimp" Version="2.20.0" />
<PackageVersion Include="SharpGLTF.Core" Version="1.0.0" />
<PackageVersion Include="Silk.NET.Assimp" Version="2.21.0" />
<PackageVersion Include="Vortice.SPIRV.Reflect" Version="1.0.1" />

<!-- Editor -->
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" />

<!-- Tests -->
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
<PackageVersion Include="xunit" Version="2.7.0" />
<PackageVersion Include="xunit.console" Version="2.7.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.5.7" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageVersion Include="xunit" Version="2.8.1" />
<PackageVersion Include="xunit.console" Version="2.8.1" />
<PackageVersion Include="xunit.runner.visualstudio" Version="2.8.1" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions samples/Alimer.Samples/Alimer.Samples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
</ItemGroup>

<!-- Assets-->
<ItemGroup>
<Shader Include="Assets\Shaders\*.hlsl" />
</ItemGroup>

<ItemGroup>
<Content Include="Assets\**" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
Expand Down
Binary file modified samples/Alimer.Samples/Assets/Meshes/DamagedHelmet.glb
Binary file not shown.
4 changes: 2 additions & 2 deletions samples/Alimer.Samples/Graphics/DrawCubeSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public DrawCubeSample(IServiceRegistry services, Window mainWindow)
_pipelineLayout = ToDispose(GraphicsDevice.CreatePipelineLayout(_bindGroupLayout0));

Dictionary<string, string> vsDefines = new() { { "VERTEX_COLOR", "0" } };
ShaderStageDescription vertexShader = CompileShader("Cube.hlsl", "vertexMain", ShaderStages.Vertex, vsDefines);
ShaderStageDescription fragmentShader = CompileShader("Cube.hlsl", "fragmentMain", ShaderStages.Fragment);
ShaderStageDescription vertexShader = LoadShader("Cube", ShaderStages.Vertex, "vertexMain");
ShaderStageDescription fragmentShader = LoadShader("Cube", ShaderStages.Fragment, "fragmentMain");

var shaderStages = new ShaderStageDescription[2]
{
Expand Down
21 changes: 21 additions & 0 deletions samples/Alimer.Samples/GraphicsSampleBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ protected GraphicsBuffer CreateBuffer<T>(List<T> initialData,
return GraphicsDevice.CreateBuffer(dataSpan, usage, cpuAccess);
}

protected Stream OpenEmbeddedAssetStream(string name) => typeof(GraphicsSampleBase).Assembly!.GetManifestResourceStream(name);
protected byte[] ReadEmbeddedAssetBytes(string name)
{
using Stream stream = OpenEmbeddedAssetStream(name);
byte[] bytes = new byte[stream.Length];
using (MemoryStream ms = new MemoryStream(bytes))
{
stream.CopyTo(ms);
return bytes;
}
}

protected ShaderStageDescription LoadShader(string name, ShaderStages stage, string entryPoint)
{
string shaderFormat = GraphicsDevice.Backend == GraphicsBackendType.Vulkan ? "spirv" : "dxil";

string entryName = $"{name}_{entryPoint}_{shaderFormat}.bin";
byte[] bytecode = ReadEmbeddedAssetBytes(entryName);
return new ShaderStageDescription(stage, bytecode, entryPoint);
}

protected ShaderStageDescription CompileShader(
string fileName,
string entryPoint,
Expand Down
5 changes: 5 additions & 0 deletions samples/Directory.Build.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.props" />

</Project>
34 changes: 34 additions & 0 deletions samples/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<Import Project="$(MSBuildThisFileDirectory)..\Directory.Build.targets" />

<PropertyGroup>
<_ShaderCompilerPath>$(AlimerSrcDirectory)assets/Alimer.ShaderCompiler/bin/$(Configuration)/net8.0/Alimer.ShaderCompiler.dll</_ShaderCompilerPath>
<_ProcessDir>$(BaseIntermediateOutputPath)/CompiledShaders</_ProcessDir>
</PropertyGroup>

<Target Name="ProcessShaders" AfterTargets="AssignTargetPaths" Condition="'@(Shader)' != ''">
<PropertyGroup>
<_Command>dotnet $(_ShaderCompilerPath)</_Command>
<_Command>$(_Command) $(_ProcessDir)</_Command>
<_Command>$(_Command) @(Shader->'%(Identity)', ' ')</_Command>
</PropertyGroup>
<Message Importance="high" Text="Executing: $(_Command)" />
<Exec Command="$(_Command)" />
<ItemGroup>
<_ProcessedAsset Include="$(_ProcessDir)/*.bin" />
<EmbeddedResource Include="@(_ProcessedAsset)">
<LogicalName>%(FileName)%(Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>

</Target>

<ItemGroup Condition=" '$(_AlimerNoTargetPlatform)' == 'True' ">
<ProjectReference Include="$(AlimerSrcDirectory)assets/Alimer.ShaderCompiler/Alimer.ShaderCompiler.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
</ProjectReference>
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions src/assets/Alimer.ShaderCompiler/Alimer.ShaderCompiler.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Exe</OutputType>
<IsPackable>false</IsPackable>
<RootNamespace>Alimer.Shaders</RootNamespace>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Alimer.Shaders\Alimer.Shaders.csproj" />
</ItemGroup>

</Project>
90 changes: 90 additions & 0 deletions src/assets/Alimer.ShaderCompiler/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright (c) Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.

using Alimer.Graphics;
using Alimer.Shaders;

namespace Alimer.Shaders;

class Program
{
public static int Main(string[] args)
{
string outputDirectory = args[0];
if (!Directory.Exists(outputDirectory))
{
Directory.CreateDirectory(outputDirectory);
}
//else
//{
// Directory.Delete(outputDirectory, true);
// Directory.CreateDirectory(outputDirectory);
//}

for (int i = 1; i < args.Length; i++)
{
string arg = args[i];

Console.WriteLine($"Compile SPIRV: {arg}");
Compile(outputDirectory, arg, ShaderFormat.SPIRV, ShaderStages.Vertex, "vertexMain");
Compile(outputDirectory, arg, ShaderFormat.SPIRV, ShaderStages.Fragment, "fragmentMain");

Console.WriteLine($"Compile DXIL: {arg}");
Compile(outputDirectory, arg, ShaderFormat.DXIL, ShaderStages.Vertex, "vertexMain");
Compile(outputDirectory, arg, ShaderFormat.DXIL, ShaderStages.Fragment, "fragmentMain");
}


return 0;
}

private static void Compile(string outputDirectory, string shaderSourceFileName,
ShaderFormat format, ShaderStages stage, string entryPoint)
{
string shadersPath = Path.GetDirectoryName(shaderSourceFileName);
string shaderSource = File.ReadAllText(shaderSourceFileName);

ShaderCompilationOptions options = new()
{
SourceFileName = shaderSourceFileName,
ShaderStage = stage,
EntryPoint = entryPoint,
IncludeDirs =
{
shadersPath
},
};

//f (defines != null && defines.Count > 0)
//
// foreach (KeyValuePair<string, string> pair in defines)
// {
// options.Defines.Add(pair.Key, pair.Value);
// }
//

using ShaderCompilationResult result = ShaderCompiler.Instance.Compile(format, shaderSource, in options);
if (result.Failed)
{
Console.Error.WriteLine($"Shader compilation failed: {result.ErrorMessage}.");
return;
//throw new GraphicsException(result.ErrorMessage);
}

string shaderFile = Path.GetFileNameWithoutExtension(shaderSourceFileName);
string outputFile = Path.GetFileNameWithoutExtension(shaderFile) + "_" + options.EntryPoint + "_" + result.Format.ToString().ToLower();
switch (result.Format)
{
case ShaderFormat.DXIL:
//outputFile = Path.ChangeExtension(outputFile, ".cso");
outputFile = Path.ChangeExtension(outputFile, ".bin");
break;
case ShaderFormat.SPIRV:
//outputFile = Path.ChangeExtension(outputFile, ".spv");
outputFile = Path.ChangeExtension(outputFile, ".bin");
break;
}

File.WriteAllBytes(Path.Combine(outputDirectory, outputFile), result.GetByteCode().ToArray());
}
}
5 changes: 4 additions & 1 deletion src/assets/Alimer.Shaders/DxcShaderCompilationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,20 @@ public DxcShaderCompilationResult(string error)
{
}

public DxcShaderCompilationResult(ComPtr<IDxcBlob> byteCode)
public DxcShaderCompilationResult(ComPtr<IDxcBlob> byteCode, ShaderFormat format)
{
_byteCode = byteCode.Move();
_byteCode.Get()->AddRef();
Format = format;
}

public override void Dispose()
{
_byteCode.Dispose();
}

public override ShaderFormat Format { get; }

public override ReadOnlySpan<byte> GetByteCode()
{
IDxcBlob* ptr = _byteCode.Get();
Expand Down
1 change: 1 addition & 0 deletions src/assets/Alimer.Shaders/ShaderCompilationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ public abstract class ShaderCompilationResult : IDisposable
public string ErrorMessage { get; }
public bool Failed => !string.IsNullOrWhiteSpace(ErrorMessage);
public bool Succeeded => !Failed;
public abstract ShaderFormat Format { get; }

public abstract void Dispose();

Expand Down
2 changes: 1 addition & 1 deletion src/assets/Alimer.Shaders/ShaderCompiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ public ShaderCompilationResult Compile(
spvReflectDestroyShaderModule(&module);
}

return new DxcShaderCompilationResult(byteCode);
return new DxcShaderCompilationResult(byteCode, format);
}

private HRESULT Compile(ReadOnlySpan<char> source, string[] arguments, Guid* riid, void** ppResult)
Expand Down

0 comments on commit 4fffe65

Please sign in to comment.