[spirv] Support CheckAccessFullyMapped intrinsic. (#897)
This commit is contained in:
Родитель
546b159729
Коммит
679b7c80c7
|
@ -1516,6 +1516,7 @@ The following intrinsic HLSL functions have direct SPIR-V opcodes for them:
|
|||
``isInf`` ``OpIsInf``
|
||||
``reversebits`` ``OpBitReverse``
|
||||
``transpose`` ``OpTranspose``
|
||||
``CheckAccessFullyMapped`` ``OpImageSparseTexelsResident``
|
||||
==================================== =================================
|
||||
|
||||
Using GLSL extended instructions
|
||||
|
@ -2279,8 +2280,6 @@ either because of no Vulkan equivalents at the moment, or because of deprecation
|
|||
emit a warning and ignore it.
|
||||
* ``abort()`` intrinsic function: no Vulkan equivalent. The compiler will emit
|
||||
an error.
|
||||
* ``CheckAccessFullyMapped()`` intrinsic function: no Vulkan equivalent.
|
||||
The compiler will emit an error.
|
||||
* ``GetRenderTargetSampleCount()`` intrinsic function: no Vulkan equivalent.
|
||||
(Its GLSL counterpart is ``gl_NumSamples``, which is not available in GLSL for
|
||||
Vulkan.) The compiler will emit an error.
|
||||
|
|
|
@ -863,7 +863,7 @@ public:
|
|||
opImageSample(uint32_t result_type, uint32_t result_id,
|
||||
uint32_t sampled_image, uint32_t coordinate, uint32_t dref,
|
||||
llvm::Optional<spv::ImageOperandsMask> image_operands,
|
||||
bool isExplicit, bool isSparse);
|
||||
bool is_explicit, bool is_sparse);
|
||||
|
||||
// Methods for supplying additional parameters.
|
||||
InstBuilder &fPFastMathMode(spv::FPFastMathModeMask);
|
||||
|
|
|
@ -172,7 +172,7 @@ public:
|
|||
/// be generated.
|
||||
///
|
||||
/// If bias, lod, grad, or minLod is given a non-zero value, an additional
|
||||
/// image operands, Bias, Lod, Grad, or minLod will be attached to the current
|
||||
/// image operands, Bias, Lod, Grad, or MinLod will be attached to the current
|
||||
/// instruction, respectively. Panics if both lod and minLod are non-zero.
|
||||
///
|
||||
/// If residencyCodeId is not zero, the sparse version of the instructions
|
||||
|
@ -216,6 +216,10 @@ public:
|
|||
uint32_t varOffset, uint32_t constOffsets,
|
||||
uint32_t sample, uint32_t residencyCodeId);
|
||||
|
||||
/// \brief Creates an OpImageSparseTexelsResident SPIR-V instruction for the
|
||||
/// given Resident Code and returns the <result-id> of the instruction.
|
||||
uint32_t createImageSparseTexelsResident(uint32_t resident_code);
|
||||
|
||||
/// \brief Creates a select operation with the given values for true and false
|
||||
/// cases and returns the <result-id> for the result.
|
||||
uint32_t createSelect(uint32_t resultType, uint32_t condition,
|
||||
|
|
|
@ -83,19 +83,19 @@ InstBuilder &InstBuilder::opConstant(uint32_t resultType, uint32_t resultId,
|
|||
InstBuilder &InstBuilder::opImageSample(
|
||||
uint32_t result_type, uint32_t result_id, uint32_t sampled_image,
|
||||
uint32_t coordinate, uint32_t dref,
|
||||
llvm::Optional<spv::ImageOperandsMask> image_operands, bool isExplicit,
|
||||
bool isSparse) {
|
||||
llvm::Optional<spv::ImageOperandsMask> image_operands, bool is_explicit,
|
||||
bool is_sparse) {
|
||||
spv::Op op = spv::Op::Max;
|
||||
if (dref) {
|
||||
op = isExplicit ? (isSparse ? spv::Op::OpImageSparseSampleDrefExplicitLod
|
||||
: spv::Op::OpImageSampleDrefExplicitLod)
|
||||
: (isSparse ? spv::Op::OpImageSparseSampleDrefImplicitLod
|
||||
: spv::Op::OpImageSampleDrefImplicitLod);
|
||||
op = is_explicit ? (is_sparse ? spv::Op::OpImageSparseSampleDrefExplicitLod
|
||||
: spv::Op::OpImageSampleDrefExplicitLod)
|
||||
: (is_sparse ? spv::Op::OpImageSparseSampleDrefImplicitLod
|
||||
: spv::Op::OpImageSampleDrefImplicitLod);
|
||||
} else {
|
||||
op = isExplicit ? (isSparse ? spv::Op::OpImageSparseSampleExplicitLod
|
||||
: spv::Op::OpImageSampleExplicitLod)
|
||||
: (isSparse ? spv::Op::OpImageSparseSampleImplicitLod
|
||||
: spv::Op::OpImageSampleImplicitLod);
|
||||
op = is_explicit ? (is_sparse ? spv::Op::OpImageSparseSampleExplicitLod
|
||||
: spv::Op::OpImageSampleExplicitLod)
|
||||
: (is_sparse ? spv::Op::OpImageSparseSampleImplicitLod
|
||||
: spv::Op::OpImageSampleImplicitLod);
|
||||
}
|
||||
|
||||
TheInst.emplace_back(static_cast<uint32_t>(op));
|
||||
|
@ -103,7 +103,7 @@ InstBuilder &InstBuilder::opImageSample(
|
|||
TheInst.emplace_back(result_id);
|
||||
TheInst.emplace_back(sampled_image);
|
||||
TheInst.emplace_back(coordinate);
|
||||
if(dref)
|
||||
if (dref)
|
||||
TheInst.emplace_back(dref);
|
||||
if (image_operands.hasValue()) {
|
||||
const auto &val = image_operands.getValue();
|
||||
|
|
|
@ -339,6 +339,17 @@ spv::ImageOperandsMask ModuleBuilder::composeImageOperandsMask(
|
|||
return mask;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
ModuleBuilder::createImageSparseTexelsResident(uint32_t resident_code) {
|
||||
assert(insertPoint && "null insert point");
|
||||
// Result type must be a boolean
|
||||
const uint32_t result_type = getBoolType();
|
||||
const uint32_t id = theContext.takeNextId();
|
||||
instBuilder.opImageSparseTexelsResident(result_type, id, resident_code).x();
|
||||
insertPoint->appendInstruction(std::move(constructSite));
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32_t ModuleBuilder::createImageTexelPointer(uint32_t resultType,
|
||||
uint32_t imageId,
|
||||
uint32_t coordinate,
|
||||
|
|
|
@ -4625,6 +4625,10 @@ SpirvEvalInfo SPIRVEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
|
|||
/*groupSync*/ true,
|
||||
/*isAllBarrier*/ true);
|
||||
break;
|
||||
case hlsl::IntrinsicOp::IOP_CheckAccessFullyMapped:
|
||||
retVal =
|
||||
theBuilder.createImageSparseTexelsResident(doExpr(callExpr->getArg(0)));
|
||||
break;
|
||||
case hlsl::IntrinsicOp::IOP_mul:
|
||||
retVal = processIntrinsicMul(callExpr);
|
||||
break;
|
||||
|
@ -4695,7 +4699,6 @@ SpirvEvalInfo SPIRVEmitter::processIntrinsicCallExpr(const CallExpr *callExpr) {
|
|||
retVal = processIntrinsicF32ToF16(callExpr);
|
||||
break;
|
||||
case hlsl::IntrinsicOp::IOP_abort:
|
||||
case hlsl::IntrinsicOp::IOP_CheckAccessFullyMapped:
|
||||
case hlsl::IntrinsicOp::IOP_GetRenderTargetSampleCount:
|
||||
case hlsl::IntrinsicOp::IOP_GetRenderTargetSamplePosition: {
|
||||
emitError("no equivalent for %0 intrinsic function in Vulkan",
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
// Run: %dxc -T ps_6_0 -E main
|
||||
|
||||
void main() {
|
||||
uint status;
|
||||
bool fullyMapped = CheckAccessFullyMapped(status);
|
||||
}
|
||||
SamplerState gSampler : register(s5);
|
||||
Texture2D<float4> t : register(t1);
|
||||
|
||||
// CHECK: error: no equivalent for CheckAccessFullyMapped intrinsic function in Vulkan
|
||||
// CHECK: OpCapability SparseResidency
|
||||
|
||||
// CHECK: %SparseResidencyStruct = OpTypeStruct %uint %v4float
|
||||
|
||||
float4 main(int2 offset: A) : SV_Target {
|
||||
uint status;
|
||||
float clamp;
|
||||
float4 val = t.Sample(gSampler, float2(0.1, 0.2), offset, clamp, status);
|
||||
|
||||
// CHECK: [[residency_code:%\d+]] = OpLoad %uint %status
|
||||
// CHECK: [[success:%\d+]] = OpImageSparseTexelsResident %bool [[residency_code]]
|
||||
// CHECK: OpStore %success [[success]]
|
||||
bool success = CheckAccessFullyMapped(status);
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
|
|
@ -831,7 +831,7 @@ TEST_F(FileTest, IntrinsicsAbort) {
|
|||
runFileTest("intrinsics.abort.hlsl", Expect::Failure);
|
||||
}
|
||||
TEST_F(FileTest, IntrinsicsCheckAccessFullyMapped) {
|
||||
runFileTest("intrinsics.check-access-fully-mapped.hlsl", Expect::Failure);
|
||||
runFileTest("intrinsics.check-access-fully-mapped.hlsl");
|
||||
}
|
||||
TEST_F(FileTest, IntrinsicsGetRenderTargetSampleCount) {
|
||||
runFileTest("intrinsics.get-render-target-sample-count.hlsl",
|
||||
|
|
Загрузка…
Ссылка в новой задаче