void FShaderResource::InitRHI() { checkf(Code.Num() > 0, TEXT("FShaderResource::InitRHI was called with empty bytecode, which can happen if the resource is initialized multiple times on platforms with no editor data.")); // we can't have this called on the wrong platform's shaders if (!ArePlatformsCompatible(GMaxRHIShaderPlatform, (EShaderPlatform)Target.Platform)) { if (FPlatformProperties::RequiresCookedData()) { UE_LOG(LogShaders, Fatal, TEXT("FShaderResource::InitRHI got platform %s but it is not compatible with %s"), *LegacyShaderPlatformToShaderFormat((EShaderPlatform)Target.Platform).ToString(), *LegacyShaderPlatformToShaderFormat(GMaxRHIShaderPlatform).ToString()); } return; } INC_DWORD_STAT_BY(STAT_Shaders_NumShadersUsedForRendering, 1); SCOPE_CYCLE_COUNTER(STAT_Shaders_RTShaderLoadTime); if(Target.Frequency == SF_Vertex) { VertexShader = RHICreateVertexShader(Code); } else if(Target.Frequency == SF_Pixel) { PixelShader = RHICreatePixelShader(Code); } else if(Target.Frequency == SF_Hull) { HullShader = RHICreateHullShader(Code); } else if(Target.Frequency == SF_Domain) { DomainShader = RHICreateDomainShader(Code); } else if(Target.Frequency == SF_Geometry) { GeometryShader = RHICreateGeometryShader(Code); } else if(Target.Frequency == SF_Compute) { ComputeShader = RHICreateComputeShader(Code); } if (!FPlatformProperties::HasEditorOnlyData()) { DEC_DWORD_STAT_BY_FName(GetMemoryStatType((EShaderFrequency)Target.Frequency).GetName(), Code.Num()); DEC_DWORD_STAT_BY(STAT_Shaders_ShaderResourceMemory, Code.GetAllocatedSize()); Code.Empty(); } }
void FShaderResource::InitRHI() { checkf(Code.Num() > 0, TEXT("FShaderResource::InitRHI was called with empty bytecode, which can happen if the resource is initialized multiple times on platforms with no editor data.")); // we can't have this called on the wrong platform's shaders if (!ArePlatformsCompatible(GMaxRHIShaderPlatform, (EShaderPlatform)Target.Platform)) { if (FPlatformProperties::RequiresCookedData()) { UE_LOG(LogShaders, Fatal, TEXT("FShaderResource::InitRHI got platform %s but it is not compatible with %s"), *LegacyShaderPlatformToShaderFormat((EShaderPlatform)Target.Platform).ToString(), *LegacyShaderPlatformToShaderFormat(GMaxRHIShaderPlatform).ToString()); } return; } INC_DWORD_STAT_BY(STAT_Shaders_NumShadersUsedForRendering, 1); SCOPE_CYCLE_COUNTER(STAT_Shaders_RTShaderLoadTime); FShaderCache* ShaderCache = FShaderCache::GetShaderCache(); if(Target.Frequency == SF_Vertex) { VertexShader = ShaderCache ? ShaderCache->GetVertexShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateVertexShader(Code); } else if(Target.Frequency == SF_Pixel) { PixelShader = ShaderCache ? ShaderCache->GetPixelShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreatePixelShader(Code); } else if(Target.Frequency == SF_Hull) { HullShader = ShaderCache ? ShaderCache->GetHullShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateHullShader(Code); } else if(Target.Frequency == SF_Domain) { DomainShader = ShaderCache ? ShaderCache->GetDomainShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateDomainShader(Code); } else if(Target.Frequency == SF_Geometry) { if (SpecificType) { FStreamOutElementList ElementList; TArray<uint32> StreamStrides; int32 RasterizedStream = -1; SpecificType->GetStreamOutElements(ElementList, StreamStrides, RasterizedStream); checkf(ElementList.Num(), *FString::Printf(TEXT("Shader type %s was given GetStreamOutElements implementation that had no elements!"), SpecificType->GetName())); //@todo - not using the cache GeometryShader = RHICreateGeometryShaderWithStreamOutput(Code, ElementList, StreamStrides.Num(), StreamStrides.GetData(), RasterizedStream); } else { GeometryShader = ShaderCache ? ShaderCache->GetGeometryShader((EShaderPlatform)Target.Platform, OutputHash, Code) : RHICreateGeometryShader(Code); } } else if(Target.Frequency == SF_Compute) { ComputeShader = ShaderCache ? ShaderCache->GetComputeShader((EShaderPlatform)Target.Platform, Code) : RHICreateComputeShader(Code); } if (Target.Frequency != SF_Geometry) { checkf(!SpecificType, *FString::Printf(TEXT("Only geometry shaders can use GetStreamOutElements, shader type %s"), SpecificType->GetName())); } if (!FPlatformProperties::HasEditorOnlyData()) { DEC_DWORD_STAT_BY_FName(GetMemoryStatType((EShaderFrequency)Target.Frequency).GetName(), Code.Num()); DEC_DWORD_STAT_BY(STAT_Shaders_ShaderResourceMemory, Code.GetAllocatedSize()); Code.Empty(); } }