@@ -236,6 +236,9 @@ struct GLSLSystemValueInfo
236
236
237
237
// The kind of the system value that requires special treatment.
238
238
GLSLSystemValueKind kind = GLSLSystemValueKind::General;
239
+
240
+ // The target builtin name.
241
+ IRTargetBuiltinVarName targetVarName = IRTargetBuiltinVarName::Unknown;
239
242
};
240
243
241
244
static void leafAddressesImpl(List<IRInst*>& ret, const ScalarizedVal& v)
@@ -283,6 +286,7 @@ struct GLSLLegalizationContext
283
286
DiagnosticSink* sink;
284
287
Stage stage;
285
288
IRFunc* entryPointFunc;
289
+ Dictionary<IRTargetBuiltinVarName, IRInst*> builtinVarMap;
286
290
287
291
/// This dictionary stores all bindings of 'VaryingIn/VaryingOut'. We assume 'space' is 0.
288
292
Dictionary<LayoutResourceKind, UIntSet> usedBindingIndex;
@@ -414,7 +418,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
414
418
char const* outerArrayName = nullptr;
415
419
int arrayIndex = -1;
416
420
GLSLSystemValueKind systemValueKind = GLSLSystemValueKind::General;
417
-
421
+ IRTargetBuiltinVarName targetVarName = IRTargetBuiltinVarName::Unknown;
418
422
auto semanticInst = varLayout->findSystemValueSemanticAttr();
419
423
if (!semanticInst)
420
424
return nullptr;
@@ -621,6 +625,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
621
625
622
626
requiredType = builder->getBasicType(BaseType::Int);
623
627
name = "gl_InstanceIndex";
628
+ targetVarName = IRTargetBuiltinVarName::HlslInstanceID;
624
629
}
625
630
else if (semanticName == "sv_isfrontface")
626
631
{
@@ -869,6 +874,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
869
874
name = "gl_BaseInstance";
870
875
}
871
876
877
+ inStorage->targetVarName = targetVarName;
872
878
if (name)
873
879
{
874
880
inStorage->name = name;
@@ -976,6 +982,12 @@ void createVarLayoutForLegalizedGlobalParam(
976
982
default:
977
983
break;
978
984
}
985
+
986
+ if (systemValueInfo->targetVarName != IRTargetBuiltinVarName::Unknown)
987
+ {
988
+ builder->addTargetBuiltinVarDecoration(globalParam, systemValueInfo->targetVarName);
989
+ context->builtinVarMap[systemValueInfo->targetVarName] = globalParam;
990
+ }
979
991
}
980
992
}
981
993
@@ -1262,7 +1274,7 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
1262
1274
// Validate the system value, convert to a regular parameter if this is not a valid system
1263
1275
// value for a given target.
1264
1276
if (systemSemantic && isSPIRV(codeGenContext->getTargetFormat()) &&
1265
- systemSemantic->getName().caseInsensitiveEquals(UnownedStringSlice("sv_instanceid")) &&
1277
+ systemValueInfo->targetVarName == IRTargetBuiltinVarName::HlslInstanceID &&
1266
1278
((stage == Stage::Fragment) ||
1267
1279
(stage == Stage::Vertex &&
1268
1280
inVarLayout->usesResourceKind(LayoutResourceKind::VaryingOutput))))
@@ -1287,6 +1299,7 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
1287
1299
newVarLayout->sourceLoc = inVarLayout->sourceLoc;
1288
1300
1289
1301
inVarLayout->replaceUsesWith(newVarLayout);
1302
+ systemValueInfo->targetVarName = IRTargetBuiltinVarName::Unknown;
1290
1303
}
1291
1304
}
1292
1305
@@ -3746,6 +3759,60 @@ ScalarizedVal legalizeEntryPointReturnValueForGLSL(
3746
3759
return result;
3747
3760
}
3748
3761
3762
+ void legalizeTargetBuiltinVar(GLSLLegalizationContext& context)
3763
+ {
3764
+ List<KeyValuePair<IRTargetBuiltinVarName, IRInst*>> workItems;
3765
+ for (auto [builtinVarName, varInst] : context.builtinVarMap)
3766
+ {
3767
+ if (builtinVarName == IRTargetBuiltinVarName::HlslInstanceID)
3768
+ {
3769
+ workItems.add(KeyValuePair(builtinVarName, varInst));
3770
+ }
3771
+ }
3772
+
3773
+ auto getOrCreateBuiltinVar = [&](IRTargetBuiltinVarName name, IRType* type)
3774
+ {
3775
+ if (auto var = context.builtinVarMap.tryGetValue(name))
3776
+ return *var;
3777
+ IRBuilder builder(context.entryPointFunc);
3778
+ builder.setInsertBefore(context.entryPointFunc);
3779
+ IRInst* var = builder.createGlobalParam(type);
3780
+ builder.addTargetBuiltinVarDecoration(var, name);
3781
+ return var;
3782
+ };
3783
+ for (auto& kv : workItems)
3784
+ {
3785
+ auto builtinVarName = kv.key;
3786
+ auto varInst = kv.value;
3787
+
3788
+ // Repalce SV_InstanceID with gl_InstanceIndex - gl_BaseInstance.
3789
+ if (builtinVarName == IRTargetBuiltinVarName::HlslInstanceID)
3790
+ {
3791
+ auto instanceIndex = getOrCreateBuiltinVar(
3792
+ IRTargetBuiltinVarName::SpvInstanceIndex,
3793
+ varInst->getDataType());
3794
+ auto baseInstance = getOrCreateBuiltinVar(
3795
+ IRTargetBuiltinVarName::SpvBaseInstance,
3796
+ varInst->getDataType());
3797
+ traverseUses(
3798
+ varInst,
3799
+ [&](IRUse* use)
3800
+ {
3801
+ auto user = use->getUser();
3802
+ if (user->getOp() == kIROp_Load)
3803
+ {
3804
+ IRBuilder builder(use->getUser());
3805
+ builder.setInsertBefore(use->getUser());
3806
+ auto sub = builder.emitSub(
3807
+ tryGetPointedToType(&builder, varInst->getDataType()),
3808
+ builder.emitLoad(instanceIndex),
3809
+ builder.emitLoad(baseInstance));
3810
+ user->replaceUsesWith(sub);
3811
+ }
3812
+ });
3813
+ }
3814
+ }
3815
+ }
3749
3816
3750
3817
void legalizeEntryPointForGLSL(
3751
3818
Session* session,
@@ -3937,6 +4004,11 @@ void legalizeEntryPointForGLSL(
3937
4004
value.globalParam->setFullType(sizedArrayType);
3938
4005
}
3939
4006
}
4007
+
4008
+ // Some system value vars can't be mapped 1:1 to a GLSL/Vulkan builtin,
4009
+ // for example, SV_InstanceID should map to gl_InstanceIndex - gl_BaseInstance,
4010
+ // we will replace these builtins with additional compute logic here.
4011
+ legalizeTargetBuiltinVar(context);
3940
4012
}
3941
4013
3942
4014
void decorateModuleWithSPIRVVersion(IRModule* module, SemanticVersion spirvVersion)
0 commit comments