diff --git a/src/Veldrid.SPIRV.Tests/CompilationTests.cs b/src/Veldrid.SPIRV.Tests/CompilationTests.cs index c44ba9d..0d21aef 100644 --- a/src/Veldrid.SPIRV.Tests/CompilationTests.cs +++ b/src/Veldrid.SPIRV.Tests/CompilationTests.cs @@ -79,6 +79,32 @@ public void VertexFragmentSucceeds(string vs, string fs, CrossCompileTarget targ Assert.NotNull(result.FragmentShader); } + [Theory] + [InlineData("instance.vert.hlsl", "instance.frag.hlsl", CrossCompileTarget.HLSL)] + [InlineData("instance.vert.hlsl", "instance.frag.hlsl", CrossCompileTarget.GLSL)] + [InlineData("instance.vert.hlsl", "instance.frag.hlsl", CrossCompileTarget.ESSL)] + [InlineData("instance.vert.hlsl", "instance.frag.hlsl", CrossCompileTarget.MSL)] + [InlineData("planet.vert.hlsl", "planet.frag.hlsl", CrossCompileTarget.HLSL)] + [InlineData("planet.vert.hlsl", "planet.frag.hlsl", CrossCompileTarget.GLSL)] + [InlineData("planet.vert.hlsl", "planet.frag.hlsl", CrossCompileTarget.ESSL)] + [InlineData("planet.vert.hlsl", "planet.frag.hlsl", CrossCompileTarget.MSL)] + [InlineData("starfield.vert.hlsl", "starfield.frag.hlsl", CrossCompileTarget.HLSL)] + [InlineData("starfield.vert.hlsl", "starfield.frag.hlsl", CrossCompileTarget.GLSL)] + [InlineData("starfield.vert.hlsl", "starfield.frag.hlsl", CrossCompileTarget.ESSL)] + [InlineData("starfield.vert.hlsl", "starfield.frag.hlsl", CrossCompileTarget.MSL)] + public void VertexFragmentSucceeds_Hlsl(string vs, string fs, CrossCompileTarget target) + { + byte[] vsBytes = TestUtil.LoadBytes(vs); + byte[] fsBytes = TestUtil.LoadBytes(fs); + VertexFragmentCompilationResult result = SpirvCompilation.CompileVertexFragment( + vsBytes, + fsBytes, + target, + new CrossCompileOptions(SourceLanguage.HLSL, false, false)); + Assert.NotNull(result.VertexShader); + Assert.NotNull(result.FragmentShader); + } + [Theory] [InlineData("simple.comp", CrossCompileTarget.HLSL)] [InlineData("simple.comp", CrossCompileTarget.GLSL)] @@ -143,5 +169,30 @@ public void GlslToSpirv_Succeeds(string name, ShaderStages stage) Assert.True(result.SpirvBytes.Length > 4); Assert.True(result.SpirvBytes.Length % 4 == 0); } + + [Theory] + [InlineData("instance.vert.hlsl", ShaderStages.Vertex)] + [InlineData("instance.frag.hlsl", ShaderStages.Fragment)] + [InlineData("planet.vert.hlsl", ShaderStages.Vertex)] + [InlineData("planet.frag.hlsl", ShaderStages.Fragment)] + [InlineData("starfield.vert.hlsl", ShaderStages.Vertex)] + [InlineData("starfield.frag.hlsl", ShaderStages.Fragment)] + public void HlslToSpirv_Succeeds(string name, ShaderStages stage) + { + SpirvCompilationResult result = SpirvCompilation.CompileGlslToSpirv( + TestUtil.LoadShaderText(name), + name, + stage, + new GlslCompileOptions( + false, + SourceLanguage.HLSL, + new MacroDefinition("Name0", "Value0"), + new MacroDefinition("Name1", "Value1"), + new MacroDefinition("Name2"))); + + Assert.NotNull(result.SpirvBytes); + Assert.True(result.SpirvBytes.Length > 4); + Assert.True(result.SpirvBytes.Length % 4 == 0); + } } } diff --git a/src/Veldrid.SPIRV.Tests/TestShaders/instance.frag.hlsl b/src/Veldrid.SPIRV.Tests/TestShaders/instance.frag.hlsl new file mode 100644 index 0000000..598dad9 --- /dev/null +++ b/src/Veldrid.SPIRV.Tests/TestShaders/instance.frag.hlsl @@ -0,0 +1,45 @@ +struct FragmentIn +{ + float4 Position : SV_Position; + float3 Position_WorldSpace : POSITION0; + float3 Normal : NORMAL0; + float3 TexCoord : TEXCOORD0; +}; + +[[vk::binding(2)]] +cbuffer LightInfo +{ + float3 LightDirection; + float padding0; + float3 CameraPosition; + float padding1; +} + +[[vk::binding(0)]] +Texture2DArray Tex; +[[vk::binding(1)]] +SamplerState Samp; + +float4 FS(FragmentIn input) : SV_Target0 +{ + float4 texColor = Tex.Sample(Samp, input.TexCoord); + + float diffuseIntensity = saturate(dot(input.Normal, -LightDirection)); + float4 diffuseColor = texColor * diffuseIntensity; + + // Specular color + float4 specColor = float4(0, 0, 0, 0); + float3 lightColor = float3(1, 1, 1); + float specPower = 5.0f; + float specIntensity = 0.3f; + float3 vertexToEye = -normalize(input.Position_WorldSpace - CameraPosition); + float3 lightReflect = normalize(reflect(LightDirection, input.Normal)); + float specularFactor = dot(vertexToEye, lightReflect); + if (specularFactor > 0) + { + specularFactor = pow(abs(specularFactor), specPower); + specColor = float4(lightColor * specIntensity * specularFactor, 1.0f) * texColor; + } + + return diffuseColor + specColor; +} diff --git a/src/Veldrid.SPIRV.Tests/TestShaders/instance.vert.hlsl b/src/Veldrid.SPIRV.Tests/TestShaders/instance.vert.hlsl new file mode 100644 index 0000000..bb62499 --- /dev/null +++ b/src/Veldrid.SPIRV.Tests/TestShaders/instance.vert.hlsl @@ -0,0 +1,86 @@ +[[vk::binding(0)]] +cbuffer ProjView +{ + float4x4 View; + float4x4 Proj; +} + +[[vk::binding(1)]] +cbuffer RotationInfo +{ + float LocalRotation; + float GlobalRotation; + float2 padding0; +} + +struct VertexIn +{ + float3 Position : POSITION0; + float3 Normal : NORMAL0; + float2 TexCoord : TEXCOORD0; + float3 InstancePosition : POSITION1; + float3 InstanceRotation : TEXCOORD1; + float3 InstanceScale : TEXCOORD2; + int InstanceTexArrayIndex : TEXCOORD3; +}; + +struct FragmentIn +{ + float4 Position : SV_Position; + float3 Position_WorldSpace : POSITION0; + float3 Normal : NORMAL0; + float3 TexCoord : TEXCOORD0; +}; + +FragmentIn VS(VertexIn input) +{ + float cosX = cos(input.InstanceRotation.x); + float sinX = sin(input.InstanceRotation.x); + float3x3 instanceRotX = + { + 1, 0, 0, + 0, cosX, -sinX, + 0, sinX, cosX + }; + + float cosY = cos(input.InstanceRotation.y + LocalRotation); + float sinY = sin(input.InstanceRotation.y + LocalRotation); + float3x3 instanceRotY = + { + cosY, 0, sinY, + 0, 1, 0, + -sinY, 0, cosY + }; + + float cosZ = cos(input.InstanceRotation.z); + float sinZ = sin(input.InstanceRotation.z); + float3x3 instanceRotZ = + { + cosZ, -sinZ, 0, + sinZ, cosZ, 0, + 0, 0, 1 + }; + + float3x3 instanceRotFull = mul(instanceRotZ, mul(instanceRotY, instanceRotZ)); + float3x3 scalingMat = { input.InstanceScale.x, 0, 0, 0, input.InstanceScale.y, 0, 0, 0, input.InstanceScale.z }; + + float globalCos = cos(GlobalRotation); + float globalSin = sin(GlobalRotation); + + float3x3 globalRotMat = + { + globalCos, 0, globalSin, + 0, 1, 0, + -globalSin, 0, globalCos + }; + + FragmentIn output; + float3 transformedPos = (mul(scalingMat, mul(instanceRotFull, input.Position)) + input.InstancePosition); + transformedPos = mul(globalRotMat, transformedPos); + float4 pos = float4(transformedPos, 1); + output.Position_WorldSpace = transformedPos; + output.Position = mul(Proj, mul(View, pos)); + output.Normal = normalize(mul(globalRotMat, mul(instanceRotFull, input.Normal))); + output.TexCoord = float3(input.TexCoord, input.InstanceTexArrayIndex); + return output; +} diff --git a/src/Veldrid.SPIRV.Tests/TestShaders/planet.frag.hlsl b/src/Veldrid.SPIRV.Tests/TestShaders/planet.frag.hlsl new file mode 100644 index 0000000..5927c5c --- /dev/null +++ b/src/Veldrid.SPIRV.Tests/TestShaders/planet.frag.hlsl @@ -0,0 +1,45 @@ +struct FragmentIn +{ + float4 Position : SV_Position; + float3 Position_WorldSpace : POSITION0; + float3 Normal : NORMAL0; + float2 TexCoord : TEXCOORD0; +}; + +[[vk::binding(2)]] +cbuffer LightInfo +{ + float3 LightDirection; + float padding0; + float3 CameraPosition; + float padding1; +} + +[[vk::binding(0)]] +Texture2D Tex; +[[vk::binding(1)]] +SamplerState Samp; + +float4 FS(FragmentIn input) : SV_Target0 +{ + float4 texColor = Tex.Sample(Samp, input.TexCoord); + + float diffuseIntensity = saturate(dot(input.Normal, -LightDirection)); + float4 diffuseColor = texColor * diffuseIntensity; + + // Specular color + float4 specColor = float4(0, 0, 0, 0); + float3 lightColor = float3(1, 1, 1); + float specPower = 5.0f; + float specIntensity = 1.f; + float3 vertexToEye = -normalize(input.Position_WorldSpace - CameraPosition); + float3 lightReflect = normalize(reflect(LightDirection, input.Normal)); + float specularFactor = dot(vertexToEye, lightReflect); + if (specularFactor > 0) + { + specularFactor = pow(abs(specularFactor), specPower); + specColor = float4(lightColor * specIntensity * specularFactor, 1.0f) * texColor; + } + + return diffuseColor + specColor; +} diff --git a/src/Veldrid.SPIRV.Tests/TestShaders/planet.vert.hlsl b/src/Veldrid.SPIRV.Tests/TestShaders/planet.vert.hlsl new file mode 100644 index 0000000..b50853e --- /dev/null +++ b/src/Veldrid.SPIRV.Tests/TestShaders/planet.vert.hlsl @@ -0,0 +1,32 @@ +[[vk::binding(0)]] +cbuffer ProjView +{ + float4x4 View; + float4x4 Proj; +} + +struct VertexIn +{ + float3 Position : POSITION0; + float3 Normal : NORMAL0; + float2 TexCoord : TEXCOORD0; +}; + +struct FragmentIn +{ + float4 Position : SV_Position; + float3 Position_WorldSpace : POSITION0; + float3 Normal : NORMAL0; + float2 TexCoord : TEXCOORD0; +}; + +FragmentIn VS(VertexIn input) +{ + FragmentIn output; + float4 pos = float4(input.Position, 1); + output.Position_WorldSpace = input.Position; + output.Position = mul(Proj, mul(View, pos)); + output.Normal = input.Normal; + output.TexCoord = input.TexCoord * float2(10, 6); + return output; +} diff --git a/src/Veldrid.SPIRV.Tests/TestShaders/starfield.frag.hlsl b/src/Veldrid.SPIRV.Tests/TestShaders/starfield.frag.hlsl new file mode 100644 index 0000000..150671b --- /dev/null +++ b/src/Veldrid.SPIRV.Tests/TestShaders/starfield.frag.hlsl @@ -0,0 +1,52 @@ +#define HASHSCALE3 float3(443.897, 441.423, 437.195) +#define STARFREQUENCY 0.01 + +[[vk::binding(0)]] +cbuffer InvCameraInfo +{ + float4x4 InvProj; + float4x4 InvView; +} + +struct FragmentIn +{ + float4 Position : SV_Position; + float4 ClipPos : Position0; + float3 TexCoord : TEXCOORD0; +}; + +// Hash function by Dave Hoskins (https://www.shadertoy.com/view/4djSRW) +float hash33(float3 p3) +{ + p3 = frac(p3 * HASHSCALE3); + p3 += dot(p3, p3.yxz + float3(19.19, 19.19, 19.19)); + return frac((p3.x + p3.y) * p3.z + (p3.x + p3.z) * p3.y + (p3.y + p3.z) * p3.x); +} + +float3 starField(float3 pos) +{ + float3 color = float3(0, 0, 0); + float threshhold = (1.0 - STARFREQUENCY); + float rnd = hash33(pos); + if (rnd >= threshhold) + { + float starCol = pow(abs((rnd - threshhold) / (1.0 - threshhold)), 16.0); + color += float3(starCol, starCol, starCol); + } + return color; +} + +float4 FS(FragmentIn input) : SV_Target0 +{ + // View Coordinates + float4 viewCoords = mul(InvProj, input.ClipPos); + viewCoords.z = -1.0f; + viewCoords.w = 0.0f; + + float3 worldDirection = mul(InvView, viewCoords).xyz; + worldDirection = normalize(worldDirection); + + worldDirection = floor(worldDirection * 700) / 700; + + return float4(starField(worldDirection), 1.0); +} diff --git a/src/Veldrid.SPIRV.Tests/TestShaders/starfield.vert.hlsl b/src/Veldrid.SPIRV.Tests/TestShaders/starfield.vert.hlsl new file mode 100644 index 0000000..6c81d46 --- /dev/null +++ b/src/Veldrid.SPIRV.Tests/TestShaders/starfield.vert.hlsl @@ -0,0 +1,16 @@ +struct FragmentIn +{ + float4 Position : SV_Position; + float4 ClipPos : POSITION0; + float3 TexCoord : TEXCOORD0; +}; + +FragmentIn VS(uint vertexID : SV_VertexID) +{ + FragmentIn output; + output.TexCoord = float3((vertexID << 1) & 2, vertexID & 2, vertexID & 2); + output.Position = float4(output.TexCoord.xy * 2.0f - 1.0f, 0.0f, 1.0f); + output.ClipPos = output.Position; + + return output; +} diff --git a/src/Veldrid.SPIRV/CrossCompileOptions.cs b/src/Veldrid.SPIRV/CrossCompileOptions.cs index 8f1be1c..510b67b 100644 --- a/src/Veldrid.SPIRV/CrossCompileOptions.cs +++ b/src/Veldrid.SPIRV/CrossCompileOptions.cs @@ -7,6 +7,9 @@ namespace Veldrid.SPIRV /// public class CrossCompileOptions { + /// Source language from which to translate. The default is GLSL. + public SourceLanguage SourceLanguage { get; set; } + /// /// Indicates whether or not the compiled shader output should include a clip-space Z-range fixup at the end of the /// vertex shader. @@ -33,6 +36,7 @@ public class CrossCompileOptions /// public CrossCompileOptions() { + SourceLanguage = SourceLanguage.GLSL; Specializations = Array.Empty(); } @@ -58,7 +62,23 @@ public CrossCompileOptions(bool fixClipSpaceZ, bool invertVertexOutputY) /// An array of which will be substituted into the /// shader as new constants. public CrossCompileOptions(bool fixClipSpaceZ, bool invertVertexOutputY, params SpecializationConstant[] specializations) + : this(SourceLanguage.GLSL, fixClipSpaceZ, invertVertexOutputY, specializations) + { + } + + /// + /// Constructs a new , used to control the parameters of shader translation. + /// + /// Source language from which to translate. + /// Indicates whether or not the compiled shader output should include a clip-space Z-range + /// fixup at the end of the vertex shader. + /// Indicates whether or not the compiled shader output should include a fixup at the + /// end of the vertex shader which inverts the clip-space Y value. + /// An array of which will be substituted into the + /// shader as new constants. + public CrossCompileOptions(SourceLanguage sourceLanguage, bool fixClipSpaceZ, bool invertVertexOutputY, params SpecializationConstant[] specializations) { + SourceLanguage = sourceLanguage; FixClipSpaceZ = fixClipSpaceZ; InvertVertexOutputY = invertVertexOutputY; Specializations = specializations; diff --git a/src/Veldrid.SPIRV/GlslCompileInfo.cs b/src/Veldrid.SPIRV/GlslCompileInfo.cs index 028e284..f6f2015 100644 --- a/src/Veldrid.SPIRV/GlslCompileInfo.cs +++ b/src/Veldrid.SPIRV/GlslCompileInfo.cs @@ -13,6 +13,7 @@ internal unsafe struct GlslCompileInfo /// Element type: byte /// public InteropArray FileName; + public ShadercSourceLanguage Language; public ShadercShaderKind Kind; public Bool32 Debug; /// diff --git a/src/Veldrid.SPIRV/GlslCompileOptions.cs b/src/Veldrid.SPIRV/GlslCompileOptions.cs index fd48b15..8b67462 100644 --- a/src/Veldrid.SPIRV/GlslCompileOptions.cs +++ b/src/Veldrid.SPIRV/GlslCompileOptions.cs @@ -3,10 +3,13 @@ namespace Veldrid.SPIRV { /// - /// An object used to control the options for compiling from GLSL to SPIR-V. + /// An object used to control the options for compiling from GLSL/HLSL to SPIR-V. /// public class GlslCompileOptions { + /// Source language from which to compile. The default is GLSL. + public SourceLanguage Language { get; set; } + /// /// Indicates whether the compiled output should preserve debug information. NOTE: If the resulting SPIR-V is intended to /// be used as the source of an OpenGL-style GLSL shader, then this property should be set to . @@ -28,6 +31,7 @@ public class GlslCompileOptions /// public GlslCompileOptions() { + Language = SourceLanguage.GLSL; Macros = Array.Empty(); } @@ -41,6 +45,23 @@ public GlslCompileOptions() /// when compiling the GLSL source code. public GlslCompileOptions(bool debug, params MacroDefinition[] macros) { + Language = SourceLanguage.GLSL; + Debug = debug; + Macros = macros; + } + + /// + /// Constructs a new . + /// + /// Indicates whether the compiled output should preserve debug information. NOTE: If the resulting + /// SPIR-V is intended to be used as the source of an OpenGL-style GLSL shader, then this property should be set to + /// . + /// Source language from which to compile a shader. + /// An array of which defines the set of preprocessor macros to define + /// when compiling the GLSL source code. + public GlslCompileOptions(bool debug, SourceLanguage language, params MacroDefinition[] macros) + { + Language = language; Debug = debug; Macros = macros ?? Array.Empty(); } diff --git a/src/Veldrid.SPIRV/ResourceFactoryExtensions.cs b/src/Veldrid.SPIRV/ResourceFactoryExtensions.cs index 6457a84..8d1f740 100644 --- a/src/Veldrid.SPIRV/ResourceFactoryExtensions.cs +++ b/src/Veldrid.SPIRV/ResourceFactoryExtensions.cs @@ -48,8 +48,8 @@ public static Shader[] CreateFromSpirv( GraphicsBackend backend = factory.BackendType; if (backend == GraphicsBackend.Vulkan) { - vertexShaderDescription.ShaderBytes = EnsureSpirv(vertexShaderDescription); - fragmentShaderDescription.ShaderBytes = EnsureSpirv(fragmentShaderDescription); + vertexShaderDescription.ShaderBytes = EnsureSpirv(vertexShaderDescription, options); + fragmentShaderDescription.ShaderBytes = EnsureSpirv(fragmentShaderDescription, options); return new Shader[] { @@ -121,7 +121,7 @@ public static Shader CreateFromSpirv( GraphicsBackend backend = factory.BackendType; if (backend == GraphicsBackend.Vulkan) { - computeShaderDescription.ShaderBytes = EnsureSpirv(computeShaderDescription); + computeShaderDescription.ShaderBytes = EnsureSpirv(computeShaderDescription, options); return factory.CreateShader(ref computeShaderDescription); } @@ -141,7 +141,7 @@ public static Shader CreateFromSpirv( computeEntryPoint)); } - private static unsafe byte[] EnsureSpirv(ShaderDescription description) + private static unsafe byte[] EnsureSpirv(ShaderDescription description, CrossCompileOptions options) { if (Util.HasSpirvHeader(description.ShaderBytes)) { @@ -155,6 +155,7 @@ private static unsafe byte[] EnsureSpirv(ShaderDescription description) (uint)description.ShaderBytes.Length, sourceAsciiPtr, null, + options.SourceLanguage, description.Stage, description.Debug, 0, diff --git a/src/Veldrid.SPIRV/ShadercSourceLanguage.cs b/src/Veldrid.SPIRV/ShadercSourceLanguage.cs new file mode 100644 index 0000000..a6d35e2 --- /dev/null +++ b/src/Veldrid.SPIRV/ShadercSourceLanguage.cs @@ -0,0 +1,8 @@ +namespace Veldrid.SPIRV +{ + internal enum ShadercSourceLanguage + { + GLSL, + HLSL, + } +} diff --git a/src/Veldrid.SPIRV/SourceLanguage.cs b/src/Veldrid.SPIRV/SourceLanguage.cs new file mode 100644 index 0000000..5eeb530 --- /dev/null +++ b/src/Veldrid.SPIRV/SourceLanguage.cs @@ -0,0 +1,15 @@ +namespace Veldrid.SPIRV +{ + /// Source language from which to compile a shader. + public enum SourceLanguage + { + /// + /// Compile a shader from GLSL source. + /// + GLSL, + /// + /// Compile a shader from HLSL source. + /// + HLSL, + } +} \ No newline at end of file diff --git a/src/Veldrid.SPIRV/SpirvCompilation.cs b/src/Veldrid.SPIRV/SpirvCompilation.cs index b7ddfa4..72e08ba 100644 --- a/src/Veldrid.SPIRV/SpirvCompilation.cs +++ b/src/Veldrid.SPIRV/SpirvCompilation.cs @@ -52,6 +52,7 @@ public static unsafe VertexFragmentCompilationResult CompileVertexFragment( (uint)vsBytes.Length, sourceTextPtr, string.Empty, + options.SourceLanguage, ShaderStages.Vertex, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, @@ -72,6 +73,7 @@ public static unsafe VertexFragmentCompilationResult CompileVertexFragment( (uint)fsBytes.Length, sourceTextPtr, string.Empty, + options.SourceLanguage, ShaderStages.Fragment, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, @@ -161,9 +163,9 @@ ref NativeVertexElementDescription nativeDesc } /// - /// Cross-compiles the given vertex-fragment pair into some target language. + /// Cross-compiles the given compute shader into some target language. /// - /// The compute shader's SPIR-V bytecode or ASCII-encoded GLSL source code. + /// The compute shader's SPIR-V bytecode or ASCII-encoded GLSL/HLSL source code. /// The target language. /// A containing the compiled output. public static unsafe ComputeCompilationResult CompileCompute( @@ -171,9 +173,9 @@ public static unsafe ComputeCompilationResult CompileCompute( CrossCompileTarget target) => CompileCompute(csBytes, target, new CrossCompileOptions()); /// - /// Cross-compiles the given vertex-fragment pair into some target language. + /// Cross-compiles the given compute shader into some target language. /// - /// The compute shader's SPIR-V bytecode or ASCII-encoded GLSL source code. + /// The compute shader's SPIR-V bytecode or ASCII-encoded GLSL/HLSL source code. /// The target language. /// The options for shader translation. /// A containing the compiled output. @@ -192,15 +194,16 @@ public static unsafe ComputeCompilationResult CompileCompute( { fixed (byte* sourceTextPtr = csBytes) { - SpirvCompilationResult vsCompileResult = CompileGlslToSpirv( + SpirvCompilationResult compileResult = CompileGlslToSpirv( (uint)csBytes.Length, sourceTextPtr, string.Empty, + options.SourceLanguage, ShaderStages.Compute, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, null); - csSpirvBytes = vsCompileResult.SpirvBytes; + csSpirvBytes = compileResult.SpirvBytes; } } @@ -263,12 +266,12 @@ public static unsafe ComputeCompilationResult CompileCompute( } /// - /// Compiles the given GLSL source code into SPIR-V. + /// Compiles the given GLSL/HLSL source code into SPIR-V. /// /// The shader source code. /// A descriptive name for the shader. May be null. /// The which the shader is used in. - /// Parameters for the GLSL compiler. + /// Parameters for the compiler. /// A containing the compiled SPIR-V bytecode. public static unsafe SpirvCompilationResult CompileGlslToSpirv( string sourceText, @@ -294,6 +297,7 @@ public static unsafe SpirvCompilationResult CompileGlslToSpirv( (uint)sourceAsciiCount, sourceAsciiPtr, fileName, + options.Language, stage, options.Debug, (uint)macroCount, @@ -304,12 +308,14 @@ internal static unsafe SpirvCompilationResult CompileGlslToSpirv( uint sourceLength, byte* sourceTextPtr, string fileName, + SourceLanguage language, ShaderStages stage, bool debug, uint macroCount, NativeMacroDefinition* macros) { GlslCompileInfo info; + info.Language = GetShadercLanguage(language); info.Kind = GetShadercKind(stage); info.SourceText = new InteropArray(sourceLength, sourceTextPtr); info.Debug = debug; @@ -355,6 +361,16 @@ internal static unsafe SpirvCompilationResult CompileGlslToSpirv( } } + private static ShadercSourceLanguage GetShadercLanguage(SourceLanguage language) + { + switch (language) + { + case SourceLanguage.GLSL: return ShadercSourceLanguage.GLSL; + case SourceLanguage.HLSL: return ShadercSourceLanguage.HLSL; + default: throw new SpirvCompilationException($"Invalid shader source language: {language}"); + } + } + private static ShadercShaderKind GetShadercKind(ShaderStages stage) { switch (stage) diff --git a/src/libveldrid-spirv/InteropStructs.hpp b/src/libveldrid-spirv/InteropStructs.hpp index 92d90d8..99c0a76 100644 --- a/src/libveldrid-spirv/InteropStructs.hpp +++ b/src/libveldrid-spirv/InteropStructs.hpp @@ -146,6 +146,7 @@ struct GlslCompileInfo { InteropArray SourceText; InteropArray FileName; + shaderc_source_language Language; shaderc_shader_kind Kind; Bool32 Debug; InteropArray Macros; @@ -270,4 +271,4 @@ struct CompilationResult } }; #pragma pack(pop) -} // namespace Veldrid \ No newline at end of file +} // namespace Veldrid diff --git a/src/libveldrid-spirv/libveldrid-spirv.cpp b/src/libveldrid-spirv/libveldrid-spirv.cpp index 01d92d1..6982b95 100644 --- a/src/libveldrid-spirv/libveldrid-spirv.cpp +++ b/src/libveldrid-spirv/libveldrid-spirv.cpp @@ -632,6 +632,8 @@ VD_EXPORT CompilationResult *CompileGlslToSpirv(GlslCompileInfo *info) { shaderc::CompileOptions options; + options.SetSourceLanguage(info->Language); + if (info->Debug) { options.SetGenerateDebugInfo();