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();