Ejemplo n.º 1
0
        public static bool CompileMaterial(CapnpGen.CapMaterial material, string outputDirectory, out string error)
        {
            error = "";
            Directory.CreateDirectory(outputDirectory);

            // Load templates
            string vsTemplate = "";

            if (!GetEmbeddedResource("templateVS.hlsl", out error, out vsTemplate))
            {
                return(false);
            }

            string psTemplate = "";

            if (!GetEmbeddedResource("templatePS.hlsl", out error, out psTemplate))
            {
                return(false);
            }

            // Mutate the templates
            string vs = MutateVS(material, vsTemplate);
            string ps = MutatePS(material, psTemplate);

            // Compile the shaders
            DxcCompilerOptions options = new DxcCompilerOptions();

            options.ShaderModel       = DxcShaderModel.Model6_4;
            options.EnableDebugInfo   = true;
            options.OptimizationLevel = 0;

            IDxcBlob vsBlob;

            if (!CompileShader(vs, material.Header.Name, DxcShaderStage.VertexShader, options, out vsBlob, out error))
            {
                return(false);
            }

            IDxcBlob psBlob;

            if (!CompileShader(ps, material.Header.Name, DxcShaderStage.PixelShader, options, out psBlob, out error))
            {
                return(false);
            }

            // Save the shader files
            string vsPath = Path.Combine(outputDirectory, material.Header.Name + ".vs.hlsl.cso");

            byte[] vsBytes = new byte[vsBlob.GetBufferSize()];
            unsafe
            {
                Marshal.Copy((IntPtr)vsBlob.GetBufferPointer(), vsBytes, 0, (int)vsBlob.GetBufferSize());
            }
            File.WriteAllBytes(vsPath, vsBytes);

            string psPath = Path.Combine(outputDirectory, material.Header.Name + ".ps.hlsl.cso");

            byte[] psBytes = new byte[psBlob.GetBufferSize()];
            unsafe
            {
                Marshal.Copy((IntPtr)psBlob.GetBufferPointer(), psBytes, 0, (int)psBlob.GetBufferSize());
            }
            File.WriteAllBytes(psPath, psBytes);

            return(true);
        }
