summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/slang-emit-glsl.cpp3
-rw-r--r--source/slang/slang-emit-hlsl.cpp2
-rw-r--r--source/slang/slang-ir-any-value-marshalling.cpp7
-rw-r--r--source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp13
-rw-r--r--source/slang/slang-ir-specialize.cpp54
-rw-r--r--tests/compute/dynamic-dispatch-18.slang53
-rw-r--r--tests/compute/dynamic-dispatch-18.slang.expected.txt2
7 files changed, 119 insertions, 15 deletions
diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp
index 634067ab7..5540daa19 100644
--- a/source/slang/slang-emit-glsl.cpp
+++ b/source/slang/slang-emit-glsl.cpp
@@ -1488,6 +1488,9 @@ bool GLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
break;
}
break;
+ case BaseType::Bool:
+ m_writer->emit("bool");
+ break;
}
m_writer->emit("(");
diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp
index 9ebf204ac..dd5c18315 100644
--- a/source/slang/slang-emit-hlsl.cpp
+++ b/source/slang/slang-emit-hlsl.cpp
@@ -471,6 +471,7 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
case BaseType::UInt16:
case BaseType::UInt:
case BaseType::UInt64:
+ case BaseType::Bool:
// Because the intermediate type will always
// be an integer type, we can convert to
// another integer type of the same size
@@ -512,6 +513,7 @@ bool HLSLSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOu
case BaseType::UInt:
case BaseType::Int:
+ case BaseType::Bool:
break;
case BaseType::UInt16:
case BaseType::Int16:
diff --git a/source/slang/slang-ir-any-value-marshalling.cpp b/source/slang/slang-ir-any-value-marshalling.cpp
index c7f40efc0..2c6dcb84c 100644
--- a/source/slang/slang-ir-any-value-marshalling.cpp
+++ b/source/slang/slang-ir-any-value-marshalling.cpp
@@ -147,6 +147,7 @@ namespace Slang
case kIROp_UInt8Type:
case kIROp_UInt16Type:
case kIROp_HalfType:
+ case kIROp_BoolType:
context->marshalBasicType(builder, dataType, concreteTypedVar);
break;
case kIROp_VectorType:
@@ -234,6 +235,7 @@ namespace Slang
{
case kIROp_IntType:
case kIROp_FloatType:
+ case kIROp_BoolType:
{
ensureOffsetAt4ByteBoundary();
if (fieldOffset < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
@@ -303,11 +305,11 @@ namespace Slang
advanceOffset(2);
break;
}
+ case kIROp_Int8Type:
+ case kIROp_UInt8Type:
case kIROp_UInt64Type:
case kIROp_Int64Type:
case kIROp_DoubleType:
- case kIROp_Int8Type:
- case kIROp_UInt8Type:
SLANG_UNIMPLEMENTED_X("AnyValue type packing for non 32-bit elements");
break;
default:
@@ -397,6 +399,7 @@ namespace Slang
{
case kIROp_IntType:
case kIROp_FloatType:
+ case kIROp_BoolType:
{
ensureOffsetAt4ByteBoundary();
if (fieldOffset < static_cast<uint32_t>(anyValInfo->fieldKeys.getCount()))
diff --git a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
index e2d321ed4..670202161 100644
--- a/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
+++ b/source/slang/slang-ir-specialize-dynamic-associatedtype-lookup.cpp
@@ -122,7 +122,18 @@ struct AssociatedTypeLookupSpecializationContext
{
// Ignore lookups for RTTI objects for now, since they are not used anywhere.
if (!as<IRWitnessTableType>(inst->getDataType()))
+ {
+ IRBuilder builder;
+ builder.sharedBuilder = &sharedContext->sharedBuilderStorage;
+ builder.setInsertBefore(inst);
+ auto uint2Type = builder.getVectorType(
+ builder.getUIntType(), builder.getIntValue(builder.getIntType(), 2));
+ auto zero = builder.getIntValue(builder.getUIntType(), 0);
+ IRInst* args[] = { zero, zero };
+ auto zeroUint2 = builder.emitMakeVector(uint2Type, 2, args);
+ inst->replaceUsesWith(zeroUint2);
return;
+ }
// Replace all witness table lookups with calls to specialized functions that directly
// returns the sequential ID of the resulting witness table, effectively getting rid
@@ -165,7 +176,7 @@ struct AssociatedTypeLookupSpecializationContext
{
// If the operand is a witness table, it is already replaced with a uint2
// at this point, where the first element in the uint2 is the id of the
- // witneess table.
+ // witness table.
auto vectorType = inst->getRTTIOperand()->getDataType();
IRBuilder builder;
builder.sharedBuilder = &sharedContext->sharedBuilderStorage;
diff --git a/source/slang/slang-ir-specialize.cpp b/source/slang/slang-ir-specialize.cpp
index 9522dbeca..b1da92ff1 100644
--- a/source/slang/slang-ir-specialize.cpp
+++ b/source/slang/slang-ir-specialize.cpp
@@ -1102,6 +1102,47 @@ struct SpecializationContext
return false;
}
+ // Test if a type is compile time constant.
+ static bool isCompileTimeConstantType(IRInst* inst)
+ {
+ // TODO: We probably need/want a more robust test here.
+ // For now we are just look into the dependency graph of the inst and
+ // see if there are any opcodes that are causing problems.
+ List<IRInst*> localWorkList;
+ HashSet<IRInst*> processedInsts;
+ localWorkList.add(inst);
+ processedInsts.Add(inst);
+
+ while (localWorkList.getCount() != 0)
+ {
+ IRInst* curInst = localWorkList.getLast();
+
+ localWorkList.removeLast();
+ processedInsts.Remove(curInst);
+
+ switch (curInst->getOp())
+ {
+ case kIROp_Load:
+ case kIROp_Call:
+ case kIROp_ExtractExistentialType:
+ case kIROp_CreateExistentialObject:
+ return false;
+ default:
+ break;
+ }
+
+ for (UInt i = 0; i < curInst->getOperandCount(); ++i)
+ {
+ auto operand = curInst->getOperand(i);
+ if (processedInsts.Add(operand))
+ {
+ localWorkList.add(operand);
+ }
+ }
+ }
+ return true;
+ }
+
// Similarly, we want to be able to test whether an instruction
// used as an argument for an existential-type parameter is
// suitable for use in specialization.
@@ -1127,18 +1168,7 @@ struct SpecializationContext
auto concreteVal = makeExistential->getWrappedValue();
auto concreteType = concreteVal->getDataType();
- // TODO: We probably need/want a more robust test here.
- // For now we are just listing the single opcode that is
- // causing problems.
- //
- // TODO: eventually this check would become unnecessary because
- // we can simply check if the `concreteType` is a compile-time
- // constant value.
- //
- if(concreteType->getOp() == kIROp_ExtractExistentialType)
- return false;
-
- return true;
+ return isCompileTimeConstantType(concreteType);
}
// A `wrapExistential(v, T0,w0, T1, w1, ...)` instruction
diff --git a/tests/compute/dynamic-dispatch-18.slang b/tests/compute/dynamic-dispatch-18.slang
new file mode 100644
index 000000000..23cdabbbd
--- /dev/null
+++ b/tests/compute/dynamic-dispatch-18.slang
@@ -0,0 +1,53 @@
+// Test using generic interface methods with dynamic dispatch.
+
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx12 -profile sm_6_0 -use-dxil -output-using-type
+//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -dx11 -profile sm_5_0 -output-using-type
+//TEST(compute, vulkan):COMPARE_COMPUTE_EX:-vk -compute -output-using-type
+
+[anyValueSize(12)]
+interface IReturnsZero
+{
+ float get();
+}
+
+[anyValueSize(16)]
+interface IInterface
+{
+ associatedtype Getter : IReturnsZero;
+ Getter createGetter();
+}
+
+struct Impl : IInterface
+{
+ int data;
+ struct Getter : IReturnsZero
+ {
+ bool data;
+ float get() { if (data) return 0.0; else return 1.0;}
+ }
+ Getter createGetter() { Getter g; g.data = true; return g; }
+};
+
+
+float test(IReturnsZero r)
+{
+ return r.get();
+}
+
+//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=gOutputBuffer
+RWStructuredBuffer<float> gOutputBuffer;
+
+//TEST_INPUT: set gObj = new StructuredBuffer<IInterface>[new Impl{1}];
+RWStructuredBuffer<IInterface> gObj;
+
+//TEST_INPUT: type_conformance Impl:IInterface = 3
+
+[numthreads(1, 1, 1)]
+void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
+{
+ float result = 0.0;
+ let i = createDynamicObject<IInterface, int>(3, 0);
+ IReturnsZero iobj = i.createGetter();
+ result = test(iobj);
+ gOutputBuffer[0] = result;
+}
diff --git a/tests/compute/dynamic-dispatch-18.slang.expected.txt b/tests/compute/dynamic-dispatch-18.slang.expected.txt
new file mode 100644
index 000000000..4b1f4c0d9
--- /dev/null
+++ b/tests/compute/dynamic-dispatch-18.slang.expected.txt
@@ -0,0 +1,2 @@
+type: float
+0.000000