summaryrefslogtreecommitdiff
path: root/tools/gfx/shader-cursor.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-01-17 22:00:49 -0800
committerGitHub <noreply@github.com>2021-01-17 22:00:49 -0800
commit1296c7bb55b14db24308f31cacdda7f7a71fc937 (patch)
tree935ebf1e829361a17f98f5ead3460998719acf42 /tools/gfx/shader-cursor.cpp
parent2a5d5b32348c33aac7ca62aa9a4c2bb7cff8e08a (diff)
Make `gfx` compile to a DLL. (#1660)
* Make `gfx` compile to a DLL. * Fix cuda * Fix cuda build * Bug gl screen capture bug.
Diffstat (limited to 'tools/gfx/shader-cursor.cpp')
-rw-r--r--tools/gfx/shader-cursor.cpp249
1 files changed, 0 insertions, 249 deletions
diff --git a/tools/gfx/shader-cursor.cpp b/tools/gfx/shader-cursor.cpp
deleted file mode 100644
index 65cf2f8ac..000000000
--- a/tools/gfx/shader-cursor.cpp
+++ /dev/null
@@ -1,249 +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;
- }
- }
-}
-
-Result ShaderCursor::getField(Slang::UnownedStringSlice const& name, ShaderCursor& outCursor)
-{
- // 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.begin(), name.end());
- if (fieldIndex == -1)
- return SLANG_E_INVALID_ARG;
-
- // 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 + 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, outCursor);
- }
- break;
- }
-
- return SLANG_E_INVALID_ARG;
-}
-
-ShaderCursor ShaderCursor::getElement(Slang::Index index)
-{
- // TODO: need to auto-dereference various buffer types...
-
- if (m_typeLayout->getKind() == 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 * m_typeLayout->getElementCount() + index;
- return elementCursor;
- }
-
- return ShaderCursor();
-}
-
-
-static int _peek(Slang::UnownedStringSlice const& slice)
-{
- const char* b = slice.begin();
- const char* e = slice.end();
- if (b == e)
- return -1;
- return *b;
-}
-
-static int _get(Slang::UnownedStringSlice& slice)
-{
- const char* b = slice.begin();
- const char* e = slice.end();
- if (b == e)
- return -1;
- auto result = *b++;
- slice = Slang::UnownedStringSlice(b, e);
- return result;
-}
-
-Result ShaderCursor::followPath(Slang::UnownedStringSlice const& path, ShaderCursor& ioCursor)
-{
- ShaderCursor cursor = ioCursor;
-
- enum
- {
- ALLOW_NAME = 0x1,
- ALLOW_SUBSCRIPT = 0x2,
- ALLOW_DOT = 0x4,
- };
- int state = ALLOW_NAME | ALLOW_SUBSCRIPT;
-
- Slang::UnownedStringSlice 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);
- Slang::Index 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.begin();
- for (;;)
- {
- switch (_peek(rest))
- {
- default:
- _get(rest);
- continue;
-
- case -1:
- case '.':
- case '[':
- break;
- }
- break;
- }
- char const* nameEnd = rest.begin();
- Slang::UnownedStringSlice name(nameBegin, nameEnd);
- cursor = cursor.getField(name);
- state = ALLOW_DOT | ALLOW_SUBSCRIPT;
- continue;
- }
- }
-
- ioCursor = cursor;
- return SLANG_OK;
-}
-
-} // namespace gfx