Exemplo n.º 1
0
        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);
                }
            }
        }
Exemplo n.º 3
0
        /// <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);
                    }
                }
            }
        }
Exemplo n.º 4
0
        /// <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);
                        }
                    }
Exemplo n.º 5
0
        /// <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);
                    }
                }
            }
        }