diff options
| author | Yong He <yonghe@outlook.com> | 2021-01-22 09:22:45 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-22 09:22:45 -0800 |
| commit | 76db3366cb6cfb5432e5d26acb67e5a96224900e (patch) | |
| tree | 32b9b969b99a47c3d5de7bcdf61cf1fbfc724439 | |
| parent | dc063e58ec0d937465566edeea70b112e4d3e72c (diff) | |
Fix existential specialization of mutable buffer loads. (#1671)
* Fix existential specialization of mutable buffer loads.
* fix
Co-authored-by: Yong He <yhe@nvidia.com>
| -rw-r--r-- | source/core/slang-dictionary.h | 12 | ||||
| -rw-r--r-- | source/slang/slang-ir-specialize.cpp | 40 | ||||
| -rw-r--r-- | tests/bugs/rwstructuredbuffer-existential-in-struct.slang | 32 | ||||
| -rw-r--r-- | tests/bugs/rwstructuredbuffer-existential-in-struct.slang.expected.txt | 4 |
4 files changed, 72 insertions, 16 deletions
diff --git a/source/core/slang-dictionary.h b/source/core/slang-dictionary.h index df5ee520d..4c352d55b 100644 --- a/source/core/slang-dictionary.h +++ b/source/core/slang-dictionary.h @@ -1003,7 +1003,17 @@ namespace Slang }; template <typename T> class OrderedHashSet : public HashSetBase<T, OrderedDictionary<T, _DummyClass>> - {}; + { + public: + T& getLast() + { + return this->dict.Last().Key; + } + void removeLast() + { + this->Remove(getLast()); + } + }; } #endif diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp index 91852ff88..7fb6a06bd 100644 --- a/source/slang/slang-ir-specialize.cpp +++ b/source/slang/slang-ir-specialize.cpp @@ -107,9 +107,7 @@ struct SpecializationContext // to be considered for specialization or simplification, // whether generic, existential, etc. // - List<IRInst*> workList; - HashSet<IRInst*> workListSet; - + OrderedHashSet<IRInst*> workList; HashSet<IRInst*> cleanInsts; void addToWorkList( @@ -125,14 +123,12 @@ struct SpecializationContext return; } - if(workListSet.Contains(inst)) - return; - - workList.add(inst); - workListSet.Add(inst); - cleanInsts.Remove(inst); + if (workList.Add(inst)) + { + cleanInsts.Remove(inst); - addUsersToWorkList(inst); + addUsersToWorkList(inst); + } } // When a transformation makes a change to an instruction, @@ -682,17 +678,17 @@ struct SpecializationContext // addToWorkList(module->getModuleInst()); - while(workList.getCount() != 0) + while(workList.Count() != 0) { // We will then iterate until our work list goes dry. // - while(workList.getCount() != 0) + while(workList.Count() != 0) { IRInst* inst = workList.getLast(); workList.removeLast(); - workListSet.Remove(inst); + cleanInsts.Add(inst); // For each instruction we process, we want to perform @@ -838,15 +834,29 @@ struct SpecializationContext // we should update it to be `specialize(.operator[], elementType)`, so the return type // of the load call is `elementType`. auto oldCallee = inst->getCallee(); - auto newCallee = getNewSpecializedBufferLoadCallee(inst->getCallee(), sbType, elementType); - auto newCall = builder.emitCallInst(elementType, newCallee, args); + + // A subscript operation on mutable buffers returns a ptr type instead of a value type. + // We need to make sure the pointer-ness is preserved correctly. + auto innerResultType = elementType; + if (auto ptrResultType = as<IRPtrType>(inst->getDataType())) + { + innerResultType = builder.getPtrType(elementType); + } + auto newCallee = getNewSpecializedBufferLoadCallee(inst->getCallee(), sbType, innerResultType); + auto newCall = builder.emitCallInst(innerResultType, newCallee, args); auto newWrapExistential = builder.emitWrapExistential( resultType, newCall, slotOperandCount, slotOperands.getBuffer()); inst->replaceUsesWith(newWrapExistential); + workList.Remove(inst); inst->removeAndDeallocate(); SLANG_ASSERT(!oldCallee->hasUses()); + workList.Remove(oldCallee); oldCallee->removeAndDeallocate(); addUsersToWorkList(newWrapExistential); + + workList.Remove(wrapExistential); + SLANG_ASSERT(!wrapExistential->hasUses()); + wrapExistential->removeAndDeallocate(); return true; } } diff --git a/tests/bugs/rwstructuredbuffer-existential-in-struct.slang b/tests/bugs/rwstructuredbuffer-existential-in-struct.slang new file mode 100644 index 000000000..c763dd3c1 --- /dev/null +++ b/tests/bugs/rwstructuredbuffer-existential-in-struct.slang @@ -0,0 +1,32 @@ +//TEST(compute):COMPARE_COMPUTE:-dx11 -shaderobj + +[anyValueSize(8)] +interface IMaterial +{ + float eval(); +} + +struct MaterialImpl : IMaterial +{ + float eval() { return 0.0f; } +}; + +struct Parameters +{ + uint ordinary; + +//TEST_INPUT: entryPointExistentialType MaterialImpl +//TEST_INPUT:ubuffer(data=[0 0 0 0 0 0], stride=4):name=params.materials + RWStructuredBuffer<IMaterial> materials; + +//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=params.result + RWStructuredBuffer<float> result; +}; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID, uniform Parameters params, uniform int id) +{ + uint tid = dispatchThreadID.x; + float rs = params.materials[0].eval(); + params.result[tid] = rs; +} diff --git a/tests/bugs/rwstructuredbuffer-existential-in-struct.slang.expected.txt b/tests/bugs/rwstructuredbuffer-existential-in-struct.slang.expected.txt new file mode 100644 index 000000000..44e0be8e3 --- /dev/null +++ b/tests/bugs/rwstructuredbuffer-existential-in-struct.slang.expected.txt @@ -0,0 +1,4 @@ +0 +0 +0 +0 |
