From 7826afcaad78cc33c976bb3db3cdc9eada4c77e8 Mon Sep 17 00:00:00 2001 From: Ellie Hermaszewska Date: Wed, 18 Oct 2023 06:26:00 +0800 Subject: Type layouts for structured buffers with counters (#3269) * More tests for append structured buffer * Append and Consume structured buffer tests for DX12 * neaten * test wobble * Add counter layout information to append/consume structured buffers * add getRWStructuredBufferType * Correct definition of get size for append/consume structured buffers * tweak append structured buffer test * Allow initializing counter buffer in render test * vulkan test for consume structured buffer * Handle null counterVarLayout in getExplicitCounterBindingRangeOffset * remove dead code * Implement atomic counter increment/decrement for spirv * explicit spirv test * Add missing check on result * Hold on to counter resources --------- Co-authored-by: Yong He --- tools/gfx-util/shader-cursor.cpp | 52 ++++++++++++++++++++++++++++++++++++++++ tools/gfx-util/shader-cursor.h | 7 ++++++ 2 files changed, 59 insertions(+) (limited to 'tools/gfx-util') diff --git a/tools/gfx-util/shader-cursor.cpp b/tools/gfx-util/shader-cursor.cpp index 5a2cdfd33..c849673bf 100644 --- a/tools/gfx-util/shader-cursor.cpp +++ b/tools/gfx-util/shader-cursor.cpp @@ -20,6 +20,58 @@ Result gfx::ShaderCursor::getDereferenced(ShaderCursor& outCursor) const } } +ShaderCursor ShaderCursor::getExplicitCounter() const +{ + // Similar to getField below + + // The alternative to handling this here would be to augment IResourceView + // with a `getCounterResourceView()`, and set that also in `setResource` + if(const auto counterVarLayout = m_typeLayout->getExplicitCounter()) + { + ShaderCursor counterCursor; + + // The counter cursor will point into the same parent object. + counterCursor.m_baseObject = m_baseObject; + + // The type being pointed to is the type of the field. + counterCursor.m_typeLayout = counterVarLayout->getTypeLayout(); + + // The byte offset is the current offset plus the relative offset of the counter. + // The offset in binding ranges is computed similarly. + counterCursor.m_offset.uniformOffset + = m_offset.uniformOffset + SlangInt(counterVarLayout->getOffset()); + counterCursor.m_offset.bindingRangeIndex + = m_offset.bindingRangeIndex + GfxIndex(m_typeLayout->getExplicitCounterBindingRangeOffset()); + + // The index of the counter within any binding ranges will be the same + // as the index computed for the parent structure. + // + // Note: this case would arise for an array of structured buffers + // + // AppendStructuredBuffer g[4]; + // + // In this scenario, `g` holds two binding ranges: + // + // * Range #0 comprises 4 element buffers, representing `g[...].elements` + // * Range #1 comprises 4 counter buffers, representing `g[...].counter` + // + // A cursor for `g[2]` would have a `bindingRangeIndex` of zero but + // a `bindingArrayIndex` of 2, indicating that we could end up + // referencing either range, but no matter what we know the index + // is 2. Thus when we form a cursor for `g[2].counter` we want to + // apply the binding range offset to get a `bindingRangeIndex` of + // 1, while the `bindingArrayIndex` is unmodified. + // + // The result is that `g[2].counter` is stored in range #1 at array index 2. + // + counterCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex; + + return counterCursor; + } + // Otherwise, return an invalid cursor + return ShaderCursor{}; +} + Result ShaderCursor::getField(const char* name, const char* nameEnd, ShaderCursor& outCursor) const { // If this cursor is invalid, then can't possible fetch a field. diff --git a/tools/gfx-util/shader-cursor.h b/tools/gfx-util/shader-cursor.h index 5dfc57f6d..3d35bb2ed 100644 --- a/tools/gfx-util/shader-cursor.h +++ b/tools/gfx-util/shader-cursor.h @@ -63,6 +63,13 @@ struct ShaderCursor return cursor; } + /// Some resources such as RWStructuredBuffer, AppendStructuredBuffer and + /// ConsumeStructuredBuffer need to have their counter explicitly bound on + /// APIs other than DirectX, this will return a valid ShaderCursor pointing + /// to that resource if that is the case. + /// Otherwise, this returns an invalid cursor. + ShaderCursor getExplicitCounter() const; + ShaderCursor getElement(GfxIndex index) const; static Result followPath(const char* path, ShaderCursor& ioCursor); -- cgit v1.2.3