예제 #1
0
        private System.Tuple <Shader, System.Exception> LoadShader(string shaderFile, params InputElement[] inputElements)
        {
            var result = new Shader()
            {
                vertexShader   = null,
                pixelShader    = null,
                geometryShader = null,
                layout         = null,
                validState     = false
            };

            ShaderBytecode  vertexShaderByteCode   = null;
            ShaderBytecode  pixelShaderByteCode    = null;
            ShaderBytecode  geometryShaderByteCode = null;
            ShaderSignature signature      = null;
            VertexShader    vertexShader   = null;
            PixelShader     pixelShader    = null;
            GeometryShader  geometryShader = null;
            InputLayout     layout         = null;

            System.Exception error = null;
            try
            {
                var shaderFileBytecode = File.ReadAllBytes(shaderFile);
                vertexShaderByteCode = ShaderBytecode.Compile(shaderFileBytecode, "VS", "vs_4_0", ShaderFlags.OptimizationLevel0);
                vertexShader         = new VertexShader(device, vertexShaderByteCode);
                var reflection = new ShaderReflection(vertexShaderByteCode);
                /* Iterate through constant buffers */
                for (int i = 0; i < reflection.Description.ConstantBuffers; ++i)
                {
                    var cb = reflection.GetConstantBuffer(i);
                    if (cb.Description.Name == "worldViewProj")
                    {
                        result.vertexShaderSlot.worldViewProj = i;
                    }
                }
                reflection.Dispose();

                pixelShaderByteCode = ShaderBytecode.Compile(shaderFileBytecode, "PS", "ps_4_0", ShaderFlags.OptimizationLevel0);
                pixelShader         = new PixelShader(device, pixelShaderByteCode);

                try
                {
                    geometryShaderByteCode = ShaderBytecode.Compile(shaderFileBytecode, "GS", "gs_4_0", ShaderFlags.OptimizationLevel0);
                    geometryShader         = new GeometryShader(device, geometryShaderByteCode);
                }
                catch (CompilationException e)
                {
                    if (!e.Message.Contains("'GS': entrypoint"))
                    {
                        throw e;
                    }
                }

                signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
                layout    = new InputLayout(device, signature, inputElements);
                signature.Dispose();

                result.vertexShader   = vertexShader;
                result.pixelShader    = pixelShader;
                result.geometryShader = geometryShader;
                result.layout         = layout;
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine("Error while compiling shader {0}:\n{1}", shaderFile, e);
                error = e;
            }
            finally
            {
                if (geometryShaderByteCode != null)
                {
                    geometryShaderByteCode.Dispose();
                }
                if (vertexShaderByteCode != null)
                {
                    vertexShaderByteCode.Dispose();
                }
                if (pixelShaderByteCode != null)
                {
                    pixelShaderByteCode.Dispose();
                }
                if (geometryShaderByteCode != null)
                {
                    geometryShaderByteCode.Dispose();
                }
                if (signature != null)
                {
                    signature.Dispose();
                }

                if (error != null && vertexShader != null)
                {
                    vertexShader.Dispose();
                }
                if (error != null && pixelShader != null)
                {
                    pixelShader.Dispose();
                }
                if (error != null && geometryShader != null)
                {
                    geometryShader.Dispose();
                }
                if (error != null && layout != null)
                {
                    signature.Dispose();
                }
            }

            result.validState = error == null;

            return(System.Tuple.Create(result, error));
        }
예제 #2
0
        public static void CompileD3D12Shader(H1ShaderCompileInput input, H1ShaderCompileOutput output)
        {
            // process shared/single environments
            String includeContent = "";
            List <SharpDX.Direct3D.ShaderMacro> macros = new List <SharpDX.Direct3D.ShaderMacro>();

            // 1. shared environment
            ProcessShaderCompilerEnvironment(input.SharedEnvironment, ref includeContent, macros);

            // 2. single environment
            ProcessShaderCompilerEnvironment(input.Environment, ref includeContent, macros);

            // load shader file content
            String sourceContent = includeContent + "\n" + LoadShaderFile(input.SourceFileName);

            // preprocess the shader file
            sourceContent = ShaderBytecode.Preprocess(sourceContent, macros.ToArray(), new H1SharpDXCompileInclude());
#if DEBUG
            var shader = ShaderBytecode.Compile(sourceContent, input.EntryPointName, input.Target.ToFormat, SharpDX.D3DCompiler.ShaderFlags.Debug | SharpDX.D3DCompiler.ShaderFlags.SkipOptimization);
#else
            var shader = ShaderBytecode.Compile(sourceContent, input.EntryPointName, input.Target.ToFormat);
#endif
            if (shader.Message != null) // failed to compile the shader
            {
                // @TODO - should log the error for failing compiling shader
                output.IsSucceed = false;
                return;
            }

            // assign the resultant byte code
            output.Code = shader;
            // create shader parameter map
            output.ParameterMap = new H1ShaderParameterMap();

            // reflection for the compiled shader
            ShaderReflection  shaderReflect = new ShaderReflection(shader);
            ShaderDescription shaderDesc    = shaderReflect.Description;

            int bindResCounts = shaderDesc.BoundResources;
            for (int resIdx = 0; resIdx < bindResCounts; ++resIdx)
            {
                InputBindingDescription bindDesc = shaderReflect.GetResourceBindingDescription(resIdx);

                // for constant buffers
                if (bindDesc.Type == ShaderInputType.ConstantBuffer)
                {
                    int            cbIndex = bindDesc.BindPoint;
                    ConstantBuffer cb      = shaderReflect.GetConstantBuffer(cbIndex);

                    ConstantBufferDescription cbDesc;
                    cbDesc = cb.Description;

                    // track all variables in this constant buffer
                    for (int varIdx = 0; varIdx < cbDesc.VariableCount; varIdx++)
                    {
                        ShaderReflectionVariable  variable     = cb.GetVariable(varIdx);
                        ShaderVariableDescription variableDesc = variable.Description;

                        output.ParameterMap.ParameterMap.Add(variableDesc.Name,
                                                             new H1ParameterAllocation(H1ParameterType.Variable, cbIndex, variableDesc.StartOffset, variableDesc.Size));
                    }

                    // add constant buffer parameter
                    output.ParameterMap.ParameterMap.Add(cbDesc.Name,
                                                         new H1ParameterAllocation(H1ParameterType.ConstantBuffer, cbIndex, -1, cbDesc.Size));
                }

                // texture, samplers .... other various GDI data
            }

            // release shader reflection
            shaderReflect.Dispose();
            output.IsSucceed = true; // successfully compiled
        }