From 5f0b492f46e59db336590ccac0244710611c737d Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Tue, 6 Nov 2018 13:34:16 -0700 Subject: [PATCH] [spirv] Add support for casting involving vector decomposition Fixes https://github.com/Microsoft/DirectXShaderCompiler/issues/1673 Fixes https://github.com/Microsoft/DirectXShaderCompiler/issues/1675 Fixes https://github.com/Microsoft/DirectXShaderCompiler/issues/1676 --- tools/clang/lib/SPIRV/InitListHandler.cpp | 19 +++++++++++++++++-- tools/clang/lib/SPIRV/InitListHandler.h | 8 ++++++-- tools/clang/lib/SPIRV/SPIRVEmitter.cpp | 8 +++++--- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/tools/clang/lib/SPIRV/InitListHandler.cpp b/tools/clang/lib/SPIRV/InitListHandler.cpp index 54db48fe4..1f8fbc7e8 100644 --- a/tools/clang/lib/SPIRV/InitListHandler.cpp +++ b/tools/clang/lib/SPIRV/InitListHandler.cpp @@ -27,7 +27,7 @@ InitListHandler::InitListHandler(const ASTContext &ctx, SPIRVEmitter &emitter) spvBuilder(emitter.getSpirvBuilder()), diags(emitter.getDiagnosticsEngine()) {} -SpirvInstruction *InitListHandler::process(const InitListExpr *expr) { +SpirvInstruction *InitListHandler::processInit(const InitListExpr *expr) { initializers.clear(); scalars.clear(); @@ -36,7 +36,22 @@ SpirvInstruction *InitListHandler::process(const InitListExpr *expr) { // tail of the vector. This is more efficient than using a deque. std::reverse(std::begin(initializers), std::end(initializers)); - auto *init = createInitForType(expr->getType(), expr->getExprLoc()); + return doProcess(expr->getType(), expr->getExprLoc()); +} + +SpirvInstruction *InitListHandler::processCast(QualType toType, + const Expr *expr) { + initializers.clear(); + scalars.clear(); + + initializers.push_back(expr); + + return doProcess(toType, expr->getExprLoc()); +} + +SpirvInstruction *InitListHandler::doProcess(QualType type, + SourceLocation srcLoc) { + auto *init = createInitForType(type, srcLoc); if (init) { // For successful translation, we should have consumed all initializers and diff --git a/tools/clang/lib/SPIRV/InitListHandler.h b/tools/clang/lib/SPIRV/InitListHandler.h index 15f9467b3..e157385ad 100644 --- a/tools/clang/lib/SPIRV/InitListHandler.h +++ b/tools/clang/lib/SPIRV/InitListHandler.h @@ -83,7 +83,11 @@ public: /// Processes the given InitListExpr and returns the for the final /// SPIR-V value. - SpirvInstruction *process(const InitListExpr *expr); + SpirvInstruction *processInit(const InitListExpr *expr); + + /// Casts the given Expr to the given toType and returns the for + /// the final SPIR-V value. + SpirvInstruction *processCast(QualType toType, const Expr *expr); private: /// \brief Wrapper method to create an error message and report it @@ -97,7 +101,7 @@ private: /// Processes the expressions in initializers and returns the for /// the final SPIR-V value of the given type. - uint32_t doProcess(QualType type, SourceLocation srcLoc); + SpirvInstruction *doProcess(QualType type, SourceLocation srcLoc); /// Flattens the given InitListExpr and puts all non-InitListExpr AST nodes /// into initializers. diff --git a/tools/clang/lib/SPIRV/SPIRVEmitter.cpp b/tools/clang/lib/SPIRV/SPIRVEmitter.cpp index e49806b5b..fefda871c 100644 --- a/tools/clang/lib/SPIRV/SPIRVEmitter.cpp +++ b/tools/clang/lib/SPIRV/SPIRVEmitter.cpp @@ -2291,8 +2291,10 @@ SpirvInstruction *SPIRVEmitter::doCastExpr(const CastExpr *expr) { // as FlatConversion. For such cases, we can rely on the InitListHandler, // which can decompse vectors/matrices. else if (subExprType->isArrayType()) { - auto valId = InitListHandler(*this).processCast(expr->getType(), subExpr); - return SpirvEvalInfo(valId).setRValue(); + auto *valInstr = InitListHandler(astContext, *this) + .processCast(expr->getType(), subExpr); + valInstr->setRValue(); + return valInstr; } if (!subExprInstr) @@ -4431,7 +4433,7 @@ SpirvInstruction *SPIRVEmitter::doInitListExpr(const InitListExpr *expr) { return id; } - SpirvInstruction *result = InitListHandler(astContext, *this).process(expr); + auto *result = InitListHandler(astContext, *this).processInit(expr); result->setRValue(); return result; }