Skip to content

Commit

Permalink
[SPRIV] Allow vk-invert-y for MS shaders (#6839)
Browse files Browse the repository at this point in the history
Fixes #3154
  • Loading branch information
s-perron authored Jul 31, 2024
1 parent bb373fb commit 01fa18a
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 25 deletions.
20 changes: 2 additions & 18 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3667,7 +3667,7 @@ bool DeclResultIdMapper::createStageVars(StageVarDataBundle &stageVarData,
return true;
// Negate SV_Position.y if requested
if (semanticKind == hlsl::Semantic::Kind::Position)
*value = invertYIfRequested(*value, thisSemantic.loc);
*value = theEmitter.invertYIfRequested(*value, thisSemantic.loc);
storeToShaderOutputVariable(varInstr, *value, stageVarData);
}

Expand Down Expand Up @@ -3856,7 +3856,7 @@ bool DeclResultIdMapper::writeBackOutputStream(const NamedDecl *decl,

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

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

SpirvInstruction *
DeclResultIdMapper::invertYIfRequested(SpirvInstruction *position,
SourceLocation loc, SourceRange range) {
// Negate SV_Position.y if requested
if (spirvOptions.invertY) {
const auto oldY = spvBuilder.createCompositeExtract(
astContext.FloatTy, position, {1}, loc, range);
const auto newY = spvBuilder.createUnaryOp(
spv::Op::OpFNegate, astContext.FloatTy, oldY, loc, range);
position = spvBuilder.createCompositeInsert(
astContext.getExtVectorType(astContext.FloatTy, 4), position, {1}, newY,
loc, range);
}
return position;
}

SpirvInstruction *
DeclResultIdMapper::invertWIfRequested(SpirvInstruction *position,
SourceLocation loc) {
Expand Down
5 changes: 0 additions & 5 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -516,11 +516,6 @@ class DeclResultIdMapper {
bool writeBackOutputStream(const NamedDecl *decl, QualType type,
SpirvInstruction *value, SourceRange range = {});

/// \brief Negates to get the additive inverse of SV_Position.y if requested.
SpirvInstruction *invertYIfRequested(SpirvInstruction *position,
SourceLocation loc,
SourceRange range = {});

/// \brief Reciprocates to get the multiplicative inverse of SV_Position.w
/// if requested.
SpirvInstruction *invertWIfRequested(SpirvInstruction *position,
Expand Down
23 changes: 21 additions & 2 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -594,8 +594,8 @@ SpirvEmitter::SpirvEmitter(CompilerInstance &ci)
emitError("unknown shader module: %0", {}) << shaderModel->GetName();

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

if (spirvOptions.useGlLayout && spirvOptions.useDxLayout)
emitError("cannot specify both -fvk-use-dx-layout and -fvk-use-gl-layout",
Expand Down Expand Up @@ -7933,6 +7933,9 @@ void SpirvEmitter::assignToMSOutAttribute(
valueType = astContext.UnsignedIntTy;
}
varInstr = spvBuilder.createAccessChain(valueType, varInstr, indices, loc);
if (semanticInfo.semantic->GetKind() == hlsl::Semantic::Kind::Position)
value = invertYIfRequested(value, semanticInfo.loc);

spvBuilder.createStore(varInstr, value, loc);
}

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

SpirvInstruction *SpirvEmitter::invertYIfRequested(SpirvInstruction *position,
SourceLocation loc,
SourceRange range) {
// Negate SV_Position.y if requested
if (spirvOptions.invertY) {
const auto oldY = spvBuilder.createCompositeExtract(
astContext.FloatTy, position, {1}, loc, range);
const auto newY = spvBuilder.createUnaryOp(
spv::Op::OpFNegate, astContext.FloatTy, oldY, loc, range);
position = spvBuilder.createCompositeInsert(
astContext.getExtVectorType(astContext.FloatTy, 4), position, {1}, newY,
loc, range);
}
return position;
}

SpirvInstruction *
SpirvEmitter::processSpvIntrinsicCallExpr(const CallExpr *expr) {
const auto *funcDecl = expr->getDirectCallee();
Expand Down
5 changes: 5 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ class SpirvEmitter : public ASTConsumer {
llvm::ArrayRef<SpirvInstruction *> spvArgs,
bool isInstr, SourceLocation loc);

/// \brief Negates to get the additive inverse of SV_Position.y if requested.
SpirvInstruction *invertYIfRequested(SpirvInstruction *position,
SourceLocation loc,
SourceRange range = {});

private:
void doFunctionDecl(const FunctionDecl *decl);
void doVarDecl(const VarDecl *decl);
Expand Down
34 changes: 34 additions & 0 deletions tools/clang/test/CodeGenSPIRV/mesh.invert.y.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv -fvk-invert-y | FileCheck %s -check-prefix=CHECK -check-prefix=INVERT
// RUN: %dxc -T ms_6_5 -E main -fcgl %s -spirv | FileCheck %s -check-prefix=CHECK -check-prefix=NINVERT

struct MeshPerVertex {
float4 position : SV_Position;
};

#define NUM_THREADS 128
#define MAX_VERT 256
#define MAX_PRIM 256

// CHECK: [[v:%[0-9]+]] = OpConstantComposite %v4float %float_4 %float_5 %float_6 %float_7

[outputtopology("point")]
[numthreads(NUM_THREADS, 1, 1)]
void main(out vertices MeshPerVertex verts[MAX_VERT],
out indices uint primitiveInd[MAX_PRIM],
in uint tid : SV_DispatchThreadID)
{

SetMeshOutputCounts(MAX_VERT, MAX_PRIM);

// CHECK: [[glPosition:%[0-9]+]] = OpAccessChain %_ptr_Output_v4float %gl_Position %47
// NINVERT: OpStore [[glPosition]] [[v]]

// INVERT: [[vy:%[0-9]+]] = OpCompositeExtract %float [[v]] 1
// INVERT: [[nvy:%[0-9]+]] = OpFNegate %float [[vy]]
// INVERT: [[nv:%[0-9]+]] = OpCompositeInsert %v4float [[nvy]] [[v]] 1
// INVERT: OpStore [[glPosition]] [[nv]]
verts[tid].position = float4(4.0,5.0,6.0,7.0);

primitiveInd[6] = 2;
}

0 comments on commit 01fa18a

Please sign in to comment.