Add --hlsl-dx-position-w option

This reciprocates the w component of SV_Position in HLSL fragment shaders
to provide DirectX compatibility for HLSL shaders in Vulkan.

Fixes #2244
This commit is contained in:
Greg Fischer 2021-11-16 18:42:12 -07:00
parent 8a7860e4cb
commit e9564feb55
9 changed files with 323 additions and 2 deletions

View file

@ -2167,8 +2167,21 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
TIntermSymbol* arg = intermediate.addSymbol(*argVars.back());
handleFunctionArgument(&callee, callingArgs, arg);
if (param.type->getQualifier().isParamInput()) {
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg,
intermediate.addSymbol(**inputIt)));
TIntermTyped* input = intermediate.addSymbol(**inputIt);
if (input->getType().getQualifier().builtIn == EbvFragCoord && intermediate.getDxPositionW()) {
// Replace FragCoord W with reciprocal
auto pos_xyz = handleDotDereference(loc, input, "xyz");
auto pos_w = handleDotDereference(loc, input, "w");
auto one = intermediate.addConstantUnion(1.0, EbtFloat, loc);
auto recip_w = intermediate.addBinaryMath(EOpDiv, one, pos_w, loc);
TIntermAggregate* dst = new TIntermAggregate(EOpConstructVec4);
dst->getSequence().push_back(pos_xyz);
dst->getSequence().push_back(recip_w);
dst->setType(TType(EbtFloat, EvqTemporary, 4));
dst->setLoc(loc);
input = dst;
}
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg, input));
inputIt++;
}
if (param.type->getQualifier().storage == EvqUniform) {