Merge remote-tracking branch 'upstream/development' into Atom/rbarrand/MaterialVersionUpdate
This commit is contained in:
@@ -44,14 +44,14 @@ namespace AZ
|
||||
AZStd::string GetSourcePathByAssetId(const AZ::Data::AssetId& assetId);
|
||||
|
||||
//! Tries to resolve a relative file reference, given the path of a referencing file.
|
||||
//! @param originatingSourceFilePath Path to the parent file that references referencedSourceFilePath. May be absolute or relative to asset-root.
|
||||
//! @param originatingSourceFilePath Path to the parent file that references referencedSourceFilePath. May be absolute or relative to asset-root.
|
||||
//! @param referencedSourceFilePath Path that the parent file references. May be relative to the parent file location or relative to asset-root.
|
||||
//! @return A full path for referencedSourceFilePath, if a full path was found. If a full path could not be constructed, returns referencedSourceFilePath unmodified.
|
||||
AZStd::string ResolvePathReference(const AZStd::string& originatingSourceFilePath, const AZStd::string& referencedSourceFilePath);
|
||||
|
||||
//! Returns the list of paths where a source asset file could possibly appear.
|
||||
//! Returns the list of paths where a source asset file could possibly appear.
|
||||
//! This is intended for use by AssetBuilders when reporting dependencies, to support relative paths between source files.
|
||||
//! When a source data file references another file using a relative path, the path might be relative to the originating
|
||||
//! When a source data file references another file using a relative path, the path might be relative to the originating
|
||||
//! file or it might be a standard source asset path (i.e. relative to the logical asset-root). This function will help reporting
|
||||
//! dependencies on all possible locations where that file may appear at some point in the future.
|
||||
//! For example a file MyGem/Assets/Foo/a.json might reference another file as "Bar/b.json". In this case, calling
|
||||
@@ -94,9 +94,9 @@ namespace AZ
|
||||
template<typename AssetDataT>
|
||||
Outcome<AZ::Data::Asset<AssetDataT>> LoadAsset(const AZ::Data::AssetId& assetId, [[maybe_unused]] const char* sourcePathForDebug)
|
||||
{
|
||||
if (nullptr == AZ::IO::FileIOBase::GetInstance()->GetAlias("@assets@"))
|
||||
if (nullptr == AZ::IO::FileIOBase::GetInstance()->GetAlias("@products@"))
|
||||
{
|
||||
// The absence of "@assets@" is not necessarily the reason LoadAsset() can't be used in CreateJobs(), but it
|
||||
// The absence of "@products@" is not necessarily the reason LoadAsset() can't be used in CreateJobs(), but it
|
||||
// is a symptom of calling LoadAsset() from CreateJobs() which is not supported.
|
||||
AZ_Assert(false, "It appears AssetUtils::LoadAsset() is being called in CreateJobs(). It can only be used in ProcessJob().");
|
||||
return AZ::Failure();
|
||||
|
||||
@@ -268,6 +268,8 @@ namespace AZ
|
||||
AZStd::vector<RHI::StreamBufferView> m_cachedStreamBufferViews;
|
||||
AZStd::vector<RHI::IndexBufferView> m_cachedIndexBufferViews;
|
||||
AZStd::vector<Data::Instance<ShaderResourceGroup>> m_cachedDrawSrg;
|
||||
|
||||
uint32_t m_nextDrawSrgIdx = 0;
|
||||
|
||||
// structure includes DrawItem and stream and index buffer index
|
||||
using BufferViewIndexType = uint32_t;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include <AtomCore/Instance/Instance.h>
|
||||
|
||||
#include <Atom/RHI/DispatchItem.h>
|
||||
#include <Atom/RPI.Public/Base.h>
|
||||
#include <Atom/RPI.Public/Image/StreamingImage.h>
|
||||
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
|
||||
@@ -40,6 +41,23 @@ namespace AZ
|
||||
|
||||
//! Loads a streaming image asset for the given file path
|
||||
Data::Instance<RPI::StreamingImage> LoadStreamingTexture(AZStd::string_view path);
|
||||
|
||||
//! Looks for a three arguments attribute named @attributeName in the given shader asset.
|
||||
//! Assigns the value to each non-null output variables.
|
||||
//! @param shaderAsset
|
||||
//! @param attributeName
|
||||
//! @param numThreadsX Can be NULL. If not NULL it takes the value of the 1st argument of the attribute. Becomes 1 on error.
|
||||
//! @param numThreadsY Can be NULL. If not NULL it takes the value of the 2nd argument of the attribute. Becomes 1 on error.
|
||||
//! @param numThreadsZ Can be NULL. If not NULL it takes the value of the 3rd argument of the attribute. Becomes 1 on error.
|
||||
//! @returns An Outcome instance with error message in case of error.
|
||||
AZ::Outcome<void, AZStd::string> GetComputeShaderNumThreads(const Data::Asset<ShaderAsset>& shaderAsset, const AZ::Name& attributeName, uint16_t* numThreadsX, uint16_t* numThreadsY, uint16_t* numThreadsZ);
|
||||
|
||||
//! Same as above, but assumes the name of the attribute to be 'numthreads'.
|
||||
AZ::Outcome<void, AZStd::string> GetComputeShaderNumThreads(const Data::Asset<ShaderAsset>& shaderAsset, uint16_t* numThreadsX, uint16_t* numThreadsY, uint16_t* numThreadsZ);
|
||||
|
||||
//! Same as above. Provided as a convenience when all arguments of the 'numthreads' attributes should be assigned to RHI::DispatchDirect::m_threadsPerGroup* variables.
|
||||
AZ::Outcome<void, AZStd::string> GetComputeShaderNumThreads(const Data::Asset<ShaderAsset>& shaderAsset, RHI::DispatchDirect& dispatchDirect);
|
||||
|
||||
} // namespace RPI
|
||||
} // namespace AZ
|
||||
|
||||
|
||||
@@ -228,9 +228,6 @@ namespace AZ
|
||||
|
||||
PipelineViewMap m_pipelineViewsByTag;
|
||||
|
||||
/// The system time when the last time this pipeline render was started
|
||||
float m_lastRenderStartTime = 0;
|
||||
|
||||
// RenderPipeline's name id, it will be used to identify the render pipeline when it's added to a Scene
|
||||
RenderPipelineId m_nameId;
|
||||
|
||||
|
||||
@@ -133,6 +133,9 @@ namespace AZ
|
||||
/// Returns an array of RPI buffers associated with the buffer shader input index.
|
||||
AZStd::array_view<Data::Instance<Buffer>> GetBufferArray(RHI::ShaderInputNameIndex& inputIndex) const;
|
||||
AZStd::array_view<Data::Instance<Buffer>> GetBufferArray(RHI::ShaderInputBufferIndex inputIndex) const;
|
||||
|
||||
//! Reset image and buffer views so that it won't hold references for any RHI resources
|
||||
void ResetViews();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Methods for assignment / access of RHI Image types.
|
||||
|
||||
@@ -518,7 +518,6 @@ namespace AZ
|
||||
if (drawSrg)
|
||||
{
|
||||
drawItem.m_uniqueShaderResourceGroup = drawSrg->GetRHIShaderResourceGroup();
|
||||
m_cachedDrawSrg.push_back(drawSrg);
|
||||
}
|
||||
|
||||
// Set scissor per draw if scissor is enabled.
|
||||
@@ -608,7 +607,6 @@ namespace AZ
|
||||
if (drawSrg)
|
||||
{
|
||||
drawItem.m_uniqueShaderResourceGroup = drawSrg->GetRHIShaderResourceGroup();
|
||||
m_cachedDrawSrg.push_back(drawSrg);
|
||||
}
|
||||
|
||||
// Set scissor per draw if scissor is enabled.
|
||||
@@ -635,7 +633,22 @@ namespace AZ
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
auto drawSrg = AZ::RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), m_shader->GetSupervariantIndex(), m_drawSrgLayout->GetName());
|
||||
|
||||
Data::Instance<ShaderResourceGroup> drawSrg;
|
||||
if (m_nextDrawSrgIdx == m_cachedDrawSrg.size())
|
||||
{
|
||||
drawSrg = AZ::RPI::ShaderResourceGroup::Create(m_shader->GetAsset(), m_shader->GetSupervariantIndex(), m_drawSrgLayout->GetName());
|
||||
m_cachedDrawSrg.push_back(drawSrg);
|
||||
}
|
||||
else if (m_nextDrawSrgIdx < m_cachedDrawSrg.size())
|
||||
{
|
||||
drawSrg = m_cachedDrawSrg[m_nextDrawSrgIdx];
|
||||
}
|
||||
else
|
||||
{
|
||||
AZ_Assert(false, "Unexpected next draw srg index");
|
||||
}
|
||||
m_nextDrawSrgIdx++;
|
||||
|
||||
// Set fallback value for shader variant if draw srg contains constant for shader variant fallback
|
||||
if (m_hasShaderVariantKeyFallbackEntry)
|
||||
@@ -727,7 +740,7 @@ namespace AZ
|
||||
}
|
||||
|
||||
for (auto& drawItemProperties : m_cachedDrawList)
|
||||
{
|
||||
{
|
||||
view->AddDrawItem(m_drawListTag, drawItemProperties);
|
||||
}
|
||||
}
|
||||
@@ -743,9 +756,14 @@ namespace AZ
|
||||
m_cachedDrawItems.clear();
|
||||
m_cachedStreamBufferViews.clear();
|
||||
m_cachedIndexBufferViews.clear();
|
||||
m_cachedDrawSrg.clear();
|
||||
m_cachedDrawList.clear();
|
||||
m_nextDrawSrgIdx = 0;
|
||||
m_drawFinalized = false;
|
||||
|
||||
for (auto srg:m_cachedDrawSrg)
|
||||
{
|
||||
srg->ResetViews();
|
||||
}
|
||||
}
|
||||
|
||||
const RHI::PipelineState* DynamicDrawContext::GetCurrentPipelineState()
|
||||
|
||||
@@ -107,30 +107,13 @@ namespace AZ
|
||||
dispatchArgs.m_totalNumberOfThreadsY = passData->m_totalNumberOfThreadsY;
|
||||
dispatchArgs.m_totalNumberOfThreadsZ = passData->m_totalNumberOfThreadsZ;
|
||||
|
||||
const auto numThreads = m_shader->GetAsset()->GetAttribute(RHI::ShaderStage::Compute, Name{ "numthreads" });
|
||||
if (numThreads)
|
||||
const auto outcome = RPI::GetComputeShaderNumThreads(m_shader->GetAsset(), dispatchArgs);
|
||||
if (!outcome.IsSuccess())
|
||||
{
|
||||
const RHI::ShaderStageAttributeArguments& args = *numThreads;
|
||||
bool validArgs = args.size() == 3;
|
||||
if (validArgs)
|
||||
{
|
||||
validArgs &= args[0].type() == azrtti_typeid<int>();
|
||||
validArgs &= args[1].type() == azrtti_typeid<int>();
|
||||
validArgs &= args[2].type() == azrtti_typeid<int>();
|
||||
}
|
||||
|
||||
if (!validArgs)
|
||||
{
|
||||
AZ_Error("PassSystem", false, "[ComputePass '%s']: Shader '%s' contains invalid numthreads arguments.",
|
||||
GetPathName().GetCStr(),
|
||||
passData->m_shaderReference.m_filePath.data());
|
||||
return;
|
||||
}
|
||||
|
||||
dispatchArgs.m_threadsPerGroupX = aznumeric_cast<uint16_t>(AZStd::any_cast<int>(args[0]));
|
||||
dispatchArgs.m_threadsPerGroupY = aznumeric_cast<uint16_t>(AZStd::any_cast<int>(args[1]));
|
||||
dispatchArgs.m_threadsPerGroupZ = aznumeric_cast<uint16_t>(AZStd::any_cast<int>(args[2]));
|
||||
AZ_Error("PassSystem", false, "[ComputePass '%s']: Shader '%.*s' contains invalid numthreads arguments:\n%s",
|
||||
GetPathName().GetCStr(), passData->m_shaderReference.m_filePath.size(), passData->m_shaderReference.m_filePath.data(), outcome.GetError().c_str());
|
||||
}
|
||||
|
||||
m_dispatchItem.m_arguments = dispatchArgs;
|
||||
|
||||
m_isFullscreenPass = passData->m_makeFullscreenPass;
|
||||
|
||||
@@ -263,7 +263,7 @@ namespace AZ
|
||||
AZ::TickRequestBus::BroadcastResult(m_tickTime.m_gameDeltaTime, &AZ::TickRequestBus::Events::GetTickDeltaTime);
|
||||
ScriptTimePoint currentTime;
|
||||
AZ::TickRequestBus::BroadcastResult(currentTime, &AZ::TickRequestBus::Events::GetTimeAtCurrentTick);
|
||||
m_tickTime.m_currentGameTime = static_cast<float>(currentTime.GetMilliseconds());
|
||||
m_tickTime.m_currentGameTime = static_cast<float>(currentTime.GetSeconds());
|
||||
}
|
||||
|
||||
void RPISystem::RenderTick()
|
||||
|
||||
@@ -143,5 +143,79 @@ namespace AZ
|
||||
|
||||
return RPI::StreamingImage::FindOrCreate(streamingImageAsset);
|
||||
}
|
||||
|
||||
//! A helper function for GetComputeShaderNumThreads(), to consolidate error messages, etc.
|
||||
static bool GetAttributeArgumentByIndex(const Data::Asset<ShaderAsset>& shaderAsset, const AZ::Name& attributeName, const RHI::ShaderStageAttributeArguments& args, const size_t argIndex, uint16_t* value, AZStd::string& errorMsg)
|
||||
{
|
||||
if (value)
|
||||
{
|
||||
const auto numArguments = args.size();
|
||||
if (numArguments > argIndex)
|
||||
{
|
||||
if (args[argIndex].type() == azrtti_typeid<int>())
|
||||
{
|
||||
*value = aznumeric_caster(AZStd::any_cast<int>(args[argIndex]));
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg = AZStd::string::format("Was expecting argument '%zu' in attribute '%s' to be of type 'int' from shader asset '%s'", argIndex, attributeName.GetCStr(), shaderAsset.GetHint().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMsg = AZStd::string::format("Was expecting at least '%zu' arguments in attribute '%s' from shader asset '%s'", argIndex + 1, attributeName.GetCStr(), shaderAsset.GetHint().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> GetComputeShaderNumThreads(const Data::Asset<ShaderAsset>& shaderAsset, const AZ::Name& attributeName, uint16_t* numThreadsX, uint16_t* numThreadsY, uint16_t* numThreadsZ)
|
||||
{
|
||||
// Set default 1, 1, 1 now. In case of errors later this is what the caller will get.
|
||||
if (numThreadsX)
|
||||
{
|
||||
*numThreadsX = 1;
|
||||
}
|
||||
if (numThreadsY)
|
||||
{
|
||||
*numThreadsY = 1;
|
||||
}
|
||||
if (numThreadsZ)
|
||||
{
|
||||
*numThreadsZ = 1;
|
||||
}
|
||||
const auto numThreads = shaderAsset->GetAttribute(RHI::ShaderStage::Compute, attributeName);
|
||||
if (!numThreads)
|
||||
{
|
||||
return AZ::Failure(AZStd::string::format("Couldn't find attribute '%s' in shader asset '%s'", attributeName.GetCStr(), shaderAsset.GetHint().c_str()));
|
||||
}
|
||||
const RHI::ShaderStageAttributeArguments& args = *numThreads;
|
||||
AZStd::string errorMsg;
|
||||
if (!GetAttributeArgumentByIndex(shaderAsset, attributeName, args, 0, numThreadsX, errorMsg))
|
||||
{
|
||||
return AZ::Failure(errorMsg);
|
||||
}
|
||||
if (!GetAttributeArgumentByIndex(shaderAsset, attributeName, args, 1, numThreadsY, errorMsg))
|
||||
{
|
||||
return AZ::Failure(errorMsg);
|
||||
}
|
||||
if (!GetAttributeArgumentByIndex(shaderAsset, attributeName, args, 2, numThreadsZ, errorMsg))
|
||||
{
|
||||
return AZ::Failure(errorMsg);
|
||||
}
|
||||
return AZ::Success();
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> GetComputeShaderNumThreads(const Data::Asset<ShaderAsset>& shaderAsset, uint16_t* numThreadsX, uint16_t* numThreadsY, uint16_t* numThreadsZ)
|
||||
{
|
||||
return GetComputeShaderNumThreads(shaderAsset, Name{ "numthreads" }, numThreadsX, numThreadsY, numThreadsZ);
|
||||
}
|
||||
|
||||
AZ::Outcome<void, AZStd::string> GetComputeShaderNumThreads(const Data::Asset<ShaderAsset>& shaderAsset, RHI::DispatchDirect& dispatchDirect)
|
||||
{
|
||||
return GetComputeShaderNumThreads(shaderAsset, &dispatchDirect.m_threadsPerGroupX, &dispatchDirect.m_threadsPerGroupY, &dispatchDirect.m_threadsPerGroupZ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -375,12 +375,10 @@ namespace AZ
|
||||
m_scene->RemoveRenderPipeline(m_nameId);
|
||||
}
|
||||
|
||||
void RenderPipeline::OnStartFrame(const TickTimeInfo& tick)
|
||||
void RenderPipeline::OnStartFrame([[maybe_unused]] const TickTimeInfo& tick)
|
||||
{
|
||||
AZ_PROFILE_SCOPE(RPI, "RenderPipeline: OnStartFrame");
|
||||
|
||||
m_lastRenderStartTime = tick.m_currentGameTime;
|
||||
|
||||
OnPassModified();
|
||||
|
||||
for (auto& viewItr : m_pipelineViewsByTag)
|
||||
|
||||
@@ -114,6 +114,10 @@ namespace AZ
|
||||
void ShaderResourceGroup::Compile()
|
||||
{
|
||||
m_shaderResourceGroup->Compile(m_data);
|
||||
|
||||
//Disable compilation for all resource types as a performance optimization
|
||||
//No need to re-update SRG data on GPU timeline if nothing was updated.
|
||||
m_data.DisableCompilationForAllResourceTypes();
|
||||
}
|
||||
|
||||
bool ShaderResourceGroup::IsQueuedForCompile() const
|
||||
@@ -580,6 +584,11 @@ namespace AZ
|
||||
return {};
|
||||
}
|
||||
|
||||
void ShaderResourceGroup::ResetViews()
|
||||
{
|
||||
m_data.ResetViews();
|
||||
}
|
||||
|
||||
const RHI::SamplerState& ShaderResourceGroup::GetSampler(RHI::ShaderInputNameIndex& inputIndex, uint32_t arrayIndex) const
|
||||
{
|
||||
inputIndex.ValidateOrFindSamplerIndex(GetLayout());
|
||||
|
||||
@@ -53,16 +53,6 @@ namespace UnitTest
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* AssetSystemStub::GetAbsoluteDevGameFolderPath()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char* AssetSystemStub::GetAbsoluteDevRootFolderPath()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AssetSystemStub::GetRelativeProductPathFromFullSourceOrProductPath([[maybe_unused]] const AZStd::string& fullPath, [[maybe_unused]] AZStd::string& relativeProductPath)
|
||||
{
|
||||
return false;
|
||||
|
||||
@@ -56,8 +56,6 @@ namespace UnitTest
|
||||
AZStd::unordered_map<AZStd::string, SourceInfo> m_sourceInfoMap;
|
||||
|
||||
bool GetSourceInfoBySourcePath(const char* sourcePath, AZ::Data::AssetInfo& assetInfo, AZStd::string& watchFolder) override;
|
||||
const char* GetAbsoluteDevGameFolderPath() override;
|
||||
const char* GetAbsoluteDevRootFolderPath() override;
|
||||
bool GetRelativeProductPathFromFullSourceOrProductPath(const AZStd::string& fullPath, AZStd::string& relativeProductPath) override;
|
||||
bool GenerateRelativeSourcePath(
|
||||
const AZStd::string& sourcePath, AZStd::string& relativePath, AZStd::string& watchFolder) override;
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace UnitTest
|
||||
void EndFrameInternal() override {}
|
||||
void WaitForIdleInternal() override {}
|
||||
void CompileMemoryStatisticsInternal(AZ::RHI::MemoryStatisticsBuilder&) override {}
|
||||
void UpdateCpuTimingStatisticsInternal([[maybe_unused]] AZ::RHI::CpuTimingStatistics& cpuTimingStatistics) const override {}
|
||||
void UpdateCpuTimingStatisticsInternal() const override {}
|
||||
AZStd::chrono::microseconds GpuTimestampToMicroseconds([[maybe_unused]] uint64_t gpuTimestamp, [[maybe_unused]] AZ::RHI::HardwareQueueClass queueClass) const override
|
||||
{
|
||||
return AZStd::chrono::microseconds();
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace UnitTest
|
||||
|
||||
AZ::IO::Path assetPath = AZStd::string_view{ AZ::Utils::GetProjectPath() };
|
||||
assetPath /= "Cache";
|
||||
AZ::IO::FileIOBase::GetInstance()->SetAlias("@assets@", assetPath.c_str());
|
||||
AZ::IO::FileIOBase::GetInstance()->SetAlias("@products@", assetPath.c_str());
|
||||
|
||||
m_jsonRegistrationContext = AZStd::make_unique<AZ::JsonRegistrationContext>();
|
||||
m_jsonSystemComponent = AZStd::make_unique<AZ::JsonSystemComponent>();
|
||||
@@ -90,7 +90,7 @@ namespace UnitTest
|
||||
JobManagerThreadDesc threadDesc;
|
||||
#if AZ_TRAIT_SET_JOB_PROCESSOR_ID
|
||||
threadDesc.m_cpuId = 0; // Don't set processors IDs on windows
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint32_t numWorkerThreads = AZStd::thread::hardware_concurrency();
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace UnitTest
|
||||
desc.m_workerThreads.push_back(threadDesc);
|
||||
#if AZ_TRAIT_SET_JOB_PROCESSOR_ID
|
||||
threadDesc.m_cpuId++;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
m_jobManager = AZStd::make_unique<JobManager>(desc);
|
||||
|
||||
Reference in New Issue
Block a user