| 398 | } |
| 399 | |
| 400 | bool ProcessShaderBase(CookAssetsStep::AssetCookData& data, ShaderAssetBase* assetBase) |
| 401 | { |
| 402 | auto asset = static_cast<BinaryAsset*>(data.Asset); |
| 403 | |
| 404 | // Decrypt source code |
| 405 | auto sourceChunk = asset->GetChunk(SHADER_FILE_CHUNK_SOURCE); |
| 406 | auto source = sourceChunk->Get<char>(); |
| 407 | auto sourceLength = sourceChunk->Size(); |
| 408 | Encryption::DecryptBytes((byte*)source, sourceLength); |
| 409 | source[sourceLength - 1] = 0; |
| 410 | while (sourceLength > 2 && source[sourceLength - 1] == 0) |
| 411 | sourceLength--; |
| 412 | |
| 413 | // Init shader cache output stream |
| 414 | // TODO: reuse MemoryWriteStream per cooking process to reduce dynamic memory allocations |
| 415 | MemoryWriteStream cacheStream(32 * 1024); |
| 416 | |
| 417 | // Compile shader source |
| 418 | ShaderCompilationOptions options; |
| 419 | options.TargetName = StringUtils::GetFileNameWithoutExtension(asset->GetPath()); |
| 420 | options.TargetID = asset->GetID(); |
| 421 | options.Source = source; |
| 422 | options.SourceLength = sourceLength; |
| 423 | options.NoOptimize = data.Cache.Settings.Global.ShadersNoOptimize; |
| 424 | options.GenerateDebugData = data.Cache.Settings.Global.ShadersGenerateDebugData; |
| 425 | options.TreatWarningsAsErrors = false; |
| 426 | options.Output = &cacheStream; |
| 427 | Array<String> includes; |
| 428 | |
| 429 | #define COMPILE_PROFILE(profile, cacheChunk) \ |
| 430 | { \ |
| 431 | cacheStream.SetPosition(0); \ |
| 432 | options.Profile = ShaderProfile::profile; \ |
| 433 | options.Macros.Clear(); \ |
| 434 | auto& platformDefine = options.Macros.AddOne(); \ |
| 435 | platformDefine.Name = platformDefineName; \ |
| 436 | platformDefine.Definition = nullptr; \ |
| 437 | assetBase->InitCompilationOptions(options); \ |
| 438 | if (ShadersCompilation::Compile(options)) \ |
| 439 | { \ |
| 440 | data.Data.Error(String::Format(TEXT("Failed to compile shader '{0}' (profile: {1})."), asset->ToString(), ::ToString(options.Profile))); \ |
| 441 | return true; \ |
| 442 | } \ |
| 443 | includes.Clear(); \ |
| 444 | ShadersCompilation::ExtractShaderIncludes(cacheStream.GetHandle(), cacheStream.GetPosition(), includes); \ |
| 445 | for (auto& include : includes) \ |
| 446 | data.FileDependencies.Add(ToPair(include, FileSystem::GetFileLastEditTime(include))); \ |
| 447 | auto chunk = New<FlaxChunk>(); \ |
| 448 | chunk->Data.Copy(cacheStream.GetHandle(), cacheStream.GetPosition()); \ |
| 449 | data.InitData.Header.Chunks[cacheChunk] = chunk; \ |
| 450 | } |
| 451 | |
| 452 | // Compile for a target platform |
| 453 | switch (data.Data.Platform) |
| 454 | { |
| 455 | #if PLATFORM_TOOLS_WINDOWS |
| 456 | case BuildPlatform::Windows32: |
| 457 | case BuildPlatform::Windows64: |
no test coverage detected