summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorTim Foley <tfoleyNV@users.noreply.github.com>2018-04-19 09:34:54 -0700
committerGitHub <noreply@github.com>2018-04-19 09:34:54 -0700
commitc68c6fa02690012f54928202811050cee649d81e (patch)
tree614447345c070429b1b2ea0c3639cdc4ffbf81a9 /source
parent17fa424a195ed562e0c9d87cee57577c90c1fc37 (diff)
Fix up DXR type emission from IR type system (#498)
* There was a simple typo where we were emitting `RaytracingAccelerationStructureType` instead of `RaytracingAccelerationStructure` * The IR lowering logic was failing to handle types with an `__intrinsic_type` modifier (which maps them to a single IR opcode) that weren't in one of the various special cases. I added a catch-all case to the handling of `DeclRefType`. This notably affected the `RayDesc` type. * Even if we lower `RayDesc` to an intrinsic type, we still need to lower its *fields* too, and these were getting emitted with mangled names (as would happen for any user-defined fields). The solution I implemented was to allow for fields to have `__target_intrinsic` modifiers in the stdlib, to specify the un-mangled name they should use on each target. I'm not 100% happy with this solution, because it seems odd to have `RayDesc` be an intrinsic type, but then to also have field keys used in `getField` instructions as if it were an ordinary `struct`. It seems like a better solution would be to have it lower to an IR `struct`, just with an appropriate modifier.
Diffstat (limited to 'source')
-rw-r--r--source/slang/emit.cpp24
-rw-r--r--source/slang/hlsl.meta.slang8
-rw-r--r--source/slang/hlsl.meta.slang.h8
-rw-r--r--source/slang/lower-to-ir.cpp57
4 files changed, 73 insertions, 24 deletions
diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp
index e93dfbbb5..71d323c9e 100644
--- a/source/slang/emit.cpp
+++ b/source/slang/emit.cpp
@@ -1095,9 +1095,9 @@ struct EmitVisitor
{
switch (type->op)
{
- case kIROp_HLSLByteAddressBufferType: Emit("ByteAddressBuffer"); break;
- case kIROp_HLSLRWByteAddressBufferType: Emit("RWByteAddressBuffer"); break;
- case kIROp_RaytracingAccelerationStructureType: Emit("RaytracingAccelerationStructureType"); break;
+ case kIROp_HLSLByteAddressBufferType: Emit("ByteAddressBuffer"); break;
+ case kIROp_HLSLRWByteAddressBufferType: Emit("RWByteAddressBuffer"); break;
+ case kIROp_RaytracingAccelerationStructureType: Emit("RaytracingAccelerationStructure"); break;
default:
SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled buffer type");
@@ -1110,9 +1110,9 @@ struct EmitVisitor
{
switch (type->op)
{
- case kIROp_HLSLByteAddressBufferType: Emit("ByteAddressBuffer"); break;
- case kIROp_HLSLRWByteAddressBufferType: Emit("RWByteAddressBuffer"); break;
- case kIROp_RaytracingAccelerationStructureType: Emit("RaytracingAccelerationStructureType"); break;
+ case kIROp_HLSLByteAddressBufferType: Emit("ByteAddressBuffer"); break;
+ case kIROp_HLSLRWByteAddressBufferType: Emit("RWByteAddressBuffer"); break;
+ case kIROp_RaytracingAccelerationStructureType: Emit("RaytracingAccelerationStructure"); break;
default:
SLANG_DIAGNOSE_UNEXPECTED(getSink(), SourceLoc(), "unhandled buffer type");
@@ -1898,6 +1898,14 @@ struct EmitVisitor
String getIRName(
IRInst* inst)
{
+ // If the instruction names something
+ // that should be emitted as a target intrinsic,
+ // then use that name instead.
+ if(auto intrinsicDecoration = findTargetIntrinsicDecoration(context, inst))
+ {
+ return intrinsicDecoration->definition;
+ }
+
// If the instruction has a mangled name, then emit using that.
if (auto globalValue = as<IRGlobalValue>(inst))
{
@@ -2498,9 +2506,9 @@ struct EmitVisitor
IRTargetIntrinsicDecoration* findTargetIntrinsicDecoration(
EmitContext* /* ctx */,
- IRFunc* func)
+ IRInst* inst)
{
- for (auto dd = func->firstDecoration; dd; dd = dd->next)
+ for (auto dd = inst->firstDecoration; dd; dd = dd->next)
{
if (dd->op != kIRDecorationOp_TargetIntrinsic)
continue;
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index 977cb54b9..bf235eb3c 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -1182,9 +1182,16 @@ __magic_type(RayDescType)
__intrinsic_type($(kIROp_RayDescType))
struct RayDesc
{
+ __target_intrinsic(hlsl, Origin)
float3 Origin;
+
+ __target_intrinsic(hlsl, TMin)
float TMin;
+
+ __target_intrinsic(hlsl, Direction)
float3 Direction;
+
+ __target_intrinsic(hlsl, TMax)
float TMax;
};
@@ -1209,6 +1216,7 @@ __magic_type(BuiltInTriangleIntersectionAttributesType)
__intrinsic_type($(kIROp_BuiltInTriangleIntersectionAttributesType))
struct BuiltInTriangleIntersectionAttributes
{
+ __target_intrinsic(hlsl, barycentrics)
float2 barycentrics;
};
diff --git a/source/slang/hlsl.meta.slang.h b/source/slang/hlsl.meta.slang.h
index 7e79eccf6..a1e40c37b 100644
--- a/source/slang/hlsl.meta.slang.h
+++ b/source/slang/hlsl.meta.slang.h
@@ -1218,9 +1218,16 @@ SLANG_SPLICE(kIROp_RayDescType
SLANG_RAW(")\n")
SLANG_RAW("struct RayDesc\n")
SLANG_RAW("{\n")
+SLANG_RAW(" __target_intrinsic(hlsl, Origin)\n")
SLANG_RAW(" float3 Origin;\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(hlsl, TMin)\n")
SLANG_RAW(" float TMin;\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(hlsl, Direction)\n")
SLANG_RAW(" float3 Direction;\n")
+SLANG_RAW("\n")
+SLANG_RAW(" __target_intrinsic(hlsl, TMax)\n")
SLANG_RAW(" float TMax;\n")
SLANG_RAW("};\n")
SLANG_RAW("\n")
@@ -1251,6 +1258,7 @@ SLANG_SPLICE(kIROp_BuiltInTriangleIntersectionAttributesType
SLANG_RAW(")\n")
SLANG_RAW("struct BuiltInTriangleIntersectionAttributes\n")
SLANG_RAW("{\n")
+SLANG_RAW(" __target_intrinsic(hlsl, barycentrics)\n")
SLANG_RAW(" float2 barycentrics;\n")
SLANG_RAW("};\n")
SLANG_RAW("\n")
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp
index 3953490fe..e5cf19a10 100644
--- a/source/slang/lower-to-ir.cpp
+++ b/source/slang/lower-to-ir.cpp
@@ -1030,9 +1030,19 @@ struct ValLoweringVisitor : ValVisitor<ValLoweringVisitor, LoweredValInfo, Lower
IRType* visitDeclRefType(DeclRefType* type)
{
+ auto declRef = type->declRef;
+ auto decl = declRef.getDecl();
+
+ // Check for types with teh `__intrinsic_type` modifier.
+ if(decl->FindModifier<IntrinsicTypeModifier>())
+ {
+ return lowerSimpleIntrinsicType(type);
+ }
+
+
return (IRType*) getSimpleVal(
context,
- emitDeclRef(context, type->declRef,
+ emitDeclRef(context, declRef,
context->irBuilder->getTypeKind()));
}
@@ -3500,6 +3510,12 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
semanticDecoration->semanticName = semanticModifier->name.getName();
}
+ // We allow a field to be marked as a target intrinsic,
+ // so that we can override its mangled name in the
+ // output for the chosen target.
+ addTargetIntrinsicDecorations(irFieldKey, fieldDecl);
+
+
return LoweredValInfo::simple(irFieldKey);
}
@@ -3967,6 +3983,29 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
return v;
}
+ // Attach target-intrinsic decorations to an instruction,
+ // based on modifiers on an AST declaration.
+ void addTargetIntrinsicDecorations(
+ IRInst* irInst,
+ Decl* decl)
+ {
+ for (auto targetMod : decl->GetModifiersOfType<TargetIntrinsicModifier>())
+ {
+ auto decoration = getBuilder()->addDecoration<IRTargetIntrinsicDecoration>(irInst);
+ decoration->targetName = targetMod->targetToken.Content;
+
+ auto definitionToken = targetMod->definitionToken;
+ if (definitionToken.type == TokenType::StringLiteral)
+ {
+ decoration->definition = getStringLiteralTokenValue(definitionToken);
+ }
+ else
+ {
+ decoration->definition = definitionToken.Content;
+ }
+ }
+ }
+
LoweredValInfo lowerFuncDecl(FunctionDeclBase* decl)
{
// We are going to use a nested builder, because we will
@@ -4259,21 +4298,7 @@ struct DeclLoweringVisitor : DeclVisitor<DeclLoweringVisitor, LoweredValInfo>
// If this declaration was marked as having a target-specific lowering
// for a particular target, then handle that here.
- for (auto targetMod : decl->GetModifiersOfType<TargetIntrinsicModifier>())
- {
- auto decoration = getBuilder()->addDecoration<IRTargetIntrinsicDecoration>(irFunc);
- decoration->targetName = targetMod->targetToken.Content;
-
- auto definitionToken = targetMod->definitionToken;
- if (definitionToken.type == TokenType::StringLiteral)
- {
- decoration->definition = getStringLiteralTokenValue(definitionToken);
- }
- else
- {
- decoration->definition = definitionToken.Content;
- }
- }
+ addTargetIntrinsicDecorations(irFunc, decl);
// For convenience, ensure that any additional global
// values that were emitted while outputting the function