Add support for re-binding SRG entries if the drawItem has a new pso which changes how a srg is used in the shader. Also optimized api usage to use single call for UseResource and for setting stream buffers.
This commit is contained in:
@@ -16,7 +16,7 @@
|
||||
|
||||
ShaderResourceGroup MorphTargetPassSrg : SRG_PerPass
|
||||
{
|
||||
RWStruturedBuffer<int> m_accumulatedDeltas;
|
||||
RWStructuredBuffer<int> m_accumulatedDeltas;
|
||||
}
|
||||
|
||||
// This class represents the data that is passed to the morph target compute shader of an individual delta
|
||||
|
||||
@@ -386,6 +386,11 @@ namespace AZ
|
||||
|
||||
void ArgumentBuffer::AddUntrackedResourcesToEncoder(id<MTLCommandEncoder> commandEncoder, const ShaderResourceGroupVisibility& srgResourcesVisInfo) const
|
||||
{
|
||||
|
||||
ComputeResourcesToMakeResidentMap resourcesToMakeResidentCompute;
|
||||
GraphicsResourcesToMakeResidentMap resourcesToMakeResidentGraphics;
|
||||
|
||||
//Cache the constant buffer associated with a srg
|
||||
if (m_constantBufferSize)
|
||||
{
|
||||
uint8_t numBitsSet = RHI::CountBitsSet(static_cast<uint64_t>(srgResourcesVisInfo.m_constantDataStageMask));
|
||||
@@ -393,28 +398,19 @@ namespace AZ
|
||||
{
|
||||
if(RHI::CheckBitsAny(srgResourcesVisInfo.m_constantDataStageMask, RHI::ShaderStageMask::Compute))
|
||||
{
|
||||
[static_cast<id<MTLComputeCommandEncoder>>(commandEncoder) useResource:m_constantBuffer.GetGpuAddress<id<MTLBuffer>>() usage:MTLResourceUsageRead];
|
||||
resourcesToMakeResidentCompute[MTLResourceUsageRead].m_resourceArray[resourcesToMakeResidentCompute[MTLResourceUsageRead].m_resourceArrayLen++] = m_constantBuffer.GetGpuAddress<id<MTLResource>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
MTLRenderStages mtlRenderStages = GetRenderStages(srgResourcesVisInfo.m_constantDataStageMask);
|
||||
[static_cast<id<MTLRenderCommandEncoder>>(commandEncoder) useResource:m_constantBuffer.GetGpuAddress<id<MTLBuffer>>()
|
||||
usage:MTLResourceUsageRead
|
||||
stages:mtlRenderStages];
|
||||
AZStd::pair <MTLResourceUsage,MTLRenderStages> key = AZStd::make_pair(MTLResourceUsageRead, mtlRenderStages);
|
||||
resourcesToMakeResidentGraphics[key].m_resourceArray[resourcesToMakeResidentGraphics[key].m_resourceArrayLen++] = m_constantBuffer.GetGpuAddress<id<MTLResource>>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
ApplyUseResource(commandEncoder, m_resourceBindings, srgResourcesVisInfo);
|
||||
}
|
||||
|
||||
void ArgumentBuffer::ApplyUseResource(id<MTLCommandEncoder> encoder,
|
||||
const ResourceBindingsMap& resourceMap,
|
||||
const ShaderResourceGroupVisibility& srgResourcesVisInfo) const
|
||||
{
|
||||
|
||||
CommandEncoderType encodeType = CommandEncoderType::Invalid;
|
||||
for (const auto& it : resourceMap)
|
||||
|
||||
//Cach all the resources within a srg that are used by the shader based on the visibility information
|
||||
for (const auto& it : m_resourceBindings)
|
||||
{
|
||||
//Extract the visibility mask for the give resource
|
||||
auto visMaskIt = srgResourcesVisInfo.m_resourcesStageMask.find(it.first);
|
||||
@@ -426,75 +422,50 @@ namespace AZ
|
||||
{
|
||||
if(RHI::CheckBitsAny(visMaskIt->second, RHI::ShaderStageMask::Compute))
|
||||
{
|
||||
//Call UseResource on all resources for Compute stage
|
||||
ApplyUseResourceToCompute(encoder, it.second);
|
||||
encodeType = CommandEncoderType::Compute;
|
||||
ApplyUseResourceToCompute(commandEncoder, it.second, resourcesToMakeResidentCompute);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Call UseResource on all resources for Vertex and Fragment stages
|
||||
AZ_Assert(RHI::CheckBitsAny(visMaskIt->second, RHI::ShaderStageMask::Vertex) || RHI::CheckBitsAny(visMaskIt->second, RHI::ShaderStageMask::Fragment), "The visibility mask %i is not set for Vertex or fragment stage", visMaskIt->second);
|
||||
ApplyUseResourceToGraphic(encoder, visMaskIt->second, it.second);
|
||||
encodeType = CommandEncoderType::Render;
|
||||
ApplyUseResourceToGraphic(commandEncoder, visMaskIt->second, it.second, resourcesToMakeResidentGraphics);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArgumentBuffer::ApplyUseResourceToCompute(id<MTLCommandEncoder> encoder, const ResourceBindingsSet& resourceBindingDataSet) const
|
||||
{
|
||||
for (const auto& resourceBindingData : resourceBindingDataSet)
|
||||
{
|
||||
ResourceType rescType = resourceBindingData.m_resourcPtr->GetResourceType();
|
||||
switch(rescType)
|
||||
{
|
||||
case ResourceType::MtlTextureType:
|
||||
{
|
||||
MTLResourceUsage resourceUsage = GetImageResourceUsage(resourceBindingData.m_imageAccess);
|
||||
[static_cast<id<MTLComputeCommandEncoder>>(encoder) useResource:resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLTexture>>() usage:resourceUsage];
|
||||
|
||||
break;
|
||||
}
|
||||
case ResourceType::MtlBufferType:
|
||||
{
|
||||
MTLResourceUsage resourceUsage = GetBufferResourceUsage(resourceBindingData.m_bufferAccess);
|
||||
[static_cast<id<MTLComputeCommandEncoder>>(encoder) useResource:resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLBuffer>>() usage:resourceUsage];
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
AZ_Assert(false, "Undefined Resource type");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArgumentBuffer::ApplyUseResourceToGraphic(id<MTLCommandEncoder> encoder, RHI::ShaderStageMask visShaderMask, const ResourceBindingsSet& resourceBindingDataSet) const
|
||||
{
|
||||
|
||||
MTLRenderStages mtlRenderStages = GetRenderStages(visShaderMask);
|
||||
//Call UseResource on all resources for Compute stage
|
||||
for (const auto& key : resourcesToMakeResidentCompute)
|
||||
{
|
||||
[static_cast<id<MTLComputeCommandEncoder>>(commandEncoder) useResources: key.second.m_resourceArray.data()
|
||||
count: key.second.m_resourceArrayLen
|
||||
usage: key.first];
|
||||
}
|
||||
|
||||
//Call UseResource on all resources for Vertex and Fragment stages
|
||||
for (const auto& key : resourcesToMakeResidentGraphics)
|
||||
{
|
||||
[static_cast<id<MTLRenderCommandEncoder>>(commandEncoder) useResources: key.second.m_resourceArray.data()
|
||||
count: key.second.m_resourceArrayLen
|
||||
usage: key.first.first
|
||||
stages: key.first.second];
|
||||
}
|
||||
}
|
||||
|
||||
void ArgumentBuffer::ApplyUseResourceToCompute(id<MTLCommandEncoder> encoder, const ResourceBindingsSet& resourceBindingDataSet, ComputeResourcesToMakeResidentMap& resourcesToMakeResidentMap) const
|
||||
{
|
||||
for (const auto& resourceBindingData : resourceBindingDataSet)
|
||||
{
|
||||
ResourceType rescType = resourceBindingData.m_resourcPtr->GetResourceType();
|
||||
MTLResourceUsage resourceUsage = MTLResourceUsageRead;
|
||||
switch(rescType)
|
||||
{
|
||||
case ResourceType::MtlTextureType:
|
||||
{
|
||||
MTLResourceUsage resourceUsage = GetImageResourceUsage(resourceBindingData.m_imageAccess);
|
||||
[static_cast<id<MTLRenderCommandEncoder>>(encoder) useResource:resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLTexture>>()
|
||||
usage:resourceUsage
|
||||
stages:mtlRenderStages];
|
||||
|
||||
resourceUsage |= GetImageResourceUsage(resourceBindingData.m_imageAccess);
|
||||
break;
|
||||
}
|
||||
case ResourceType::MtlBufferType:
|
||||
{
|
||||
MTLResourceUsage resourceUsage = GetBufferResourceUsage(resourceBindingData.m_bufferAccess);
|
||||
[static_cast<id<MTLRenderCommandEncoder>>(encoder) useResource:resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLBuffer>>()
|
||||
usage:resourceUsage
|
||||
stages:mtlRenderStages];
|
||||
|
||||
resourceUsage |= GetBufferResourceUsage(resourceBindingData.m_bufferAccess);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -502,8 +473,38 @@ namespace AZ
|
||||
AZ_Assert(false, "Undefined Resource type");
|
||||
}
|
||||
}
|
||||
resourcesToMakeResidentMap[resourceUsage].m_resourceArray[resourcesToMakeResidentMap[resourceUsage].m_resourceArrayLen++] = resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLResource>>();
|
||||
}
|
||||
}
|
||||
|
||||
void ArgumentBuffer::ApplyUseResourceToGraphic(id<MTLCommandEncoder> encoder, RHI::ShaderStageMask visShaderMask, const ResourceBindingsSet& resourceBindingDataSet, GraphicsResourcesToMakeResidentMap& resourcesToMakeResidentMap) const
|
||||
{
|
||||
|
||||
MTLRenderStages mtlRenderStages = GetRenderStages(visShaderMask);
|
||||
MTLResourceUsage resourceUsage = MTLResourceUsageRead;
|
||||
for (const auto& resourceBindingData : resourceBindingDataSet)
|
||||
{
|
||||
ResourceType rescType = resourceBindingData.m_resourcPtr->GetResourceType();
|
||||
switch(rescType)
|
||||
{
|
||||
case ResourceType::MtlTextureType:
|
||||
{
|
||||
resourceUsage |= GetImageResourceUsage(resourceBindingData.m_imageAccess);
|
||||
break;
|
||||
}
|
||||
case ResourceType::MtlBufferType:
|
||||
{
|
||||
resourceUsage |= GetBufferResourceUsage(resourceBindingData.m_bufferAccess);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
AZ_Assert(false, "Undefined Resource type");
|
||||
}
|
||||
}
|
||||
AZStd::pair <MTLResourceUsage,MTLRenderStages> key = AZStd::make_pair(resourceUsage, mtlRenderStages);
|
||||
resourcesToMakeResidentMap[key].m_resourceArray[resourcesToMakeResidentMap[key].m_resourceArrayLen++] = resourceBindingData.m_resourcPtr->GetGpuAddress<id<MTLResource>>();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -119,8 +119,17 @@ namespace AZ
|
||||
using ResourceBindingsMap = AZStd::unordered_map<AZ::Name, ResourceBindingsSet>;
|
||||
ResourceBindingsMap m_resourceBindings;
|
||||
|
||||
void ApplyUseResourceToCompute(id<MTLCommandEncoder> encoder, const ResourceBindingsSet& resourceBindingData) const;
|
||||
void ApplyUseResourceToGraphic(id<MTLCommandEncoder> encoder, RHI::ShaderStageMask visShaderMask, const ResourceBindingsSet& resourceBindingDataSet) const;
|
||||
static const int MaxEntriesInArgTable = 31;
|
||||
struct MetalResourceArray
|
||||
{
|
||||
AZStd::array<id <MTLResource>, MaxEntriesInArgTable> m_resourceArray;
|
||||
int m_resourceArrayLen = 0;
|
||||
};
|
||||
using ComputeResourcesToMakeResidentMap = AZStd::unordered_map<MTLResourceUsage, MetalResourceArray>;
|
||||
using GraphicsResourcesToMakeResidentMap = AZStd::unordered_map<AZStd::pair<MTLResourceUsage,MTLRenderStages>, MetalResourceArray>;
|
||||
|
||||
void ApplyUseResourceToCompute(id<MTLCommandEncoder> encoder, const ResourceBindingsSet& resourceBindingData, ComputeResourcesToMakeResidentMap& resourcesToMakeResidentMap) const;
|
||||
void ApplyUseResourceToGraphic(id<MTLCommandEncoder> encoder, RHI::ShaderStageMask visShaderMask, const ResourceBindingsSet& resourceBindingDataSet, GraphicsResourcesToMakeResidentMap& resourcesToMakeResidentMap) const;
|
||||
//! Use visibility information to call UseResource on all resources for this Argument Buffer
|
||||
void ApplyUseResource(id<MTLCommandEncoder> encoder,
|
||||
const ResourceBindingsMap& resourceMap,
|
||||
@@ -144,8 +153,6 @@ namespace AZ
|
||||
#endif
|
||||
|
||||
ShaderResourceGroupPool* m_srgPool = nullptr;
|
||||
|
||||
static const int MaxEntriesInArgTable = 31;
|
||||
NSCache* m_samplerCache;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -258,24 +258,19 @@ namespace AZ
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t srgVisIndex = pipelineLayout.GetSlotByIndex(shaderResourceGroup->GetBindingSlot());
|
||||
const RHI::ShaderStageMask& srgVisInfo = pipelineLayout.GetSrgVisibility(srgVisIndex);
|
||||
|
||||
if (bindings.m_srgsByIndex[srgIndex] != shaderResourceGroup)
|
||||
{
|
||||
bindings.m_srgsByIndex[srgIndex] = shaderResourceGroup;
|
||||
auto& compiledArgBuffer = shaderResourceGroup->GetCompiledArgumentBuffer();
|
||||
|
||||
id<MTLBuffer> argBuffer = compiledArgBuffer.GetArgEncoderBuffer();
|
||||
size_t argBufferOffset = compiledArgBuffer.GetOffset();
|
||||
|
||||
uint32_t srgVisIndex = pipelineLayout.GetSlotByIndex(shaderResourceGroup->GetBindingSlot());
|
||||
const RHI::ShaderStageMask& srgVisInfo = pipelineLayout.GetSrgVisibility(srgVisIndex);
|
||||
|
||||
|
||||
if(srgVisInfo != RHI::ShaderStageMask::None)
|
||||
{
|
||||
const ShaderResourceGroupVisibility& srgResourcesVisInfo = pipelineLayout.GetSrgResourcesVisibility(srgVisIndex);
|
||||
|
||||
//For graphics and compute encoder bind the argument buffer and
|
||||
//make the resource resident for the duration of the work associated with the current scope
|
||||
//and ensure that it's in a format compatible with the appropriate metal function.
|
||||
//For graphics and compute encoder bind the argument buffer
|
||||
if(m_commandEncoderType == CommandEncoderType::Render)
|
||||
{
|
||||
id<MTLRenderCommandEncoder> renderEncoder = GetEncoder<id<MTLRenderCommandEncoder>>();
|
||||
@@ -293,7 +288,6 @@ namespace AZ
|
||||
offset:argBufferOffset
|
||||
atIndex:slotIndex];
|
||||
}
|
||||
shaderResourceGroup->AddUntrackedResourcesToEncoder(m_encoder, srgResourcesVisInfo);
|
||||
}
|
||||
else if(m_commandEncoderType == CommandEncoderType::Compute)
|
||||
{
|
||||
@@ -301,6 +295,28 @@ namespace AZ
|
||||
[computeEncoder setBuffer:argBuffer
|
||||
offset:argBufferOffset
|
||||
atIndex:pipelineLayout.GetSlotByIndex(srgIndex)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Check againgst the srg resources visibility hash as it is possible for draw items to have different PSO in the same pass.
|
||||
const AZ::HashValue64 srgResourcesVisHash = pipelineLayout.GetSrgResourcesVisibilityHash(srgVisIndex);
|
||||
if(bindings.m_srgVisHashByIndex[srgIndex] != srgResourcesVisHash)
|
||||
{
|
||||
bindings.m_srgVisHashByIndex[srgIndex] = srgResourcesVisHash;
|
||||
if(srgVisInfo != RHI::ShaderStageMask::None)
|
||||
{
|
||||
const ShaderResourceGroupVisibility& srgResourcesVisInfo = pipelineLayout.GetSrgResourcesVisibility(srgVisIndex);
|
||||
|
||||
//For graphics and compute encoder bind the argument buffer and
|
||||
//make the resource resident for the duration of the work associated with the current scope
|
||||
//and ensure that it's in a format compatible with the appropriate metal function.
|
||||
if(m_commandEncoderType == CommandEncoderType::Render)
|
||||
{
|
||||
shaderResourceGroup->AddUntrackedResourcesToEncoder(m_encoder, srgResourcesVisInfo);
|
||||
}
|
||||
else if(m_commandEncoderType == CommandEncoderType::Compute)
|
||||
{
|
||||
shaderResourceGroup->AddUntrackedResourcesToEncoder(m_encoder, srgResourcesVisInfo);
|
||||
}
|
||||
}
|
||||
@@ -447,6 +463,7 @@ namespace AZ
|
||||
for (size_t i = 0; i < bindings.m_srgsByIndex.size(); ++i)
|
||||
{
|
||||
bindings.m_srgsByIndex[i] = nullptr;
|
||||
bindings.m_srgVisHashByIndex[i] = AZ::HashValue64{0};
|
||||
}
|
||||
|
||||
const PipelineLayout& pipelineLayout = pipelineState->GetPipelineLayout();
|
||||
@@ -469,6 +486,10 @@ namespace AZ
|
||||
|
||||
void CommandList::SetStreamBuffers(const RHI::StreamBufferView* streams, uint32_t count)
|
||||
{
|
||||
int bufferArrayLen = 0;
|
||||
AZStd::array<id<MTLBuffer>, METAL_MAX_ENTRIES_BUFFER_ARG_TABLE> mtlStreamBuffers;
|
||||
AZStd::array<NSUInteger, METAL_MAX_ENTRIES_BUFFER_ARG_TABLE> mtlStreamBufferOffsets;
|
||||
|
||||
AZ::HashValue64 streamsHash = AZ::HashValue64{0};
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
{
|
||||
@@ -479,18 +500,23 @@ namespace AZ
|
||||
{
|
||||
m_state.m_streamsHash = streamsHash;
|
||||
AZ_Assert(count <= METAL_MAX_ENTRIES_BUFFER_ARG_TABLE , "Slots needed cannot exceed METAL_MAX_ENTRIES_BUFFER_ARG_TABLE");
|
||||
for (uint32_t i = 0; i < count; ++i)
|
||||
|
||||
NSRange range = {METAL_MAX_ENTRIES_BUFFER_ARG_TABLE - count, count};
|
||||
//For metal the stream buffers are populated from bottom to top as the top slots are taken by argument buffers
|
||||
for (int i = count-1; i >= 0; --i)
|
||||
{
|
||||
if (streams[i].GetBuffer())
|
||||
{
|
||||
const Buffer * buff = static_cast<const Buffer*>(streams[i].GetBuffer());
|
||||
id<MTLBuffer> mtlBuff = buff->GetMemoryView().GetGpuAddress<id<MTLBuffer>>();
|
||||
uint32_t VBIndex = (METAL_MAX_ENTRIES_BUFFER_ARG_TABLE - 1) - i;
|
||||
uint32_t offset = streams[i].GetByteOffset() + buff->GetMemoryView().GetOffset();
|
||||
id<MTLRenderCommandEncoder> renderEncoder = GetEncoder<id<MTLRenderCommandEncoder>>();
|
||||
[renderEncoder setVertexBuffer: mtlBuff offset: offset atIndex: VBIndex];
|
||||
mtlStreamBuffers[bufferArrayLen] = mtlBuff;
|
||||
mtlStreamBufferOffsets[bufferArrayLen] = offset;
|
||||
bufferArrayLen++;
|
||||
}
|
||||
}
|
||||
id<MTLRenderCommandEncoder> renderEncoder = GetEncoder<id<MTLRenderCommandEncoder>>();
|
||||
[renderEncoder setVertexBuffers: mtlStreamBuffers.data() offsets: mtlStreamBufferOffsets.data() withRange: range];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ namespace AZ
|
||||
{
|
||||
AZStd::array<const ShaderResourceGroup*, RHI::Limits::Pipeline::ShaderResourceGroupCountMax> m_srgsByIndex;
|
||||
AZStd::array<const ShaderResourceGroup*, RHI::Limits::Pipeline::ShaderResourceGroupCountMax> m_srgsBySlot;
|
||||
AZStd::array<AZ::HashValue64, RHI::Limits::Pipeline::ShaderResourceGroupCountMax> m_srgVisHashByIndex;
|
||||
};
|
||||
|
||||
ShaderResourceBindings& GetShaderResourceBindingsByPipelineType(RHI::PipelineStateType pipelineType);
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace AZ
|
||||
|
||||
m_srgVisibilities.resize(RHI::Limits::Pipeline::ShaderResourceGroupCountMax);
|
||||
m_srgResourcesVisibility.resize(RHI::Limits::Pipeline::ShaderResourceGroupCountMax);
|
||||
m_srgResourcesVisibilityHash.resize(RHI::Limits::Pipeline::ShaderResourceGroupCountMax);
|
||||
for (uint32_t srgLayoutIdx = 0; srgLayoutIdx < groupLayoutCount; ++srgLayoutIdx)
|
||||
{
|
||||
const RHI::ShaderResourceGroupLayout& srgLayout = *descriptor.GetShaderResourceGroupLayout(srgLayoutIdx);
|
||||
@@ -111,6 +112,7 @@ namespace AZ
|
||||
|
||||
m_srgVisibilities[srgIndex] = mask;
|
||||
m_srgResourcesVisibility[srgIndex] = srgVis;
|
||||
m_srgResourcesVisibilityHash[srgIndex] = srgVis.GetHash();
|
||||
}
|
||||
|
||||
// Cache the inline constant size and slot index
|
||||
@@ -141,6 +143,11 @@ namespace AZ
|
||||
return m_srgResourcesVisibility[index];
|
||||
}
|
||||
|
||||
const AZ::HashValue64 PipelineLayout::GetSrgResourcesVisibilityHash(uint32_t index) const
|
||||
{
|
||||
return m_srgResourcesVisibilityHash[index];
|
||||
}
|
||||
|
||||
uint32_t PipelineLayout::GetRootConstantsSize() const
|
||||
{
|
||||
return m_rootConstantsSize;
|
||||
|
||||
@@ -57,6 +57,9 @@ namespace AZ
|
||||
/// Returns srgVisibility data
|
||||
const ShaderResourceGroupVisibility& GetSrgResourcesVisibility(uint32_t index) const;
|
||||
|
||||
/// Returns srgVisibility hash
|
||||
const AZ::HashValue64 GetSrgResourcesVisibilityHash(uint32_t index) const;
|
||||
|
||||
/// Returns the root constant specific layout information
|
||||
uint32_t GetRootConstantsSize() const;
|
||||
uint32_t GetRootConstantsSlotIndex() const;
|
||||
@@ -84,6 +87,9 @@ namespace AZ
|
||||
/// Cache Visibility across all the resources within the SRG
|
||||
AZStd::fixed_vector<ShaderResourceGroupVisibility, RHI::Limits::Pipeline::ShaderResourceGroupCountMax> m_srgResourcesVisibility;
|
||||
|
||||
/// Cache Visibility hash across all the resources within the SRG
|
||||
AZStd::fixed_vector<AZ::HashValue64, RHI::Limits::Pipeline::ShaderResourceGroupCountMax> m_srgResourcesVisibilityHash;
|
||||
|
||||
uint32_t m_rootConstantSlotIndex = (uint32_t)-1;
|
||||
uint32_t m_rootConstantsSize = 0;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user