Skip to content

Commit 3321df7

Browse files
authored
Handle partial existential parameter type specialization. (shader-slang#1568)
* Specialize exsitentials parameters in struct fields. * Cleanup. * Handle partial existential parameter type specialization. Co-authored-by: Yong He <yhe@nvidia.com>
1 parent 24ecd1f commit 3321df7

4 files changed

+59
-3
lines changed

source/slang/slang-ir-insts.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1807,7 +1807,7 @@ struct IRBuilder
18071807
IRInOutType* getInOutType(IRType* valueType);
18081808
IRRefType* getRefType(IRType* valueType);
18091809
IRPtrTypeBase* getPtrType(IROp op, IRType* valueType);
1810-
IRExistentialBoxType* getExistentialBoxType(IRType* concreteType, IRType* interfaceType);
1810+
IRType* getExistentialBoxType(IRType* concreteType, IRType* interfaceType);
18111811

18121812
IRArrayTypeBase* getArrayTypeBase(
18131813
IROp op,

source/slang/slang-ir.cpp

+8-2
Original file line numberDiff line numberDiff line change
@@ -2336,10 +2336,14 @@ namespace Slang
23362336
operands);
23372337
}
23382338

2339-
IRExistentialBoxType* IRBuilder::getExistentialBoxType(IRType* concreteType, IRType* interfaceType)
2339+
IRType* IRBuilder::getExistentialBoxType(IRType* concreteType, IRType* interfaceType)
23402340
{
2341+
// Don't wrap an existential box if concreteType is __Dynamic.
2342+
if (as<IRDynamicType>(concreteType))
2343+
return interfaceType;
2344+
23412345
IRInst* operands[] = {concreteType, interfaceType};
2342-
return (IRExistentialBoxType*)getType(kIROp_ExistentialBoxType, 2, operands);
2346+
return getType(kIROp_ExistentialBoxType, 2, operands);
23432347
}
23442348

23452349
IRArrayTypeBase* IRBuilder::getArrayTypeBase(
@@ -2845,6 +2849,8 @@ namespace Slang
28452849
// We want to emit `makeExistential(load(value), witnessTable)`.
28462850
//
28472851
auto deref = emitLoad(value);
2852+
if (slotArgs[0]->op == kIROp_DynamicType)
2853+
return deref;
28482854
return emitMakeExistential(type, deref, slotArgs[1]);
28492855
}
28502856
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Tests generating dynamic dispatch code for a function
2+
// with existential-struct-typed param by specializing it
3+
// with __Dynamic. This verifies that the handling of
4+
// "partially" specializing an existential type is correct.
5+
6+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cuda
7+
//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -cpu
8+
9+
[anyValueSize(8)]
10+
interface IInterface
11+
{
12+
uint eval();
13+
}
14+
15+
public struct Impl : IInterface
16+
{
17+
uint val;
18+
uint eval()
19+
{
20+
return val;
21+
}
22+
};
23+
24+
struct Params
25+
{
26+
StructuredBuffer<IInterface> obj;
27+
};
28+
29+
//TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name=gOutputBuffer
30+
RWStructuredBuffer<uint> gOutputBuffer;
31+
32+
void compute(uint tid, Params p)
33+
{
34+
gOutputBuffer[tid] = p.obj[0].eval();
35+
}
36+
37+
//TEST_INPUT: entryPointExistentialType __Dynamic
38+
39+
[numthreads(4, 1, 1)]
40+
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID,
41+
//TEST_INPUT:ubuffer(data=[rtti(Impl) witness(Impl, IInterface) 1 0], stride=4):name=params.obj
42+
uniform Params params)
43+
{
44+
uint tid = dispatchThreadID.x;
45+
compute(tid, params);
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
1
3+
1
4+
1

0 commit comments

Comments
 (0)