protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            var compiler = GetOrCreateEffectCompiler(context);

            var isPdxfx = ShaderMixinManager.Contains(effectName);
            var source  = isPdxfx ? new ShaderMixinGeneratorSource(effectName) : (ShaderSource) new ShaderClassSource(effectName);

            int permutationCount;

            lock (PermutationCount)
            {
                PermutationCount.TryGetValue(effectName, out permutationCount);
                permutationCount++;
                PermutationCount[effectName] = permutationCount;
            }
            commandContext.Logger.Info("Create permutation #{0} for effect [{1}]: \n{2}", permutationCount, effectName, compilerParameters.ToStringDetailed());

            var compilerResults = compiler.Compile(source, compilerParameters, null, null);

            // Copy logs and if there are errors, exit directlry
            compilerResults.CopyTo(commandContext.Logger);
            if (compilerResults.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // Register all dependencies
            var bytecode = compilerResults.MainBytecode;

            foreach (var hashSource in bytecode.HashSources)
            {
                commandContext.Logger.Verbose("Shader [{0}] is using [{1}]", effectName, hashSource.Key);
                commandContext.RegisterInputDependency(new ObjectUrl(UrlType.Internal, hashSource.Key));
            }

            // Generate sourcecode if configured
            if (compilerParameters.ContainsKey(EffectSourceCodeKeys.Enable))
            {
                var outputDirectory     = UPath.Combine(context.Package.RootDirectory, baseUrl);
                var outputClassFile     = effectName + ".bytecode." + compilerParameters.Platform + "." + compilerParameters.Profile + ".cs";
                var fullOutputClassFile = Path.Combine(outputDirectory, outputClassFile);

                commandContext.Logger.Info("Writing shader bytecode to .cs source [{0}]", fullOutputClassFile);
                using (var stream = new FileStream(fullOutputClassFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                    EffectByteCodeToSourceCodeWriter.Write(effectName, compilerParameters, bytecode, new StreamWriter(stream, Encoding.UTF8));
            }

            return(Task.FromResult(ResultStatus.Successful));
        }
示例#2
0
        protected override Task <ResultStatus> DoCommandOverride(ICommandContext commandContext)
        {
            var compiler = GetOrCreateEffectCompiler(context);

            // Get main effect name (before the first dot)
            var isPdxfx = ShaderMixinManager.Contains(effectName);
            var source  = isPdxfx ? new ShaderMixinGeneratorSource(effectName) : (ShaderSource) new ShaderClassSource(effectName);

            int permutationCount;

            lock (PermutationCount)
            {
                PermutationCount.TryGetValue(effectName, out permutationCount);
                permutationCount++;
                PermutationCount[effectName] = permutationCount;
            }
            commandContext.Logger.Verbose("Trying permutation #{0} for effect [{1}]: \n{2}", permutationCount, effectName, compilerParameters.ToStringDetailed());

            var compilerResults = compiler.Compile(source, compilerParameters);

            // Copy logs and if there are errors, exit directly
            compilerResults.CopyTo(commandContext.Logger);
            if (compilerResults.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // wait for result an check compilation status
            var completedTask = compilerResults.Bytecode.WaitForResult();

            completedTask.CompilationLog.CopyTo(commandContext.Logger);
            if (completedTask.CompilationLog.HasErrors)
            {
                return(Task.FromResult(ResultStatus.Failed));
            }

            // Register all dependencies
            var allSources = new HashSet <string>(completedTask.Bytecode.HashSources.Select(keyPair => keyPair.Key));

            foreach (var className in allSources)
            {
                commandContext.RegisterInputDependency(new ObjectUrl(UrlType.Internal, EffectCompilerBase.GetStoragePathFromShaderType(className)));
            }

            // Generate sourcecode if configured
            if (compilerParameters.ContainsKey(EffectSourceCodeKeys.Enable))
            {
                var outputDirectory = UPath.Combine(package.RootDirectory, baseUrl);

                var fieldName = compilerParameters.Get(EffectSourceCodeKeys.FieldName);
                if (fieldName.StartsWith("binary"))
                {
                    fieldName = fieldName.Substring("binary".Length);
                    if (char.IsUpper(fieldName[0]))
                    {
                        fieldName = char.ToLower(fieldName[0]) + fieldName.Substring(1);
                    }
                }

                var outputClassFile     = effectName + "." + fieldName + "." + compilerParameters.Platform + "." + compilerParameters.Profile + ".cs";
                var fullOutputClassFile = Path.Combine(outputDirectory.ToWindowsPath(), outputClassFile);

                commandContext.Logger.Verbose("Writing shader bytecode to .cs source [{0}]", fullOutputClassFile);
                using (var stream = new FileStream(fullOutputClassFile, FileMode.Create, FileAccess.Write, FileShare.Write))
                    EffectByteCodeToSourceCodeWriter.Write(effectName, compilerParameters, compilerResults.Bytecode.WaitForResult().Bytecode, new StreamWriter(stream, System.Text.Encoding.UTF8));
            }

            return(Task.FromResult(ResultStatus.Successful));
        }