@@ -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