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);
        }
Exemplo n.º 2
0
        private string[] CompileCompute(ShaderVariantDescription variant)
        {
            List <string> generatedFiles = new List <string>();

            byte[] csBytes = CompileToSpirv(variant, variant.Shaders[0].FileName, ShaderStages.Compute);
            string spvPath = Path.Combine(_outputPath, $"{variant.Name}_{ShaderStages.Compute.ToString()}.spv");

            File.WriteAllBytes(spvPath, csBytes);
            generatedFiles.Add(spvPath);

            List <Exception> compilationExceptions = new List <Exception>();

            foreach (CrossCompileTarget target in variant.Targets)
            {
                try
                {
                    ComputeCompilationResult result = SpirvCompilation.CompileCompute(csBytes, target, variant.CrossCompileOptions);
                    string csPath = Path.Combine(_outputPath, $"{variant.Name}_Compute.{GetExtension(target)}");
                    File.WriteAllText(csPath, result.ComputeShader);
                    generatedFiles.Add(csPath);

                    string reflectionPath = Path.Combine(_outputPath, $"{variant.Name}_ReflectionInfo.json");

                    JsonSerializer serializer = new JsonSerializer();
                    serializer.Formatting = Formatting.Indented;
                    StringEnumConverter enumConverter = new StringEnumConverter();
                    serializer.Converters.Add(enumConverter);
                    using (StreamWriter sw = File.CreateText(reflectionPath))
                        using (JsonTextWriter jtw = new JsonTextWriter(sw))
                        {
                            serializer.Serialize(jtw, result.Reflection);
                        }
                    generatedFiles.Add(reflectionPath);
                }
                catch (Exception e)
                {
                    compilationExceptions.Add(e);
                }
            }

            if (compilationExceptions.Count > 0)
            {
                throw new AggregateException($"Errors were encountered when compiling shader variant(s).", compilationExceptions);
            }

            return(generatedFiles.ToArray());
        }
Exemplo n.º 3
0
        public string[] Compile(ShaderVariantDescription variant)
        {
            if (variant.Shaders.Length == 1)
            {
                if (variant.Shaders[0].Stage == ShaderStages.Vertex)
                {
                    return(CompileVertexFragment(variant));
                }
                if (variant.Shaders[0].Stage == ShaderStages.Compute)
                {
                    return(CompileCompute(variant));
                }
            }
            if (variant.Shaders.Length == 2)
            {
                bool hasVertex   = false;
                bool hasFragment = false;
                foreach (var shader in variant.Shaders)
                {
                    hasVertex   |= shader.Stage == ShaderStages.Vertex;
                    hasFragment |= shader.Stage == ShaderStages.Fragment;
                }

                if (!hasVertex)
                {
                    throw new SpirvCompilationException($"Variant \"{variant.Name}\" is missing a vertex shader.");
                }
                if (!hasFragment)
                {
                    throw new SpirvCompilationException($"Variant \"{variant.Name}\" is missing a fragment shader.");
                }

                return(CompileVertexFragment(variant));
            }
            else
            {
                throw new SpirvCompilationException(
                          $"Variant \"{variant.Name}\" has an unsupported combination of shader stages.");
            }
        }
Exemplo n.º 4
0
 private GlslCompileOptions GetOptions(ShaderVariantDescription variant)
 {
     return(new GlslCompileOptions(true, variant.Macros));
 }
Exemplo n.º 5
0
        private string[] CompileVertexFragment(ShaderVariantDescription variant)
        {
            List <string>    generatedFiles        = new List <string>();
            List <Exception> compilationExceptions = new List <Exception>();

            byte[] vsBytes = null;
            byte[] fsBytes = null;

            string vertexFileName = variant.Shaders.FirstOrDefault(vsd => vsd.Stage == ShaderStages.Vertex)?.FileName;

            if (vertexFileName != null)
            {
                try
                {
                    vsBytes = CompileToSpirv(variant, vertexFileName, ShaderStages.Vertex);
                    //string spvPath = Path.Combine(_outputPath, $"{variant.Name}_{ShaderStages.Vertex.ToString()}.spv");
                    string spvPath = Path.Combine(_outputPath, $"{variant.Name}.vert.spv");
                    File.WriteAllBytes(spvPath, vsBytes);
                    generatedFiles.Add(spvPath);
                }
                catch (Exception e)
                {
                    compilationExceptions.Add(e);
                }
            }

            string fragmentFileName = variant.Shaders.FirstOrDefault(vsd => vsd.Stage == ShaderStages.Fragment)?.FileName;

            if (fragmentFileName != null)
            {
                try
                {
                    fsBytes = CompileToSpirv(variant, fragmentFileName, ShaderStages.Fragment);
                    //string spvPath = Path.Combine(_outputPath, $"{variant.Name}_{ShaderStages.Fragment.ToString()}.spv");
                    string spvPath = Path.Combine(_outputPath, $"{variant.Name}.frag.spv");
                    File.WriteAllBytes(spvPath, fsBytes);
                    generatedFiles.Add(spvPath);
                }
                catch (Exception e)
                {
                    compilationExceptions.Add(e);
                }
            }

            if (compilationExceptions.Count > 0)
            {
                throw new AggregateException(
                          $"Errors were encountered when compiling from GLSL to SPIR-V.",
                          compilationExceptions);
            }

            foreach (CrossCompileTarget target in variant.Targets)
            {
                try
                {
                    bool writeReflectionFile = true;
                    VertexFragmentCompilationResult result = SpirvCompilation.CompileVertexFragment(
                        vsBytes,
                        fsBytes,
                        target,
                        variant.CrossCompileOptions);
                    if (result.VertexShader != null)
                    {
                        string vsPath = Path.Combine(_outputPath, $"{variant.Name}_Vertex.{GetExtension(target)}");
                        File.WriteAllText(vsPath, result.VertexShader);
                        generatedFiles.Add(vsPath);
                    }
                    if (result.FragmentShader != null)
                    {
                        string fsPath = Path.Combine(_outputPath, $"{variant.Name}_Fragment.{GetExtension(target)}");
                        File.WriteAllText(fsPath, result.FragmentShader);
                        generatedFiles.Add(fsPath);
                    }

                    if (writeReflectionFile)
                    {
                        writeReflectionFile = false;
                        string reflectionPath = Path.Combine(_outputPath, $"{variant.Name}_ReflectionInfo.json");

                        JsonSerializer serializer = new JsonSerializer();
                        serializer.Formatting = Formatting.Indented;
                        StringEnumConverter enumConverter = new StringEnumConverter();
                        serializer.Converters.Add(enumConverter);
                        using (StreamWriter sw = File.CreateText(reflectionPath))
                            using (JsonTextWriter jtw = new JsonTextWriter(sw))
                            {
                                serializer.Serialize(jtw, result.Reflection);
                            }
                        generatedFiles.Add(reflectionPath);
                    }
                }
                catch (Exception e)
                {
                    compilationExceptions.Add(e);
                }
            }

            if (compilationExceptions.Count > 0)
            {
                throw new AggregateException($"Errors were encountered when compiling shader variant(s).", compilationExceptions);
            }

            return(generatedFiles.ToArray());
        }