|
@@ -1710,6 +1710,8 @@ bool DeclResultIdMapper::createStageVars(
|
|
|
// * SV_DispatchThreadID, SV_GroupThreadID, and SV_GroupID are allowed to be
|
|
|
// uint, uint2, or uint3, but the corresponding builtins
|
|
|
// (GlobalInvocationId, LocalInvocationId, WorkgroupId) must be a uint3.
|
|
|
+ // * SV_ShadingRate is a uint value, but the builtin it corresponds to is a
|
|
|
+ // int2.
|
|
|
|
|
|
if (glPerVertex.tryToAccess(sigPoint->GetKind(), semanticKind,
|
|
|
semanticToUse->index, invocationId, value,
|
|
@@ -1747,6 +1749,9 @@ bool DeclResultIdMapper::createStageVars(
|
|
|
hlsl::IsHLSLVecType(type) ? hlsl::GetHLSLVecElementType(type) : type,
|
|
|
3);
|
|
|
break;
|
|
|
+ case hlsl::Semantic::Kind::ShadingRate:
|
|
|
+ evalType = astContext.getExtVectorType(astContext.IntTy, 2);
|
|
|
+ break;
|
|
|
default:
|
|
|
// Only the semantic kinds mentioned above are handled.
|
|
|
break;
|
|
@@ -1919,6 +1924,24 @@ bool DeclResultIdMapper::createStageVars(
|
|
|
astContext.getExtVectorType(srcVecElemType, 2), *value, *value,
|
|
|
{0, 1}, thisSemantic.loc);
|
|
|
}
|
|
|
+ // Special handling of SV_ShadingRate, which is a bitpacked enum value,
|
|
|
+ // but SPIR-V's FragSizeEXT uses an int2. We build the enum value from
|
|
|
+ // the separate axis values.
|
|
|
+ else if (semanticKind == hlsl::Semantic::Kind::ShadingRate) {
|
|
|
+ // From the D3D12 functional spec for Variable-Rate Shading.
|
|
|
+ // #define D3D12_MAKE_COARSE_SHADING_RATE(x,y) ((x) << 2 | (y))
|
|
|
+ const auto x = spvBuilder.createCompositeExtract(
|
|
|
+ astContext.IntTy, *value, {0}, thisSemantic.loc);
|
|
|
+ const auto y = spvBuilder.createCompositeExtract(
|
|
|
+ astContext.IntTy, *value, {1}, thisSemantic.loc);
|
|
|
+ const auto constTwo =
|
|
|
+ spvBuilder.getConstantInt(astContext.IntTy, llvm::APInt(32, 2));
|
|
|
+ *value = spvBuilder.createBinaryOp(
|
|
|
+ spv::Op::OpBitwiseOr, astContext.UnsignedIntTy,
|
|
|
+ spvBuilder.createBinaryOp(spv::Op::OpShiftLeftLogical,
|
|
|
+ astContext.IntTy, x, constTwo),
|
|
|
+ y, /* SourceLocation */ {});
|
|
|
+ }
|
|
|
|
|
|
// Reciprocate SV_Position.w if requested
|
|
|
if (semanticKind == hlsl::Semantic::Kind::Position)
|
|
@@ -2732,6 +2755,23 @@ SpirvVariable *DeclResultIdMapper::createSpirvStageVar(
|
|
|
return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FullyCoveredEXT,
|
|
|
isPrecise, srcLoc);
|
|
|
}
|
|
|
+ // According to DXIL spec, the ShadingRate SV can only be used by GSOut,
|
|
|
+ // VSOut, or PSIn. According to Vulkan spec, the FragSizeEXT BuiltIn can only
|
|
|
+ // be used as PSIn.
|
|
|
+ case hlsl::Semantic::Kind::ShadingRate: {
|
|
|
+ switch (sigPointKind) {
|
|
|
+ case hlsl::SigPoint::Kind::PSIn:
|
|
|
+ stageVar->setIsSpirvBuiltin();
|
|
|
+ return spvBuilder.addStageBuiltinVar(type, sc, BuiltIn::FragSizeEXT,
|
|
|
+ isPrecise, srcLoc);
|
|
|
+ default:
|
|
|
+ emitError("semantic ShadingRate currently unsupported in non-PS shader"
|
|
|
+ " stages",
|
|
|
+ srcLoc);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
default:
|
|
|
emitError("semantic %0 unimplemented", srcLoc)
|
|
|
<< stageVar->getSemanticStr();
|