Skip to content

Commit dfd74af

Browse files
SPIRVShaderResources: make resource data offset handling more flexible
1 parent 0aba2a3 commit dfd74af

File tree

2 files changed

+95
-75
lines changed

2 files changed

+95
-75
lines changed

Graphics/ShaderTools/include/SPIRVShaderResources.hpp

Lines changed: 78 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -224,39 +224,73 @@ class SPIRVShaderResources
224224

225225
~SPIRVShaderResources();
226226

227+
enum class ResourceClass : Uint8
228+
{
229+
UniformBuffer,
230+
StorageBuffer,
231+
StorageImage,
232+
SampledImage,
233+
AtomicCounter,
234+
SeparateSampler,
235+
SeparateImage,
236+
InputAttachment,
237+
AccelStruct,
238+
PushConstant,
239+
NumClasses
240+
};
241+
242+
Uint32 GetNumResources(ResourceClass ResClass) const noexcept
243+
{
244+
VERIFY(static_cast<size_t>(ResClass) < static_cast<size_t>(ResourceClass::NumClasses), "Invalid resource class");
245+
return m_Offsets[static_cast<size_t>(ResClass) + 1] - m_Offsets[static_cast<size_t>(ResClass)];
246+
}
247+
248+
const SPIRVShaderResourceAttribs& GetResAttribs(ResourceClass ResClass, Uint32 n) const noexcept
249+
{
250+
VERIFY(n < GetNumResources(ResClass), "Resource index (", n, ") is out of range. Resource count: ", GetNumResources(ResClass));
251+
OffsetType Offset = m_Offsets[static_cast<size_t>(ResClass)];
252+
return GetResource(Offset + n);
253+
}
254+
255+
const SPIRVShaderResourceAttribs& GetResource(Uint32 n) const noexcept
256+
{
257+
VERIFY(n < GetTotalResources(), "Resource index (", n, ") is out of range. Total resource count: ", GetTotalResources());
258+
return reinterpret_cast<const SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get())[n];
259+
}
260+
227261
// clang-format off
228262

229-
Uint32 GetNumUBs ()const noexcept{ return (m_StorageBufferOffset - 0); }
230-
Uint32 GetNumSBs ()const noexcept{ return (m_StorageImageOffset - m_StorageBufferOffset); }
231-
Uint32 GetNumImgs ()const noexcept{ return (m_SampledImageOffset - m_StorageImageOffset); }
232-
Uint32 GetNumSmpldImgs ()const noexcept{ return (m_AtomicCounterOffset - m_SampledImageOffset); }
233-
Uint32 GetNumACs ()const noexcept{ return (m_SeparateSamplerOffset - m_AtomicCounterOffset); }
234-
Uint32 GetNumSepSmplrs ()const noexcept{ return (m_SeparateImageOffset - m_SeparateSamplerOffset); }
235-
Uint32 GetNumSepImgs ()const noexcept{ return (m_InputAttachmentOffset - m_SeparateImageOffset); }
236-
Uint32 GetNumInptAtts ()const noexcept{ return (m_AccelStructOffset - m_InputAttachmentOffset); }
237-
Uint32 GetNumAccelStructs ()const noexcept{ return (m_PushConstantOffset - m_AccelStructOffset); }
238-
Uint32 GetNumPushConstants()const noexcept{ return (m_TotalResources - m_PushConstantOffset); }
239-
Uint32 GetTotalResources () const noexcept { return m_TotalResources; }
263+
Uint32 GetNumUBs ()const noexcept{ return GetNumResources(ResourceClass::UniformBuffer); }
264+
Uint32 GetNumSBs ()const noexcept{ return GetNumResources(ResourceClass::StorageBuffer); }
265+
Uint32 GetNumImgs ()const noexcept{ return GetNumResources(ResourceClass::StorageImage); }
266+
Uint32 GetNumSmpldImgs ()const noexcept{ return GetNumResources(ResourceClass::SampledImage); }
267+
Uint32 GetNumACs ()const noexcept{ return GetNumResources(ResourceClass::AtomicCounter); }
268+
Uint32 GetNumSepSmplrs ()const noexcept{ return GetNumResources(ResourceClass::SeparateSampler); }
269+
Uint32 GetNumSepImgs ()const noexcept{ return GetNumResources(ResourceClass::SeparateImage); }
270+
Uint32 GetNumInptAtts ()const noexcept{ return GetNumResources(ResourceClass::InputAttachment); }
271+
Uint32 GetNumAccelStructs ()const noexcept{ return GetNumResources(ResourceClass::AccelStruct); }
272+
Uint32 GetNumPushConstants()const noexcept{ return GetNumResources(ResourceClass::PushConstant); }
273+
274+
Uint32 GetTotalResources() const noexcept { return m_Offsets[static_cast<size_t>(ResourceClass::NumClasses)]; }
240275
Uint32 GetNumShaderStageInputs()const noexcept { return m_NumShaderStageInputs; }
241276

