Skip to content

Commit

Permalink
[SPIRV] Add SM6.6 IsHelperLane (#5488)
Browse files Browse the repository at this point in the history
Fix #5427
  • Loading branch information
jeremy-lunarg authored Aug 14, 2023
1 parent 4b6e799 commit daeba0c
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 1 deletion.
2 changes: 1 addition & 1 deletion tools/clang/include/clang/SPIRV/FeatureManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class FeatureManager {
std::string getKnownExtensions(const char *delimiter, const char *prefix = "",
const char *postfix = "");

/// Rqeusts the given target environment for translating the given feature at
/// Request the given target environment for translating the given feature at
/// the given source location. Emits an error if the requested target
/// environment does not match user's target environemnt.
bool requestTargetEnv(spv_target_env, llvm::StringRef target, SourceLocation);
Expand Down
1 change: 1 addition & 0 deletions tools/clang/lib/SPIRV/DeclResultIdMapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3312,6 +3312,7 @@ SpirvVariable *DeclResultIdMapper::getBuiltinVar(spv::BuiltIn builtIn,
spv::StorageClass sc = spv::StorageClass::Max;
// Valid builtins supported
switch (builtIn) {
case spv::BuiltIn::HelperInvocation:
case spv::BuiltIn::SubgroupSize:
case spv::BuiltIn::SubgroupLocalInvocationId:
needsLegalization = true;
Expand Down
29 changes: 29 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8504,6 +8504,9 @@ SpirvEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
retVal = spvBuilder.createLoad(retType, var, srcLoc, srcRange);
needsLegalization = true;
} break;
case hlsl::IntrinsicOp::IOP_IsHelperLane:
retVal = processIsHelperLane(callExpr, srcLoc, srcRange);
break;
case hlsl::IntrinsicOp::IOP_WaveIsFirstLane:
retVal = processWaveQuery(callExpr, spv::Op::OpGroupNonUniformElect);
break;
Expand Down Expand Up @@ -9161,6 +9164,32 @@ SpirvInstruction *SpirvEmitter::processWaveQuery(const CallExpr *callExpr,
opcode, retType, spv::Scope::Subgroup, callExpr->getExprLoc());
}

SpirvInstruction *SpirvEmitter::processIsHelperLane(const CallExpr *callExpr,
SourceLocation loc,
SourceRange range) {
assert(callExpr->getNumArgs() == 0);

if(!featureManager.isTargetEnvVulkan1p3OrAbove()) {
// If IsHelperlane is used for Vulkan 1.2 or less, we enable
// SPV_EXT_demote_to_helper_invocation extension to use
// OpIsHelperInvocationEXT instruction.
featureManager.allowExtension("SPV_EXT_demote_to_helper_invocation");

const QualType retType = callExpr->getCallReturnType(astContext);
return spvBuilder.createIsHelperInvocationEXT(retType, callExpr->getExprLoc());
}

// The SpreadVolatileSemanticsPass legalization pass will decorate the
// load with Volatile.
const QualType retType = callExpr->getCallReturnType(astContext);
auto *var =
declIdMapper.getBuiltinVar(spv::BuiltIn::HelperInvocation, retType, loc);
auto retVal = spvBuilder.createLoad(retType, var, loc, range);
needsLegalization = true;

return retVal;
}

SpirvInstruction *SpirvEmitter::processWaveVote(const CallExpr *callExpr,
spv::Op opcode) {
// Signatures:
Expand Down
4 changes: 4 additions & 0 deletions tools/clang/lib/SPIRV/SpirvEmitter.h
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,10 @@ class SpirvEmitter : public ASTConsumer {
/// Processes SM6.0 wave query intrinsic calls.
SpirvInstruction *processWaveQuery(const CallExpr *, spv::Op opcode);

/// Processes SM6.6 IsHelperLane intrisic calls.
SpirvInstruction *processIsHelperLane(const CallExpr *, SourceLocation loc,
SourceRange range);

/// Processes SM6.0 wave vote intrinsic calls.
SpirvInstruction *processWaveVote(const CallExpr *, spv::Op opcode);

Expand Down
13 changes: 13 additions & 0 deletions tools/clang/test/CodeGenSPIRV/intrinsics.sm6_6.ishelperlane.hlsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %dxc -T ps_6_0 -E main

// CHECK-NOT: OpDecorate {{%\w+}} BuiltIn HelperInvocation

float4 main() : SV_Target {
float ret = 1.0;

if (IsHelperLane()) ret = 2.0;

return ret;
}
// CHECK: [[HelperInvocation:%\d+]] = OpIsHelperInvocationEXT %bool
// CHECK: OpBranchConditional [[HelperInvocation]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %dxc -T ps_6_0 -E main -fspv-target-env=vulkan1.3

// CHECK: OpEntryPoint Fragment
// CHECK-SAME: %gl_HelperInvocation

// CHECK: OpDecorate %gl_HelperInvocation BuiltIn HelperInvocation

// CHECK: %gl_HelperInvocation = OpVariable %_ptr_Input_bool Input

float4 main() : SV_Target {
// CHECK: [[val:%\d+]] = OpLoad %bool %gl_HelperInvocation
// CHECK: OpBranchConditional [[val]]
float ret = 1.0;

if (IsHelperLane()) ret = 2.0;

return ret;
}
6 changes: 6 additions & 0 deletions tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1493,6 +1493,12 @@ TEST_F(FileTest, IntrinsicsSM66PackClampU8S8) {
TEST_F(FileTest, IntrinsicsSM66Unpack) {
runFileTest("intrinsics.sm6_6.unpack.hlsl");
}
TEST_F(FileTest, IntrinsicsSM66IsHelperLane) {
runFileTest("intrinsics.sm6_6.ishelperlane.hlsl");
}
TEST_F(FileTest, IntrinsicsSM66IsHelperLaneVk1p3) {
runFileTest("intrinsics.sm6_6.ishelperlane.vk1p3.hlsl");
}

// For attributes
TEST_F(FileTest, AttributeEarlyDepthStencil) {
Expand Down

0 comments on commit daeba0c

Please sign in to comment.