Ejemplo n.º 1
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);
                        }
                    }
Ejemplo n.º 2
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);
                    }
                }
            }
        }