- Optimize SRG compilation to not update the whole SRG if not needed across all backends (#4499)
- Each resource type is tracked and updated separately - Added caching ability for Raytracing srg to save ~2ms for a scene containing 100 x 50 vegetation patch Signed-off-by: moudgils <moudgils@amazon.com>
This commit is contained in:
@@ -507,8 +507,13 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
RHI::ShaderInputBufferUnboundedArrayIndex bufferUnboundedArrayIndex = srgLayout->FindShaderInputBufferUnboundedArrayIndex(AZ::Name("m_meshBuffers"));
|
||||
m_rayTracingSceneSrg->SetBufferViewUnboundedArray(bufferUnboundedArrayIndex, meshBuffers);
|
||||
//Check if buffer view data changed from previous frame.
|
||||
if (m_meshBuffers.size() != meshBuffers.size() || m_meshBuffers != meshBuffers)
|
||||
{
|
||||
m_meshBuffers = meshBuffers;
|
||||
RHI::ShaderInputBufferUnboundedArrayIndex bufferUnboundedArrayIndex = srgLayout->FindShaderInputBufferUnboundedArrayIndex(AZ::Name("m_meshBuffers"));
|
||||
m_rayTracingSceneSrg->SetBufferViewUnboundedArray(bufferUnboundedArrayIndex, m_meshBuffers);
|
||||
}
|
||||
}
|
||||
|
||||
m_rayTracingSceneSrg->Compile();
|
||||
@@ -554,8 +559,13 @@ namespace AZ
|
||||
}
|
||||
}
|
||||
|
||||
RHI::ShaderInputImageUnboundedArrayIndex textureUnboundedArrayIndex = srgLayout->FindShaderInputImageUnboundedArrayIndex(AZ::Name("m_materialTextures"));
|
||||
m_rayTracingMaterialSrg->SetImageViewUnboundedArray(textureUnboundedArrayIndex, materialTextures);
|
||||
// Check if image view data changed from previous frame.
|
||||
if (m_materialTextures.size() != materialTextures.size() || m_materialTextures != materialTextures)
|
||||
{
|
||||
m_materialTextures = materialTextures;
|
||||
RHI::ShaderInputImageUnboundedArrayIndex textureUnboundedArrayIndex = srgLayout->FindShaderInputImageUnboundedArrayIndex(AZ::Name("m_materialTextures"));
|
||||
m_rayTracingMaterialSrg->SetImageViewUnboundedArray(textureUnboundedArrayIndex, materialTextures);
|
||||
}
|
||||
}
|
||||
|
||||
m_rayTracingMaterialSrg->Compile();
|
||||
|
||||
@@ -281,6 +281,10 @@ namespace AZ
|
||||
|
||||
using BlasInstanceMap = AZStd::unordered_map<AZ::Data::AssetId, MeshBlasInstance>;
|
||||
BlasInstanceMap m_blasInstanceMap;
|
||||
|
||||
// Cache view pointers so we dont need to update them if none changed from frame to frame.
|
||||
AZStd::vector<const RHI::BufferView*> m_meshBuffers;
|
||||
AZStd::vector<const RHI::ImageView*> m_materialTextures;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +183,42 @@ namespace AZ
|
||||
//! Returns the shader resource layout for this group.
|
||||
const ShaderResourceGroupLayout* GetLayout() const;
|
||||
|
||||
enum class ResourceType : uint32_t
|
||||
{
|
||||
ConstantData,
|
||||
BufferView,
|
||||
ImageView,
|
||||
BufferViewUnboundedArray,
|
||||
ImageViewUnboundedArray,
|
||||
Sampler,
|
||||
Count
|
||||
};
|
||||
|
||||
enum class ResourceTypeMask : uint32_t
|
||||
{
|
||||
None = 0,
|
||||
ConstantDataMask = AZ_BIT(static_cast<uint32_t>(ResourceType::ConstantData)),
|
||||
BufferViewMask = AZ_BIT(static_cast<uint32_t>(ResourceType::BufferView)),
|
||||
ImageViewMask = AZ_BIT(static_cast<uint32_t>(ResourceType::ImageView)),
|
||||
BufferViewUnboundedArrayMask = AZ_BIT(static_cast<uint32_t>(ResourceType::BufferViewUnboundedArray)),
|
||||
ImageViewUnboundedArrayMask = AZ_BIT(static_cast<uint32_t>(ResourceType::ImageViewUnboundedArray)),
|
||||
SamplerMask = AZ_BIT(static_cast<uint32_t>(ResourceType::Sampler))
|
||||
};
|
||||
|
||||
//! Returns true if a resource type specified by resourceTypeMask is enabled for compilation
|
||||
bool IsResourceTypeEnabledForCompilation(uint32_t resourceTypeMask) const;
|
||||
|
||||
//! Disables all resource types for compilation after m_updateMaskResetLatency number of compiles
|
||||
//! This allows higher level code to ensure that if SRG is multi-buffered it can compile multiple
|
||||
//! times in order to ensure all SRG buffers are updated.
|
||||
void DisableCompilationForAllResourceTypes();
|
||||
|
||||
//! Returns true if any of the resource type has been enabled for compilation.
|
||||
bool IsAnyResourceTypeUpdated() const;
|
||||
|
||||
//! Enable compilation for a resourceType specified by resourceType/resourceTypeMask
|
||||
void EnableResourceTypeCompilation(ResourceTypeMask resourceTypeMask, ResourceType resourceType);
|
||||
|
||||
private:
|
||||
static const ConstPtr<ImageView> s_nullImageView;
|
||||
static const ConstPtr<BufferView> s_nullBufferView;
|
||||
@@ -207,23 +243,43 @@ namespace AZ
|
||||
|
||||
//! The backing data store of constants for the shader resource group.
|
||||
ConstantsData m_constantsData;
|
||||
|
||||
//! Mask used to check whether to compile a specific resource type
|
||||
uint32_t m_updateMask = 0;
|
||||
|
||||
//! Track iteration for each resource type in order to keep compiling it for m_updateMaskResetLatency number of times
|
||||
uint32_t m_resourceTypeIteration[static_cast<uint32_t>(ResourceType::Count)] = { 0 };
|
||||
uint32_t m_updateMaskResetLatency = RHI::Limits::Device::FrameCountMax;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
bool ShaderResourceGroupData::SetConstant(ShaderInputConstantIndex inputIndex, const T& value)
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ConstantDataMask, ResourceType::ConstantData);
|
||||
return m_constantsData.SetConstant(inputIndex, value);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ShaderResourceGroupData::SetConstant(ShaderInputConstantIndex inputIndex, const T& value, uint32_t arrayIndex)
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ConstantDataMask, ResourceType::ConstantData);
|
||||
return m_constantsData.SetConstant(inputIndex, value, arrayIndex);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool ShaderResourceGroupData::SetConstantMatrixRows(ShaderInputConstantIndex inputIndex, const T& value, uint32_t rowCount)
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ConstantDataMask, ResourceType::ConstantData);
|
||||
return m_constantsData.SetConstantMatrixRows(inputIndex, value, rowCount);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ShaderResourceGroupData::SetConstantArray(ShaderInputConstantIndex inputIndex, AZStd::array_view<T> values)
|
||||
{
|
||||
if (!values.empty())
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ConstantDataMask, ResourceType::ConstantData);
|
||||
}
|
||||
return m_constantsData.SetConstantArray(inputIndex, values);
|
||||
}
|
||||
|
||||
@@ -245,12 +301,6 @@ namespace AZ
|
||||
return m_constantsData.GetConstant<T>(inputIndex, arrayIndex);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool ShaderResourceGroupData::SetConstantMatrixRows(ShaderInputConstantIndex inputIndex, const T& value, uint32_t rowCount)
|
||||
{
|
||||
return m_constantsData.SetConstantMatrixRows(inputIndex, value, rowCount);
|
||||
}
|
||||
|
||||
template<typename TShaderInput, typename TShaderInputDescriptor>
|
||||
bool ShaderResourceGroupData::ValidateImageViewAccess(TShaderInput inputIndex, const ImageView* imageView, [[maybe_unused]] uint32_t arrayIndex) const
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
#include <Atom/RHI/ShaderResourceGroupData.h>
|
||||
#include <Atom/RHI/ShaderResourceGroupPool.h>
|
||||
#include <Atom/RHI.Reflect/Bits.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -126,6 +127,12 @@ namespace AZ
|
||||
}
|
||||
isValidAll &= isValid;
|
||||
}
|
||||
|
||||
if(!imageViews.empty())
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ImageViewMask, ResourceType::ImageView);
|
||||
}
|
||||
|
||||
return isValidAll;
|
||||
}
|
||||
return false;
|
||||
@@ -146,6 +153,11 @@ namespace AZ
|
||||
}
|
||||
isValidAll &= isValid;
|
||||
}
|
||||
|
||||
if (!imageViews.empty())
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ImageViewUnboundedArrayMask, ResourceType::ImageViewUnboundedArray);
|
||||
}
|
||||
return isValidAll;
|
||||
}
|
||||
return false;
|
||||
@@ -172,6 +184,11 @@ namespace AZ
|
||||
}
|
||||
isValidAll &= isValid;
|
||||
}
|
||||
|
||||
if (!bufferViews.empty())
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::BufferViewMask, ResourceType::BufferView);
|
||||
}
|
||||
return isValidAll;
|
||||
}
|
||||
return false;
|
||||
@@ -192,6 +209,11 @@ namespace AZ
|
||||
}
|
||||
isValidAll &= isValid;
|
||||
}
|
||||
|
||||
if (!bufferViews.empty())
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::BufferViewUnboundedArrayMask, ResourceType::BufferViewUnboundedArray);
|
||||
}
|
||||
return isValidAll;
|
||||
}
|
||||
return false;
|
||||
@@ -211,6 +233,11 @@ namespace AZ
|
||||
{
|
||||
m_samplers[interval.m_min + arrayIndex + i] = samplers[i];
|
||||
}
|
||||
|
||||
if (!samplers.empty())
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::SamplerMask, ResourceType::Sampler);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -223,16 +250,19 @@ namespace AZ
|
||||
|
||||
bool ShaderResourceGroupData::SetConstantRaw(ShaderInputConstantIndex inputIndex, const void* bytes, uint32_t byteOffset, uint32_t byteCount)
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ConstantDataMask, ResourceType::ConstantData);
|
||||
return m_constantsData.SetConstantRaw(inputIndex, bytes, byteOffset, byteCount);
|
||||
}
|
||||
|
||||
bool ShaderResourceGroupData::SetConstantData(const void* bytes, uint32_t byteCount)
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ConstantDataMask, ResourceType::ConstantData);
|
||||
return m_constantsData.SetConstantData(bytes, byteCount);
|
||||
}
|
||||
|
||||
bool ShaderResourceGroupData::SetConstantData(const void* bytes, uint32_t byteOffset, uint32_t byteCount)
|
||||
{
|
||||
EnableResourceTypeCompilation(ResourceTypeMask::ConstantDataMask, ResourceType::ConstantData);
|
||||
return m_constantsData.SetConstantData(bytes, byteOffset, byteCount);
|
||||
}
|
||||
|
||||
@@ -348,5 +378,33 @@ namespace AZ
|
||||
return m_constantsData;
|
||||
}
|
||||
|
||||
bool ShaderResourceGroupData::IsResourceTypeEnabledForCompilation(uint32_t resourceTypeMask) const
|
||||
{
|
||||
return RHI::CheckBitsAny(m_updateMask, resourceTypeMask);
|
||||
}
|
||||
|
||||
bool ShaderResourceGroupData::IsAnyResourceTypeUpdated() const
|
||||
{
|
||||
return m_updateMask != 0;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupData::EnableResourceTypeCompilation(ResourceTypeMask resourceTypeMask, ResourceType resourceType)
|
||||
{
|
||||
AZ_Assert(static_cast<uint32_t>(resourceTypeMask) == AZ_BIT(static_cast<uint32_t>(resourceType)), "resourceType and resourceTypeMask should point to the same ResourceType");
|
||||
m_updateMask = RHI::SetBits(m_updateMask, static_cast<uint32_t>(resourceTypeMask));
|
||||
m_resourceTypeIteration[static_cast<uint32_t>(resourceType)] = 0;
|
||||
}
|
||||
|
||||
void ShaderResourceGroupData::DisableCompilationForAllResourceTypes()
|
||||
{
|
||||
for (uint32_t i = 0; i < static_cast<uint32_t>(ResourceType::Count); i++)
|
||||
{
|
||||
if (m_resourceTypeIteration[i] == m_updateMaskResetLatency)
|
||||
{
|
||||
m_updateMask = RHI::ResetBits(m_updateMask, AZ_BIT(i));
|
||||
}
|
||||
m_resourceTypeIteration[i]++;
|
||||
}
|
||||
}
|
||||
} // namespace RHI
|
||||
} // namespace AZ
|
||||
|
||||
@@ -206,12 +206,21 @@ namespace AZ
|
||||
auto& device = static_cast<Device&>(GetDevice());
|
||||
group.m_compiledDataIndex = (group.m_compiledDataIndex + 1) % RHI::Limits::Device::FrameCountMax;
|
||||
|
||||
if (m_constantBufferSize)
|
||||
if (!groupData.IsAnyResourceTypeUpdated())
|
||||
{
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
if (m_constantBufferSize &&
|
||||
groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ConstantDataMask)))
|
||||
{
|
||||
memcpy(group.GetCompiledData().m_cpuConstantAddress, groupData.GetConstantData().data(), groupData.GetConstantData().size());
|
||||
}
|
||||
|
||||
if (m_viewsDescriptorTableSize)
|
||||
if (m_viewsDescriptorTableSize &&
|
||||
groupData.IsResourceTypeEnabledForCompilation(
|
||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewMask) |
|
||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewMask)))
|
||||
{
|
||||
//Lazy initialization for cbv/srv/uav Descriptor Tables
|
||||
if (!group.m_viewsDescriptorTable.IsValid())
|
||||
@@ -236,12 +245,17 @@ namespace AZ
|
||||
UpdateViewsDescriptorTable(descriptorTable, groupData);
|
||||
}
|
||||
|
||||
if (m_unboundedArrayCount)
|
||||
if (m_unboundedArrayCount &&
|
||||
groupData.IsResourceTypeEnabledForCompilation(
|
||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewUnboundedArrayMask) |
|
||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewUnboundedArrayMask)))
|
||||
{
|
||||
UpdateUnboundedArrayDescriptorTables(group, groupData);
|
||||
}
|
||||
|
||||
if (m_samplersDescriptorTableSize)
|
||||
if (m_samplersDescriptorTableSize &&
|
||||
groupData.IsResourceTypeEnabledForCompilation(
|
||||
static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::SamplerMask)))
|
||||
{
|
||||
const DescriptorTable descriptorTable(
|
||||
group.m_samplersDescriptorTable.GetOffset() + group.m_compiledDataIndex * m_samplersDescriptorTableSize,
|
||||
|
||||
@@ -63,39 +63,58 @@ namespace AZ
|
||||
{
|
||||
ShaderResourceGroup& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||
group.UpdateCompiledDataIndex();
|
||||
|
||||
|
||||
if (!groupData.IsAnyResourceTypeUpdated())
|
||||
{
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
ArgumentBuffer& argBuffer = *group.m_compiledArgBuffers[group.m_compiledDataIndex];
|
||||
argBuffer.ClearResourceTracking();
|
||||
argBuffer.UpdateConstantBufferViews(groupData.GetConstantData());
|
||||
|
||||
|
||||
auto constantData = groupData.GetConstantData();
|
||||
if (!constantData.empty() && groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ConstantDataMask)))
|
||||
{
|
||||
argBuffer.UpdateConstantBufferViews(groupData.GetConstantData());
|
||||
}
|
||||
|
||||
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
||||
uint32_t shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputImageDescriptor& shaderInputImage : layout->GetShaderInputListForImages())
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewMask)))
|
||||
{
|
||||
const RHI::ShaderInputImageIndex imageInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::ImageView>> imageViews = groupData.GetImageViewArray(imageInputIndex);
|
||||
argBuffer.UpdateImageViews(shaderInputImage, imageInputIndex, imageViews);
|
||||
++shaderInputIndex;
|
||||
for (const RHI::ShaderInputImageDescriptor& shaderInputImage : layout->GetShaderInputListForImages())
|
||||
{
|
||||
const RHI::ShaderInputImageIndex imageInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::ImageView>> imageViews = groupData.GetImageViewArray(imageInputIndex);
|
||||
argBuffer.UpdateImageViews(shaderInputImage, imageInputIndex, imageViews);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
}
|
||||
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputSamplerDescriptor& shaderInputSampler : layout->GetShaderInputListForSamplers())
|
||||
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::SamplerMask)))
|
||||
{
|
||||
const RHI::ShaderInputSamplerIndex samplerInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::SamplerState> samplerStates= groupData.GetSamplerArray(samplerInputIndex);
|
||||
argBuffer.UpdateSamplers(shaderInputSampler, samplerInputIndex, samplerStates);
|
||||
++shaderInputIndex;
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputSamplerDescriptor& shaderInputSampler : layout->GetShaderInputListForSamplers())
|
||||
{
|
||||
const RHI::ShaderInputSamplerIndex samplerInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::SamplerState> samplerStates = groupData.GetSamplerArray(samplerInputIndex);
|
||||
argBuffer.UpdateSamplers(shaderInputSampler, samplerInputIndex, samplerStates);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
}
|
||||
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputBufferDescriptor& shaderInputBuffer : layout->GetShaderInputListForBuffers())
|
||||
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewMask)))
|
||||
{
|
||||
const RHI::ShaderInputBufferIndex bufferInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::BufferView>> bufferViews = groupData.GetBufferViewArray(bufferInputIndex);
|
||||
argBuffer.UpdateBufferViews(shaderInputBuffer, bufferInputIndex, bufferViews);
|
||||
++shaderInputIndex;
|
||||
shaderInputIndex = 0;
|
||||
for (const RHI::ShaderInputBufferDescriptor& shaderInputBuffer : layout->GetShaderInputListForBuffers())
|
||||
{
|
||||
const RHI::ShaderInputBufferIndex bufferInputIndex(shaderInputIndex);
|
||||
AZStd::array_view<RHI::ConstPtr<RHI::BufferView>> bufferViews = groupData.GetBufferViewArray(bufferInputIndex);
|
||||
argBuffer.UpdateBufferViews(shaderInputBuffer, bufferInputIndex, bufferViews);
|
||||
++shaderInputIndex;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
|
||||
@@ -105,66 +105,87 @@ namespace AZ
|
||||
{
|
||||
auto& group = static_cast<ShaderResourceGroup&>(groupBase);
|
||||
group.UpdateCompiledDataIndex(m_currentIteration);
|
||||
|
||||
if (!groupData.IsAnyResourceTypeUpdated())
|
||||
{
|
||||
return RHI::ResultCode::Success;
|
||||
}
|
||||
|
||||
DescriptorSet& descriptorSet = *group.m_compiledData[group.GetCompileDataIndex()];
|
||||
|
||||
const RHI::ShaderResourceGroupLayout* layout = groupData.GetLayout();
|
||||
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForBuffers().size()); ++groupIndex)
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewMask)))
|
||||
{
|
||||
const RHI::ShaderInputBufferIndex index(groupIndex);
|
||||
auto bufViews = groupData.GetBufferViewArray(index);
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::BufferView);
|
||||
descriptorSet.UpdateBufferViews(layoutIndex, bufViews);
|
||||
}
|
||||
|
||||
auto const& shaderImageList = layout->GetShaderInputListForImages();
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForImages().size()); ++groupIndex)
|
||||
{
|
||||
const RHI::ShaderInputImageIndex index(groupIndex);
|
||||
auto imgViews = groupData.GetImageViewArray(index);
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::ImageView);
|
||||
descriptorSet.UpdateImageViews(layoutIndex, imgViews, shaderImageList[groupIndex].m_type);
|
||||
}
|
||||
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForBufferUnboundedArrays().size()); ++groupIndex)
|
||||
{
|
||||
const RHI::ShaderInputBufferUnboundedArrayIndex index(groupIndex);
|
||||
auto bufViews = groupData.GetBufferViewUnboundedArray(index);
|
||||
if (bufViews.empty())
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForBuffers().size()); ++groupIndex)
|
||||
{
|
||||
// skip empty unbounded arrays
|
||||
continue;
|
||||
const RHI::ShaderInputBufferIndex index(groupIndex);
|
||||
auto bufViews = groupData.GetBufferViewArray(index);
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::BufferView);
|
||||
descriptorSet.UpdateBufferViews(layoutIndex, bufViews);
|
||||
}
|
||||
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::BufferViewUnboundedArray);
|
||||
descriptorSet.UpdateBufferViews(layoutIndex, bufViews);
|
||||
}
|
||||
|
||||
auto const& shaderImageUnboundeArrayList = layout->GetShaderInputListForImageUnboundedArrays();
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForImageUnboundedArrays().size()); ++groupIndex)
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewMask)))
|
||||
{
|
||||
const RHI::ShaderInputImageUnboundedArrayIndex index(groupIndex);
|
||||
auto imgViews = groupData.GetImageViewUnboundedArray(index);
|
||||
if (imgViews.empty())
|
||||
auto const& shaderImageList = layout->GetShaderInputListForImages();
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForImages().size()); ++groupIndex)
|
||||
{
|
||||
// skip empty unbounded arrays
|
||||
continue;
|
||||
const RHI::ShaderInputImageIndex index(groupIndex);
|
||||
auto imgViews = groupData.GetImageViewArray(index);
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::ImageView);
|
||||
descriptorSet.UpdateImageViews(layoutIndex, imgViews, shaderImageList[groupIndex].m_type);
|
||||
}
|
||||
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::ImageViewUnboundedArray);
|
||||
descriptorSet.UpdateImageViews(layoutIndex, imgViews, shaderImageUnboundeArrayList[groupIndex].m_type);
|
||||
}
|
||||
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForSamplers().size()); ++groupIndex)
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::BufferViewUnboundedArrayMask)))
|
||||
{
|
||||
const RHI::ShaderInputSamplerIndex index(groupIndex);
|
||||
auto samplerArray = groupData.GetSamplerArray(index);
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::Sampler);
|
||||
descriptorSet.UpdateSamplers(layoutIndex, samplerArray);
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForBufferUnboundedArrays().size()); ++groupIndex)
|
||||
{
|
||||
const RHI::ShaderInputBufferUnboundedArrayIndex index(groupIndex);
|
||||
auto bufViews = groupData.GetBufferViewUnboundedArray(index);
|
||||
if (bufViews.empty())
|
||||
{
|
||||
// skip empty unbounded arrays
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::BufferViewUnboundedArray);
|
||||
descriptorSet.UpdateBufferViews(layoutIndex, bufViews);
|
||||
}
|
||||
}
|
||||
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ImageViewUnboundedArrayMask)))
|
||||
{
|
||||
auto const& shaderImageUnboundeArrayList = layout->GetShaderInputListForImageUnboundedArrays();
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForImageUnboundedArrays().size()); ++groupIndex)
|
||||
{
|
||||
const RHI::ShaderInputImageUnboundedArrayIndex index(groupIndex);
|
||||
auto imgViews = groupData.GetImageViewUnboundedArray(index);
|
||||
if (imgViews.empty())
|
||||
{
|
||||
// skip empty unbounded arrays
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::ImageViewUnboundedArray);
|
||||
descriptorSet.UpdateImageViews(layoutIndex, imgViews, shaderImageUnboundeArrayList[groupIndex].m_type);
|
||||
}
|
||||
}
|
||||
|
||||
if (groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::SamplerMask)))
|
||||
{
|
||||
for (uint32_t groupIndex = 0; groupIndex < static_cast<uint32_t>(layout->GetShaderInputListForSamplers().size()); ++groupIndex)
|
||||
{
|
||||
const RHI::ShaderInputSamplerIndex index(groupIndex);
|
||||
auto samplerArray = groupData.GetSamplerArray(index);
|
||||
uint32_t layoutIndex = m_descriptorSetLayout->GetLayoutIndexFromGroupIndex(groupIndex, DescriptorSetLayout::ResourceType::Sampler);
|
||||
descriptorSet.UpdateSamplers(layoutIndex, samplerArray);
|
||||
}
|
||||
}
|
||||
|
||||
auto constantData = groupData.GetConstantData();
|
||||
if (!constantData.empty())
|
||||
if (!constantData.empty() && groupData.IsResourceTypeEnabledForCompilation(static_cast<uint32_t>(RHI::ShaderResourceGroupData::ResourceTypeMask::ConstantDataMask)))
|
||||
{
|
||||
descriptorSet.UpdateConstantData(constantData);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user