void FShaderUniformBufferParameter::Bind(const FShaderParameterMap& ParameterMap,const TCHAR* ParameterName,EShaderParameterFlags Flags) { uint16 UnusedBaseIndex = 0; uint16 UnusedNumBytes = 0; #if UE_BUILD_DEBUG bInitialized = true; #endif if(!ParameterMap.FindParameterAllocation(ParameterName,BaseIndex,UnusedBaseIndex,UnusedNumBytes)) { bIsBound = false; if(Flags == SPF_Mandatory) { if (!UE_LOG_ACTIVE(LogShaders, Log)) { UE_LOG(LogShaders, Fatal,TEXT("Failure to bind non-optional shader resource parameter %s! The parameter is either not present in the shader, or the shader compiler optimized it out."),ParameterName); } else { // We use a non-Slate message box to avoid problem where we haven't compiled the shaders for Slate. FPlatformMisc::MessageBoxExt( EAppMsgType::Ok, *FText::Format( NSLOCTEXT("UnrealEd", "Error_FailedToBindShaderParameter", "Failure to bind non-optional shader parameter {0}! The parameter is either not present in the shader, or the shader compiler optimized it out. This will be an assert with LogShaders suppressed!"), FText::FromString(ParameterName)).ToString(), TEXT("Warning")); } } } else { bIsBound = true; } }
void BuildResourceTableMapping( const TMap<FString,FResourceTableEntry>& ResourceTableMap, const TMap<FString,uint32>& ResourceTableLayoutHashes, TBitArray<>& UsedUniformBufferSlots, FShaderParameterMap& ParameterMap, FShaderResourceTable& OutSRT) { check(OutSRT.ResourceTableBits == 0); check(OutSRT.ResourceTableLayoutHashes.Num() == 0); // Build resource table mapping int32 MaxBoundResourceTable = -1; TArray<uint32> ResourceTableSRVs; TArray<uint32> ResourceTableSamplerStates; TArray<uint32> ResourceTableUAVs; for( auto MapIt = ResourceTableMap.CreateConstIterator(); MapIt; ++MapIt ) { const FString& Name = MapIt->Key; const FResourceTableEntry& Entry = MapIt->Value; uint16 BufferIndex, BaseIndex, Size; if (ParameterMap.FindParameterAllocation( *Name, BufferIndex, BaseIndex, Size ) ) { ParameterMap.RemoveParameterAllocation(*Name); uint16 UniformBufferIndex = INDEX_NONE, UBBaseIndex, UBSize; if (ParameterMap.FindParameterAllocation(*Entry.UniformBufferName, UniformBufferIndex, UBBaseIndex, UBSize) == false) { UniformBufferIndex = UsedUniformBufferSlots.FindAndSetFirstZeroBit(); ParameterMap.AddParameterAllocation(*Entry.UniformBufferName,UniformBufferIndex,0,0); } OutSRT.ResourceTableBits |= (1 << UniformBufferIndex); MaxBoundResourceTable = FMath::Max<int32>(MaxBoundResourceTable, (int32)UniformBufferIndex); while (OutSRT.ResourceTableLayoutHashes.Num() <= MaxBoundResourceTable) { OutSRT.ResourceTableLayoutHashes.Add(0); } OutSRT.ResourceTableLayoutHashes[UniformBufferIndex] = ResourceTableLayoutHashes.FindChecked(Entry.UniformBufferName); auto ResourceMap = FRHIResourceTableEntry::Create(UniformBufferIndex, Entry.ResourceIndex, BaseIndex); switch( Entry.Type ) { case UBMT_TEXTURE: OutSRT.TextureMap.Add(ResourceMap); break; case UBMT_SAMPLER: OutSRT.SamplerMap.Add(ResourceMap); break; case UBMT_SRV: OutSRT.ShaderResourceViewMap.Add(ResourceMap); break; case UBMT_UAV: OutSRT.UnorderedAccessViewMap.Add(ResourceMap); break; default: check(0); } } } OutSRT.MaxBoundResourceTable = MaxBoundResourceTable; }