diff --git a/docs/SPIR-V.rst b/docs/SPIR-V.rst index b5e9c05079..f3981ba854 100644 --- a/docs/SPIR-V.rst +++ b/docs/SPIR-V.rst @@ -4227,7 +4227,7 @@ codegen for Vulkan: - ``-fvk-use-dx-layout``: Uses DirectX layout rules for resources. - ``-fvk-invert-y``: Negates (additively inverts) SV_Position.y before writing to stage output. Used to accommodate the difference between Vulkan's - coordinate system and DirectX's. Only allowed in VS/DS/GS. + coordinate system and DirectX's. Only allowed in VS/DS/GS/MS/Lib. - ``-fvk-use-dx-position-w``: Reciprocates (multiplicatively inverts) SV_Position.w after reading from stage input. Used to accommodate the difference between Vulkan DirectX: the w component of SV_Position in PS is diff --git a/include/dxc/Support/HLSLOptions.td b/include/dxc/Support/HLSLOptions.td index 4d72cb2312..58f6bdfbf3 100644 --- a/include/dxc/Support/HLSLOptions.td +++ b/include/dxc/Support/HLSLOptions.td @@ -368,7 +368,7 @@ def fvk_bind_register : MultiArg<["-"], "fvk-bind-register", 4>, MetaVarName<"; def vkbr : MultiArg<["-"], "vkbr", 4>, Flags<[CoreOption, DriverOption]>, Alias; def fvk_invert_y: Flag<["-"], "fvk-invert-y">, Group, Flags<[CoreOption, DriverOption]>, - HelpText<"Negate SV_Position.y before writing to stage output in VS/DS/GS to accommodate Vulkan's coordinate system">; + HelpText<"Negate SV_Position.y before writing to stage output in VS/DS/GS/MS/Lib to accommodate Vulkan's coordinate system">; def fvk_use_dx_position_w: Flag<["-"], "fvk-use-dx-position-w">, Group, Flags<[CoreOption, DriverOption]>, HelpText<"Reciprocate SV_Position.w after reading from stage input in PS to accommodate the difference between Vulkan and DirectX">; def fvk_support_nonzero_base_instance: Flag<["-"], "fvk-support-nonzero-base-instance">, Group, Flags<[CoreOption, DriverOption]>, diff --git a/tools/clang/lib/SPIRV/SpirvEmitter.cpp b/tools/clang/lib/SPIRV/SpirvEmitter.cpp index 7337a33b01..7042854504 100644 --- a/tools/clang/lib/SPIRV/SpirvEmitter.cpp +++ b/tools/clang/lib/SPIRV/SpirvEmitter.cpp @@ -604,8 +604,8 @@ SpirvEmitter::SpirvEmitter(CompilerInstance &ci) emitError("unknown shader module: %0", {}) << shaderModel->GetName(); if (spirvOptions.invertY && !shaderModel->IsVS() && !shaderModel->IsDS() && - !shaderModel->IsGS() && !shaderModel->IsMS()) - emitError("-fvk-invert-y can only be used in VS/DS/GS/MS", {}); + !shaderModel->IsGS() && !shaderModel->IsMS() && !shaderModel->IsLib()) + emitError("-fvk-invert-y can only be used in VS/DS/GS/MS/Lib", {}); if (spirvOptions.useGlLayout && spirvOptions.useDxLayout) emitError("cannot specify both -fvk-use-dx-layout and -fvk-use-gl-layout", @@ -14881,8 +14881,12 @@ SpirvEmitter::createSpirvIntrInstExt(llvm::ArrayRef attrs, SpirvInstruction *SpirvEmitter::invertYIfRequested(SpirvInstruction *position, SourceLocation loc, SourceRange range) { - // Negate SV_Position.y if requested - if (spirvOptions.invertY) { + // Negate SV_Position.y if requested and supported + + bool supportsInvertY = spvContext.isVS() || spvContext.isGS() || + spvContext.isDS() || spvContext.isMS(); + + if (spirvOptions.invertY && supportsInvertY) { const auto oldY = spvBuilder.createCompositeExtract( astContext.FloatTy, position, {1}, loc, range); const auto newY = spvBuilder.createUnaryOp( diff --git a/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.lib.hlsl b/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.lib.hlsl new file mode 100644 index 0000000000..6dac20fc6f --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/vk.cloption.invert-y.lib.hlsl @@ -0,0 +1,12 @@ +// RUN: %dxc -T lib_6_3 -fvk-invert-y -fcgl %s -spirv | FileCheck %s + +[shader("vertex")] +float4 main(float4 a : A) : SV_Position { + return a; +} + +// CHECK: [[a:%[0-9]+]] = OpFunctionCall %v4float %src_main %param_var_a +// CHECK-NEXT: [[oldY:%[0-9]+]] = OpCompositeExtract %float [[a]] 1 +// CHECK-NEXT: [[newY:%[0-9]+]] = OpFNegate %float [[oldY]] +// CHECK-NEXT: [[pos:%[0-9]+]] = OpCompositeInsert %v4float [[newY]] [[a]] 1 +// CHECK-NEXT: OpStore %gl_Position [[pos]]