Ejemplo n.º 2
0
    public static IDxcResult Compile(DxcShaderStage shaderStage, string source, string entryPoint,
                                     DxcCompilerOptions?options        = null,
                                     string?fileName                   = null,
                                     DxcDefine[]?defines               = null,
                                     IDxcIncludeHandler?includeHandler = null,
                                     string[]?additionalArguments      = null)
    {
        if (options == null)
        {
            options = new DxcCompilerOptions();
        }

        string profile = GetShaderProfile(shaderStage, options.ShaderModel);

        var arguments = new List <string>();

        if (!string.IsNullOrEmpty(fileName))
        {
            arguments.Add(fileName !);
        }

        arguments.Add("-E");
        arguments.Add(entryPoint);

        arguments.Add("-T");
        arguments.Add(profile);

        // Defines
        if (defines != null && defines.Length > 0)
        {
            foreach (DxcDefine define in defines)
            {
                string defineValue = define.Value;
                if (string.IsNullOrEmpty(defineValue))
                {
                    defineValue = "1";
                }

                arguments.Add("-D");
                arguments.Add($"{define.Name}={defineValue}");
            }
        }

        if (options.EnableDebugInfo)
        {
            arguments.Add("-Zi");
        }

        if (options.SkipValidation)
        {
            arguments.Add("-Vd");
        }

        if (options.SkipOptimizations)
        {
            arguments.Add("-Od");
        }
        else
        {
            if (options.OptimizationLevel < 4)
            {
                arguments.Add($"-O{options.OptimizationLevel}");
            }
            else
            {
                throw new InvalidOperationException("Invalid optimization level.");
            }
        }

        // HLSL matrices are translated into SPIR-V OpTypeMatrixs in a transposed manner,
        // See also https://antiagainst.github.io/post/hlsl-for-vulkan-matrices/
        if (options.PackMatrixRowMajor)
        {
            arguments.Add("-Zpr");
        }
        if (options.PackMatrixColumnMajor)
        {
            arguments.Add("-Zpc");
        }
        if (options.AvoidFlowControl)
        {
            arguments.Add("-Gfa");
        }
        if (options.PreferFlowControl)
        {
            arguments.Add("-Gfp");
        }

        if (options.EnableStrictness)
        {
            arguments.Add("-Ges");
        }

        if (options.EnableBackwardCompatibility)
        {
            arguments.Add("-Gec");
        }

        if (options.IEEEStrictness)
        {
            arguments.Add("-Gis");
        }

        if (options.WarningsAreErrors)
        {
            arguments.Add("-WX");
        }

        if (options.ResourcesMayAlias)
        {
            arguments.Add("-res_may_alias");
        }

        if (options.AllResourcesBound)
        {
            arguments.Add("-all_resources_bound");
        }

        if (options.Enable16bitTypes)
        {
            if (options.ShaderModel.Major >= 6 &&
                options.ShaderModel.Minor >= 2)
            {
                arguments.Add("-enable-16bit-types");
            }
            else
            {
                throw new InvalidOperationException("16-bit types requires shader model 6.2 or up.");
            }
        }

        if (options.StripReflectionIntoSeparateBlob)
        {
            arguments.Add("-Qstrip_reflect");
        }

        if (options.GenerateSPIRV)
        {
            arguments.Add("-spirv");
        }

        // HLSL version, default 2018.
        arguments.Add("-HV");
        arguments.Add($"{options.HLSLVersion}");

        if (options.ShiftAllConstantBuffersBindings > 0)
        {
            arguments.Add("-fvk-b-shift");
            arguments.Add($"{options.ShiftAllConstantBuffersBindings}");
            arguments.Add($"all");
        }

        if (options.ShiftAllTexturesBindings > 0)
        {
            arguments.Add("-fvk-t-shift");
            arguments.Add($"{options.ShiftAllTexturesBindings}");
            arguments.Add($"all");
        }

        if (options.ShiftAllSamplersBindings > 0)
        {
            arguments.Add("-fvk-s-shift");
            arguments.Add($"{options.ShiftAllSamplersBindings}");
            arguments.Add($"all");
        }

        if (options.ShiftAllUAVBuffersBindings > 0)
        {
            arguments.Add("-fvk-u-shift");
            arguments.Add($"{options.ShiftAllUAVBuffersBindings}");
            arguments.Add($"all");
        }

        if (options.UseOpenGLLayout)
        {
            arguments.Add("-fvk-use-gl-layout");
        }
        if (options.UseDirectXLayout)
        {
            arguments.Add("-fvk-use-dx-layout");
        }
        if (options.UseScalarLayout)
        {
            arguments.Add("-fvk-use-scalar-layout");
        }

        if (options.SPIRVFlattenResourceArrays)
        {
            arguments.Add("-fspv-flatten-resource-arrays");
        }
        if (options.SPIRVReflect)
        {
            arguments.Add("-fspv-reflect");
        }

        arguments.Add("-fspv-target-env=vulkan1.1");

        if (additionalArguments != null && additionalArguments.Length > 0)
        {
            arguments.AddRange(additionalArguments);
        }

        return(Compile(source, arguments.ToArray(), includeHandler));
    }
Ejemplo n.º 3
0
        public static byte[] Compile(DxcShaderStage shaderStage, string source, string entryPoint, string sourceName, DxcCompilerOptions options)
        {
            IDxcOperationResult result = DxcCompiler.Compile(shaderStage, source, entryPoint, sourceName, options);

            if (result.GetStatus() == 0)
            {
                IDxcBlob blob = result.GetResult();
                return(Dxc.GetBytesFromBlob(blob));
            }
            else
            {
                string resultText = Dxc.GetStringFromBlob(DxcCompiler.Library, result.GetErrors());
                throw new Exception(resultText);
            }
        }
