123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <ResourcePool/ResourcePoolBuilder.h>
- #include <AzCore/Serialization/Utils.h>
- #include <AzCore/std/smart_ptr/make_shared.h>
- #include <AzFramework/IO/LocalFileIO.h>
- #include <AzFramework/StringFunc/StringFunc.h>
- #include <AzToolsFramework/API/EditorAssetSystemAPI.h>
- #include <AzCore/Serialization/Json/JsonUtils.h>
- #include <Atom/RHI.Reflect/BufferPoolDescriptor.h>
- #include <Atom/RHI.Reflect/ImagePoolDescriptor.h>
- #include <Atom/RPI.Reflect/ResourcePoolAssetCreator.h>
- #include <Atom/RPI.Reflect/Image/StreamingImagePoolAssetCreator.h>
- namespace AZ
- {
- AZ_TYPE_INFO_SPECIALIZE(RPI::ResourcePoolAssetType, "{09D35821-2D42-456B-B53C-C02BF387C5C4}");
- using namespace RPI;
- namespace RPI
- {
- // The file extension for the source file of resource pool Asset
- const char* s_sourcePoolAssetExt = "resourcepool";
- void ResourcePoolBuilder::RegisterBuilder()
- {
- AssetBuilderSDK::AssetBuilderDesc builderDescriptor;
- builderDescriptor.m_name = "Atom Resource Pool Asset Builder";
- builderDescriptor.m_version = 2; //ATOM-15196
- builderDescriptor.m_patterns.emplace_back(AssetBuilderSDK::AssetBuilderPattern(AZStd::string("*.") + s_sourcePoolAssetExt,
- AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard));
- builderDescriptor.m_busId = azrtti_typeid<ResourcePoolBuilder>();
- builderDescriptor.m_createJobFunction = AZStd::bind(&ResourcePoolBuilder::CreateJobs, this,
- AZStd::placeholders::_1, AZStd::placeholders::_2);
- builderDescriptor.m_processJobFunction = AZStd::bind(&ResourcePoolBuilder::ProcessJob, this,
- AZStd::placeholders::_1, AZStd::placeholders::_2);
- BusConnect(builderDescriptor.m_busId);
- AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor);
- }
- ResourcePoolBuilder::~ResourcePoolBuilder()
- {
- BusDisconnect();
- }
-
- void ResourcePoolBuilder::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response)
- {
- if (m_isShuttingDown)
- {
- response.m_result = AssetBuilderSDK::CreateJobsResultCode::ShuttingDown;
- return;
- }
- for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms)
- {
- AssetBuilderSDK::JobDescriptor descriptor;
- descriptor.m_jobKey = "Atom Resource Pool";
- descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str());
- descriptor.m_critical = false;
- response.m_createJobOutputs.push_back(descriptor);
- }
- response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
- }
- void ResourcePoolBuilder::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response)
- {
- AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId);
- if (jobCancelListener.IsCancelled())
- {
- response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled;
- return;
- }
- if (m_isShuttingDown)
- {
- response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled;
- return;
- }
- ResourcePoolSourceData poolSourceData;
- Outcome<void, AZStd::string> loadResult = AZ::JsonSerializationUtils::LoadObjectFromFile<ResourcePoolSourceData>(poolSourceData,
- request.m_fullPath);
- if (!loadResult.IsSuccess())
- {
- AZ_Error("PoolAssetProducer", false, "Failed to load source asset file %s", request.m_fullPath.c_str());
- AZ_Error("PoolAssetProducer", false, "Loading issues: %s", loadResult.GetError().c_str());
- response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
- return;
- }
- AZ_TracePrintf("AssetBuilder", "Load source data success\n");
- // Convert source format to asset used for runtime
- Data::AssetData* assetData = nullptr;
- const char* extension;
- Data::Asset<Data::AssetData> poolAsset;
- if (poolSourceData.m_poolType == ResourcePoolAssetType::StreamingImagePool)
- {
- extension = StreamingImagePoolAsset::Extension;
- poolAsset = CreateStreamingPoolAssetFromSource(poolSourceData);
- }
- else
- {
- extension = ResourcePoolAsset::Extension;
- poolAsset = CreatePoolAssetFromSource(poolSourceData);
- }
- assetData = poolAsset.GetData();
- if (!assetData)
- {
- AZ_Error("PoolAssetProducer", false, "Failed to create asset data");
- response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
- return;
- }
- AZ_TracePrintf("AssetBuilder", "Convert data success\n");
- // Get file name from source file path, then replace the extension to generate product file name
- AZStd::string destFileName;
- AzFramework::StringFunc::Path::GetFullFileName(request.m_fullPath.c_str(), destFileName);
- AzFramework::StringFunc::Path::ReplaceExtension(destFileName, extension);
- // Construct product full path
- AZStd::string destPath;
- AzFramework::StringFunc::Path::ConstructFull(request.m_tempDirPath.c_str(), destFileName.c_str(), destPath, true);
-
- // Save the asset to binary format for production
- bool result = AZ::Utils::SaveObjectToFile(destPath, AZ::DataStream::ST_BINARY, assetData, assetData->GetType(), nullptr);
- if (result == false)
- {
- AZ_Error("PoolAssetProducer", false, "Failed to save asset to cache")
- response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed;
- return;
- }
- AZ_TracePrintf("AssetBuilder", "Saved data to file %s \n", destPath.c_str());
- // Success. Save output product(s) to response
- AssetBuilderSDK::JobProduct jobProduct(destPath, assetData->GetType(), 0);
- jobProduct.m_dependenciesHandled = true; // This builder has no dependencies to output.
- response.m_outputProducts.push_back(jobProduct);
- response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
- }
- void ResourcePoolBuilder::ShutDown()
- {
- m_isShuttingDown = true;
- }
- Data::Asset<Data::AssetData> ResourcePoolBuilder::CreatePoolAssetFromSource(const ResourcePoolSourceData& sourceData)
- {
- ResourcePoolAssetCreator assetCreator;
- assetCreator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
- assetCreator.SetPoolName(sourceData.m_poolName);
- switch (sourceData.m_poolType)
- {
- case ResourcePoolAssetType::BufferPool:
- {
- // [GFX TODO][ATOM-112] - Need to create pool descriptor based on device .
- AZStd::unique_ptr<RHI::BufferPoolDescriptor> bufferPoolDescriptor = AZStd::make_unique<RHI::BufferPoolDescriptor>();
- bufferPoolDescriptor->m_budgetInBytes = sourceData.m_budgetInBytes;
- bufferPoolDescriptor->m_heapMemoryLevel = sourceData.m_heapMemoryLevel;
- bufferPoolDescriptor->m_hostMemoryAccess = sourceData.m_hostMemoryAccess;
- bufferPoolDescriptor->m_bindFlags = sourceData.m_bufferPoolBindFlags;
- assetCreator.SetPoolDescriptor(AZStd::move(bufferPoolDescriptor));
- break;
- }
- case ResourcePoolAssetType::ImagePool:
- {
- AZStd::unique_ptr<RHI::ImagePoolDescriptor> imagePoolDescriptor = AZStd::make_unique<RHI::ImagePoolDescriptor>();
- imagePoolDescriptor->m_budgetInBytes = sourceData.m_budgetInBytes;
- imagePoolDescriptor->m_bindFlags = sourceData.m_imagePoolBindFlags;
- assetCreator.SetPoolDescriptor(AZStd::move(imagePoolDescriptor));
- break;
- }
- default:
- break;
- }
- Data::Asset<ResourcePoolAsset> poolAsset;
- if (assetCreator.End(poolAsset))
- {
- return poolAsset;
- }
- return {};
- }
- Data::Asset<Data::AssetData> ResourcePoolBuilder::CreateStreamingPoolAssetFromSource(const ResourcePoolSourceData& sourceData)
- {
- AZ_Assert(sourceData.m_poolType == ResourcePoolAssetType::StreamingImagePool, "Please use CreatePoolAssetFromSource for other type of pools");
- StreamingImagePoolAssetCreator assetCreator;
- assetCreator.Begin(Data::AssetId(AZ::Uuid::CreateRandom()));
-
- AZStd::unique_ptr<RHI::StreamingImagePoolDescriptor> poolDescriptor = AZStd::make_unique<RHI::StreamingImagePoolDescriptor>();
- poolDescriptor->m_budgetInBytes = sourceData.m_budgetInBytes;
- assetCreator.SetPoolDescriptor(AZStd::move(poolDescriptor));
- assetCreator.SetPoolName(sourceData.m_poolName);
- Data::Asset<StreamingImagePoolAsset> poolAsset;
- assetCreator.End(poolAsset);
- return poolAsset;
- }
- void ResourcePoolSourceData::Reflect(ReflectContext* context)
- {
- if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
- {
- serializeContext->Class<ResourcePoolSourceData>()
- ->Field("PoolName", &ResourcePoolSourceData::m_poolName)
- ->Field("PoolType", &ResourcePoolSourceData::m_poolType)
- ->Field("BudgetInBytes", &ResourcePoolSourceData::m_budgetInBytes)
- ->Field("BufferPoolHeapMemoryLevel", &ResourcePoolSourceData::m_heapMemoryLevel)
- ->Field("BufferPoolhostMemoryAccess", &ResourcePoolSourceData::m_hostMemoryAccess)
- ->Field("BufferPoolBindFlags", &ResourcePoolSourceData::m_bufferPoolBindFlags)
- ->Field("ImagePoolBindFlags", &ResourcePoolSourceData::m_imagePoolBindFlags)
- ;
- // register enum strings
- serializeContext->Enum<ResourcePoolAssetType>()
- ->Value("Unknown", ResourcePoolAssetType::Unknown)
- ->Value("BufferPool", ResourcePoolAssetType::BufferPool)
- ->Value("ImagePool", ResourcePoolAssetType::ImagePool)
- ->Value("StreamingImagePool", ResourcePoolAssetType::StreamingImagePool)
- ;
- }
- }
- } // namespace RPI_Builder
- } // namespace AZ
|