From ae8c5febf75709dcce1a4de543dd1efcb93c584a Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 6 Feb 2018 15:32:53 -0500 Subject: [PATCH] [spirv] Turn on legalization for invalid opcode (#1058) Certain opcodes are not available in non-pixel stages. Call the pass to replace them. --- external/SPIRV-Tools | 2 +- tools/clang/lib/SPIRV/DeclResultIdMapper.h | 3 ++- tools/clang/lib/SPIRV/SPIRVEmitter.cpp | 23 ++++++++++++++++++++++ tools/clang/lib/SPIRV/SPIRVEmitter.h | 5 +++-- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/external/SPIRV-Tools b/external/SPIRV-Tools index 50e85c865..e7fafdaa6 160000 --- a/external/SPIRV-Tools +++ b/external/SPIRV-Tools @@ -1 +1 @@ -Subproject commit 50e85c865ca9c4b53e2724f36a84fb2566c1ce97 +Subproject commit e7fafdaa68a3775be5f2406e91db4b5d3fbc7b35 diff --git a/tools/clang/lib/SPIRV/DeclResultIdMapper.h b/tools/clang/lib/SPIRV/DeclResultIdMapper.h index 101e0190c..a3e062aa5 100644 --- a/tools/clang/lib/SPIRV/DeclResultIdMapper.h +++ b/tools/clang/lib/SPIRV/DeclResultIdMapper.h @@ -653,7 +653,8 @@ private: /// The following cases will require legalization: /// /// 1. Opaque types (textures, samplers) within structs - /// 2. Structured buffer assignments + /// 2. Structured buffer aliasing + /// 3. Using SPIR-V instructions not allowed in the currect shader stage /// /// This covers the second case: /// diff --git a/tools/clang/lib/SPIRV/SPIRVEmitter.cpp b/tools/clang/lib/SPIRV/SPIRVEmitter.cpp index dda6f5e83..a34db12cd 100644 --- a/tools/clang/lib/SPIRV/SPIRVEmitter.cpp +++ b/tools/clang/lib/SPIRV/SPIRVEmitter.cpp @@ -3620,6 +3620,14 @@ uint32_t SPIRVEmitter::createImageSample( texelTypeId = theBuilder.getVecType(elemTypeId, 4); } + // The Lod and Grad image operands requires explicit-lod instructions. + // Otherwise we use implicit-lod instructions. + const bool isExplicit = lod || (grad.first && grad.second); + + // Implicit-lod instructions are only allowed in pixel shader. + if (!shaderModel.IsPS() && !isExplicit) + needsLegalization = true; + uint32_t retVal = theBuilder.createImageSample( texelTypeId, imageType, image, sampler, coordinate, compareVal, bias, lod, grad, constOffset, varOffset, constOffsets, sample, minLod, @@ -7227,6 +7235,21 @@ uint32_t SPIRVEmitter::processIntrinsicF32ToF16(const CallExpr *callExpr) { uint32_t SPIRVEmitter::processIntrinsicUsingSpirvInst( const CallExpr *callExpr, spv::Op opcode, bool actPerRowForMatrices) { + // Certain opcodes are only allowed in pixel shader + if (!shaderModel.IsPS()) + switch (opcode) { + case spv::Op::OpDPdx: + case spv::Op::OpDPdy: + case spv::Op::OpDPdxFine: + case spv::Op::OpDPdyFine: + case spv::Op::OpDPdxCoarse: + case spv::Op::OpDPdyCoarse: + case spv::Op::OpFwidth: + case spv::Op::OpFwidthFine: + case spv::Op::OpFwidthCoarse: + needsLegalization = true; + } + const uint32_t returnType = typeTranslator.translateType(callExpr->getType()); if (callExpr->getNumArgs() == 1u) { const Expr *arg = callExpr->getArg(0); diff --git a/tools/clang/lib/SPIRV/SPIRVEmitter.h b/tools/clang/lib/SPIRV/SPIRVEmitter.h index 97579d8bb..543595ea8 100644 --- a/tools/clang/lib/SPIRV/SPIRVEmitter.h +++ b/tools/clang/lib/SPIRV/SPIRVEmitter.h @@ -862,9 +862,10 @@ private: /// The following cases will require legalization: /// /// 1. Opaque types (textures, samplers) within structs - /// 2. Structured buffer assignments + /// 2. Structured buffer aliasing + /// 3. Using SPIR-V instructions not allowed in the currect shader stage /// - /// This covers the first case. + /// This covers the first and third case. /// /// If this is true, SPIRV-Tools legalization passes will be executed after /// the translation to legalize the generated SPIR-V binary.