Merge branch 'development' into ExposeLodControls

This commit is contained in:
Kyle Birnbaum
2021-08-20 12:45:00 -07:00
committed by GitHub
3092 changed files with 61511 additions and 87536 deletions
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="AZ::RPI::ShaderOptionGroup">
<DisplayString>shader option group</DisplayString>
<Expand>
<Item Name="id">m_id.m_key</Item>
<CustomListItems>
<Variable Name="iOption" InitialValue="-1" /><Loop>
<Break Condition="iOption &gt;= m_layout.px-&gt;m_options.m_last - m_layout.px-&gt;m_options.m_start - 1" />
<Exec>iOption++</Exec>
<!-- Thanks to the fact that options don't cross 32-bit boundaries, the following equation works -->
<!-- < "{ shader option name for option iOption }">(( the word in the bitset that corresponds to this option >> ( bit offset, adjusted by the corresponding word ))) & (( bit mask )) + ( this option's min value )</Item>-->
<!-- < "{m_layout.px -> m_options[iOption].m_name.m_data.px -> m_name}">((m_id.m_key.m_bits[(int) (m_layout.px -> m_options[iOption].m_bitOffset / m_id.m_key.BitsPerWord)] >> (m_layout.px -> m_options[iOption].m_bitOffset - ((int) (m_layout.px -> m_options[iOption].m_bitOffset / 32) * 32))) & ((1u << (m_layout.px -> m_options[iOption].m_bitCount)) - 1u)) + (m_layout.px-&gt;m_options[iOption].m_minValue.m_index)</Item>-->
<Item Name="{m_layout.px-&gt;m_options[iOption].m_name.m_data.px-&gt;m_name}">((m_id.m_key.m_bits[(int) (m_layout.px-&gt;m_options[iOption].m_bitOffset / m_id.m_key.BitsPerWord)] &gt;&gt; (m_layout.px-&gt;m_options[iOption].m_bitOffset - ((int) (m_layout.px-&gt;m_options[iOption].m_bitOffset / 32) * 32))) &amp; ((1u &lt;&lt; (m_layout.px-&gt;m_options[iOption].m_bitCount)) - 1u)) + (m_layout.px-&gt;m_options[iOption].m_minValue.m_index)</Item>
</Loop>
</CustomListItems>
</Expand>
</Type>
</AutoVisualizer>
@@ -9,4 +9,5 @@
set(FILES
Atom_RPI_Traits_Platform.h
Atom_RPI_Traits_Windows.h
../Common/VisualStudio/Natvis/shaderoptiongroup.natvis
)
@@ -882,7 +882,7 @@ namespace AZ
processedMorphTargets = true;
}
totalVertexCount += vertexCount;
totalVertexCount += static_cast<uint32_t>(vertexCount);
productMeshList.emplace_back(productMesh);
}
}
@@ -960,7 +960,7 @@ namespace AZ
for (const auto& skinData : sourceMesh.m_skinData)
{
const size_t numJoints = skinData->GetBoneCount();
const AZ::u32 controlPointIndex = sourceMeshData->GetControlPointIndex(vertexIndex);
const AZ::u32 controlPointIndex = sourceMeshData->GetControlPointIndex(static_cast<int>(vertexIndex));
const size_t numSkinInfluences = skinData->GetLinkCount(controlPointIndex);
size_t numInfluencesExcess = 0;
@@ -1195,15 +1195,15 @@ namespace AZ
mesh.m_skinWeights.size(), m_numSkinJointInfluencesPerVertex, m_numSkinJointInfluencesPerVertex);
const size_t numSkinInfluences = mesh.m_skinWeights.size();
uint32_t jointIndicesSizeInBytes = numSkinInfluences * sizeof(uint16_t);
uint32_t jointIndicesSizeInBytes = static_cast<uint32_t>(numSkinInfluences * sizeof(uint16_t));
meshView.m_skinJointIndicesView = RHI::BufferViewDescriptor::CreateRaw(0, jointIndicesSizeInBytes);
meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(0, numSkinInfluences, SkinWeightFormat);
meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(0, static_cast<uint32_t>(numSkinInfluences), SkinWeightFormat);
}
if (!mesh.m_morphTargetVertexData.empty())
{
const size_t numTotalVertices = mesh.m_morphTargetVertexData.size();
meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(0, numTotalVertices, sizeof(PackedCompressedMorphTargetDelta));
meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(0, static_cast<uint32_t>(numTotalVertices), sizeof(PackedCompressedMorphTargetDelta));
}
if (!mesh.m_clothData.empty())
@@ -1235,7 +1235,8 @@ namespace AZ
// ProductMesh. That large buffer gets set on the LOD directly
// rather than a Mesh in the LOD.
ProductMeshContentAllocInfo lodBufferInfo;
bool isFirstMesh = true;
for (const ProductMeshContent& mesh : lodMeshList)
{
if (lodBufferInfo.m_uvSetFloatCounts.size() < mesh.m_uvSets.size())
@@ -1347,6 +1348,14 @@ namespace AZ
if (!mesh.m_skinJointIndices.empty() && !mesh.m_skinWeights.empty())
{
if (!isFirstMesh && lodBufferInfo.m_skinInfluencesCount == 0)
{
AZ_Error(
s_builderName, false,
"Attempting to merge a mix of static and skinned meshes, this will fail on buffer generation later. Mesh with "
"name %s is skinned, but previous meshes were not skinned.",
mesh.m_name.GetCStr());
}
AZ_Assert(mesh.m_skinJointIndices.size() == mesh.m_skinWeights.size(),
"Number of skin influence joint indices (%d) should match the number of weights (%d).",
mesh.m_skinJointIndices.size(), mesh.m_skinWeights.size());
@@ -1358,23 +1367,29 @@ namespace AZ
const size_t numPrevSkinInfluences = lodBufferInfo.m_skinInfluencesCount;
const size_t numNewSkinInfluences = mesh.m_skinWeights.size();
meshView.m_skinJointIndicesView = RHI::BufferViewDescriptor::CreateRaw(/*byteOffset=*/numPrevSkinInfluences * sizeof(uint16_t), numNewSkinInfluences * sizeof(uint16_t));
meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(/*elementOffset=*/numPrevSkinInfluences, numNewSkinInfluences, SkinWeightFormat);
meshView.m_skinJointIndicesView = RHI::BufferViewDescriptor::CreateRaw(/*byteOffset=*/ static_cast<uint32_t>(numPrevSkinInfluences * sizeof(uint16_t)), static_cast<uint32_t>(numNewSkinInfluences * sizeof(uint16_t)));
meshView.m_skinWeightsView = RHI::BufferViewDescriptor::CreateTyped(/*elementOffset=*/ static_cast<uint32_t>(numPrevSkinInfluences), static_cast<uint32_t>(numNewSkinInfluences), SkinWeightFormat);
lodBufferInfo.m_skinInfluencesCount += numNewSkinInfluences;
}
else if (lodBufferInfo.m_skinInfluencesCount > 0)
{
AZ_Error(s_builderName, false, "Attempting to merge a mix of static and skinned meshes, this will fail on buffer generation later. Mesh with name %s is not skinned, but previous meshes were skinned.",
mesh.m_name.GetCStr());
}
if (!mesh.m_morphTargetVertexData.empty())
{
const size_t numPrevVertexDeltas = lodBufferInfo.m_morphTargetVertexDeltaCount;
const size_t numNewVertexDeltas = mesh.m_morphTargetVertexData.size();
meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(/*elementOffset=*/numPrevVertexDeltas, numNewVertexDeltas, sizeof(PackedCompressedMorphTargetDelta));
meshView.m_morphTargetVertexDataView = RHI::BufferViewDescriptor::CreateStructured(/*elementOffset=*/ static_cast<uint32_t>(numPrevVertexDeltas), static_cast<uint32_t>(numNewVertexDeltas), sizeof(PackedCompressedMorphTargetDelta));
lodBufferInfo.m_morphTargetVertexDeltaCount += numNewVertexDeltas;
}
meshViews.emplace_back(AZStd::move(meshView));
isFirstMesh = false;
}
// Now that we have the views settled, we can just merge the mesh
@@ -1807,7 +1822,7 @@ namespace AZ
if (iter != materialAssetsByUid.end())
{
ModelMaterialSlot materialSlot;
materialSlot.m_stableId = meshView.m_materialUid;
materialSlot.m_stableId = static_cast<AZ::RPI::ModelMaterialSlot::StableId>(meshView.m_materialUid);
materialSlot.m_displayName = iter->second.m_name;
materialSlot.m_defaultMaterialAsset = iter->second.m_asset;
@@ -110,8 +110,8 @@ namespace AZ::RPI
{
AZ::Aabb meshAabb = AZ::Aabb::CreateNull();
const size_t numVertices = mesh.m_meshData->GetVertexCount();
for (size_t i = 0; i < numVertices; ++i)
const unsigned int numVertices = static_cast<unsigned int>(mesh.m_meshData->GetVertexCount());
for (unsigned int i = 0; i < numVertices; ++i)
{
meshAabb.AddPoint(mesh.m_meshData->GetPosition(i));
}
@@ -159,12 +159,17 @@ namespace AZ::RPI
// Determine the vertex index range for the morph target.
const uint32_t numVertices = blendShapeData->GetVertexCount();
AZ_Assert(blendShapeData->GetVertexCount() == sourceMesh.m_meshData->GetVertexCount(),
"Blend shape (%s) contains more/less vertices (%d) than the neutral mesh (%d).",
blendShapeName.c_str(), numVertices, sourceMesh.m_meshData->GetVertexCount());
if (blendShapeData->GetVertexCount() != sourceMesh.m_meshData->GetVertexCount())
{
AZ_Error(ModelAssetBuilderComponent::s_builderName, false,
"Skipping blend shape (%s) as it contains more/less vertices (%d) than the neutral mesh (%d). "
"The blend shape is most likely influencing multiple meshes, which is currently not supported.",
blendShapeName.c_str(), numVertices, sourceMesh.m_meshData->GetVertexCount());
return;
}
// The start index is after any previously added deltas
metaData.m_startIndex = aznumeric_caster<uint32_t>(packedCompressedMorphTargetVertexData.size());
metaData.m_startIndex = aznumeric_cast<uint32_t>(packedCompressedMorphTargetVertexData.size());
// Multiply normal by inverse transpose to avoid incorrect values produced by non-uniformly scaled transforms.
@@ -37,7 +37,7 @@ namespace AZ
{
AssetBuilderSDK::AssetBuilderDesc builder;
builder.m_name = PassBuilderJobKey;
builder.m_version = 12; // ATOM-15472
builder.m_version = 13; // antonmic: making .pass files declare dependency on shaders they reference
builder.m_busId = azrtti_typeid<PassBuilder>();
builder.m_createJobFunction = AZStd::bind(&PassBuilder::CreateJobs, this, AZStd::placeholders::_1, AZStd::placeholders::_2);
builder.m_processJobFunction = AZStd::bind(&PassBuilder::ProcessJob, this, AZStd::placeholders::_1, AZStd::placeholders::_2);
@@ -65,36 +65,52 @@ namespace AZ
m_isShuttingDown = true;
}
void PassBuilder::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) const
// --- Code related to dependency shader asset handling ---
// Helper class to pass parameters to the AddDependency and FindReferencedAssets functions below
struct FindPassReferenceAssetParams
{
if (m_isShuttingDown)
void* passAssetObject = nullptr;
Uuid passAssetUuid;
SerializeContext* serializeContext = nullptr;
AZStd::string_view passAssetSourceFile; // File path of the pass asset
AZStd::string_view dependencySourceFile; // File pass of the asset the pass asset depends on
const char* jobKey = nullptr; // Job key for adding job dependency
};
// Helper function to get a file reference and create a corresponding job dependency
bool AddDependency(FindPassReferenceAssetParams& params, AssetBuilderSDK::JobDescriptor* job)
{
AZStd::string_view& file = params.dependencySourceFile;
AZ::Data::AssetInfo sourceInfo;
AZStd::string watchFolder;
bool fileFound = false;
AzToolsFramework::AssetSystemRequestBus::BroadcastResult(fileFound, &AzToolsFramework::AssetSystem::AssetSystemRequest::GetSourceInfoBySourcePath, file.data(), sourceInfo, watchFolder);
if (fileFound)
{
response.m_result = AssetBuilderSDK::CreateJobsResultCode::ShuttingDown;
return;
AssetBuilderSDK::JobDependency jobDependency;
jobDependency.m_jobKey = params.jobKey;
jobDependency.m_type = AssetBuilderSDK::JobDependencyType::Order;
jobDependency.m_sourceFile.m_sourceFileDependencyPath = file;
job->m_jobDependencyList.push_back(jobDependency);
AZ_TracePrintf(PassBuilderName, "Creating job dependency on file [%s] \n", file.data());
return true;
}
for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms)
else
{
AssetBuilderSDK::JobDescriptor job;
job.m_jobKey = PassBuilderJobKey;
job.SetPlatformIdentifier(platformInfo.m_identifier.c_str());
// Passes are a critical part of the rendering system
job.m_critical = true;
response.m_createJobOutputs.push_back(job);
AZ_Error(PassBuilderName, false, "Could not find referenced file [%s]", file.data());
return false;
}
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
}
// Helper function to find all assetId's and object references
bool PassBuilder::FindPassReferencedAssets(void* objectPtr, Uuid passAssetUuid, SerializeContext* context, AZStd::unordered_set<Data::AssetId> &referencedAssetList) const
bool FindReferencedAssets(FindPassReferenceAssetParams& params, AssetBuilderSDK::JobDescriptor* job)
{
SerializeContext::ErrorHandler errorLogger;
errorLogger.Reset();
bool foundProblems = false;
bool success = true;
// This callback will check whether the given element is an asset reference. If so, it will add it to the list of asset references
auto beginCallback = [&](void* ptr, const SerializeContext::ClassData* classData, [[maybe_unused]] const SerializeContext::ClassElement* classElement)
@@ -103,30 +119,33 @@ namespace AZ
if (classData->m_typeId == azrtti_typeid<AssetReference>())
{
AssetReference* assetReference = reinterpret_cast<AssetReference*>(ptr);
// If the asset id isn't already provided, get it using the source file path
if (!assetReference->m_assetId.IsValid() && !assetReference->m_filePath.empty())
{
AZStd::string path = assetReference->m_filePath;
const AZStd::string& path = assetReference->m_filePath;
uint32_t subId = 0;
auto assetIdOutcome = AssetUtils::MakeAssetId(path, subId);
if (job != nullptr) // Create Job Phase
{
params.dependencySourceFile = path;
bool dependencyAddedSuccessfully = AddDependency(params, job);
success = dependencyAddedSuccessfully && success;
}
else // Process Job Phase
{
auto assetIdOutcome = AssetUtils::MakeAssetId(path, subId);
if (assetIdOutcome)
{
assetReference->m_assetId = assetIdOutcome.GetValue();
if (assetIdOutcome)
{
assetReference->m_assetId = assetIdOutcome.GetValue();
}
else
{
AZ_Error(PassBuilderName, false, "Could not get AssetId for [%s]", assetReference->m_filePath.c_str());
success = false;
}
}
else
{
AZ_Error(PassBuilderName, false, "Could not get AssetId for [%s]", assetReference->m_filePath.c_str());
foundProblems = true;
}
}
// If the asset ID is valid, add it as a dependency
if (assetReference->m_assetId.IsValid())
{
referencedAssetList.insert(assetReference->m_assetId);
}
}
return true;
@@ -136,26 +155,100 @@ namespace AZ
SerializeContext::EnumerateInstanceCallContext callContext(
AZStd::move(beginCallback),
nullptr,
context,
params.serializeContext,
SerializeContext::ENUM_ACCESS_FOR_READ,
&errorLogger
);
// Recursively iterate over all elements in the object to find asset references with the above callback
context->EnumerateInstance(
params.serializeContext->EnumerateInstance(
&callContext
, objectPtr
, passAssetUuid
, params.passAssetObject
, params.passAssetUuid
, nullptr
, nullptr
);
return !foundProblems;
return success;
}
// --- Code related to dependency shader asset handling ---
void PassBuilder::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) const
{
// --- Handle shutdown case ---
if (m_isShuttingDown)
{
response.m_result = AssetBuilderSDK::CreateJobsResultCode::ShuttingDown;
return;
}
// --- Get serialization context ---
SerializeContext* serializeContext = nullptr;
ComponentApplicationBus::BroadcastResult(serializeContext, &ComponentApplicationBus::Events::GetSerializeContext);
if (!serializeContext)
{
AZ_Assert(false, "No serialize context");
return;
}
// --- Load PassAsset ---
AZStd::string fullPath;
AzFramework::StringFunc::Path::ConstructFull(request.m_watchFolder.c_str(), request.m_sourceFile.c_str(), fullPath, true);
PassAsset passAsset;
AZ::Outcome<void, AZStd::string> loadResult = JsonSerializationUtils::LoadObjectFromFile(passAsset, fullPath);
if (!loadResult.IsSuccess())
{
AZ_Error(PassBuilderName, false, "Failed to load pass asset [%s]", request.m_sourceFile.c_str());
AZ_Error(PassBuilderName, false, "Loading issues: %s", loadResult.GetError().data());
return;
}
AssetBuilderSDK::JobDescriptor job;
job.m_jobKey = PassBuilderJobKey;
job.m_critical = true; // Passes are a critical part of the rendering system
// --- Find all dependencies ---
AZStd::unordered_set<Data::AssetId> dependentList;
Uuid passAssetUuid = AzTypeInfo<PassAsset>::Uuid();
FindPassReferenceAssetParams params;
params.passAssetObject = &passAsset;
params.passAssetSourceFile = request.m_sourceFile;
params.passAssetUuid = passAssetUuid;
params.serializeContext = serializeContext;
params.jobKey = "Shader Asset";
if (!FindReferencedAssets(params, &job))
{
return;
}
// --- Create a job per platform ---
for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms)
{
for (auto& jobDependency : job.m_jobDependencyList)
{
jobDependency.m_platformIdentifier = platformInfo.m_identifier.c_str();
}
job.SetPlatformIdentifier(platformInfo.m_identifier.c_str());
response.m_createJobOutputs.push_back(job);
}
response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success;
}
void PassBuilder::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) const
{
// Handle job cancellation and shutdown cases
// --- Handle job cancellation and shutdown cases ---
AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId);
if (jobCancelListener.IsCancelled() || m_isShuttingDown)
{
@@ -163,16 +256,18 @@ namespace AZ
return;
}
// Get serialization context
SerializeContext* context = nullptr;
ComponentApplicationBus::BroadcastResult(context, &ComponentApplicationBus::Events::GetSerializeContext);
if (!context)
// --- Get serialization context ---
SerializeContext* serializeContext = nullptr;
ComponentApplicationBus::BroadcastResult(serializeContext, &ComponentApplicationBus::Events::GetSerializeContext);
if (!serializeContext)
{
AZ_Assert(false, "No serialize context");
return;
}
// Load PassAsset
// --- Load PassAsset ---
PassAsset passAsset;
AZ::Outcome<void, AZStd::string> loadResult = JsonSerializationUtils::LoadObjectFromFile(passAsset, request.m_fullPath);
@@ -183,36 +278,42 @@ namespace AZ
return;
}
// Find all Asset IDs we depend on
AZStd::unordered_set<Data::AssetId> dependentList;
// --- Find all dependencies ---
Uuid passAssetUuid = AzTypeInfo<PassAsset>::Uuid();
if (!FindPassReferencedAssets(&passAsset, passAssetUuid, context, dependentList))
FindPassReferenceAssetParams params;
params.passAssetObject = &passAsset;
params.passAssetSourceFile = request.m_sourceFile;
params.passAssetUuid = passAssetUuid;
params.serializeContext = serializeContext;
params.jobKey = "Shader Asset";
if (!FindReferencedAssets(params, nullptr))
{
return;
}
// Get destination file name and path
// --- Get destination file name and path ---
AZStd::string destFileName;
AZStd::string destPath;
AzFramework::StringFunc::Path::GetFullFileName(request.m_fullPath.c_str(), destFileName);
AzFramework::StringFunc::Path::ConstructFull(request.m_tempDirPath.c_str(), destFileName.c_str(), destPath, true);
// Save the asset to binary format for production
bool result = Utils::SaveObjectToFile(destPath, DataStream::ST_BINARY, &passAsset, passAssetUuid, context);
// --- Save the asset to binary format for production ---
bool result = Utils::SaveObjectToFile(destPath, DataStream::ST_BINARY, &passAsset, passAssetUuid, serializeContext);
if (result == false)
{
AZ_Error(PassBuilderName, false, "Failed to save asset to %s", destPath.c_str());
return;
}
// Success. Save output product(s) to response
AssetBuilderSDK::JobProduct jobProduct(destPath, PassAsset::RTTI_Type(), 0);
for (auto& assetId : dependentList)
{
jobProduct.m_dependencies.emplace_back(AssetBuilderSDK::ProductDependency(assetId, 0));
}
// --- Save output product(s) to response ---
jobProduct.m_dependenciesHandled = true; // We've output the dependencies immediately above so it's OK to tell the AP we've handled dependencies
AssetBuilderSDK::JobProduct jobProduct(destPath, PassAsset::RTTI_Type(), 0);
jobProduct.m_dependenciesHandled = true;
response.m_outputProducts.push_back(jobProduct);
response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success;
}
@@ -37,7 +37,6 @@ namespace AZ
void RegisterBuilder();
private:
bool FindPassReferencedAssets(void* objectPtr, Uuid passAssetUuid, SerializeContext* context, AZStd::unordered_set<Data::AssetId> &referencedAssetList) const;
bool m_isShuttingDown = false;
};
@@ -299,7 +299,7 @@ namespace AZ
//work function
void Process() override
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
const View::UsageFlags viewFlags = m_jobData->m_view->GetUsageFlags();
const RHI::DrawListMask drawListMask = m_jobData->m_view->GetDrawListMask();
@@ -312,7 +312,7 @@ namespace AZ
bool nodeIsContainedInFrustum = ShapeIntersection::Contains(m_jobData->m_frustum, nodeData.m_bounds);
#ifdef AZ_CULL_PROFILE_VERBOSE
AZ_PROFILE_SCOPE_DYNAMIC(Debug::ProfileCategory::AzRender, "process node (view: %s, skip fine cull: %d",
AZ_PROFILE_SCOPE(AzRender, "process node (view: %s, skip fine cull: %d",
m_view->GetName().GetCStr(), nodeIsContainedInFrustum ? 1 : 0);
#endif
@@ -385,7 +385,7 @@ namespace AZ
if (m_jobData->m_debugCtx->m_debugDraw && (m_jobData->m_view->GetName() == m_jobData->m_debugCtx->m_currentViewSelectionName))
{
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "debug draw culling");
AZ_PROFILE_SCOPE(AzRender, "debug draw culling");
AuxGeomDrawPtr auxGeomPtr = AuxGeomFeatureProcessorInterface::GetDrawQueueForScene(m_jobData->m_scene);
if (auxGeomPtr)
@@ -507,7 +507,7 @@ namespace AZ
void CullingScene::ProcessCullables(const Scene& scene, View& view, AZ::Job& parentJob)
{
AZ_PROFILE_SCOPE_DYNAMIC(Debug::ProfileCategory::AzRender, "CullingScene::ProcessCullables() - %s", view.GetName().GetCStr());
AZ_PROFILE_SCOPE(AzRender, "CullingScene::ProcessCullables() - %s", view.GetName().GetCStr());
const Matrix4x4& worldToClip = view.GetWorldToClipMatrix();
Frustum frustum = Frustum::CreateFromMatrixColumnMajor(worldToClip);
@@ -598,7 +598,7 @@ namespace AZ
auto nodeVisitorLambda = [this, jobData, &parentJob, &frustum, &worklist](const AzFramework::IVisibilityScene::NodeData& nodeData) -> void
{
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "nodeVisitorLambda()");
AZ_PROFILE_SCOPE(AzRender, "nodeVisitorLambda()");
AZ_Assert(nodeData.m_entries.size() > 0, "should not get called with 0 entries");
AZ_Assert(worklist.size() < worklist.capacity(), "we should always have room to push a node on the queue");
@@ -645,7 +645,7 @@ namespace AZ
uint32_t AddLodDataToView(const Vector3& pos, const Cullable::LodData& lodData, RPI::View& view)
{
#ifdef AZ_CULL_PROFILE_DETAILED
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
#endif
const Matrix4x4& viewToClip = view.GetViewToClipMatrix();
@@ -663,7 +663,7 @@ namespace AZ
auto addLodToDrawPacket = [&](const Cullable::LodData::Lod& lod)
{
#ifdef AZ_CULL_PROFILE_VERBOSE
AZ_PROFILE_SCOPE_DYNAMIC(Debug::ProfileCategory::AzRender, "add draw packets: %zu", lod.m_drawPackets.size());
AZ_PROFILE_SCOPE(AzRender, "add draw packets: %zu", lod.m_drawPackets.size());
#endif
numVisibleDrawPackets += static_cast<uint32_t>(lod.m_drawPackets.size()); //don't want to pay the cost of aznumeric_cast<> here so using static_cast<> instead
for (const RHI::DrawPacket* drawPacket : lod.m_drawPackets)
@@ -474,10 +474,10 @@ namespace AZ
// Get dynamic buffers for vertex and index buffer. Skip draw if failed to allocate buffers
uint32_t vertexDataSize = vertexCount * m_perVertexDataSize;
RHI::Ptr<DynamicBuffer> vertexBuffer;
vertexBuffer = DynamicDrawInterface::Get()->GetDynamicBuffer(vertexDataSize);
vertexBuffer = DynamicDrawInterface::Get()->GetDynamicBuffer(vertexDataSize, RHI::Alignment::InputAssembly);
uint32_t indexDataSize = indexCount * RHI::GetIndexFormatSize(indexFormat);
RHI::Ptr<DynamicBuffer> indexBuffer = DynamicDrawInterface::Get()->GetDynamicBuffer(indexDataSize);
RHI::Ptr<DynamicBuffer> indexBuffer = DynamicDrawInterface::Get()->GetDynamicBuffer(indexDataSize, RHI::Alignment::InputAssembly);
if (indexBuffer == nullptr || vertexBuffer == nullptr)
{
@@ -572,7 +572,7 @@ namespace AZ
// Get dynamic buffers for vertex and index buffer. Skip draw if failed to allocate buffers
uint32_t vertexDataSize = vertexCount * m_perVertexDataSize;
RHI::Ptr<DynamicBuffer> vertexBuffer;
vertexBuffer = DynamicDrawInterface::Get()->GetDynamicBuffer(vertexDataSize);
vertexBuffer = DynamicDrawInterface::Get()->GetDynamicBuffer(vertexDataSize, RHI::Alignment::InputAssembly);
if (vertexBuffer == nullptr)
{
@@ -247,7 +247,7 @@ namespace AZ
uint16_t StreamingImage::GetResidentMipLevel()
{
return m_image->GetResidentMipLevel();
return static_cast<uint16_t>(m_image->GetResidentMipLevel());
}
RHI::ResultCode StreamingImage::TrimToMipChainLevel(size_t mipChainIndex)
@@ -310,7 +310,7 @@ namespace AZ
if (NeedsCompile() && CanCompile())
{
AZ_PROFILE_EVENT_BEGIN(Debug::ProfileCategory::AzRender, "Material::Compile() Processing Functors");
AZ_PROFILE_BEGIN(AzRender, "Material::Compile() Processing Functors");
for (const Ptr<MaterialFunctor>& functor : m_materialAsset->GetMaterialFunctors())
{
if (functor)
@@ -339,7 +339,7 @@ namespace AZ
AZ_Error(s_debugTraceName, false, "Material functor is null.");
}
}
AZ_PROFILE_EVENT_END(Debug::ProfileCategory::AzRender);
AZ_PROFILE_END();
m_propertyDirtyFlags.reset();
@@ -124,7 +124,7 @@ namespace AZ
bool MeshDrawPacket::DoUpdate(const Scene& parentScene)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
const ModelLod::Mesh& mesh = m_modelLod->GetMeshes()[m_modelLodMeshIndex];
if (!m_material)
@@ -155,7 +155,7 @@ namespace AZ
auto appendShader = [&](const ShaderCollection::Item& shaderItem)
{
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "appendShader()");
AZ_PROFILE_SCOPE(AzRender, "appendShader()");
// Skip the shader item without creating the shader instance
// if the mesh is not going to be rendered based on the draw tag
@@ -256,7 +256,7 @@ namespace AZ
Data::Instance<ShaderResourceGroup> drawSrg;
if (drawSrgLayout)
{
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "create drawSrg");
AZ_PROFILE_SCOPE(AzRender, "create drawSrg");
// If the DrawSrg exists we must create and bind it, otherwise the CommandList will fail validation for SRG being null
drawSrg = RPI::ShaderResourceGroup::Create(shader->GetAsset(), shader->GetSupervariantIndex(), drawSrgLayout->GetName());
@@ -42,7 +42,7 @@ namespace AZ
Data::Instance<Model> Model::CreateInternal(const Data::Asset<ModelAsset>& modelAsset)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
Data::Instance<Model> model = aznew Model();
const RHI::ResultCode resultCode = model->Init(modelAsset);
@@ -56,7 +56,7 @@ namespace AZ
RHI::ResultCode Model::Init(const Data::Asset<ModelAsset>& modelAsset)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
m_lods.resize(modelAsset->GetLodAssets().size());
@@ -107,7 +107,7 @@ namespace AZ
{
if (m_isUploadPending)
{
AZ_PROFILE_SCOPE_STALL_DYNAMIC(Debug::ProfileCategory::AzRender, "Model::WaitForUpload - %s", GetDatabaseName());
AZ_PROFILE_SCOPE(AzRender, "Model::WaitForUpload - %s", GetDatabaseName());
for (const Data::Instance<ModelLod>& lod : m_lods)
{
lod->WaitForUpload();
@@ -128,7 +128,7 @@ namespace AZ
bool Model::LocalRayIntersection(const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, float& distanceNormalized, AZ::Vector3& normal) const
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
if (!GetModelAsset())
{
@@ -171,7 +171,7 @@ namespace AZ
float& distanceNormalized,
AZ::Vector3& normal) const
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
const AZ::Vector3 clampedScale = nonUniformScale.GetMax(AZ::Vector3(AZ::MinTransformScale));
const AZ::Transform inverseTM = modelTransform.GetInverse();
@@ -264,7 +264,7 @@ namespace AZ
const MaterialModelUvOverrideMap& materialModelUvMap,
const MaterialUvNameMap& materialUvNameMap) const
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
streamBufferViewsOut.clear();
@@ -366,7 +366,7 @@ namespace AZ
const MaterialModelUvOverrideMap& materialModelUvMap,
const MaterialUvNameMap& materialUvNameMap) const
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
const Mesh& mesh = m_meshes[meshIndex];
@@ -27,7 +27,7 @@ namespace AZ
ModelLodIndex SelectLod(const View* view, const Vector3& position, const Model& model, ModelLodIndex lodOverride)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
ModelLodIndex lodIndex;
if (model.GetLodCount() == 1)
{
@@ -121,7 +121,7 @@ namespace AZ
// Load shader and srg
const char* ShaderPath = "shader/decomposemsimage.azshader";
m_decomposeShader = LoadShader(ShaderPath);
m_decomposeShader = LoadCriticalShader(ShaderPath);
if (m_decomposeShader == nullptr)
{
@@ -155,7 +155,7 @@ namespace AZ
m_item.m_arguments = RHI::DrawArguments(draw);
m_item.m_pipelineState = m_shader->AcquirePipelineState(pipelineStateDescriptor);
m_item.m_stencilRef = m_stencilRef;
m_item.m_stencilRef = static_cast<uint8_t>(m_stencilRef);
}
void FullscreenTrianglePass::FrameBeginInternal(FramePrepareParams params)
@@ -179,10 +179,10 @@ namespace AZ
RHI::Size targetImageSize = outputAttachment->m_descriptor.m_image.m_size;
m_viewportState.m_maxX = AZStd::min(static_cast<uint32_t>(params.m_viewportState.m_maxX), targetImageSize.m_width);
m_viewportState.m_maxY = AZStd::min(static_cast<uint32_t>(params.m_viewportState.m_maxY), targetImageSize.m_height);
m_viewportState.m_minX = AZStd::min(params.m_viewportState.m_minX, m_viewportState.m_maxX);
m_viewportState.m_minY = AZStd::min(params.m_viewportState.m_minY, m_viewportState.m_maxY);
m_viewportState.m_maxX = static_cast<float>(AZStd::min(static_cast<uint32_t>(params.m_viewportState.m_maxX), targetImageSize.m_width));
m_viewportState.m_maxY = static_cast<float>(AZStd::min(static_cast<uint32_t>(params.m_viewportState.m_maxY), targetImageSize.m_height));
m_viewportState.m_minX = static_cast<float>(AZStd::min(params.m_viewportState.m_minX, m_viewportState.m_maxX));
m_viewportState.m_minY = static_cast<float>(AZStd::min(params.m_viewportState.m_minY, m_viewportState.m_maxY));
m_scissorState.m_maxX = AZStd::min(static_cast<uint32_t>(params.m_scissorState.m_maxX), targetImageSize.m_width);
m_scissorState.m_maxY = AZStd::min(static_cast<uint32_t>(params.m_scissorState.m_maxY), targetImageSize.m_height);
@@ -189,7 +189,7 @@ namespace AZ
void PassSystem::BuildPasses()
{
m_state = PassSystemState::BuildingPasses;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: BuildPassAttachments");
m_passHierarchyChanged = m_passHierarchyChanged || !m_buildPassList.empty();
@@ -239,7 +239,7 @@ namespace AZ
void PassSystem::InitializePasses()
{
m_state = PassSystemState::InitializingPasses;
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: BuildPassAttachments");
m_passHierarchyChanged = m_passHierarchyChanged || !m_initializePassList.empty();
@@ -286,7 +286,7 @@ namespace AZ
return;
}
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
PassValidationResults validationResults;
m_rootPass->Validate(validationResults);
@@ -307,9 +307,10 @@ namespace AZ
void PassSystem::FrameUpdate(RHI::FrameGraphBuilder& frameGraphBuilder)
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("RPI", "PassSystem: FrameUpdate");
ResetFrameStatistics();
ProcessQueuedChanges();
m_state = PassSystemState::Rendering;
@@ -398,6 +399,29 @@ namespace AZ
handler.Connect(m_loadTemplatesEvent);
}
void PassSystem::ResetFrameStatistics()
{
m_frameStatistics.m_numRenderPassesExecuted = 0;
m_frameStatistics.m_totalDrawItemsRendered = 0;
m_frameStatistics.m_maxDrawItemsRenderedInAPass = 0;
}
PassSystemFrameStatistics PassSystem::GetFrameStatistics()
{
return m_frameStatistics;
}
void PassSystem::IncrementFrameDrawItemCount(u32 numDrawItems)
{
m_frameStatistics.m_totalDrawItemsRendered += numDrawItems;
m_frameStatistics.m_maxDrawItemsRenderedInAPass = AZStd::max(m_frameStatistics.m_maxDrawItemsRenderedInAPass, numDrawItems);
}
void PassSystem::IncrementFrameRenderPassCount()
{
++m_frameStatistics.m_numRenderPassesExecuted;
}
// --- Pass Factory Functions ---
void PassSystem::AddPassCreator(Name className, PassCreator createFunction)
@@ -104,7 +104,7 @@ namespace AZ
m_flags.m_hasDrawListTag = true;
}
void RasterPass::SetPipelineStateDataIndex(u32 index)
void RasterPass::SetPipelineStateDataIndex(uint32_t index)
{
m_pipelineStateDataIndex.m_index = index;
}
@@ -114,6 +114,11 @@ namespace AZ
return m_shaderResourceGroup.get();
}
uint32_t RasterPass::GetDrawItemCount()
{
return m_drawItemCount;
}
// --- Pass behaviour overrides ---
void RasterPass::Validate(PassValidationResults& validationResults)
@@ -154,17 +159,21 @@ namespace AZ
// Assert the view has our draw list (the view's DrawlistTags are collected from passes using its viewTag)
AZ_Assert(view->HasDrawListTag(m_drawListTag), "View's DrawListTags out of sync with pass'. ");
// Draw List
viewDrawList = view->GetDrawList(m_drawListTag);
}
// clean up data
m_drawListView = {};
m_combinedDrawList.clear();
m_drawItemCount = 0;
// draw list from view was sorted and if it's the only draw list then we can use it directly
if (viewDrawList.size() > 0 && drawLists.size() == 0)
{
m_drawListView = viewDrawList;
m_drawItemCount += static_cast<uint32_t>(viewDrawList.size());
PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
return;
}
@@ -172,12 +181,12 @@ namespace AZ
drawLists.push_back(viewDrawList);
// combine draw items from mutiple draw lists to one draw list and sort it.
size_t itemCount = 0;
for (auto drawList : drawLists)
{
itemCount += drawList.size();
m_drawItemCount += static_cast<uint32_t>(drawList.size());
}
m_combinedDrawList.resize(itemCount);
PassSystemInterface::Get()->IncrementFrameDrawItemCount(m_drawItemCount);
m_combinedDrawList.resize(m_drawItemCount);
RHI::DrawItemProperties* currentBuffer = m_combinedDrawList.data();
for (auto drawList : drawLists)
{
@@ -202,12 +211,12 @@ namespace AZ
void RasterPass::SetupFrameGraphDependencies(RHI::FrameGraphInterface frameGraph)
{
RenderPass::SetupFrameGraphDependencies(frameGraph);
frameGraph.SetEstimatedItemCount(static_cast<u32>(m_drawListView.size()));
frameGraph.SetEstimatedItemCount(static_cast<uint32_t>(m_drawListView.size()));
}
void RasterPass::CompileResources(const RHI::FrameGraphCompileContext& context)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
if (m_shaderResourceGroup == nullptr)
{
@@ -221,7 +230,7 @@ namespace AZ
void RasterPass::BuildCommandListInternal(const RHI::FrameGraphExecuteContext& context)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
RHI::CommandList* commandList = context.GetCommandList();
@@ -201,6 +201,8 @@ namespace AZ
m_attachmentCopy.lock()->FrameBegin(params);
}
CollectSrgs();
PassSystemInterface::Get()->IncrementFrameRenderPassCount();
}
@@ -270,7 +270,7 @@ namespace AZ
return;
}
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
AZ_ATOM_PROFILE_FUNCTION("RPI", "RPISystem: RenderTick");
// Query system update is to increment the frame count
@@ -349,19 +349,6 @@ namespace AZ
return;
}
//[GFX TODO][ATOM-5867] - Move file loading code within RHI to reduce coupling with RPI
AZStd::string platformLimitsFilePath = AZStd::string::format("config/platform/%s/%s/platformlimits.azasset", AZ_TRAIT_OS_PLATFORM_NAME, GetRenderApiName().GetCStr());
AZStd::to_lower(platformLimitsFilePath.begin(), platformLimitsFilePath.end());
Data::Asset<AnyAsset> platformLimitsAsset;
platformLimitsAsset = RPI::AssetUtils::LoadCriticalAsset<AnyAsset>(platformLimitsFilePath.c_str(), RPI::AssetUtils::TraceLevel::None);
// Only read the m_platformLimits if the platformLimitsAsset is ready.
// The platformLimitsAsset may not exist for null renderer which is allowed
if (platformLimitsAsset.IsReady())
{
m_descriptor.m_rhiSystemDescriptor.m_platformLimits = RPI::GetDataFromAnyAsset<RHI::PlatformLimits>(platformLimitsAsset);
}
m_commonShaderAssetForSrgs = AssetUtils::LoadCriticalAsset<ShaderAsset>( m_descriptor.m_commonSrgsShaderAssetPath.c_str());
if (!m_commonShaderAssetForSrgs.IsReady())
{
@@ -8,6 +8,7 @@
#include <Atom/RHI/RHISystemInterface.h>
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
#include <Atom/RPI.Reflect/Shader/ShaderAsset.h>
#include <Atom/RPI.Public/RPIUtils.h>
@@ -20,7 +21,7 @@ namespace AZ
namespace RPI
{
Data::AssetId GetShaderAssetId(const AZStd::string& shaderFilePath)
Data::AssetId GetShaderAssetId(const AZStd::string& shaderFilePath, bool isCritical)
{
Data::AssetId shaderAssetId;
@@ -34,6 +35,19 @@ namespace AZ
if (!shaderAssetId.IsValid())
{
if (isCritical)
{
Data::Asset<RPI::ShaderAsset> shaderAsset = RPI::AssetUtils::LoadCriticalAsset<RPI::ShaderAsset>(shaderFilePath);
if (shaderAsset.IsReady())
{
return shaderAsset.GetId();
}
else
{
AZ_Error("RPI Utils", false, "Could not load critical shader [%s]", shaderFilePath.c_str());
}
}
AZ_Error("RPI Utils", false, "Failed to get asset id for shader [%s]", shaderFilePath.c_str());
}
@@ -83,11 +97,23 @@ namespace AZ
return FindShaderAsset(GetShaderAssetId(shaderFilePath), shaderFilePath);
}
Data::Asset<ShaderAsset> FindCriticalShaderAsset(const AZStd::string& shaderFilePath)
{
const bool isCritical = true;
return FindShaderAsset(GetShaderAssetId(shaderFilePath, isCritical), shaderFilePath);
}
Data::Instance<Shader> LoadShader(const AZStd::string& shaderFilePath)
{
return LoadShader(GetShaderAssetId(shaderFilePath), shaderFilePath);
}
Data::Instance<Shader> LoadCriticalShader(const AZStd::string& shaderFilePath)
{
const bool isCritical = true;
return LoadShader(GetShaderAssetId(shaderFilePath, isCritical), shaderFilePath);
}
AZ::Data::Instance<RPI::StreamingImage> LoadStreamingTexture(AZStd::string_view path)
{
AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown;
@@ -377,7 +377,7 @@ namespace AZ
void RenderPipeline::OnStartFrame(const TickTimeInfo& tick)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
m_lastRenderStartTime = tick.m_currentGameTime;
@@ -21,6 +21,7 @@
#include <Atom/RPI.Public/View.h>
#include <AzCore/Debug/EventTrace.h>
#include <AzCore/Debug/Profiler.h>
#include <AzCore/Jobs/JobFunction.h>
#include <AzCore/Jobs/JobEmpty.h>
@@ -399,7 +400,7 @@ namespace AZ
AZ_ATOM_PROFILE_FUNCTION("RPI", "Scene: PrepareRender");
{
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "WaitForSimulationCompletion");
AZ_PROFILE_SCOPE(AzRender, "WaitForSimulationCompletion");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "WaitForSimulationCompletion");
WaitAndCleanCompletionJob(m_simulationCompletion);
}
@@ -407,7 +408,7 @@ namespace AZ
SceneNotificationBus::Event(GetId(), &SceneNotification::OnBeginPrepareRender);
{
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "m_srgCallback");
AZ_PROFILE_SCOPE(AzRender, "m_srgCallback");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "ShaderResourceGroupCallback: SrgCallback");
// Set values for scene srg
if (m_srg && m_srgCallback)
@@ -483,7 +484,7 @@ namespace AZ
}
{
AZ_PROFILE_SCOPE(Debug::ProfileCategory::AzRender, "CollectDrawPackets");
AZ_PROFILE_SCOPE(AzRender, "CollectDrawPackets");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "CollectDrawPackets");
AZ::JobCompletion* collectDrawPacketsCompletion = aznew AZ::JobCompletion();
@@ -533,7 +534,7 @@ namespace AZ
}
{
AZ_PROFILE_SCOPE(AZ::Debug::ProfileCategory::AzRender, "FinalizeDrawLists");
AZ_PROFILE_BEGIN(AzRender, "FinalizeDrawLists");
AZ_ATOM_PROFILE_TIME_GROUP_REGION("RPI", "FinalizeDrawLists");
if (jobPolicy == RHI::JobPolicy::Serial)
{
@@ -541,6 +542,7 @@ namespace AZ
{
view->FinalizeDrawLists();
}
AZ_PROFILE_END();
}
else
{
@@ -556,7 +558,7 @@ namespace AZ
finalizeDrawListsJob->SetDependent(finalizeDrawListsCompletion);
finalizeDrawListsJob->Start();
}
AZ_PROFILE_EVENT_END(Debug::ProfileCategory::AzRender);
AZ_PROFILE_END();
WaitAndCleanCompletionJob(finalizeDrawListsCompletion);
}
}
@@ -782,7 +784,7 @@ namespace AZ
pipelineStateList.push_back();
pipelineStateList[size].m_multisampleState = rasterPass->GetMultisampleState();
pipelineStateList[size].m_renderAttachmentConfiguration = rasterPass->GetRenderAttachmentConfiguration();
rasterPass->SetPipelineStateDataIndex(size);
rasterPass->SetPipelineStateDataIndex(static_cast<AZ::u32>(size));
}
}
}
@@ -113,7 +113,7 @@ namespace AZ
return;
}
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
AZStd::lock_guard<AZStd::mutex> lock(m_metricsMutex);
@@ -297,7 +297,7 @@ namespace AZ
const ShaderVariant& Shader::GetVariant(const ShaderVariantId& shaderVariantId)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
Data::Asset<ShaderVariantAsset> shaderVariantAsset = m_asset->GetVariant(shaderVariantId, m_supervariantIndex);
if (!shaderVariantAsset || shaderVariantAsset->IsRootVariant())
{
@@ -314,14 +314,14 @@ namespace AZ
ShaderVariantSearchResult Shader::FindVariantStableId(const ShaderVariantId& shaderVariantId) const
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
ShaderVariantSearchResult variantSearchResult = m_asset->FindVariantStableId(shaderVariantId);
return variantSearchResult;
}
const ShaderVariant& Shader::GetVariant(ShaderVariantStableId shaderVariantStableId)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
if (!shaderVariantStableId.IsValid() || shaderVariantStableId == ShaderAsset::RootShaderVariantStableId)
{
+40 -56
View File
@@ -126,8 +126,6 @@ namespace AZ
m_onWorldToViewMatrixChange.Signal(m_worldToViewMatrix);
m_onWorldToClipMatrixChange.Signal(m_worldToClipMatrix);
InvalidateSrg();
}
AZ::Transform View::GetCameraTransform() const
@@ -170,8 +168,6 @@ namespace AZ
m_onWorldToViewMatrixChange.Signal(m_worldToViewMatrix);
}
m_onWorldToClipMatrixChange.Signal(m_worldToClipMatrix);
InvalidateSrg();
}
void View::SetViewToClipMatrix(const AZ::Matrix4x4& viewToClip)
@@ -202,14 +198,11 @@ namespace AZ
m_unprojectionConstants.SetW(float(tanHalfFovY));
m_onWorldToClipMatrixChange.Signal(m_worldToClipMatrix);
InvalidateSrg();
}
void View::SetClipSpaceOffset(float xOffset, float yOffset)
{
m_clipSpaceOffset.Set(xOffset, yOffset);
InvalidateSrg();
}
const AZ::Matrix4x4& View::GetWorldToViewMatrix() const
@@ -244,7 +237,7 @@ namespace AZ
void View::FinalizeDrawLists()
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
m_drawListContext.FinalizeLists();
SortFinalizedDrawLists();
}
@@ -362,58 +355,49 @@ namespace AZ
return -0.25f * cotHalfFovYSq * AZ::Constants::Pi * radiusSq * sqrt(fabsf((distanceSq - radiusSq)/radiusSqSubDepthSq))/radiusSqSubDepthSq;
}
void View::InvalidateSrg()
{
m_needBuildSrg = true;
}
void View::UpdateSrg()
{
if (m_needBuildSrg)
if (m_clipSpaceOffset.IsZero())
{
if (m_clipSpaceOffset.IsZero())
{
Matrix4x4 worldToClipPrevMatrix = m_viewToClipPrevMatrix * m_worldToViewPrevMatrix;
m_shaderResourceGroup->SetConstant(m_worldToClipPrevMatrixConstantIndex, worldToClipPrevMatrix);
m_shaderResourceGroup->SetConstant(m_viewProjectionMatrixConstantIndex, m_worldToClipMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixConstantIndex, m_viewToClipMatrix);
m_shaderResourceGroup->SetConstant(m_clipToWorldMatrixConstantIndex, m_clipToWorldMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixInverseConstantIndex, m_viewToClipMatrix.GetInverseFull());
}
else
{
// Offset the current and previous frame clip matricies
Matrix4x4 offsetViewToClipMatrix = m_viewToClipMatrix;
offsetViewToClipMatrix.SetElement(0, 2, m_clipSpaceOffset.GetX());
offsetViewToClipMatrix.SetElement(1, 2, m_clipSpaceOffset.GetY());
Matrix4x4 offsetViewToClipPrevMatrix = m_viewToClipPrevMatrix;
offsetViewToClipPrevMatrix.SetElement(0, 2, m_clipSpaceOffset.GetX());
offsetViewToClipPrevMatrix.SetElement(1, 2, m_clipSpaceOffset.GetY());
// Build other matricies dependent on the view to clip matricies
Matrix4x4 offsetWorldToClipMatrix = offsetViewToClipMatrix * m_worldToViewMatrix;
Matrix4x4 offsetWorldToClipPrevMatrix = offsetViewToClipPrevMatrix * m_worldToViewPrevMatrix;
Matrix4x4 offsetClipToViewMatrix = offsetViewToClipMatrix.GetInverseFull();
Matrix4x4 offsetClipToWorldMatrix = m_viewToWorldMatrix * offsetClipToViewMatrix;
m_shaderResourceGroup->SetConstant(m_worldToClipPrevMatrixConstantIndex, offsetWorldToClipPrevMatrix);
m_shaderResourceGroup->SetConstant(m_viewProjectionMatrixConstantIndex, offsetWorldToClipMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixConstantIndex, offsetViewToClipMatrix);
m_shaderResourceGroup->SetConstant(m_clipToWorldMatrixConstantIndex, offsetClipToWorldMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixInverseConstantIndex, offsetViewToClipMatrix.GetInverseFull());
}
m_shaderResourceGroup->SetConstant(m_worldPositionConstantIndex, m_position);
m_shaderResourceGroup->SetConstant(m_viewMatrixConstantIndex, m_worldToViewMatrix);
m_shaderResourceGroup->SetConstant(m_viewMatrixInverseConstantIndex, m_worldToViewMatrix.GetInverseFull());
m_shaderResourceGroup->SetConstant(m_zConstantsConstantIndex, m_nearZ_farZ_farZTimesNearZ_farZMinusNearZ);
m_shaderResourceGroup->SetConstant(m_unprojectionConstantsIndex, m_unprojectionConstants);
m_shaderResourceGroup->Compile();
m_needBuildSrg = false;
Matrix4x4 worldToClipPrevMatrix = m_viewToClipPrevMatrix * m_worldToViewPrevMatrix;
m_shaderResourceGroup->SetConstant(m_worldToClipPrevMatrixConstantIndex, worldToClipPrevMatrix);
m_shaderResourceGroup->SetConstant(m_viewProjectionMatrixConstantIndex, m_worldToClipMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixConstantIndex, m_viewToClipMatrix);
m_shaderResourceGroup->SetConstant(m_clipToWorldMatrixConstantIndex, m_clipToWorldMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixInverseConstantIndex, m_viewToClipMatrix.GetInverseFull());
}
else
{
// Offset the current and previous frame clip matricies
Matrix4x4 offsetViewToClipMatrix = m_viewToClipMatrix;
offsetViewToClipMatrix.SetElement(0, 2, m_clipSpaceOffset.GetX());
offsetViewToClipMatrix.SetElement(1, 2, m_clipSpaceOffset.GetY());
Matrix4x4 offsetViewToClipPrevMatrix = m_viewToClipPrevMatrix;
offsetViewToClipPrevMatrix.SetElement(0, 2, m_clipSpaceOffset.GetX());
offsetViewToClipPrevMatrix.SetElement(1, 2, m_clipSpaceOffset.GetY());
// Build other matricies dependent on the view to clip matricies
Matrix4x4 offsetWorldToClipMatrix = offsetViewToClipMatrix * m_worldToViewMatrix;
Matrix4x4 offsetWorldToClipPrevMatrix = offsetViewToClipPrevMatrix * m_worldToViewPrevMatrix;
Matrix4x4 offsetClipToViewMatrix = offsetViewToClipMatrix.GetInverseFull();
Matrix4x4 offsetClipToWorldMatrix = m_viewToWorldMatrix * offsetClipToViewMatrix;
m_shaderResourceGroup->SetConstant(m_worldToClipPrevMatrixConstantIndex, offsetWorldToClipPrevMatrix);
m_shaderResourceGroup->SetConstant(m_viewProjectionMatrixConstantIndex, offsetWorldToClipMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixConstantIndex, offsetViewToClipMatrix);
m_shaderResourceGroup->SetConstant(m_clipToWorldMatrixConstantIndex, offsetClipToWorldMatrix);
m_shaderResourceGroup->SetConstant(m_projectionMatrixInverseConstantIndex, offsetViewToClipMatrix.GetInverseFull());
}
m_shaderResourceGroup->SetConstant(m_worldPositionConstantIndex, m_position);
m_shaderResourceGroup->SetConstant(m_viewMatrixConstantIndex, m_worldToViewMatrix);
m_shaderResourceGroup->SetConstant(m_viewMatrixInverseConstantIndex, m_worldToViewMatrix.GetInverseFull());
m_shaderResourceGroup->SetConstant(m_zConstantsConstantIndex, m_nearZ_farZ_farZTimesNearZ_farZMinusNearZ);
m_shaderResourceGroup->SetConstant(m_unprojectionConstantsIndex, m_unprojectionConstants);
m_shaderResourceGroup->Compile();
m_viewToClipPrevMatrix = m_viewToClipMatrix;
m_worldToViewPrevMatrix = m_worldToViewMatrix;
@@ -17,19 +17,6 @@
#include <AzCore/Console/IConsole.h>
#include <AzCore/Math/MathUtils.h>
void OnVsyncIntervalChanged(uint32_t const& interval)
{
AzFramework::WindowNotificationBus::Broadcast(
&AzFramework::WindowNotificationBus::Events::OnVsyncIntervalChanged,
AZ::GetClamp(interval, 0u, 4u));
}
// NOTE: On change, broadcasts the new requested vsync interval to all windows.
// The value of the vsync interval is constrained between 0 and 4
// Vsync intervals greater than 1 are not currently supported on the Vulkan RHI (see #2061 for discussion)
AZ_CVAR(uint32_t, rpi_vsync_interval, 1, OnVsyncIntervalChanged, AZ::ConsoleFunctorFlags::Null, "Set swapchain vsync interval");
namespace AZ
{
namespace RPI
@@ -158,9 +145,13 @@ namespace AZ
const RHI::WindowHandle windowHandle = RHI::WindowHandle(reinterpret_cast<uintptr_t>(m_windowHandle));
uint32_t syncInterval = 1;
AzFramework::WindowRequestBus::EventResult(
syncInterval, m_windowHandle, &AzFramework::WindowRequestBus::Events::GetSyncInterval);
RHI::SwapChainDescriptor descriptor;
descriptor.m_window = windowHandle;
descriptor.m_verticalSyncInterval = rpi_vsync_interval;
descriptor.m_verticalSyncInterval = syncInterval;
descriptor.m_dimensions.m_imageWidth = width;
descriptor.m_dimensions.m_imageHeight = height;
descriptor.m_dimensions.m_imageCount = 3;
@@ -96,7 +96,7 @@ namespace AZ
const AZ::Vector3& rayStart, const AZ::Vector3& rayDir, bool allowBruteForce,
float& distanceNormalized, AZ::Vector3& normal) const
{
AZ_PROFILE_FUNCTION(AZ::Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
if (!m_modelTriangleCount)
{
@@ -15,7 +15,7 @@ namespace AZ
{
// Normally this would be defined in the header file and substituted by the compiler, but for
// some reason clang doesn't accept it.
const ModelMaterialSlot::StableId ModelMaterialSlot::InvalidStableId = -1;
const ModelMaterialSlot::StableId ModelMaterialSlot::InvalidStableId = std::numeric_limits<ModelMaterialSlot::StableId>::max();
void ModelMaterialSlot::Reflect(AZ::ReflectContext* context)
{
@@ -172,7 +172,7 @@ namespace AZ
Data::Asset<ShaderVariantAsset> ShaderAsset::GetVariant(
const ShaderVariantId& shaderVariantId, SupervariantIndex supervariantIndex)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
auto variantFinder = AZ::Interface<IShaderVariantFinder>::Get();
AZ_Assert(variantFinder, "The IShaderVariantFinder doesn't exist");
@@ -189,7 +189,7 @@ namespace AZ
ShaderVariantSearchResult ShaderAsset::FindVariantStableId(const ShaderVariantId& shaderVariantId)
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
uint32_t dynamicOptionCount = aznumeric_cast<uint32_t>(GetShaderOptionGroupLayout()->GetShaderOptions().size());
ShaderVariantSearchResult variantSearchResult{RootShaderVariantStableId, dynamicOptionCount };
@@ -516,7 +516,7 @@ namespace AZ
SupervariantIndex ShaderAsset::GetSupervariantIndexInternal(AZ::Name supervariantName) const
{
const auto& supervariants = GetCurrentShaderApiData().m_supervariants;
const uint32_t supervariantCount = supervariants.size();
const uint32_t supervariantCount = static_cast<uint32_t>(supervariants.size());
for (uint32_t index = 0; index < supervariantCount; ++index)
{
if (supervariants[index].m_name == supervariantName)
@@ -72,7 +72,7 @@ namespace AZ
ShaderVariantSearchResult ShaderVariantTreeAsset::FindVariantStableId(const ShaderOptionGroupLayout* shaderOptionGroupLayout, const ShaderVariantId& shaderVariantId) const
{
AZ_PROFILE_FUNCTION(Debug::ProfileCategory::AzRender);
AZ_PROFILE_FUNCTION(AzRender);
struct NodeToVisit
{