242-
const SPIRVShaderResourceAttribs& GetUB (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumUBs(), 0 ); }
243-
const SPIRVShaderResourceAttribs& GetSB (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSBs(), m_StorageBufferOffset ); }
244-
const SPIRVShaderResourceAttribs& GetImg (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumImgs(), m_StorageImageOffset ); }
245-
const SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSmpldImgs(), m_SampledImageOffset ); }
246-
const SPIRVShaderResourceAttribs& GetAC (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumACs(), m_AtomicCounterOffset ); }
247-
const SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSepSmplrs(), m_SeparateSamplerOffset ); }
248-
const SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumSepImgs(), m_SeparateImageOffset ); }
249-
const SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumInptAtts(), m_InputAttachmentOffset ); }
250-
const SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)const noexcept{ return GetResAttribs(n, GetNumAccelStructs(), m_AccelStructOffset ); }
251-
const SPIRVShaderResourceAttribs& GetPushConstant(Uint32 n)const noexcept{ return GetResAttribs(n, GetNumPushConstants(), m_PushConstantOffset ); }
252-
const SPIRVShaderResourceAttribs& GetResource (Uint32 n)const noexcept{ return GetResAttribs(n, GetTotalResources(), 0 ); }
277+
const SPIRVShaderResourceAttribs& GetUB (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::UniformBuffer, n); }
278+
const SPIRVShaderResourceAttribs& GetSB (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::StorageBuffer, n); }
279+
const SPIRVShaderResourceAttribs& GetImg (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::StorageImage, n); }
280+
const SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::SampledImage, n); }
281+
const SPIRVShaderResourceAttribs& GetAC (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::AtomicCounter, n); }
282+
const SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::SeparateSampler, n); }
283+
const SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::SeparateImage, n); }
284+
const SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::InputAttachment, n); }
285+
const SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::AccelStruct, n); }
286+
const SPIRVShaderResourceAttribs& GetPushConstant(Uint32 n)const noexcept{ return GetResAttribs(ResourceClass::PushConstant, n); }
253287

254288
// clang-format on
255289

256290
const SPIRVShaderStageInputAttribs& GetShaderStageInputAttribs(Uint32 n) const noexcept
257291
{
258292
VERIFY(n < m_NumShaderStageInputs, "Shader stage input index (", n, ") is out of range. Total input count: ", m_NumShaderStageInputs);
259-
const SPIRVShaderResourceAttribs* ResourceMemoryEnd = reinterpret_cast<const SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get()) + m_TotalResources;
293+
const SPIRVShaderResourceAttribs* ResourceMemoryEnd = reinterpret_cast<const SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get()) + GetTotalResources();
260294
return reinterpret_cast<const SPIRVShaderStageInputAttribs*>(ResourceMemoryEnd)[n];
261295
}
262296

@@ -415,34 +449,30 @@ class SPIRVShaderResources
415449
size_t ResourceNamesPoolSize,
416450
StringPool& ResourceNamesPool);
417451

418-
SPIRVShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) noexcept
452+
SPIRVShaderResourceAttribs& GetResAttribs(ResourceClass ResClass, Uint32 n) noexcept
419453
{
420-
VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Total resource count: ", NumResources);
421-
VERIFY_EXPR(Offset + n < m_TotalResources);
422-
return reinterpret_cast<SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n];
454+
VERIFY(n < GetNumResources(ResClass), "Resource index (", n, ") is out of range. Resource count: ", GetNumResources(ResClass));
455+
OffsetType Offset = m_Offsets[static_cast<size_t>(ResClass)];
456+
return GetResource(Offset + n);
423457
}
424458

425-
const SPIRVShaderResourceAttribs& GetResAttribs(Uint32 n, Uint32 NumResources, Uint32 Offset) const noexcept
459+
SPIRVShaderResourceAttribs& GetResource(Uint32 n) noexcept
426460
{
427-
VERIFY(n < NumResources, "Resource index (", n, ") is out of range. Total resource count: ", NumResources);
428-
VERIFY_EXPR(Offset + n < m_TotalResources);
429-
return reinterpret_cast<SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get())[Offset + n];
461+
VERIFY(n < GetTotalResources(), "Resource index (", n, ") is out of range. Total resource count: ", GetTotalResources());
462+
return reinterpret_cast<SPIRVShaderResourceAttribs*>(m_MemoryBuffer.get())[n];
430463
}
431464

