Skip to content

Commit

Permalink
Transfer offset decorations when legalizing laid-out structs
Browse files Browse the repository at this point in the history
Struct legalization removing fields not representable in memory should transfer offset
decorations in case the struct has already had offsets calculated.

Closes shader-slang#5264.
  • Loading branch information
aleino-nv committed Nov 8, 2024
1 parent ad72ee6 commit c8b88c3
Show file tree
Hide file tree
Showing 7 changed files with 28 additions and 10 deletions.
23 changes: 23 additions & 0 deletions source/slang/slang-ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,18 @@ struct IRInst
IRDecoration* getLastDecoration();
IRInstList<IRDecoration> getDecorations();

// Step to the next child of a certain type, T
template<typename T>
T* getNextChildOfType(IRInst* child = nullptr)
{
for (IRInst* cc = child ? child->getNextInst() : getFirstDecorationOrChild(); cc != nullptr; cc = cc->getNextInst())
{
if (T* cct = as<T>(cc))
return cct;
}
return nullptr;
}

// Look up a decoration in the list of decorations
IRDecoration* findDecorationImpl(IROp op);
template<typename T>
Expand Down Expand Up @@ -780,8 +792,19 @@ struct IRInst
void removeOperand(Index index);

/// Transfer any decorations of this instruction to the `target` instruction.
// TODO: rewrite as transferDecorationsTo(target) -> transferChildrenOfTypeTo<IRDecoration>(target)
void transferDecorationsTo(IRInst* target);

template <typename T>
void transferChildrenOfTypeTo(IRInst* target)
{
for (T* cc = getNextChildOfType<T>(); cc != nullptr; cc = getNextChildOfType<T>(cc))
{
cc->removeFromParent();
cc->insertAtStart(target);
}
}

/// Does this instruction have any uses?
bool hasUses() const { return firstUse != nullptr; }

Expand Down
7 changes: 5 additions & 2 deletions source/slang/slang-legalize-types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,8 +487,11 @@ struct TupleTypeBuilder
fieldType = context->getBuilder()->getVoidType();

// TODO: shallow clone of modifiers, etc.

builder->createStructField(ordinaryStructType, ee.fieldKey, fieldType);
IRStructField* originalField = findStructField(originalStructType, ee.fieldKey);
IRStructField* newField = builder->createStructField(ordinaryStructType, ee.fieldKey, fieldType);
// In case the original struct had offsets calculated, transfer those as well.
// The original offsets should still be valid, since we only skip fields of types that aren't representable in memory.
originalField->transferChildrenOfTypeTo<IROffsetDecoration>(newField);
}

ordinaryType = LegalType::simple((IRType*)ordinaryStructType);
Expand Down
1 change: 0 additions & 1 deletion tests/autodiff/existential-1.slang
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -output-using-type
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -output-using-type
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-wgpu

//TEST_INPUT:ubuffer(data=[0 0 0 0 0], stride=4):out,name=outputBuffer
RWStructuredBuffer<float> outputBuffer;
Expand Down
1 change: 0 additions & 1 deletion tests/autodiff/existential-2.slang
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -output-using-type
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -output-using-type
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-wgpu

//TEST_INPUT:ubuffer(data=[0 0 0 0 0], stride=4):out,name=outputBuffer
RWStructuredBuffer<float> outputBuffer;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -output-using-type
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -output-using-type
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-wgpu

// outputBuffer is defined in IBSDF.slang
//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0], stride=4):out,name=outputBuffer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -shaderobj -output-using-type
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -output-using-type
//DISABLE_TEST(compute):COMPARE_COMPUTE_EX:-wgpu

// outputBuffer is defined in IBSDF.slang
//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0 0 0 0], stride=4):out,name=outputBuffer
Expand Down
4 changes: 0 additions & 4 deletions tests/expected-failure-github.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ tests/language-feature/saturated-cooperation/fuse.slang (vk)
tests/bugs/byte-address-buffer-interlocked-add-f32.slang (vk)
tests/serialization/obfuscated-serialized-module-test.slang.2 syn (mtl)
tests/autodiff/custom-intrinsic.slang.2 syn (wgpu)
tests/autodiff/existential-1.slang.2 syn (wgpu)
tests/autodiff/existential-2.slang.2 syn (wgpu)
tests/autodiff/material/diff-bwd-falcor-material-system.slang.2 syn (wgpu)
tests/autodiff/material2/diff-bwd-falcor-material-system.slang.2 syn (wgpu)
tests/bugs/atomic-coerce.slang.3 syn (wgpu)
tests/bugs/buffer-swizzle-store.slang.3 syn (wgpu)
tests/bugs/dxbc-double-problem.slang.6 syn (wgpu)
Expand Down

0 comments on commit c8b88c3

Please sign in to comment.