/** * Enqueues a compilation for a new shader of this type. * @param Platform - The platform to compile for. * @param Material - The material to link the shader with. * @param VertexFactoryType - The vertex factory to compile with. */ FShaderCompileJob* FMeshMaterialShaderType::BeginCompileShader( uint32 ShaderMapId, EShaderPlatform Platform, const FMaterial* Material, FShaderCompilerEnvironment* MaterialEnvironment, FVertexFactoryType* VertexFactoryType, const FShaderPipelineType* ShaderPipeline, TArray<FShaderCommonCompileJob*>& NewJobs ) { FShaderCompileJob* NewJob = new FShaderCompileJob(ShaderMapId, VertexFactoryType, this); NewJob->Input.SharedEnvironment = MaterialEnvironment; FShaderCompilerEnvironment& ShaderEnvironment = NewJob->Input.Environment; // apply the vertex factory changes to the compile environment check(VertexFactoryType); VertexFactoryType->ModifyCompilationEnvironment(Platform, Material, ShaderEnvironment); //update material shader stats UpdateMaterialShaderCompilingStats(Material); UE_LOG(LogShaders, Verbose, TEXT(" %s"), GetName()); COOK_STAT(MaterialMeshCookStats::ShadersCompiled++); // Allow the shader type to modify the compile environment. SetupCompileEnvironment(Platform, Material, ShaderEnvironment); bool bAllowDevelopmentShaderCompile = Material->GetAllowDevelopmentShaderCompile(); // Compile the shader environment passed in with the shader type's source code. ::GlobalBeginCompileShader( Material->GetFriendlyName(), VertexFactoryType, this, ShaderPipeline, GetShaderFilename(), GetFunctionName(), FShaderTarget(GetFrequency(),Platform), NewJob, NewJobs, bAllowDevelopmentShaderCompile ); return NewJob; }
void FGlobalShaderType::BeginCompileShader(EShaderPlatform Platform, TArray<FShaderCompileJob*>& NewJobs) { FShaderCompileJob* NewJob = new FShaderCompileJob(GlobalShaderMapId, NULL, this); FShaderCompilerEnvironment& ShaderEnvironment = NewJob->Input.Environment; UE_LOG(LogShaders, Verbose, TEXT(" %s"), GetName()); // Allow the shader type to modify the compile environment. SetupCompileEnvironment(Platform, ShaderEnvironment); static FString GlobalName(TEXT("Global")); // Compile the shader environment passed in with the shader type's source code. ::GlobalBeginCompileShader( GlobalName, NULL, this, GetShaderFilename(), GetFunctionName(), FShaderTarget(GetFrequency(),Platform), NewJob, NewJobs ); }
FSelfContainedShaderId::FSelfContainedShaderId() : Target(FShaderTarget(SF_NumFrequencies, SP_NumPlatforms)) {}
void FMeshMaterialShaderMap::LoadMissingShadersFromMemory( const FSHAHash& MaterialShaderMapHash, const FMaterial* Material, EShaderPlatform Platform) { for (TLinkedList<FShaderType*>::TIterator ShaderTypeIt(FShaderType::GetTypeList());ShaderTypeIt;ShaderTypeIt.Next()) { FMeshMaterialShaderType* ShaderType = ShaderTypeIt->GetMeshMaterialShaderType(); if (ShaderType && ShouldCacheMeshShader(ShaderType, Platform, Material, VertexFactoryType) && !HasShader((FShaderType*)ShaderType)) { const FShaderId ShaderId(MaterialShaderMapHash, nullptr, VertexFactoryType, (FShaderType*)ShaderType, FShaderTarget(ShaderType->GetFrequency(), Platform)); FShader* FoundShader = ((FShaderType*)ShaderType)->FindShaderById(ShaderId); if (FoundShader) { AddShader((FShaderType*)ShaderType, FoundShader); } } } // Try to find necessary FShaderPipelineTypes in memory for (TLinkedList<FShaderPipelineType*>::TIterator ShaderPipelineIt(FShaderPipelineType::GetTypeList());ShaderPipelineIt;ShaderPipelineIt.Next()) { const FShaderPipelineType* PipelineType = *ShaderPipelineIt; if (PipelineType && PipelineType->IsMeshMaterialTypePipeline() && !HasShaderPipeline(PipelineType)) { auto& Stages = PipelineType->GetStages(); int32 NumShaders = 0; for (const FShaderType* Shader : Stages) { FMeshMaterialShaderType* ShaderType = (FMeshMaterialShaderType*)Shader->GetMeshMaterialShaderType(); if (ShaderType && ShouldCacheMeshShader(ShaderType, Platform, Material, VertexFactoryType)) { ++NumShaders; } else { break; } } if (NumShaders == Stages.Num()) { TArray<FShader*> ShadersForPipeline; for (auto* Shader : Stages) { FMeshMaterialShaderType* ShaderType = (FMeshMaterialShaderType*)Shader->GetMeshMaterialShaderType(); if (!HasShader(ShaderType)) { const FShaderId ShaderId(MaterialShaderMapHash, PipelineType->ShouldOptimizeUnusedOutputs() ? PipelineType : nullptr, VertexFactoryType, ShaderType, FShaderTarget(ShaderType->GetFrequency(), Platform)); FShader* FoundShader = ShaderType->FindShaderById(ShaderId); if (FoundShader) { AddShader(ShaderType, FoundShader); ShadersForPipeline.Add(FoundShader); } } } if (ShadersForPipeline.Num() == NumShaders && !HasShaderPipeline(PipelineType)) { auto* Pipeline = new FShaderPipeline(PipelineType, ShadersForPipeline); AddShaderPipeline(PipelineType, Pipeline); } } } } }