Skip to content

Commit 01fa18a

Browse files
authored
[SPRIV] Allow vk-invert-y for MS shaders (microsoft#6839)
Fixes microsoft#3154
1 parent bb373fb commit 01fa18a

File tree

5 files changed

+62
-25
lines changed

5 files changed

+62
-25
lines changed

tools/clang/lib/SPIRV/DeclResultIdMapper.cpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3667,7 +3667,7 @@ bool DeclResultIdMapper::createStageVars(StageVarDataBundle &stageVarData,
36673667
return true;
36683668
// Negate SV_Position.y if requested
36693669
if (semanticKind == hlsl::Semantic::Kind::Position)
3670-
*value = invertYIfRequested(*value, thisSemantic.loc);
3670+
*value = theEmitter.invertYIfRequested(*value, thisSemantic.loc);
36713671
storeToShaderOutputVariable(varInstr, *value, stageVarData);
36723672
}
36733673

@@ -3856,7 +3856,7 @@ bool DeclResultIdMapper::writeBackOutputStream(const NamedDecl *decl,
38563856

38573857
// Negate SV_Position.y if requested
38583858
if (semanticInfo.semantic->GetKind() == hlsl::Semantic::Kind::Position)
3859-
value = invertYIfRequested(value, loc, range);
3859+
value = theEmitter.invertYIfRequested(value, loc, range);
38603860

38613861
// Boolean stage output variables are represented as unsigned integers.
38623862
if (isBooleanStageIOVar(decl, type, semanticInfo.semantic->GetKind(),
@@ -3906,22 +3906,6 @@ bool DeclResultIdMapper::writeBackOutputStream(const NamedDecl *decl,
39063906
return true;
39073907
}
39083908

3909-
SpirvInstruction *
3910-
DeclResultIdMapper::invertYIfRequested(SpirvInstruction *position,
3911-
SourceLocation loc, SourceRange range) {
3912-
// Negate SV_Position.y if requested
3913-
if (spirvOptions.invertY) {
3914-
const auto oldY = spvBuilder.createCompositeExtract(
3915-
astContext.FloatTy, position, {1}, loc, range);
3916-
const auto newY = spvBuilder.createUnaryOp(
3917-
spv::Op::OpFNegate, astContext.FloatTy, oldY, loc, range);
3918-
position = spvBuilder.createCompositeInsert(
3919-
astContext.getExtVectorType(astContext.FloatTy, 4), position, {1}, newY,
3920-
loc, range);
3921-
}
3922-
return position;
3923-
}
3924-
39253909
SpirvInstruction *
39263910
DeclResultIdMapper::invertWIfRequested(SpirvInstruction *position,
39273911
SourceLocation loc) {

tools/clang/lib/SPIRV/DeclResultIdMapper.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -516,11 +516,6 @@ class DeclResultIdMapper {
516516
bool writeBackOutputStream(const NamedDecl *decl, QualType type,
517517
SpirvInstruction *value, SourceRange range = {});
518518

519-
/// \brief Negates to get the additive inverse of SV_Position.y if requested.
520-
SpirvInstruction *invertYIfRequested(SpirvInstruction *position,
521-
SourceLocation loc,
522-
SourceRange range = {});
523-
524519
/// \brief Reciprocates to get the multiplicative inverse of SV_Position.w
525520
/// if requested.
526521
SpirvInstruction *invertWIfRequested(SpirvInstruction *position,

tools/clang/lib/SPIRV/SpirvEmitter.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,8 @@ SpirvEmitter::SpirvEmitter(CompilerInstance &ci)
594594
emitError("unknown shader module: %0", {}) << shaderModel->GetName();
595595

596596
if (spirvOptions.invertY && !shaderModel->IsVS() && !shaderModel->IsDS() &&
597-
!shaderModel->IsGS())
598-
emitError("-fvk-invert-y can only be used in VS/DS/GS", {});
597+
!shaderModel->IsGS() && !shaderModel->IsMS())
598+
emitError("-fvk-invert-y can only be used in VS/DS/GS/MS", {});
599599

600600
if (spirvOptions.useGlLayout && spirvOptions.useDxLayout)
601601
emitError("cannot specify both -fvk-use-dx-layout and -fvk-use-gl-layout",
@@ -7933,6 +7933,9 @@ void SpirvEmitter::assignToMSOutAttribute(
79337933
valueType = astContext.UnsignedIntTy;
79347934
}
79357935
varInstr = spvBuilder.createAccessChain(valueType, varInstr, indices, loc);
7936+
if (semanticInfo.semantic->GetKind() == hlsl::Semantic::Kind::Position)
7937+
value = invertYIfRequested(value, semanticInfo.loc);
7938+
79367939
spvBuilder.createStore(varInstr, value, loc);
79377940
}
79387941

@@ -14327,6 +14330,22 @@ SpirvEmitter::createSpirvIntrInstExt(llvm::ArrayRef<const Attr *> attrs,
1432714330
return retVal;
1432814331
}
1432914332

14333+
SpirvInstruction *SpirvEmitter::invertYIfRequested(SpirvInstruction *position,
14334+
SourceLocation loc,
14335+
SourceRange range) {
14336+
// Negate SV_Position.y if requested
14337+
if (spirvOptions.invertY) {
14338+
const auto oldY = spvBuilder.createCompositeExtract(
14339+
astContext.FloatTy, position, {1}, loc, range);
14340+
const auto newY = spvBuilder.createUnaryOp(
14341+
spv::Op::OpFNegate, astContext.FloatTy, oldY, loc, range);
14342+
position = spvBuilder.createCompositeInsert(
14343+
astContext.getExtVectorType(astContext.FloatTy, 4), position, {1}, newY,
14344+
loc, range);
14345+
}
14346+
return position;
14347+
}
14348+
1433014349
SpirvInstruction *
1433114350
SpirvEmitter::processSpvIntrinsicCallExpr(const CallExpr *expr) {
1433214351
const auto *funcDecl = expr->getDirectCallee();

tools/clang/lib/SPIRV/SpirvEmitter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,11 @@ class SpirvEmitter : public ASTConsumer {
114114
llvm::ArrayRef<SpirvInstruction *> spvArgs,
115115
bool isInstr, SourceLocation loc);
116116

117+
/// \brief Negates to get the additive inverse of SV_Position.y if requested.
118+
SpirvInstruction *invertYIfRequested(SpirvInstruction *position,
119+
SourceLocation loc,
120+
SourceRange range = {});
121+
117122
private:
118123
void doFunctionDecl(const FunctionDecl *decl);
119124
void doVarDecl(const VarDecl *decl);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv -fvk-invert-y | FileCheck %s -check-prefix=CHECK -check-prefix=INVERT
2+
// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv | FileCheck %s -check-prefix=CHECK -check-prefix=NINVERT
3+
4+
struct MeshPerVertex {
5+
float4 position : SV_Position;
6+
};
7+
8+
#define NUM_THREADS 128
9+
#define MAX_VERT 256
10+
#define MAX_PRIM 256
11+
12+
// CHECK: [[v:%[0-9]+]] = OpConstantComposite %v4float %float_4 %float_5 %float_6 %float_7
13+
14+
[outputtopology("point")]
15+
[numthreads(NUM_THREADS, 1, 1)]
16+
void main(out vertices MeshPerVertex verts[MAX_VERT],
17+
out indices uint primitiveInd[MAX_PRIM],
18+
in uint tid : SV_DispatchThreadID)
19+
{
20+
21+
SetMeshOutputCounts(MAX_VERT, MAX_PRIM);
22+
23+
// CHECK: [[glPosition:%[0-9]+]] = OpAccessChain %_ptr_Output_v4float %gl_Position %47
24+
// NINVERT: OpStore [[glPosition]] [[v]]
25+
26+
// INVERT: [[vy:%[0-9]+]] = OpCompositeExtract %float [[v]] 1
27+
// INVERT: [[nvy:%[0-9]+]] = OpFNegate %float [[vy]]
28+
// INVERT: [[nv:%[0-9]+]] = OpCompositeInsert %v4float [[nvy]] [[v]] 1
29+
// INVERT: OpStore [[glPosition]] [[nv]]
30+
verts[tid].position = float4(4.0,5.0,6.0,7.0);
31+
32+
primitiveInd[6] = 2;
33+
}
34+

0 commit comments

Comments
 (0)