432465
// clang-format off
433-
434-
SPIRVShaderResourceAttribs& GetUB (Uint32 n)noexcept{ return GetResAttribs(n, GetNumUBs(), 0 ); }
435-
SPIRVShaderResourceAttribs& GetSB (Uint32 n)noexcept{ return GetResAttribs(n, GetNumSBs(), m_StorageBufferOffset ); }
436-
SPIRVShaderResourceAttribs& GetImg (Uint32 n)noexcept{ return GetResAttribs(n, GetNumImgs(), m_StorageImageOffset ); }
437-
SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)noexcept{ return GetResAttribs(n, GetNumSmpldImgs(), m_SampledImageOffset ); }
438-
SPIRVShaderResourceAttribs& GetAC (Uint32 n)noexcept{ return GetResAttribs(n, GetNumACs(), m_AtomicCounterOffset ); }
439-
SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)noexcept{ return GetResAttribs(n, GetNumSepSmplrs(), m_SeparateSamplerOffset ); }
440-
SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)noexcept{ return GetResAttribs(n, GetNumSepImgs(), m_SeparateImageOffset ); }
441-
SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)noexcept{ return GetResAttribs(n, GetNumInptAtts(), m_InputAttachmentOffset ); }
442-
SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)noexcept{ return GetResAttribs(n, GetNumAccelStructs(), m_AccelStructOffset ); }
443-
SPIRVShaderResourceAttribs& GetPushConstant(Uint32 n)noexcept{ return GetResAttribs(n, GetNumPushConstants(), m_PushConstantOffset ); }
444-
SPIRVShaderResourceAttribs& GetResource (Uint32 n)noexcept{ return GetResAttribs(n, GetTotalResources(), 0 ); }
445-
466+
SPIRVShaderResourceAttribs& GetUB (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::UniformBuffer, n); }
467+
SPIRVShaderResourceAttribs& GetSB (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::StorageBuffer, n); }
468+
SPIRVShaderResourceAttribs& GetImg (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::StorageImage, n); }
469+
SPIRVShaderResourceAttribs& GetSmpldImg (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::SampledImage, n); }
470+
SPIRVShaderResourceAttribs& GetAC (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::AtomicCounter, n); }
471+
SPIRVShaderResourceAttribs& GetSepSmplr (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::SeparateSampler, n); }
472+
SPIRVShaderResourceAttribs& GetSepImg (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::SeparateImage, n); }
473+
SPIRVShaderResourceAttribs& GetInptAtt (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::InputAttachment, n); }
474+
SPIRVShaderResourceAttribs& GetAccelStruct (Uint32 n)noexcept{ return GetResAttribs(ResourceClass::AccelStruct, n); }
475+
SPIRVShaderResourceAttribs& GetPushConstant(Uint32 n)noexcept{ return GetResAttribs(ResourceClass::PushConstant, n); }
446476
// clang-format on
447477

448478
SPIRVShaderStageInputAttribs& GetShaderStageInputAttribs(Uint32 n) noexcept
@@ -458,18 +488,10 @@ class SPIRVShaderResources
458488
const char* m_CombinedSamplerSuffix = nullptr;
459489
const char* m_ShaderName = nullptr;
460490

461-
using OffsetType = Uint16;
462-
OffsetType m_StorageBufferOffset = 0;
463-
OffsetType m_StorageImageOffset = 0;
464-
OffsetType m_SampledImageOffset = 0;
465-
OffsetType m_AtomicCounterOffset = 0;
466-
OffsetType m_SeparateSamplerOffset = 0;
467-
OffsetType m_SeparateImageOffset = 0;
468-
OffsetType m_InputAttachmentOffset = 0;
469-
OffsetType m_AccelStructOffset = 0;
470-
OffsetType m_PushConstantOffset = 0;
471-
OffsetType m_TotalResources = 0;
472-
OffsetType m_NumShaderStageInputs = 0;
491+
using OffsetType = Uint16;
492+
std::array<OffsetType, static_cast<size_t>(ResourceClass::NumClasses) + 1> m_Offsets;
493+
494+
OffsetType m_NumShaderStageInputs = 0;
473495

474496
SHADER_TYPE m_ShaderType = SHADER_TYPE_UNKNOWN;
475497

