Files
UnrealEngineUWP/Engine/Source/Developer/Virtualization/Private/VirtualizationDDCBackend.cpp
paul chipchase 84d1e56ab8 Extend VA.MissBackends commandline to work via console commands as well.
#rb PJ.Kack
#jira UE-148223
#rnx
#preflight 6260f6e4360b45c32a84fae8

- The commandline -VA-MissBackends has been extended to a console command 'VA.MissBackends' that can be used at runtime to disable specific backends or reset the list and enable all of them again.
-- Entering VA.MissBackends without any args will print help documentation to the console/output log and show the user the names of the backends that they can disable.
- Technically we don't need the command line parsing anymore and users could use -dpcvars=VA.MissBackends=X instead but since we already have the code we might as well leave it untouched.
- Disabling backends from pulling payloads for debug purposes has been split off to it's own system stored as a

- IVirtualizationBackend::EOperations has been turned into bit flags, so we no longer need the 'both' entry
- IVirtualizationBackendnow has two EOperations members, one to record the operations that the backend supports and another that allows the operations to be disabled for debugging purposes.
- IVirtualizationBackend now has one method to poll if an operation is supported ::IsOperationSupported, which should not change over the lift time of the backend. In addition there is also a method for disabling/enabling a backend for debugging purposes as well as polling the debug state.

[CL 19845175 by paul chipchase in ue5-main branch]
2022-04-21 03:15:13 -04:00

