@@ -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,9 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
621
625
622
626
requiredType = builder->getBasicType (BaseType::Int);
623
627
name = " gl_InstanceIndex" ;
628
+ targetVarName = IRTargetBuiltinVarName::HlslInstanceID;
629
+ context->requireSPIRVVersion (SemanticVersion (1 , 3 ));
630
+ context->requireGLSLExtension (toSlice (" GL_ARB_shader_draw_parameters" ));
624
631
}
625
632
else if (semanticName == " sv_isfrontface" )
626
633
{
@@ -869,6 +876,7 @@ GLSLSystemValueInfo* getGLSLSystemValueInfo(
869
876
name = " gl_BaseInstance" ;
870
877
}
871
878
879
+ inStorage->targetVarName = targetVarName;
872
880
if (name)
873
881
{
874
882
inStorage->name = name;
@@ -976,6 +984,12 @@ void createVarLayoutForLegalizedGlobalParam(
976
984
default :
977
985
break ;
978
986
}
987
+
988
+ if (systemValueInfo->targetVarName != IRTargetBuiltinVarName::Unknown)
989
+ {
990
+ builder->addTargetBuiltinVarDecoration (globalParam, systemValueInfo->targetVarName );
991
+ context->builtinVarMap [systemValueInfo->targetVarName ] = globalParam;
992
+ }
979
993
}
980
994
}
981
995
@@ -1261,8 +1275,8 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
1261
1275
auto systemSemantic = inVarLayout->findAttr <IRSystemValueSemanticAttr>();
1262
1276
// Validate the system value, convert to a regular parameter if this is not a valid system
1263
1277
// value for a given target.
1264
- if (systemSemantic && isSPIRV (codeGenContext->getTargetFormat ()) &&
1265
- systemSemantic-> getName (). caseInsensitiveEquals ( UnownedStringSlice ( " sv_instanceid " )) &&
1278
+ if (systemSemantic && systemValueInfo && isSPIRV (codeGenContext->getTargetFormat ()) &&
1279
+ systemValueInfo-> targetVarName == IRTargetBuiltinVarName::HlslInstanceID &&
1266
1280
((stage == Stage::Fragment) ||
1267
1281
(stage == Stage::Vertex &&
1268
1282
inVarLayout->usesResourceKind (LayoutResourceKind::VaryingOutput))))
@@ -1287,6 +1301,7 @@ ScalarizedVal createSimpleGLSLGlobalVarying(
1287
1301
newVarLayout->sourceLoc = inVarLayout->sourceLoc ;
1288
1302
1289
1303
inVarLayout->replaceUsesWith (newVarLayout);
1304
+ systemValueInfo->targetVarName = IRTargetBuiltinVarName::Unknown;
1290
1305
}
1291
1306
}
1292
1307
@@ -3746,6 +3761,60 @@ ScalarizedVal legalizeEntryPointReturnValueForGLSL(
3746
3761
return result;
3747
3762
}
3748
3763
3764
+ void legalizeTargetBuiltinVar (GLSLLegalizationContext& context)
3765
+ {
3766
+ List<KeyValuePair<IRTargetBuiltinVarName, IRInst*>> workItems;
3767
+ for (auto [builtinVarName, varInst] : context.builtinVarMap )
3768
+ {
3769
+ if (builtinVarName == IRTargetBuiltinVarName::HlslInstanceID)
3770
+ {
3771
+ workItems.add (KeyValuePair (builtinVarName, varInst));
3772
+ }
3773
+ }
3774
+
3775
+ auto getOrCreateBuiltinVar = [&](IRTargetBuiltinVarName name, IRType* type)
3776
+ {
3777
+ if (auto var = context.builtinVarMap .tryGetValue (name))
3778
+ return *var;
3779
+ IRBuilder builder (context.entryPointFunc );
3780
+ builder.setInsertBefore (context.entryPointFunc );
3781
+ IRInst* var = builder.createGlobalParam (type);
3782
+ builder.addTargetBuiltinVarDecoration (var, name);
3783
+ return var;
3784
+ };
3785
+ for (auto & kv : workItems)
3786
+ {
3787
+ auto builtinVarName = kv.key ;
3788
+ auto varInst = kv.value ;
3789
+
3790
+ // Repalce SV_InstanceID with gl_InstanceIndex - gl_BaseInstance.
3791
+ if (builtinVarName == IRTargetBuiltinVarName::HlslInstanceID)
3792
+ {
3793
+ auto instanceIndex = getOrCreateBuiltinVar (
3794
+ IRTargetBuiltinVarName::SpvInstanceIndex,
3795
+ varInst->getDataType ());
3796
+ auto baseInstance = getOrCreateBuiltinVar (
3797
+ IRTargetBuiltinVarName::SpvBaseInstance,
3798
+ varInst->getDataType ());
3799
+ traverseUses (
3800
+ varInst,
3801
+ [&](IRUse* use)
3802
+ {
3803
+ auto user = use->getUser ();
3804
+ if (user->getOp () == kIROp_Load )
3805
+ {
3806
+ IRBuilder builder (use->getUser ());
3807
+ builder.setInsertBefore (use->getUser ());
3808
+ auto sub = builder.emitSub (
3809
+ tryGetPointedToType (&builder, varInst->getDataType ()),
3810
+ builder.emitLoad (instanceIndex),
3811
+ builder.emitLoad (baseInstance));
3812
+ user->replaceUsesWith (sub);
3813
+ }
3814
+ });
3815
+ }
3816
+ }
3817
+ }
3749
3818
3750
3819
void legalizeEntryPointForGLSL (
3751
3820
Session* session,
@@ -3937,6 +4006,11 @@ void legalizeEntryPointForGLSL(
3937
4006
value.globalParam ->setFullType (sizedArrayType);
3938
4007
}
3939
4008
}
4009
+
4010
+ // Some system value vars can't be mapped 1:1 to a GLSL/Vulkan builtin,
4011
+ // for example, SV_InstanceID should map to gl_InstanceIndex - gl_BaseInstance,
4012
+ // we will replace these builtins with additional compute logic here.
4013
+ legalizeTargetBuiltinVar (context);
3940
4014
}
3941
4015
3942
4016
void decorateModuleWithSPIRVVersion (IRModule* module, SemanticVersion spirvVersion)
0 commit comments