[spirv] Support CheckAccessFullyMapped intrinsic. (#897)

This commit is contained in:
Ehsan 2017-12-11 14:02:21 -05:00 коммит произвёл GitHub
Родитель 546b159729
Коммит 679b7c80c7
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 52 добавлений и 22 удалений

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

@ -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",