Graphics/ShaderTools/src/SPIRVShaderResources.cpp

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -862,28 +862,26 @@ void SPIRVShaderResources::Initialize(IMemoryAllocator& Allocator,
862862
size_t ResourceNamesPoolSize,
863863
StringPool& ResourceNamesPool)
864864
{
865-
Uint32 CurrentOffset = 0;
866-
constexpr Uint32 MaxOffset = std::numeric_limits<OffsetType>::max();
867-
auto AdvanceOffset = [&CurrentOffset, MaxOffset](Uint32 NumResources) {
865+
constexpr Uint32 MaxOffset = std::numeric_limits<OffsetType>::max();
866+
867+
auto SetOffset = [CurrentOffset = 0, MaxOffset, this](ResourceClass ResClass, Uint32 NumResources) mutable {
868868
VERIFY(CurrentOffset <= MaxOffset, "Current offset (", CurrentOffset, ") exceeds max allowed value (", MaxOffset, ")");
869869
(void)MaxOffset;
870-
OffsetType Offset = static_cast<OffsetType>(CurrentOffset);
870+
m_Offsets[static_cast<size_t>(ResClass)] = static_cast<OffsetType>(CurrentOffset);
871871
CurrentOffset += NumResources;
872-
return Offset;
873872
};
874873

875-
OffsetType UniformBufferOffset = AdvanceOffset(Counters.NumUBs);
876-
(void)UniformBufferOffset;
877-
m_StorageBufferOffset = AdvanceOffset(Counters.NumSBs);
878-
m_StorageImageOffset = AdvanceOffset(Counters.NumImgs);
879-
m_SampledImageOffset = AdvanceOffset(Counters.NumSmpldImgs);
880-
m_AtomicCounterOffset = AdvanceOffset(Counters.NumACs);
881-
m_SeparateSamplerOffset = AdvanceOffset(Counters.NumSepSmplrs);
882-
m_SeparateImageOffset = AdvanceOffset(Counters.NumSepImgs);
883-
m_InputAttachmentOffset = AdvanceOffset(Counters.NumInptAtts);
884-
m_AccelStructOffset = AdvanceOffset(Counters.NumAccelStructs);
885-
m_PushConstantOffset = AdvanceOffset(Counters.NumPushConstants);
886-
m_TotalResources = AdvanceOffset(0);
874+
SetOffset(ResourceClass::UniformBuffer, Counters.NumUBs);
875+
SetOffset(ResourceClass::StorageBuffer, Counters.NumSBs);
876+
SetOffset(ResourceClass::StorageImage, Counters.NumImgs);
877+
SetOffset(ResourceClass::SampledImage, Counters.NumSmpldImgs);
878+
SetOffset(ResourceClass::AtomicCounter, Counters.NumACs);
879+
SetOffset(ResourceClass::SeparateSampler, Counters.NumSepSmplrs);
880+
SetOffset(ResourceClass::SeparateImage, Counters.NumSepImgs);
881+
SetOffset(ResourceClass::InputAttachment, Counters.NumInptAtts);
882+
SetOffset(ResourceClass::AccelStruct, Counters.NumAccelStructs);
883+
SetOffset(ResourceClass::PushConstant, Counters.NumPushConstants);
884+
SetOffset(ResourceClass::NumClasses, 0);
887885
static_assert(Uint32{SPIRVShaderResourceAttribs::ResourceType::NumResourceTypes} == 13, "Please update the new resource type offset");
888886

889887
VERIFY(NumShaderStageInputs <= MaxOffset, "Max offset exceeded");
@@ -893,7 +891,7 @@ void SPIRVShaderResources::Initialize(IMemoryAllocator& Allocator,
893891

894892
static_assert(sizeof(SPIRVShaderResourceAttribs) % sizeof(void*) == 0, "Size of SPIRVShaderResourceAttribs struct must be multiple of sizeof(void*)");
895893
// clang-format off
896-
size_t MemorySize = m_TotalResources * sizeof(SPIRVShaderResourceAttribs) +
894+
size_t MemorySize = GetTotalResources() * sizeof(SPIRVShaderResourceAttribs) +
897895
m_NumShaderStageInputs * sizeof(SPIRVShaderStageInputAttribs) +
898896
AlignedResourceNamesPoolSize * sizeof(char);
899897

@@ -915,7 +913,7 @@ void SPIRVShaderResources::Initialize(IMemoryAllocator& Allocator,
915913
void* pRawMem = Allocator.Allocate(MemorySize, "Memory for shader resources", __FILE__, __LINE__);
916914
m_MemoryBuffer = std::unique_ptr<void, STDDeleterRawMem<void>>(pRawMem, Allocator);
917915
char* NamesPool = reinterpret_cast<char*>(m_MemoryBuffer.get()) +
918-
m_TotalResources * sizeof(SPIRVShaderResourceAttribs) +
916+
GetTotalResources() * sizeof(SPIRVShaderResourceAttribs) +
919917
m_NumShaderStageInputs * sizeof(SPIRVShaderStageInputAttribs);
920918
ResourceNamesPool.AssignMemory(NamesPool, ResourceNamesPoolSize);
921919
}

0 commit comments

Comments
 (0)