9786d63596
* Hair - First introduction of Hair gem to Atom and O3DE - The hair technology is based off TressFX 4.1 - These are some of the areas we enhanced the original TressFX implementation: - Lighting model was replaced and we now use a modified Marschner model - Blending is done directly with the back buffer removing the silhouette of the original implementation - Hair depth / thickness is now calculated to remove incorrect back lighting (TT lobe in the Marschner model) - Thickness corrected to handle hair gaps hence introducing better light passage for the TT - The hair is fully integrated into the Atom pipeline and structure design - Usage of single shared buffer for the computer buffers reduces barriers sync overhead Remarks: - Collisions via SDF compute are to be introduced soon - Improved shortcut rendering method ala Eidos Montreal to be introduced soon Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - code clean pass Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - EMFX Actor visibility implementation Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - COnnecting hair passes to Atom's MainPipeline.pass Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - adding dedicated thumbnail pipeline that does not include the hair gem Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - changed Atom shader files to allow hooking the hair to the lighting data structures Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - fixed a few headers to have the latest O3DE license + verification fixes Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - enabling editor component only when tool pipline is built + default texture add Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - fixing Linux and Android compilation builds Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - another files change to make Linux compile Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - more Linux and Android build fixes Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - Adding usage of fallback white texture - Removing invalid null assignments into vectors - Removing redundant mutex preventing deletion on some platforms Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - Shame: removed forgoten #pragma optimize - Adding header complained by Android Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - removing the Hair Gem connection in the active project. - This submission removes the connection to the active project hence allowing to run without the Gem. Enable the passes in MainPipeline.pass and declare them again when you want to use the Gem. Remark: the gem file PassTemplates.azasset was renamed and will be connected via code in the future to avoid the need to declare in the global pass template. Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - registrating gem pass templates through the gem templates file (#198) * Hair - registrating gem pass templates through the gem templates file Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - adding handler disconnect for the pass template registration. Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - PPLLIndexCounter buffer going data driven via the pass declarations (#202) * Hair - PPLLIndexCounter buffer going data driven via the pass declaration - Moving PPLLIndexCounter from code allocation and attachment to be data driven - Fixed RPI typo bug that can prevent using buffers like that Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - fixing UI Editor (LYShine) crash (#209) Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair - resolved the multi pipeline mismatches and crashes + cleaned initialization & leftovers (#222) * [Hair] - multiple render pipelines handling Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair] - Shut down order is handle to allow hair feature processor be deregistered only after the bootstrap component has disabled it Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair] - minor cleanups Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair] - followups from review nits Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - code fixes based on the CR remarks for the Hair merge to Dev (#248) * Hair - First introduction of Hair gem to Atom and O3DE - The hair technology is based off TressFX 4.1 - These are some of the areas we enhanced the original TressFX implementation: - Lighting model was replaced and we now use a modified Marschner model - Blending is done directly with the back buffer removing the silhouette of the original implementation - Hair depth / thickness is now calculated to remove incorrect back lighting (TT lobe in the Marschner model) - Thickness corrected to handle hair gaps hence introducing better light passage for the TT - The hair is fully integrated into the Atom pipeline and structure design - Usage of single shared buffer for the computer buffers reduces barriers sync overhead Remarks: - Collisions via SDF compute are to be introduced soon - Improved shortcut rendering method ala Eidos Montreal to be introduced soon Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - code clean pass Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - EMFX Actor visibility implementation Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - COnnecting hair passes to Atom's MainPipeline.pass Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - adding dedicated thumbnail pipeline that does not include the hair gem Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - changed Atom shader files to allow hooking the hair to the lighting data structures Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - fixed a few headers to have the latest O3DE license + verification fixes Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - enabling editor component only when tool pipline is built + default texture add Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - fixing Linux and Android compilation builds Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - another files change to make Linux compile Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - more Linux and Android build fixes Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - Adding usage of fallback white texture - Removing invalid null assignments into vectors - Removing redundant mutex preventing deletion on some platforms Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - Shame: removed forgoten #pragma optimize - Adding header complained by Android Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - removing the Hair Gem connection in the active project. - This submission removes the connection to the active project hence allowing to run without the Gem. Enable the passes in MainPipeline.pass and declare them again when you want to use the Gem. Remark: the gem file PassTemplates.azasset was renamed and will be connected via code in the future to avoid the need to declare in the global pass template. Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - registrating gem pass templates through the gem templates file (#198) * Hair - registrating gem pass templates through the gem templates file Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - adding handler disconnect for the pass template registration. Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - PPLLIndexCounter buffer going data driven via the pass declarations (#202) * Hair - PPLLIndexCounter buffer going data driven via the pass declaration - Moving PPLLIndexCounter from code allocation and attachment to be data driven - Fixed RPI typo bug that can prevent using buffers like that Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - fixing UI Editor (LYShine) crash (#209) Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair - resolved the multi pipeline mismatches and crashes + cleaned initialization & leftovers (#222) * [Hair] - multiple render pipelines handling Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair] - Shut down order is handle to allow hair feature processor be deregistered only after the bootstrap component has disabled it Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair] - minor cleanups Signed-off-by: Adi-Amazon <barlev@amazon.com> * [Hair] - followups from review nits Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - last fixes based on CR remarks Signed-off-by: Adi-Amazon <barlev@amazon.com> * Hair - fixing AR Signed-off-by: Adi-Amazon <barlev@amazon.com>
422 lines
16 KiB
C++
422 lines
16 KiB
C++
/*
|
|
* 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 <AzCore/Interface/Interface.h>
|
|
|
|
#include <Atom/RHI/RHIUtils.h>
|
|
|
|
#include <Atom/RPI.Public/RenderPipeline.h>
|
|
#include <Atom/RPI.Public/Pass/Pass.h>
|
|
#include <Atom/RPI.Public/Pass/PassFilter.h>
|
|
#include <Atom/RPI.Public/Pass/PassSystemInterface.h>
|
|
#include <Atom/RPI.Public/Pass/PassLibrary.h>
|
|
#include <Atom/RPI.Reflect/Pass/PassAsset.h>
|
|
#include <Atom/RPI.Reflect/Pass/ComputePassData.h>
|
|
#include <Atom/RPI.Reflect/Asset/AssetUtils.h>
|
|
|
|
namespace AZ
|
|
{
|
|
namespace RPI
|
|
{
|
|
// Initialization & Shutdown...
|
|
|
|
void PassLibrary::Init()
|
|
{
|
|
AddCoreTemplates();
|
|
}
|
|
|
|
void PassLibrary::Shutdown()
|
|
{
|
|
m_isShuttingDown = true;
|
|
m_passNameMapping.clear();
|
|
m_templateEntries.clear();
|
|
m_templateMappingAssets.clear();
|
|
Data::AssetBus::MultiHandler::BusDisconnect();
|
|
}
|
|
|
|
|
|
// Getters...
|
|
|
|
PassLibrary::TemplateEntry* PassLibrary::GetEntry(const Name& templateName)
|
|
{
|
|
auto itr = m_templateEntries.find(templateName);
|
|
if (itr != m_templateEntries.end())
|
|
{
|
|
return &(itr->second);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const PassLibrary::TemplateEntry* PassLibrary::GetEntry(const Name& templateName) const
|
|
{
|
|
auto itr = m_templateEntries.find(templateName);
|
|
if (itr != m_templateEntries.end())
|
|
{
|
|
return &(itr->second);
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const AZStd::shared_ptr<PassTemplate> PassLibrary::GetPassTemplate(const Name& templateName) const
|
|
{
|
|
const TemplateEntry* entry = GetEntry(templateName);
|
|
return entry ? entry->m_template : nullptr;
|
|
}
|
|
|
|
const AZStd::vector<Pass*>& PassLibrary::GetPassesForTemplate(const Name& templateName) const
|
|
{
|
|
static AZStd::vector<Pass*> emptyPassList;
|
|
const TemplateEntry* entry = GetEntry(templateName);
|
|
return entry ? entry->m_passes : emptyPassList;
|
|
}
|
|
|
|
bool PassLibrary::HasTemplate(const Name& templateName) const
|
|
{
|
|
return m_templateEntries.find(templateName) != m_templateEntries.end();
|
|
}
|
|
|
|
bool PassLibrary::HasPassesForTemplate(const Name& templateName) const
|
|
{
|
|
return (GetPassesForTemplate(templateName).size() > 0);
|
|
}
|
|
|
|
AZStd::vector<Pass*> PassLibrary::FindPasses(const PassFilter& passFilter) const
|
|
{
|
|
const Name* passName = passFilter.GetPassName();
|
|
|
|
AZStd::vector<Pass*> result;
|
|
|
|
if (passName)
|
|
{
|
|
// If the pass' name is known, find passes with matching names first
|
|
const auto constItr = m_passNameMapping.find(*passName);
|
|
if (constItr == m_passNameMapping.end())
|
|
{
|
|
return result;
|
|
}
|
|
|
|
const AZStd::vector<Pass*>& passes = constItr->second;
|
|
|
|
for (Pass* pass : passes)
|
|
{
|
|
if (passFilter.Matches(pass))
|
|
{
|
|
result.push_back(pass);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If the filter doesn't know matching pass' name, need to go through all registered passes
|
|
for (auto& namePasses : m_passNameMapping)
|
|
{
|
|
for (Pass* pass : namePasses.second)
|
|
{
|
|
if (passFilter.Matches(pass))
|
|
{
|
|
result.push_back(pass);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Add Functions...
|
|
|
|
void PassLibrary::AddPass(Pass* pass)
|
|
{
|
|
if (pass->m_template)
|
|
{
|
|
TemplateEntry* entry = GetEntry(pass->m_template->m_name);
|
|
if (entry)
|
|
{
|
|
entry->m_passes.push_back(pass);
|
|
}
|
|
}
|
|
|
|
m_passNameMapping[pass->m_name].push_back(pass);
|
|
}
|
|
|
|
void PassLibrary::AddCoreTemplates()
|
|
{
|
|
// Put calls to pass template creation functions here...
|
|
AddCopyPassTemplate();
|
|
}
|
|
|
|
void PassLibrary::AddCopyPassTemplate()
|
|
{
|
|
AZStd::shared_ptr<PassTemplate> passTemplate = AZStd::make_shared<PassTemplate>();
|
|
passTemplate->m_passClass = "CopyPass";
|
|
passTemplate->m_name = "CopyPassTemplate";
|
|
|
|
PassSlot inputSlot;
|
|
inputSlot.m_name = "Input";
|
|
inputSlot.m_slotType = PassSlotType::Input;
|
|
inputSlot.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::Copy;
|
|
inputSlot.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Load;
|
|
passTemplate->m_slots.emplace_back(inputSlot);
|
|
|
|
PassSlot outputSlot;
|
|
outputSlot.m_name = "Output";
|
|
outputSlot.m_slotType = PassSlotType::Output;
|
|
outputSlot.m_scopeAttachmentUsage = RHI::ScopeAttachmentUsage::Copy;
|
|
outputSlot.m_loadStoreAction.m_loadAction = RHI::AttachmentLoadAction::Clear;
|
|
passTemplate->m_slots.emplace_back(outputSlot);
|
|
|
|
AddPassTemplate(passTemplate->m_name, std::move(passTemplate));
|
|
}
|
|
|
|
bool PassLibrary::AddPassTemplate(const Name& name, const AZStd::shared_ptr<PassTemplate>& passTemplate, bool hotReloading)
|
|
{
|
|
// Check if template already exists (unless we're hot reloading)
|
|
if (!hotReloading && GetPassTemplate(name) != nullptr)
|
|
{
|
|
AZ_Warning("PassLibrary", false,
|
|
"Trying to add a PassTemplate that already exists in PassLibrary. Template name: %s", name.GetCStr());
|
|
return false;
|
|
}
|
|
|
|
if (!passTemplate)
|
|
{
|
|
AZ_Warning("PassLibrary", false,
|
|
"Trying to add a null PassTemplate. Template name: %s", name.GetCStr());
|
|
return false;
|
|
}
|
|
|
|
if (passTemplate->m_name != name)
|
|
{
|
|
AZ_Warning("PassLibrary", false,
|
|
"Pass template alias [%s] is different than its name [%s]", name.GetCStr(), passTemplate->m_name.GetCStr());
|
|
passTemplate->m_name = name;
|
|
}
|
|
|
|
ValidateDeviceFormats(passTemplate);
|
|
|
|
m_templateEntries[name].m_template = std::move(passTemplate);
|
|
return true;
|
|
}
|
|
|
|
void PassLibrary::RemovePassFromLibrary(Pass* pass)
|
|
{
|
|
if (m_isShuttingDown)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// Remove from associated template
|
|
if (pass->m_template)
|
|
{
|
|
TemplateEntry* entry = GetEntry(pass->m_template->m_name);
|
|
if (entry)
|
|
{
|
|
[[maybe_unused]] auto iter = AZStd::remove(entry->m_passes.begin(), entry->m_passes.end(), pass);
|
|
|
|
AZ_Assert((iter + 1) == entry->m_passes.end(),
|
|
"Pass [%s] is being deleted but was not registered with it's PassTemlate [%s] in the PassLibrary.",
|
|
pass->m_name.GetCStr(), pass->m_template->m_name.GetCStr());
|
|
|
|
// Delete the pass that is now at the end of the list
|
|
entry->m_passes.pop_back();
|
|
}
|
|
}
|
|
|
|
// Remove pass from pass name
|
|
AZ_Assert(m_passNameMapping.find(pass->GetName()) != m_passNameMapping.end(),
|
|
"Pass [%s] is trying to be removed from PassLibrary but was not found in library",
|
|
pass->GetName().GetCStr());
|
|
|
|
AZStd::vector<Pass*>& passes = m_passNameMapping[pass->GetName()];
|
|
for (auto itr = passes.begin(); itr != passes.end(); itr++)
|
|
{
|
|
if (*itr == pass)
|
|
{
|
|
passes.erase(itr);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Pass Asset Functions...
|
|
|
|
void PassLibrary::OnAssetReloaded(Data::Asset<Data::AssetData> asset)
|
|
{
|
|
// Handle pass asset reload
|
|
Data::Asset<PassAsset> passAsset = { asset.GetAs<PassAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
|
if (passAsset && passAsset->GetPassTemplate())
|
|
{
|
|
LoadPassAsset(passAsset->GetPassTemplate()->m_name, passAsset, true);
|
|
return;
|
|
}
|
|
|
|
// Handle template mapping reload
|
|
// Note: it's a known issue that when mapping asset got reloaded, we only handle the new entries
|
|
Data::Asset<AnyAsset> templateMappings = { asset.GetAs<AnyAsset>(), AZ::Data::AssetLoadBehavior::PreLoad };
|
|
if (templateMappings)
|
|
{
|
|
auto itr = m_templateMappingAssets.find(asset->GetId());
|
|
if (itr != m_templateMappingAssets.end())
|
|
{
|
|
LoadPassTemplateMappings(templateMappings);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool PassLibrary::LoadPassAsset(const Name& name, const Data::Asset<PassAsset>& passAsset, bool hotReloading)
|
|
{
|
|
if (!passAsset.IsReady())
|
|
{
|
|
AZ_Error("PassAsset", false, "Failed to get pass asset. %s", passAsset.ToString<AZStd::string>().c_str());
|
|
return false;
|
|
}
|
|
|
|
if (!passAsset->GetPassTemplate())
|
|
{
|
|
AZ_Error("PassAsset", false, "Pass asset does not contain a pass template. %s", passAsset.ToString<AZStd::string>().c_str());
|
|
return false;
|
|
}
|
|
|
|
AZStd::shared_ptr<PassTemplate> passTemplate = passAsset->GetPassTemplate()->Clone();
|
|
|
|
bool success = AddPassTemplate(name, std::move(passTemplate), hotReloading);
|
|
if (success)
|
|
{
|
|
TemplateEntry& entry = m_templateEntries[name];
|
|
entry.m_asset = passAsset;
|
|
|
|
if (hotReloading)
|
|
{
|
|
for (Pass* pass : entry.m_passes)
|
|
{
|
|
if (pass->m_pipeline)
|
|
{
|
|
pass->m_pipeline->SetPassNeedsRecreate();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
bool PassLibrary::LoadPassAsset(const Name& name, const Data::AssetId& passAssetId)
|
|
{
|
|
Data::Asset<PassAsset> passAsset;
|
|
if (passAssetId.IsValid())
|
|
{
|
|
passAsset = Data::AssetManager::Instance().GetAsset<RPI::PassAsset>(passAssetId, AZ::Data::AssetLoadBehavior::PreLoad);
|
|
passAsset.BlockUntilLoadComplete();
|
|
}
|
|
|
|
bool loadSuccess = LoadPassAsset(name, passAsset);
|
|
|
|
if (loadSuccess)
|
|
{
|
|
Data::AssetBus::MultiHandler::BusConnect(passAssetId);
|
|
}
|
|
|
|
return loadSuccess;
|
|
}
|
|
|
|
bool PassLibrary::LoadPassTemplateMappings(const AZStd::string& templateMappingPath)
|
|
{
|
|
Data::Asset<AnyAsset> mappingAsset = AssetUtils::LoadCriticalAsset<AnyAsset>(templateMappingPath.c_str(), AssetUtils::TraceLevel::Error);
|
|
|
|
if (m_templateMappingAssets.find(mappingAsset.GetId()) != m_templateMappingAssets.end())
|
|
{
|
|
AZ_Warning("PassLibrary", false, "Pass template mapping [%s] was already loaded", mappingAsset.GetHint().c_str());
|
|
return true;
|
|
}
|
|
|
|
bool success = LoadPassTemplateMappings(mappingAsset);
|
|
if (success)
|
|
{
|
|
Data::AssetBus::MultiHandler::BusConnect(mappingAsset->GetId());
|
|
}
|
|
return success;
|
|
}
|
|
|
|
bool PassLibrary::LoadPassTemplateMappings(Data::Asset<AnyAsset> mappingAsset)
|
|
{
|
|
if (mappingAsset.IsReady())
|
|
{
|
|
const AssetAliases* mappings = GetDataFromAnyAsset<AssetAliases>(mappingAsset);
|
|
if (mappings == nullptr)
|
|
{
|
|
AZ_Error("PassLibrary", false, "Asset [%s] doesn't have assetAliases data", mappingAsset.GetHint().c_str());
|
|
return false;
|
|
}
|
|
|
|
const AZStd::unordered_map<AZStd::string, Data::AssetId>& assetMapping = mappings->GetAssetMapping();
|
|
Data::AssetId mappingAssetId = mappingAsset.GetId();
|
|
m_templateEntries.reserve(m_templateEntries.size() + assetMapping.size());
|
|
for (const auto& assetInfo : assetMapping)
|
|
{
|
|
Name templateName = AZ::Name(assetInfo.first);
|
|
if (!HasTemplate(templateName))
|
|
{
|
|
bool loaded = LoadPassAsset(templateName, assetInfo.second);
|
|
if (loaded)
|
|
{
|
|
auto& entry = m_templateEntries[templateName];
|
|
entry.m_mappingAssetId = mappingAssetId;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Report a warning if the template was setup in another mappping asset.
|
|
// We won't report a warning if the template was loaded from same asset. This only happens when the asset got reloaded.
|
|
if (m_templateEntries[templateName].m_mappingAssetId != mappingAssetId)
|
|
{
|
|
AZ_Warning("PassLibrary", false, "Template [%s] was aleady added to the library. Duplicated template from [%s]",
|
|
templateName.GetCStr(), mappingAsset.ToString<AZStd::string>().c_str());
|
|
}
|
|
}
|
|
}
|
|
|
|
m_templateMappingAssets[mappingAsset->GetId()] = mappingAsset;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void PassLibrary::ValidateDeviceFormats(const AZStd::shared_ptr<PassTemplate>& passTemplate)
|
|
{
|
|
// Validate image attachments
|
|
for (PassImageAttachmentDesc& imageAttachment : passTemplate->m_imageAttachments)
|
|
{
|
|
RHI::Format format = imageAttachment.m_imageDescriptor.m_format;
|
|
AZStd::string formatLocation = AZStd::string::format("PassAttachmentDesc [%s] on PassTemplate [%s]", imageAttachment.m_name.GetCStr(), passTemplate->m_name.GetCStr());
|
|
imageAttachment.m_imageDescriptor.m_format = RHI::ValidateFormat(format, formatLocation.c_str(), imageAttachment.m_formatFallbacks);
|
|
}
|
|
|
|
// Validate slot views
|
|
for (PassSlot& slot : passTemplate->m_slots)
|
|
{
|
|
if (slot.m_imageViewDesc)
|
|
{
|
|
RHI::Format format = slot.m_imageViewDesc->m_overrideFormat;
|
|
AZStd::string formatLocation = AZStd::string::format("ImageViewDescriptor on Slot [%s] in PassTemplate [%s]", slot.m_name.GetCStr(), passTemplate->m_name.GetCStr());
|
|
RHI::FormatCapabilities capabilities = RHI::GetCapabilities(slot.m_scopeAttachmentUsage, slot.GetAttachmentAccess(), RHI::AttachmentType::Image);
|
|
slot.m_imageViewDesc->m_overrideFormat = RHI::ValidateFormat(format, formatLocation.c_str(), slot.m_formatFallbacks, capabilities);
|
|
}
|
|
if (slot.m_bufferViewDesc)
|
|
{
|
|
RHI::Format format = slot.m_bufferViewDesc->m_elementFormat;
|
|
AZStd::string formatLocation = AZStd::string::format("BufferViewDescriptor on Slot [%s] in PassTemplate [%s]", slot.m_name.GetCStr(), passTemplate->m_name.GetCStr());
|
|
RHI::FormatCapabilities capabilities = RHI::GetCapabilities(slot.m_scopeAttachmentUsage, slot.GetAttachmentAccess(), RHI::AttachmentType::Buffer);
|
|
slot.m_bufferViewDesc->m_elementFormat = RHI::ValidateFormat(format, formatLocation.c_str(), slot.m_formatFallbacks, capabilities);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace RPI
|
|
} // namespace AZ
|