diff options
| author | Gangzheng Tong <tonggangzheng@gmail.com> | 2025-07-08 23:44:56 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-09 06:44:56 +0000 |
| commit | 43d0c2100ef1a5df4b54525e50eb29fe7c39ec16 (patch) | |
| tree | 25ec4fb9c726115f90bdaa9878f2f4ca372ad0a6 /tools/gfx-util/shader-cursor.cpp | |
| parent | 00746bf09047cdf01c19dac513a532bcf3ed3ea3 (diff) | |
Convert gfx unit tests and examples to use slang-rhi (#7577)
* Port first gfx unit test to slang-rhi
* port triangle example to use slang-rhi
* port platform-test to slang-rhi
* Update platform-test to throttle mouse move events
* port gpu-printing example to use slang-rhi
* port model-viewer example to use slang-rhi
* port ray-tracing example to use slang-rhi
* port ray-tracing pipeline example to use slang-rhi
* port reflection parameter blocks example to use slang-rhi
* port shader-object example to use slang-rhi
* port shader-toy example to use slang-rhi
* Port most of tests to slang-rhi
* port link-time-constant-array-size to use slang-rhi
* Fix tests and find matching tests in slang-rhi
* port autodiff-texture
* remove gfx target; port nv-aftermath-example
* update include path for shader-cursor.h
* Disabled 2 more ported tests
* fix build error
* remove gfx test
* put slang-rhi (static-lib) before slang (shared)
* format code (#7621)
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* add debug callback
* format code (#7649)
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
* Address review comments; revert back to use SLANG_CHECK_MSG
---------
Co-authored-by: slangbot <ellieh+slangbot@nvidia.com>
Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
Diffstat (limited to 'tools/gfx-util/shader-cursor.cpp')
| -rw-r--r-- | tools/gfx-util/shader-cursor.cpp | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/tools/gfx-util/shader-cursor.cpp b/tools/gfx-util/shader-cursor.cpp deleted file mode 100644 index 80d674768..000000000 --- a/tools/gfx-util/shader-cursor.cpp +++ /dev/null @@ -1,379 +0,0 @@ -#include "shader-cursor.h" - -namespace gfx -{ - -Result gfx::ShaderCursor::getDereferenced(ShaderCursor& outCursor) const -{ - switch (m_typeLayout->getKind()) - { - default: - return SLANG_E_INVALID_ARG; - - case slang::TypeReflection::Kind::ConstantBuffer: - case slang::TypeReflection::Kind::ParameterBlock: - { - auto subObject = m_baseObject->getObject(m_offset); - outCursor = ShaderCursor(subObject); - return SLANG_OK; - } - } -} - -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. - // - if (!isValid()) - return SLANG_E_INVALID_ARG; - - // If the cursor is valid, we want to consider the type of data - // it is referencing. - // - switch (m_typeLayout->getKind()) - { - // The easy/expected case is when the value has a structure type. - // - case slang::TypeReflection::Kind::Struct: - { - // We start by looking up the index of a field matching `name`. - // - // If there is no such field, we have an error. - // - SlangInt fieldIndex = m_typeLayout->findFieldIndexByName(name, nameEnd); - if (fieldIndex == -1) - break; - - // Once we know the index of the field being referenced, - // we create a cursor to point at the field, based on - // the offset information already in this cursor, plus - // offsets derived from the field's layout. - // - slang::VariableLayoutReflection* fieldLayout = - m_typeLayout->getFieldByIndex((unsigned int)fieldIndex); - ShaderCursor fieldCursor; - - // The field cursorwill point into the same parent object. - // - fieldCursor.m_baseObject = m_baseObject; - - // The type being pointed to is the tyep of the field. - // - fieldCursor.m_typeLayout = fieldLayout->getTypeLayout(); - - // The byte offset is the current offset plus the relative offset of the field. - // The offset in binding ranges is computed similarly. - // - fieldCursor.m_offset.uniformOffset = m_offset.uniformOffset + fieldLayout->getOffset(); - fieldCursor.m_offset.bindingRangeIndex = - m_offset.bindingRangeIndex + - (GfxIndex)m_typeLayout->getFieldBindingRangeOffset(fieldIndex); - - // The index of the field 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 structures with texture-type - // fields. Suppose we have: - // - // struct S { Texture2D t; Texture2D u; } - // S g[4]; - // - // In this scenario, `g` holds two binding ranges: - // - // * Range #0 comprises 4 textures, representing `g[...].t` - // * Range #1 comprises 4 textures, representing `g[...].u` - // - // A cursor for `g[2]` would have a `bindingRangeIndex` of zero but - // a `bindingArrayIndex` of 2, iindicating 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].u` 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].u` is stored in range #1 at array index 2. - // - fieldCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex; - - outCursor = fieldCursor; - return SLANG_OK; - } - break; - - // In some cases the user might be trying to acess a field by name - // from a cursor that references a constant buffer or parameter block, - // and in these cases we want the access to Just Work. - // - case slang::TypeReflection::Kind::ConstantBuffer: - case slang::TypeReflection::Kind::ParameterBlock: - { - // We basically need to "dereference" the current cursor - // to go from a pointer to a constant buffer to a pointer - // to the *contents* of the constant buffer. - // - ShaderCursor d = getDereferenced(); - return d.getField(name, nameEnd, outCursor); - } - break; - } - - // If a cursor is pointing at a root shader object (created for a - // program), then we will also iterate over the entry point shader - // objects attached to it and look for a matching parameter name - // on them. - // - // This is a bit of "do what I mean" logic and could potentially - // lead to problems if there could be multiple entry points with - // the same parameter name. - // - // TODO: figure out whether we should support this long-term. - // - auto entryPointCount = (GfxIndex)m_baseObject->getEntryPointCount(); - for (GfxIndex e = 0; e < entryPointCount; ++e) - { - ComPtr<IShaderObject> entryPoint; - m_baseObject->getEntryPoint(e, entryPoint.writeRef()); - - ShaderCursor entryPointCursor(entryPoint); - - auto result = entryPointCursor.getField(name, nameEnd, outCursor); - if (SLANG_SUCCEEDED(result)) - return result; - } - - return SLANG_E_INVALID_ARG; -} - -ShaderCursor ShaderCursor::getElement(GfxIndex index) const -{ - if (m_containerType != ShaderObjectContainerType::None) - { - ShaderCursor elementCursor; - elementCursor.m_baseObject = m_baseObject; - elementCursor.m_typeLayout = m_typeLayout->getElementTypeLayout(); - elementCursor.m_containerType = m_containerType; - elementCursor.m_offset.uniformOffset = index * m_typeLayout->getStride(); - elementCursor.m_offset.bindingRangeIndex = 0; - elementCursor.m_offset.bindingArrayIndex = index; - return elementCursor; - } - - switch (m_typeLayout->getKind()) - { - case slang::TypeReflection::Kind::Array: - { - ShaderCursor elementCursor; - elementCursor.m_baseObject = m_baseObject; - elementCursor.m_typeLayout = m_typeLayout->getElementTypeLayout(); - elementCursor.m_offset.uniformOffset = - m_offset.uniformOffset + - index * m_typeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM); - elementCursor.m_offset.bindingRangeIndex = m_offset.bindingRangeIndex; - elementCursor.m_offset.bindingArrayIndex = - m_offset.bindingArrayIndex * (GfxCount)m_typeLayout->getElementCount() + index; - return elementCursor; - } - break; - - case slang::TypeReflection::Kind::Struct: - { - // The logic here is similar to `getField()` except that we don't - // need to look up the field index based on a name first. - // - auto fieldIndex = index; - slang::VariableLayoutReflection* fieldLayout = - m_typeLayout->getFieldByIndex((unsigned int)fieldIndex); - if (!fieldLayout) - return ShaderCursor(); - - ShaderCursor fieldCursor; - fieldCursor.m_baseObject = m_baseObject; - fieldCursor.m_typeLayout = fieldLayout->getTypeLayout(); - fieldCursor.m_offset.uniformOffset = m_offset.uniformOffset + fieldLayout->getOffset(); - fieldCursor.m_offset.bindingRangeIndex = - m_offset.bindingRangeIndex + - (GfxIndex)m_typeLayout->getFieldBindingRangeOffset(fieldIndex); - fieldCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex; - - return fieldCursor; - } - break; - - case slang::TypeReflection::Kind::Vector: - case slang::TypeReflection::Kind::Matrix: - { - ShaderCursor fieldCursor; - fieldCursor.m_baseObject = m_baseObject; - fieldCursor.m_typeLayout = m_typeLayout->getElementTypeLayout(); - fieldCursor.m_offset.uniformOffset = - m_offset.uniformOffset + - m_typeLayout->getElementStride(SLANG_PARAMETER_CATEGORY_UNIFORM) * index; - fieldCursor.m_offset.bindingRangeIndex = m_offset.bindingRangeIndex; - fieldCursor.m_offset.bindingArrayIndex = m_offset.bindingArrayIndex; - return fieldCursor; - } - break; - } - - return ShaderCursor(); -} - - -static int _peek(const char* slice) -{ - const char* b = slice; - if (!b || !*b) - return -1; - return *b; -} - -static int _get(const char*& slice) -{ - const char* b = slice; - if (!b || !*b) - return -1; - auto result = *b++; - slice = b; - return result; -} - -Result ShaderCursor::followPath(const char* path, ShaderCursor& ioCursor) -{ - ShaderCursor cursor = ioCursor; - - enum - { - ALLOW_NAME = 0x1, - ALLOW_SUBSCRIPT = 0x2, - ALLOW_DOT = 0x4, - }; - int state = ALLOW_NAME | ALLOW_SUBSCRIPT; - - const char* rest = path; - for (;;) - { - int c = _peek(rest); - - if (c == -1) - break; - else if (c == '.') - { - if (!(state & ALLOW_DOT)) - return SLANG_E_INVALID_ARG; - - _get(rest); - state = ALLOW_NAME; - continue; - } - else if (c == '[') - { - if (!(state & ALLOW_SUBSCRIPT)) - return SLANG_E_INVALID_ARG; - - _get(rest); - GfxCount index = 0; - while (_peek(rest) != ']') - { - int d = _get(rest); - if (d >= '0' && d <= '9') - { - index = index * 10 + (d - '0'); - } - else - { - return SLANG_E_INVALID_ARG; - } - } - - if (_peek(rest) != ']') - return SLANG_E_INVALID_ARG; - _get(rest); - - cursor = cursor.getElement(index); - state = ALLOW_DOT | ALLOW_SUBSCRIPT; - continue; - } - else - { - const char* nameBegin = rest; - for (;;) - { - switch (_peek(rest)) - { - default: - _get(rest); - continue; - - case -1: - case '.': - case '[': - break; - } - break; - } - char const* nameEnd = rest; - ShaderCursor newCursor; - cursor.getField(nameBegin, nameEnd, newCursor); - cursor = newCursor; - state = ALLOW_DOT | ALLOW_SUBSCRIPT; - continue; - } - } - - ioCursor = cursor; - return SLANG_OK; -} - -} // namespace gfx |