177 lines
5.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "VirtualizationDDCBackend.h"
#include "Misc/Parse.h"
#include "DerivedDataCache.h"
#include "DerivedDataCacheRecord.h"
#include "DerivedDataRequestOwner.h"
#include "DerivedDataValue.h"
namespace UE::Virtualization
{
/** Utility function to help convert from UE::Virtualization::FIoHash to UE::DerivedData::FValueId */
static UE::DerivedData::FValueId ToDerivedDataValueId(const FIoHash& Id)
{
return UE::DerivedData::FValueId::FromHash(Id);
}
FDDCBackend::FDDCBackend(FStringView ProjectName, FStringView ConfigName, FStringView InDebugName)
: IVirtualizationBackend(ConfigName, InDebugName, EOperations::Push | EOperations::Pull)
, BucketName(TEXT("BulkData"))
, TransferPolicy(UE::DerivedData::ECachePolicy::None)
, QueryPolicy(UE::DerivedData::ECachePolicy::None)
{
}
bool FDDCBackend::Initialize(const FString& ConfigEntry)
{
TRACE_CPUPROFILER_EVENT_SCOPE(Initialize::Initialize);
if (!FParse::Value(*ConfigEntry, TEXT("Bucket="), BucketName))
{
UE_LOG(LogVirtualization, Fatal, TEXT("[%s] 'Bucket=' not found in the config file"), *GetDebugName());
}
bool bAllowLocal = true;
if (FParse::Bool(*ConfigEntry, TEXT("LocalStorage="), bAllowLocal))
{
UE_LOG(LogVirtualization, Display, TEXT("[%s] Use of local storage set to '%s"), *GetDebugName(), bAllowLocal ? TEXT("true") : TEXT("false"));
}
bool bAllowRemote = true;
if (FParse::Bool(*ConfigEntry, TEXT("RemoteStorage="), bAllowRemote))
{
UE_LOG(LogVirtualization, Display, TEXT("[%s] Use of remote storage set to '%s"), *GetDebugName(), bAllowRemote ? TEXT("true") : TEXT("false"));
}
if (!bAllowLocal && !bAllowRemote)
{
UE_LOG(LogVirtualization, Fatal, TEXT("[%s] LocalStorage and RemoteStorage cannot both be disabled"), *GetDebugName());
return false;
}
if (bAllowLocal)
{
TransferPolicy |= UE::DerivedData::ECachePolicy::Local;
QueryPolicy |= UE::DerivedData::ECachePolicy::QueryLocal;
}
if (bAllowRemote)
{
TransferPolicy |= UE::DerivedData::ECachePolicy::Remote;
QueryPolicy |= UE::DerivedData::ECachePolicy::QueryRemote;
}
Bucket = UE::DerivedData::FCacheBucket(BucketName);
return true;
}
EPushResult FDDCBackend::PushData(const FIoHash& Id, const FCompressedBuffer& Payload, const FString& PackageContext)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FDDCBackend::PushData);
if (DoesPayloadExist(Id))
{
UE_LOG(LogVirtualization, Verbose, TEXT("[%s] Already has a copy of the payload '%s'."), *GetDebugName(), *LexToString(Id));
return EPushResult::PayloadAlreadyExisted;
}
UE::DerivedData::ICache& Cache = UE::DerivedData::GetCache();
UE::DerivedData::FCacheKey Key;
Key.Bucket = Bucket;
Key.Hash = Id;
UE::DerivedData::FValue DerivedDataValue(Payload);
check(DerivedDataValue.GetRawHash() == Id);
UE::DerivedData::FCacheRecordBuilder RecordBuilder(Key);
RecordBuilder.AddValue(ToDerivedDataValueId(Id), DerivedDataValue);
UE::DerivedData::FRequestOwner Owner(UE::DerivedData::EPriority::Blocking);
UE::DerivedData::FCachePutResponse Result;
auto Callback = [&Result](UE::DerivedData::FCachePutResponse&& Response)
{
Result = Response;
};
// TODO: Improve the name when we start passing more context to this function
Cache.Put({{{TEXT("Mirage")}, RecordBuilder.Build(), TransferPolicy}}, Owner, MoveTemp(Callback));
Owner.Wait();
if (Result.Status == UE::DerivedData::EStatus::Ok)
{
return EPushResult::Success;
}
else
{
return EPushResult::Failed;
}
}
FCompressedBuffer FDDCBackend::PullData(const FIoHash& Id)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FDDCBackend::PullData);
UE::DerivedData::ICache& Cache = UE::DerivedData::GetCache();
UE::DerivedData::FCacheKey Key;
Key.Bucket = Bucket;
Key.Hash = Id;
UE::DerivedData::FRequestOwner Owner(UE::DerivedData::EPriority::Blocking);
FCompressedBuffer ResultData;
UE::DerivedData::EStatus ResultStatus;
auto Callback = [&Id, &ResultData, &ResultStatus](UE::DerivedData::FCacheGetResponse&& Response)
{
ResultStatus = Response.Status;
if (ResultStatus == UE::DerivedData::EStatus::Ok)
{
ResultData = Response.Record.GetValue(ToDerivedDataValueId(Id)).GetData();
}
};
// TODO: Improve the name when we start passing more context to this function
Cache.Get({{{TEXT("Mirage")}, Key, TransferPolicy}}, Owner, MoveTemp(Callback));
Owner.Wait();
return ResultData;
}
bool FDDCBackend::DoesPayloadExist(const FIoHash& Id)
{
TRACE_CPUPROFILER_EVENT_SCOPE(FDDCBackend::DoesPayloadExist);
UE::DerivedData::ICache& Cache = UE::DerivedData::GetCache();
UE::DerivedData::FCacheKey Key;
Key.Bucket = Bucket;
Key.Hash = Id;
UE::DerivedData::FRequestOwner Owner(UE::DerivedData::EPriority::Blocking);
UE::DerivedData::EStatus ResultStatus;
auto Callback = [&ResultStatus](UE::DerivedData::FCacheGetResponse&& Response)
{
ResultStatus = Response.Status;
};
// TODO: Improve the name when we start passing more context to this function
Cache.Get({{{TEXT("Mirage")}, Key, QueryPolicy | UE::DerivedData::ECachePolicy::SkipData}}, Owner, MoveTemp(Callback));
Owner.Wait();
return ResultStatus == UE::DerivedData::EStatus::Ok;
}
UE_REGISTER_VIRTUALIZATION_BACKEND_FACTORY(FDDCBackend, DDCBackend);
} // namespace UE::Virtualization