[SPRIV] Allow vk-invert-y for MS shaders (#6839)

Fixes #3154
This commit is contained in:
Steven Perron 2024-07-31 16:53:48 -04:00 коммит произвёл GitHub
Родитель bb373fb88e
Коммит 01fa18a57b
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 62 добавлений и 25 удалений

Просмотреть файл

@ -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);
}
@ -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(),
@ -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) {

Просмотреть файл

@ -516,11 +516,6 @@ public:
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,

Просмотреть файл

@ -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",
@ -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);
}
@ -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();

Просмотреть файл

@ -114,6 +114,11 @@ public:
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);

Просмотреть файл

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