private byte[] CompileToSpirv( ShaderVariantDescription variant, string fileName, ShaderStages stage) { GlslCompileOptions glslOptions = GetOptions(variant); string glsl = LoadGlsl(fileName); SpirvCompilationResult result = SpirvCompilation.CompileGlslToSpirv( glsl, fileName, stage, glslOptions); return(result.SpirvBytes); }
private static unsafe byte[] EnsureSpirv(ShaderDescription description) { if (Util.HasSpirvHeader(description.ShaderBytes)) { return(description.ShaderBytes); } else { fixed(byte *sourceAsciiPtr = description.ShaderBytes) { SpirvCompilationResult glslCompileResult = SpirvCompilation.CompileGlslToSpirv( (uint)description.ShaderBytes.Length, sourceAsciiPtr, null, description.Stage, description.Debug, 0, null); return(glslCompileResult.SpirvBytes); } } }
/// <summary> /// Cross-compiles the given vertex-fragment pair into some target language. /// </summary> /// <param name="vsBytes">The vertex shader's SPIR-V bytecode or ASCII-encoded GLSL source code.</param> /// <param name="fsBytes">The fragment shader's SPIR-V bytecode or ASCII-encoded GLSL source code.</param> /// <param name="target">The target language.</param> /// <param name="options">The options for shader translation.</param> /// <returns>A <see cref="VertexFragmentCompilationResult"/> containing the compiled output.</returns> public static unsafe VertexFragmentCompilationResult CompileVertexFragment( byte[] vsBytes, byte[] fsBytes, CrossCompileTarget target, CrossCompileOptions options) { int size1 = sizeof(CrossCompileInfo); int size2 = sizeof(InteropArray); byte[] vsSpirvBytes; byte[] fsSpirvBytes; if (Util.HasSpirvHeader(vsBytes)) { vsSpirvBytes = vsBytes; } else { fixed(byte *sourceTextPtr = vsBytes) { SpirvCompilationResult vsCompileResult = CompileGlslToSpirv( (uint)vsBytes.Length, sourceTextPtr, string.Empty, ShaderStages.Vertex, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, null); vsSpirvBytes = vsCompileResult.SpirvBytes; } } if (Util.HasSpirvHeader(fsBytes)) { fsSpirvBytes = fsBytes; } else { fixed(byte *sourceTextPtr = fsBytes) { SpirvCompilationResult fsCompileResult = CompileGlslToSpirv( (uint)fsBytes.Length, sourceTextPtr, string.Empty, ShaderStages.Fragment, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, null); fsSpirvBytes = fsCompileResult.SpirvBytes; } } int specConstantsCount = options.Specializations.Length; NativeSpecializationConstant *nativeSpecConstants = stackalloc NativeSpecializationConstant[specConstantsCount]; for (int i = 0; i < specConstantsCount; i++) { nativeSpecConstants[i].ID = options.Specializations[i].ID; nativeSpecConstants[i].Constant = options.Specializations[i].Data; } CrossCompileInfo info; info.Target = target; info.FixClipSpaceZ = options.FixClipSpaceZ; info.InvertY = options.InvertVertexOutputY; fixed(byte *vsBytesPtr = vsSpirvBytes) fixed(byte *fsBytesPtr = fsSpirvBytes) { info.VertexShader = new InteropArray((uint)vsSpirvBytes.Length / 4, vsBytesPtr); info.FragmentShader = new InteropArray((uint)fsSpirvBytes.Length / 4, fsBytesPtr); info.Specializations = new InteropArray((uint)specConstantsCount, nativeSpecConstants); CompilationResult *result = null; try { result = VeldridSpirvNative.CrossCompile(&info); if (!result->Succeeded) { throw new SpirvCompilationException( "Compilation failed: " + Util.GetString((byte *)result->GetData(0), result->GetLength(0))); } string vsCode = Util.GetString((byte *)result->GetData(0), result->GetLength(0)); string fsCode = Util.GetString((byte *)result->GetData(1), result->GetLength(1)); return(new VertexFragmentCompilationResult(vsCode, fsCode)); } finally { if (result != null) { VeldridSpirvNative.FreeResult(result); } } } }
/// <summary> /// Cross-compiles the given vertex-fragment pair into some target language. /// </summary> /// <param name="vsBytes">The vertex shader's SPIR-V bytecode or ASCII-encoded GLSL source code.</param> /// <param name="fsBytes">The fragment shader's SPIR-V bytecode or ASCII-encoded GLSL source code.</param> /// <param name="target">The target language.</param> /// <param name="options">The options for shader translation.</param> /// <returns>A <see cref="VertexFragmentCompilationResult"/> containing the compiled output.</returns> public static unsafe VertexFragmentCompilationResult CompileVertexFragment( byte[] vsBytes, byte[] fsBytes, CrossCompileTarget target, CrossCompileOptions options) { int size1 = sizeof(CrossCompileInfo); int size2 = sizeof(InteropArray); byte[] vsSpirvBytes; byte[] fsSpirvBytes; if (Util.HasSpirvHeader(vsBytes)) { vsSpirvBytes = vsBytes; } else { fixed(byte *sourceTextPtr = vsBytes) { SpirvCompilationResult vsCompileResult = CompileGlslToSpirv( (uint)vsBytes.Length, sourceTextPtr, string.Empty, ShaderStages.Vertex, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, null); vsSpirvBytes = vsCompileResult.SpirvBytes; } } if (Util.HasSpirvHeader(fsBytes)) { fsSpirvBytes = fsBytes; } else { fixed(byte *sourceTextPtr = fsBytes) { SpirvCompilationResult fsCompileResult = CompileGlslToSpirv( (uint)fsBytes.Length, sourceTextPtr, string.Empty, ShaderStages.Fragment, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, null); fsSpirvBytes = fsCompileResult.SpirvBytes; } } int specConstantsCount = options.Specializations.Length; NativeSpecializationConstant *nativeSpecConstants = stackalloc NativeSpecializationConstant[specConstantsCount]; for (int i = 0; i < specConstantsCount; i++) { nativeSpecConstants[i].ID = options.Specializations[i].ID; nativeSpecConstants[i].Constant = options.Specializations[i].Data; } CrossCompileInfo info; info.Target = target; info.FixClipSpaceZ = options.FixClipSpaceZ; info.InvertY = options.InvertVertexOutputY; info.NormalizeResourceNames = options.NormalizeResourceNames; fixed(byte *vsBytesPtr = vsSpirvBytes) fixed(byte *fsBytesPtr = fsSpirvBytes) { info.VertexShader = new InteropArray((uint)vsSpirvBytes.Length / 4, vsBytesPtr); info.FragmentShader = new InteropArray((uint)fsSpirvBytes.Length / 4, fsBytesPtr); info.Specializations = new InteropArray((uint)specConstantsCount, nativeSpecConstants); CompilationResult *result = null; try { result = VeldridSpirvNative.CrossCompile(&info); if (!result->Succeeded) { throw new SpirvCompilationException( "Compilation failed: " + Util.GetString((byte *)result->GetData(0), result->GetLength(0))); } string vsCode = Util.GetString((byte *)result->GetData(0), result->GetLength(0)); string fsCode = Util.GetString((byte *)result->GetData(1), result->GetLength(1)); ReflectionInfo *reflInfo = &result->ReflectionInfo; VertexElementDescription[] vertexElements = new VertexElementDescription[reflInfo->VertexElements.Count]; for (uint i = 0; i < reflInfo->VertexElements.Count; i++) { ref NativeVertexElementDescription nativeDesc = ref reflInfo->VertexElements.Ref <NativeVertexElementDescription>(i); vertexElements[i] = new VertexElementDescription( Util.GetString((byte *)nativeDesc.Name.Data, nativeDesc.Name.Count), nativeDesc.Semantic, nativeDesc.Format, nativeDesc.Offset); } ResourceLayoutDescription[] layouts = new ResourceLayoutDescription[reflInfo->ResourceLayouts.Count]; for (uint i = 0; i < reflInfo->ResourceLayouts.Count; i++) { ref NativeResourceLayoutDescription nativeDesc = ref reflInfo->ResourceLayouts.Ref <NativeResourceLayoutDescription>(i); layouts[i].Elements = new ResourceLayoutElementDescription[nativeDesc.ResourceElements.Count]; for (uint j = 0; j < nativeDesc.ResourceElements.Count; j++) { ref NativeResourceElementDescription elemDesc = ref nativeDesc.ResourceElements.Ref <NativeResourceElementDescription>(j); layouts[i].Elements[j] = new ResourceLayoutElementDescription( Util.GetString((byte *)elemDesc.Name.Data, elemDesc.Name.Count), elemDesc.Kind, elemDesc.Stages, elemDesc.Options); } }
/// <summary> /// Cross-compiles the given vertex-fragment pair into some target language. /// </summary> /// <param name="csBytes">The compute shader's SPIR-V bytecode or ASCII-encoded GLSL source code.</param> /// <param name="target">The target language.</param> /// <param name="options">The options for shader translation.</param> /// <returns>A <see cref="ComputeCompilationResult"/> containing the compiled output.</returns> public static unsafe ComputeCompilationResult CompileCompute( byte[] csBytes, CrossCompileTarget target, CrossCompileOptions options) { byte[] csSpirvBytes; if (Util.HasSpirvHeader(csBytes)) { csSpirvBytes = csBytes; } else { fixed(byte *sourceTextPtr = csBytes) { SpirvCompilationResult vsCompileResult = CompileGlslToSpirv( (uint)csBytes.Length, sourceTextPtr, string.Empty, ShaderStages.Compute, target == CrossCompileTarget.GLSL || target == CrossCompileTarget.ESSL, 0, null); csSpirvBytes = vsCompileResult.SpirvBytes; } } CrossCompileInfo info; info.Target = target; info.FixClipSpaceZ = options.FixClipSpaceZ; info.InvertY = options.InvertVertexOutputY; fixed(byte *csBytesPtr = csSpirvBytes) fixed(SpecializationConstant * specConstants = options.Specializations) { info.ComputeShader = new InteropArray((uint)csSpirvBytes.Length / 4, csBytesPtr); info.Specializations = new InteropArray((uint)options.Specializations.Length, specConstants); CompilationResult *result = null; try { result = VeldridSpirvNative.CrossCompile(&info); if (!result->Succeeded) { throw new SpirvCompilationException( "Compilation failed: " + Util.GetString((byte *)result->GetData(0), result->GetLength(0))); } string csCode = Util.GetString((byte *)result->GetData(0), result->GetLength(0)); return(new ComputeCompilationResult(csCode)); } finally { if (result != null) { VeldridSpirvNative.FreeResult(result); } } } }