Ejemplo n.º 4
0
        public static Alimer.Graphics.ShaderBytecode Compile(
            GraphicsBackend backend,
            string source,
            ShaderStages stage,
            string entryPoint = "",
            string fileName   = "")
        {
            if (string.IsNullOrEmpty(entryPoint))
            {
                entryPoint = GetDefaultEntryPoint(stage);
            }

            // We use legacy compiler for D3D11.
            bool isDxil = backend != GraphicsBackend.Direct3D11;

            if (isDxil)
            {
                var dxcShaderStage = GetDxcShaderStage(stage);
                var options        = new DxcCompilerOptions
                {
                };

                var result = DxcCompiler.Compile(dxcShaderStage, source, entryPoint, fileName, options);

                if (result.GetStatus() == 0)
                {
                    var blob     = result.GetResult();
                    var bytecode = GetBytesFromBlob(blob);

                    var containReflection = CreateDxcContainerReflection();
                    containReflection.Load(blob);
                    int hr = containReflection.FindFirstPartKind(DFCC_DXIL, out uint dxilPartIndex);
                    if (hr < 0)
                    {
                        //MessageBox.Show("Debug information not found in container.");
                        //return;
                    }

                    /*var f = containReflection.GetPartReflection(dxilPartIndex, typeof(ID3D12ShaderReflection).GUID, out var nativePtr);
                     * using (var shaderReflection = new ID3D12ShaderReflection(nativePtr))
                     * {
                     *  var shaderReflectionDesc = shaderReflection.Description;
                     *
                     *  foreach (var parameterDescription in shaderReflection.InputParameters)
                     *  {
                     *  }
                     *
                     *  foreach (var resource in shaderReflection.Resources)
                     *  {
                     *  }
                     * }*/

                    unsafe
                    {
                        var   part = containReflection.GetPartContent(dxilPartIndex);
                        uint *p    = (uint *)part.GetBufferPointer();
                        var   v    = DescribeProgramVersion(*p);
                    }

                    // Disassemble
                    //var disassembleBlob = compiler.Disassemble(blob);
                    //string disassemblyText = Dxc.GetStringFromBlob(disassembleBlob);

                    return(new Alimer.Graphics.ShaderBytecode(stage, bytecode));
                }
                else
                {
                    //var resultText = GetStringFromBlob(DxcCompiler, result.GetErrors());
                }
            }
            else
            {
                var shaderProfile = $"{GetShaderProfile(stage)}_5_0";
                var result        = Compiler.Compile(source,
                                                     entryPoint,
                                                     fileName,
                                                     shaderProfile,
                                                     out var blob,
                                                     out var errorMsgs);

                if (result.Failure)
                {
                    if (errorMsgs != null)
                    {
                        var errorText = errorMsgs.ConvertToString();
                    }
                }
                else
                {
                    var bytecode = blob.GetBytes();
                    return(new Alimer.Graphics.ShaderBytecode(stage, bytecode));
                }
            }

            return(default);
Ejemplo n.º 5
0
        private static byte[] Compile(ShaderStage shaderStage, string source, string entryPoint, string sourceName, DxcCompilerOptions options)
        {
            //IDxcOperationResult result = DxcCompiler.Compile((DxcShaderStage)shaderStage, source, entryPoint, sourceName, options);

            string shaderProfile = GetShaderProfile(shaderStage, options.ShaderModel);

            List <string> arguments = new List <string>();

            if (options.PackMatrixInColumnMajor)
            {
                arguments.Add("-Zpc");
            }
            else if (options.PackMatrixInRowMajor)
            {
                arguments.Add("-Zpr");
            }

            IDxcLibrary        library        = Dxc.CreateDxcLibrary();
            IDxcBlobEncoding   sourceBlob     = Dxc.CreateBlobForText(library, source);
            IDxcIncludeHandler includeHandler = library.CreateIncludeHandler();

            IDxcCompiler        compiler = Dxc.CreateDxcCompiler();
            IDxcOperationResult result   = compiler.Compile(
                sourceBlob,
                sourceName,
                entryPoint,
                shaderProfile,
                arguments.ToArray(),
                arguments.Count,
                null,
                0,
                includeHandler);

            if (result.GetStatus() == 0)
            {
                IDxcBlob blob = result.GetResult();
                return(Dxc.GetBytesFromBlob(blob));
            }
            else
            {
                string resultText = Dxc.GetStringFromBlob(library, result.GetErrors());
                throw new Exception(resultText);
            }
        }