@@ -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,57 @@ 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 [builtinVarName, varInst] : workItems)
3784
+ {
3785
+ // Repalce SV_InstanceID with gl_InstanceIndex - gl_BaseInstance.
3786
+ if (builtinVarName == IRTargetBuiltinVarName::HlslInstanceID)
3787
+ {
3788
+ auto instanceIndex = getOrCreateBuiltinVar (
3789
+ IRTargetBuiltinVarName::SpvInstanceIndex,
3790
+ varInst->getDataType ());
3791
+ auto baseInstance = getOrCreateBuiltinVar (
3792
+ IRTargetBuiltinVarName::SpvBaseInstance,
3793
+ varInst->getDataType ());
3794
+ traverseUses (
3795
+ varInst,
3796
+ [&](IRUse* use)
3797
+ {
3798
+ auto user = use->getUser ();
3799
+ if (user->getOp () == kIROp_Load )
3800
+ {
3801
+ IRBuilder builder (use->getUser ());
3802
+ builder.setInsertBefore (use->getUser ());
3803
+ auto sub = builder.emitSub (
3804
+ tryGetPointedToType (&builder, varInst->getDataType ()),
3805
+ builder.emitLoad (instanceIndex),
3806
+ builder.emitLoad (baseInstance));
3807
+ user->replaceUsesWith (sub);
3808
+ }
3809
+ });
3810
+ }
3811
+ }
3812
+ }
3749
3813
3750
3814
void legalizeEntryPointForGLSL (
3751
3815
Session* session,
@@ -3937,6 +4001,11 @@ void legalizeEntryPointForGLSL(
3937
4001
value.globalParam ->setFullType (sizedArrayType);
3938
4002
}
3939
4003
}
4004
+
4005
+ // Some system value vars can't be mapped 1:1 to a GLSL/Vulkan builtin,
4006
+ // for example, SV_InstanceID should map to gl_InstanceIndex - gl_BaseInstance,
4007
+ // we will replace these builtins with additional compute logic here.
4008
+ legalizeTargetBuiltinVar (context);
3940
4009
}
3941
4010
3942
4011
void decorateModuleWithSPIRVVersion (IRModule* module, SemanticVersion spirvVersion)
0 commit comments