public void Compile(UberEffectAsset asset, TargetPlatform platform) { if (string.IsNullOrEmpty(asset.Code)) { return; } var allPassed = true; var effectCodes = new Dictionary <string, Tuple <string, byte[], byte[]> >(); foreach (var rawLine in asset.Code.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var line = rawLine.Trim(); if (line.StartsWith("#line")) { continue; } if (!line.StartsWith("// uber ")) { break; } var components = line.Substring("// uber ".Length).Split(':'); var name = components[0].Trim(); var defines = components[1].Trim(); Console.WriteLine(); Console.Write("Compiling uber shader variant " + name + "... "); var output = new EffectContent(); output.EffectCode = this.GetEffectPrefixCode() + asset.Code; string tempPath = null, tempOutputPath = null; try { tempPath = Path.GetTempFileName(); tempOutputPath = Path.GetTempFileName(); using (var writer = new StreamWriter(tempPath)) { writer.Write(output.EffectCode); } output.Identity = new ContentIdentity(tempPath); var debugContent = EffectCompilerHelper.Compile( output, tempOutputPath, platform, true, defines); var releaseContent = EffectCompilerHelper.Compile( output, tempOutputPath, platform, false, defines); effectCodes[name] = new Tuple <string, byte[], byte[]>(defines, debugContent.GetEffectCode(), releaseContent.GetEffectCode()); Console.Write("done."); } catch (InvalidContentException ex) { Console.WriteLine("failed."); Console.Write(ex.Message.Trim()); allPassed = false; } finally { if (tempOutputPath != null) { File.Delete(tempOutputPath); } if (tempOutputPath != null) { File.Delete(tempPath); } } } Console.WriteLine(); Console.Write("Finalizing uber shader compilation... "); if (!allPassed) { throw new Exception("One or more uber shader variants failed to compile (see above!)"); } using (var memory = new MemoryStream()) { using (var writer = new BinaryWriter(memory)) { writer.Write((uint)2); writer.Write((uint)effectCodes.Count); foreach (var kv in effectCodes) { writer.Write(kv.Key); writer.Write(kv.Value.Item1); writer.Write(kv.Value.Item2.Length); writer.Write(kv.Value.Item2); writer.Write(kv.Value.Item3.Length); writer.Write(kv.Value.Item3); } var len = memory.Position; var data = new byte[len]; memory.Seek(0, SeekOrigin.Begin); memory.Read(data, 0, data.Length); asset.PlatformData = new PlatformData { Platform = platform, Data = data }; } } try { asset.ReadyOnGameThread(); } catch (NoAssetContentManagerException) { } }
public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output) { var code = string.Empty; using (var reader = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false))) { code = await reader.ReadToEndAsync().ConfigureAwait(false); } if (!code.Contains("// uber")) { // Do nothing with this file. return; } var dirName = Path.GetDirectoryName(assetFile.Name.Replace(".", "/")); code = await ResolveIncludes(assetDependencies, dirName.Replace(Path.DirectorySeparatorChar, '.'), code).ConfigureAwait(false); var allPassed = true; var effectCodes = new Dictionary <string, Tuple <string, byte[], byte[]> >(); foreach (var rawLine in code.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)) { var line = rawLine.Trim(); if (line.StartsWith("#line")) { continue; } if (!line.StartsWith("// uber ")) { break; } var components = line.Substring("// uber ".Length).Split(':'); var name = components[0].Trim(); var defines = components[1].Trim(); Console.WriteLine(); Console.Write("Compiling uber shader variant " + name + "... "); var effectOutput = new EffectContent(); effectOutput.EffectCode = this.GetEffectPrefixCode() + code; string tempPath = null, tempOutputPath = null; try { tempPath = Path.GetTempFileName(); tempOutputPath = Path.GetTempFileName(); using (var writer = new StreamWriter(tempPath)) { writer.Write(effectOutput.EffectCode); } effectOutput.Identity = new ContentIdentity(tempPath); var debugContent = EffectCompilerHelper.Compile( effectOutput, tempOutputPath, platform, true, defines); var releaseContent = EffectCompilerHelper.Compile( effectOutput, tempOutputPath, platform, false, defines); effectCodes[name] = new Tuple <string, byte[], byte[]>(defines, debugContent.GetEffectCode(), releaseContent.GetEffectCode()); Console.Write("done."); } catch (InvalidContentException ex) { Console.WriteLine("failed."); Console.Write(ex.Message.Trim()); allPassed = false; } finally { if (tempOutputPath != null) { File.Delete(tempOutputPath); } if (tempOutputPath != null) { File.Delete(tempPath); } } } Console.WriteLine(); Console.Write("Finalizing uber shader compilation... "); if (!allPassed) { throw new Exception("One or more uber shader variants failed to compile (see above!)"); } using (var memory = new MemoryStream()) { using (var writer = new BinaryWriter(memory)) { writer.Write((uint)2); writer.Write((uint)effectCodes.Count); foreach (var kv in effectCodes) { writer.Write(kv.Key); writer.Write(kv.Value.Item1); writer.Write(kv.Value.Item2.Length); writer.Write(kv.Value.Item2); writer.Write(kv.Value.Item3.Length); writer.Write(kv.Value.Item3); } var len = memory.Position; var data = new byte[len]; memory.Seek(0, SeekOrigin.Begin); memory.Read(data, 0, data.Length); output.SetLoader <IAssetLoader <UberEffectAsset> >(); output.SetPlatform(platform); output.SetByteArray("Data", data); } } }
public void Compile(EffectAsset asset, TargetPlatform platform) { if (string.IsNullOrEmpty(asset.Code)) { return; } var output = new EffectContent(); output.EffectCode = this.GetEffectPrefixCode() + asset.Code; var tempPath = Path.GetTempFileName(); using (var writer = new StreamWriter(tempPath)) { writer.Write(output.EffectCode); } output.Identity = new ContentIdentity(tempPath); var tempOutputPath = Path.GetTempFileName(); var debugContent = EffectCompilerHelper.Compile( output, tempOutputPath, platform, true, string.Empty); var releaseContent = EffectCompilerHelper.Compile( output, tempOutputPath, platform, false, string.Empty); using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { // Magic flag that indicates new compiled effect format. writer.Write((uint)0x12345678); // Version 1 of new effect format. writer.Write((uint)1); var debugCode = debugContent.GetEffectCode(); var releaseCode = releaseContent.GetEffectCode(); writer.Write(debugCode.Length); writer.Write(debugCode); writer.Write(releaseCode.Length); writer.Write(releaseCode); var p = stream.Position; var b = new byte[p]; stream.Seek(0, SeekOrigin.Begin); stream.Read(b, 0, b.Length); asset.PlatformData = new PlatformData { Platform = platform, Data = b }; } } File.Delete(tempPath); File.Delete(tempOutputPath); try { asset.ReloadEffect(); } catch (NoAssetContentManagerException) { } }
public async Task CompileAsync(IAssetFsFile assetFile, IAssetDependencies assetDependencies, TargetPlatform platform, IWritableSerializedAsset output) { var code = string.Empty; using (var reader = new StreamReader(await assetFile.GetContentStream().ConfigureAwait(false))) { code = await reader.ReadToEndAsync().ConfigureAwait(false); } if (code.Contains("// uber")) { // Do nothing with this file. return; } var dirName = Path.GetDirectoryName(assetFile.Name.Replace(".", "/")); code = await ResolveIncludes(assetDependencies, dirName.Replace(Path.DirectorySeparatorChar, '.'), code).ConfigureAwait(false); var effectContent = new EffectContent(); effectContent.EffectCode = this.GetEffectPrefixCode() + code; var tempPath = Path.GetTempFileName(); using (var writer = new StreamWriter(tempPath)) { writer.Write(effectContent.EffectCode); } effectContent.Identity = new ContentIdentity(tempPath); var tempOutputPath = Path.GetTempFileName(); var debugContent = EffectCompilerHelper.Compile( effectContent, tempOutputPath, platform, true, string.Empty); var releaseContent = EffectCompilerHelper.Compile( effectContent, tempOutputPath, platform, false, string.Empty); using (var stream = new MemoryStream()) { using (var writer = new BinaryWriter(stream)) { // Magic flag that indicates new compiled effect format. writer.Write((uint)0x12345678); // Version 1 of new effect format. writer.Write((uint)1); var debugCode = debugContent.GetEffectCode(); var releaseCode = releaseContent.GetEffectCode(); writer.Write(debugCode.Length); writer.Write(debugCode); writer.Write(releaseCode.Length); writer.Write(releaseCode); var p = stream.Position; var b = new byte[p]; stream.Seek(0, SeekOrigin.Begin); stream.Read(b, 0, b.Length); output.SetLoader <IAssetLoader <EffectAsset> >(); output.SetPlatform(platform); output.SetByteArray("Data", b); } } File.Delete(tempPath); File.Delete(tempOutputPath); }