diff options
-rw-r--r-- | src/sksl/SkSLCompiler.cpp | 3 | ||||
-rw-r--r-- | src/sksl/SkSLContext.h | 12 | ||||
-rw-r--r-- | src/sksl/SkSLGLSLCodeGenerator.cpp | 6 | ||||
-rw-r--r-- | src/sksl/SkSLParser.cpp | 15 | ||||
-rw-r--r-- | src/sksl/SkSLSPIRVCodeGenerator.cpp | 343 | ||||
-rw-r--r-- | src/sksl/SkSLSPIRVCodeGenerator.h | 5 | ||||
-rw-r--r-- | src/sksl/ast/SkSLASTLayout.h | 11 | ||||
-rw-r--r-- | src/sksl/ir/SkSLConstructor.h | 4 | ||||
-rw-r--r-- | src/sksl/ir/SkSLLayout.h | 22 | ||||
-rw-r--r-- | src/sksl/ir/SkSLType.h | 38 | ||||
-rw-r--r-- | src/sksl/sksl.include | 9 |
11 files changed, 278 insertions, 190 deletions
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index 62e5fa72e5..003f154908 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -113,6 +113,9 @@ Compiler::Compiler() ADD_TYPE(Image2D); ADD_TYPE(IImage2D); + ADD_TYPE(SubpassInput); + ADD_TYPE(SubpassInputMS); + ADD_TYPE(GSampler1D); ADD_TYPE(GSampler2D); ADD_TYPE(GSampler3D); diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h index 9289edeee5..6284c21a9a 100644 --- a/src/sksl/SkSLContext.h +++ b/src/sksl/SkSLContext.h @@ -88,6 +88,13 @@ public: , fImage2D_Type(new Type(SkString("image2D"), SpvDim2D, false, false, false, true)) , fIImage2D_Type(new Type(SkString("iimage2D"), SpvDim2D, false, false, false, true)) + // FIXME express these as "gsubpassInput" that expand to subpassInput, isubpassInput, + // and usubpassInput. + , fSubpassInput_Type(new Type(SkString("subpassInput"), SpvDimSubpassData, false, false, + false, false)) + , fSubpassInputMS_Type(new Type(SkString("subpassInputMS"), SpvDimSubpassData, false, false, + true, false)) + // FIXME figure out what we're supposed to do with the gsampler et al. types) , fGSampler1D_Type(new Type(SkString("$gsampler1D"), static_type(*fSampler1D_Type))) , fGSampler2D_Type(new Type(SkString("$gsampler2D"), static_type(*fSampler2D_Type))) @@ -137,7 +144,7 @@ public: , fDefined_Expression(new Defined(*fInvalid_Type)) {} static std::vector<const Type*> static_type(const Type& t) { - return { &t, &t, &t, &t }; + return { &t, &t, &t, &t }; } const std::unique_ptr<Type> fInvalid_Type; @@ -214,6 +221,9 @@ public: const std::unique_ptr<Type> fImage2D_Type; const std::unique_ptr<Type> fIImage2D_Type; + const std::unique_ptr<Type> fSubpassInput_Type; + const std::unique_ptr<Type> fSubpassInputMS_Type; + const std::unique_ptr<Type> fGSampler1D_Type; const std::unique_ptr<Type> fGSampler2D_Type; const std::unique_ptr<Type> fGSampler3D_Type; diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index 553626127b..e4aec92caf 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -4,7 +4,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ - + #include "SkSLGLSLCodeGenerator.h" #include "string.h" @@ -392,7 +392,7 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) { this->write(SkString((const char*) data->data(), data->size())); } -void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers, +void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers, bool globalContext) { if (modifiers.fFlags & Modifiers::kNoPerspective_Flag) { this->write("noperspective "); @@ -404,7 +404,7 @@ void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers, if (layout.size()) { this->write(layout + " "); } - if ((modifiers.fFlags & Modifiers::kIn_Flag) && + if ((modifiers.fFlags & Modifiers::kIn_Flag) && (modifiers.fFlags & Modifiers::kOut_Flag)) { this->write("inout "); } else if (modifiers.fFlags & Modifiers::kIn_Flag) { diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp index 03d0d337a8..58ec750168 100644 --- a/src/sksl/SkSLParser.cpp +++ b/src/sksl/SkSLParser.cpp @@ -535,7 +535,7 @@ int Parser::layoutInt() { return -1; } -/* LAYOUT LPAREN IDENTIFIER EQ INT_LITERAL (COMMA IDENTIFIER EQ INT_LITERAL)* +/* LAYOUT LPAREN IDENTIFIER EQ INT_LITERAL (COMMA IDENTIFIER EQ INT_LITERAL)* RPAREN */ ASTLayout Parser::layout() { int location = -1; @@ -543,6 +543,7 @@ ASTLayout Parser::layout() { int index = -1; int set = -1; int builtin = -1; + int inputAttachmentIndex = -1; bool originUpperLeft = false; bool overrideCoverage = false; bool blendSupportAllEquations = false; @@ -550,8 +551,8 @@ ASTLayout Parser::layout() { if (this->peek().fKind == Token::LAYOUT) { this->nextToken(); if (!this->expect(Token::LPAREN, "'('")) { - return ASTLayout(location, binding, index, set, builtin, originUpperLeft, - overrideCoverage, blendSupportAllEquations, format); + return ASTLayout(location, binding, index, set, builtin, inputAttachmentIndex, + originUpperLeft, overrideCoverage, blendSupportAllEquations, format); } for (;;) { Token t = this->nextToken(); @@ -565,6 +566,8 @@ ASTLayout Parser::layout() { set = this->layoutInt(); } else if (t.fText == "builtin") { builtin = this->layoutInt(); + } else if (t.fText == "input_attachment_index") { + inputAttachmentIndex = this->layoutInt(); } else if (t.fText == "origin_upper_left") { originUpperLeft = true; } else if (t.fText == "override_coverage") { @@ -574,7 +577,7 @@ ASTLayout Parser::layout() { } else if (ASTLayout::ReadFormat(t.fText, &format)) { // AST::ReadFormat stored the result in 'format'. } else { - this->error(t.fPosition, ("'" + t.fText + + this->error(t.fPosition, ("'" + t.fText + "' is not a valid layout qualifier").c_str()); } if (this->peek().fKind == Token::RPAREN) { @@ -586,8 +589,8 @@ ASTLayout Parser::layout() { } } } - return ASTLayout(location, binding, index, set, builtin, originUpperLeft, overrideCoverage, - blendSupportAllEquations, format); + return ASTLayout(location, binding, index, set, builtin, inputAttachmentIndex, originUpperLeft, + overrideCoverage, blendSupportAllEquations, format); } /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE)* */ diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index b5cd54abae..300d3c5d66 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -106,9 +106,11 @@ void SPIRVCodeGenerator::setupIntrinsics() { fIntrinsicMap[SkString("texture2D")] = SPECIAL(Texture2D); fIntrinsicMap[SkString("textureProj")] = SPECIAL(TextureProj); - fIntrinsicMap[SkString("any")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, + fIntrinsicMap[SkString("subpassLoad")] = SPECIAL(SubpassLoad); + + fIntrinsicMap[SkString("any")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, SpvOpUndef, SpvOpUndef, SpvOpAny); - fIntrinsicMap[SkString("all")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, + fIntrinsicMap[SkString("all")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, SpvOpUndef, SpvOpUndef, SpvOpAll); fIntrinsicMap[SkString("equal")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpFOrdEqual, SpvOpIEqual, @@ -121,18 +123,18 @@ void SPIRVCodeGenerator::setupIntrinsics() { SpvOpSLessThan, SpvOpULessThan, SpvOpFOrdLessThan, SpvOpUndef); fIntrinsicMap[SkString("lessThanEqual")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpSLessThanEqual, + SpvOpSLessThanEqual, SpvOpULessThanEqual, SpvOpFOrdLessThanEqual, SpvOpUndef); fIntrinsicMap[SkString("greaterThan")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpSGreaterThan, + SpvOpSGreaterThan, SpvOpUGreaterThan, - SpvOpFOrdGreaterThan, + SpvOpFOrdGreaterThan, SpvOpUndef); - fIntrinsicMap[SkString("greaterThanEqual")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpSGreaterThanEqual, - SpvOpUGreaterThanEqual, + fIntrinsicMap[SkString("greaterThanEqual")] = std::make_tuple(kSPIRV_IntrinsicKind, + SpvOpSGreaterThanEqual, + SpvOpUGreaterThanEqual, SpvOpFOrdGreaterThanEqual, SpvOpUndef); @@ -869,7 +871,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, const char* string, SkW } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, SkWStream& out) { int32_t length = (int32_t) strlen(string); this->writeOpCode(opCode, 2 + (length + 4) / 4, out); @@ -877,7 +879,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, const ch this->writeString(string, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const char* string, SkWStream& out) { int32_t length = (int32_t) strlen(string); this->writeOpCode(opCode, 3 + (length + 4) / 4, out); @@ -886,14 +888,14 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t this->writeString(string, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, SkWStream& out) { this->writeOpCode(opCode, 3, out); this->writeWord(word1, out); this->writeWord(word2, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, SkWStream& out) { this->writeOpCode(opCode, 4, out); this->writeWord(word1, out); @@ -901,7 +903,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t this->writeWord(word3, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, SkWStream& out) { this->writeOpCode(opCode, 5, out); this->writeWord(word1, out); @@ -910,8 +912,8 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t this->writeWord(word4, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, - int32_t word3, int32_t word4, int32_t word5, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, + int32_t word3, int32_t word4, int32_t word5, SkWStream& out) { this->writeOpCode(opCode, 6, out); this->writeWord(word1, out); @@ -921,7 +923,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t this->writeWord(word5, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, int32_t word5, int32_t word6, SkWStream& out) { this->writeOpCode(opCode, 7, out); @@ -933,7 +935,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t this->writeWord(word6, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, int32_t word5, int32_t word6, int32_t word7, SkWStream& out) { this->writeOpCode(opCode, 8, out); @@ -946,7 +948,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t this->writeWord(word7, out); } -void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, +void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4, int32_t word5, int32_t word6, int32_t word7, int32_t word8, SkWStream& out) { @@ -998,13 +1000,13 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, SpvId resultId) { fNameBuffer); this->writeLayout(type.fields()[i].fModifiers.fLayout, resultId, i); if (type.fields()[i].fModifiers.fLayout.fBuiltin < 0) { - this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, SpvDecorationOffset, + this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, SpvDecorationOffset, (SpvId) offset, fDecorationBuffer); } if (type.fields()[i].fType->kind() == Type::kMatrix_Kind) { - this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationColMajor, + this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationColMajor, fDecorationBuffer); - this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationMatrixStride, + this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationMatrixStride, (SpvId) type.fields()[i].fType->stride(), fDecorationBuffer); } offset += size; @@ -1036,13 +1038,13 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) { } break; case Type::kVector_Kind: - this->writeInstruction(SpvOpTypeVector, result, + this->writeInstruction(SpvOpTypeVector, result, this->getType(type.componentType()), type.columns(), fConstantBuffer); break; case Type::kMatrix_Kind: - this->writeInstruction(SpvOpTypeMatrix, result, - this->getType(index_type(fContext, type)), + this->writeInstruction(SpvOpTypeMatrix, result, + this->getType(index_type(fContext, type)), type.columns(), fConstantBuffer); break; case Type::kStruct_Kind: @@ -1051,25 +1053,30 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) { case Type::kArray_Kind: { if (type.columns() > 0) { IntLiteral count(fContext, Position(), type.columns()); - this->writeInstruction(SpvOpTypeArray, result, - this->getType(type.componentType()), + this->writeInstruction(SpvOpTypeArray, result, + this->getType(type.componentType()), this->writeIntLiteral(count), fConstantBuffer); - this->writeInstruction(SpvOpDecorate, result, SpvDecorationArrayStride, + this->writeInstruction(SpvOpDecorate, result, SpvDecorationArrayStride, (int32_t) type.stride(), fDecorationBuffer); } else { ABORT("runtime-sized arrays are not yet supported"); - this->writeInstruction(SpvOpTypeRuntimeArray, result, + this->writeInstruction(SpvOpTypeRuntimeArray, result, this->getType(type.componentType()), fConstantBuffer); } break; } case Type::kSampler_Kind: { - SpvId image = this->nextId(); - this->writeInstruction(SpvOpTypeImage, image, this->getType(*fContext.fFloat_Type), + SpvId image = result; + if (SpvDimSubpassData != type.dimensions()) { + image = this->nextId(); + } + this->writeInstruction(SpvOpTypeImage, image, this->getType(*fContext.fFloat_Type), type.dimensions(), type.isDepth(), type.isArrayed(), - type.isMultisampled(), type.isSampled(), + type.isMultisampled(), type.isSampled() ? 1 : 2, SpvImageFormatUnknown, fConstantBuffer); - this->writeInstruction(SpvOpTypeSampledImage, result, image, fConstantBuffer); + if (SpvDimSubpassData != type.dimensions()) { + this->writeInstruction(SpvOpTypeSampledImage, result, image, fConstantBuffer); + } break; } default: @@ -1101,26 +1108,26 @@ SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { SpvId returnType = this->getType(function.fReturnType); std::vector<SpvId> parameterTypes; for (size_t i = 0; i < function.fParameters.size(); i++) { - // glslang seems to treat all function arguments as pointers whether they need to be or - // not. I was initially puzzled by this until I ran bizarre failures with certain - // patterns of function calls and control constructs, as exemplified by this minimal + // glslang seems to treat all function arguments as pointers whether they need to be or + // not. I was initially puzzled by this until I ran bizarre failures with certain + // patterns of function calls and control constructs, as exemplified by this minimal // failure case: // // void sphere(float x) { // } - // + // // void map() { // sphere(1.0); // } - // + // // void main() { // for (int i = 0; i < 1; i++) { // map(); // } // } // - // As of this writing, compiling this in the "obvious" way (with sphere taking a float) - // crashes. Making it take a float* and storing the argument in a temporary variable, + // As of this writing, compiling this in the "obvious" way (with sphere taking a float) + // crashes. Making it take a float* and storing the argument in a temporary variable, // as glslang does, fixes it. It's entirely possible I simply missed whichever part of // the spec makes this make sense. // if (is_out(function->fParameters[i])) { @@ -1142,13 +1149,13 @@ SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { return entry->second; } -SpvId SPIRVCodeGenerator::getPointerType(const Type& type, +SpvId SPIRVCodeGenerator::getPointerType(const Type& type, SpvStorageClass_ storageClass) { SkString key = type.description() + "*" + to_string(storageClass); auto entry = fTypeMap.find(key); if (entry == fTypeMap.end()) { SpvId result = this->nextId(); - this->writeInstruction(SpvOpTypePointer, result, storageClass, + this->writeInstruction(SpvOpTypePointer, result, storageClass, this->getType(type), fConstantBuffer); fTypeMap[key] = result; return result; @@ -1245,7 +1252,7 @@ SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, SkWStream& o } } -SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, +SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, SkWStream& out) { SpvId result = this->nextId(); switch (kind) { @@ -1262,7 +1269,7 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn for (SpvId id : arguments) { this->writeWord(id, out); } - return result; + return result; } case kTexture_SpecialIntrinsic: { SpvId type = this->getType(c.fType); @@ -1290,7 +1297,7 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn out); } else { ASSERT(c.fArguments.size() == 2); - this->writeInstruction(SpvOpImageSampleProjImplicitLod, type, result, sampler, uv, + this->writeInstruction(SpvOpImageSampleProjImplicitLod, type, result, sampler, uv, out); } break; @@ -1300,12 +1307,40 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn SpvId coords = this->writeExpression(*c.fArguments[1], out); this->writeInstruction(SpvOpImageSampleImplicitLod, this->getType(c.fType), - result, + result, img, coords, out); break; } + case kSubpassLoad_SpecialIntrinsic: { + SpvId img = this->writeExpression(*c.fArguments[0], out); + std::vector<std::unique_ptr<Expression>> args; + args.emplace_back(new FloatLiteral(fContext, Position(), 0.0)); + args.emplace_back(new FloatLiteral(fContext, Position(), 0.0)); + Constructor ctor(Position(), *fContext.fVec2_Type, std::move(args)); + SpvId coords = this->writeConstantVector(ctor); + if (1 == c.fArguments.size()) { + this->writeInstruction(SpvOpImageRead, + this->getType(c.fType), + result, + img, + coords, + out); + } else { + SkASSERT(2 == c.fArguments.size()); + SpvId sample = this->writeExpression(*c.fArguments[1], out); + this->writeInstruction(SpvOpImageRead, + this->getType(c.fType), + result, + img, + coords, + SpvImageOperandsSampleMask, + sample, + out); + } + break; + } } return result; } @@ -1319,7 +1354,7 @@ SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, SkWStream& ou std::vector<std::tuple<SpvId, SpvId, std::unique_ptr<LValue>>> lvalues; std::vector<SpvId> arguments; for (size_t i = 0; i < c.fArguments.size(); i++) { - // id of temporary variable that we will use to hold this argument, or 0 if it is being + // id of temporary variable that we will use to hold this argument, or 0 if it is being // passed directly SpvId tmpVar; // if we need a temporary var to store this argument, this is the value to store in the var @@ -1344,10 +1379,10 @@ SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, SkWStream& ou tmpValueId = this->writeExpression(*c.fArguments[i], out); tmpVar = this->nextId(); } - this->writeInstruction(SpvOpVariable, - this->getPointerType(c.fArguments[i]->fType, + this->writeInstruction(SpvOpVariable, + this->getPointerType(c.fArguments[i]->fType, SpvStorageClassFunction), - tmpVar, + tmpVar, SpvStorageClassFunction, fVariableBuffer); this->writeInstruction(SpvOpStore, tmpVar, tmpValueId, out); @@ -1388,7 +1423,7 @@ SpvId SPIRVCodeGenerator::writeConstantVector(const Constructor& c) { this->writeWord(arguments[0], fConstantBuffer); } } else { - this->writeOpCode(SpvOpConstantComposite, 3 + (int32_t) c.fArguments.size(), + this->writeOpCode(SpvOpConstantComposite, 3 + (int32_t) c.fArguments.size(), fConstantBuffer); this->writeWord(type, fConstantBuffer); this->writeWord(result, fConstantBuffer); @@ -1406,10 +1441,10 @@ SpvId SPIRVCodeGenerator::writeFloatConstructor(const Constructor& c, SkWStream& SpvId result = this->nextId(); SpvId parameter = this->writeExpression(*c.fArguments[0], out); if (c.fArguments[0]->fType == *fContext.fInt_Type) { - this->writeInstruction(SpvOpConvertSToF, this->getType(c.fType), result, parameter, + this->writeInstruction(SpvOpConvertSToF, this->getType(c.fType), result, parameter, out); } else if (c.fArguments[0]->fType == *fContext.fUInt_Type) { - this->writeInstruction(SpvOpConvertUToF, this->getType(c.fType), result, parameter, + this->writeInstruction(SpvOpConvertUToF, this->getType(c.fType), result, parameter, out); } else if (c.fArguments[0]->fType == *fContext.fFloat_Type) { return parameter; @@ -1424,10 +1459,10 @@ SpvId SPIRVCodeGenerator::writeIntConstructor(const Constructor& c, SkWStream& o SpvId result = this->nextId(); SpvId parameter = this->writeExpression(*c.fArguments[0], out); if (c.fArguments[0]->fType == *fContext.fFloat_Type) { - this->writeInstruction(SpvOpConvertFToS, this->getType(c.fType), result, parameter, + this->writeInstruction(SpvOpConvertFToS, this->getType(c.fType), result, parameter, out); } else if (c.fArguments[0]->fType == *fContext.fUInt_Type) { - this->writeInstruction(SpvOpSatConvertUToS, this->getType(c.fType), result, parameter, + this->writeInstruction(SpvOpSatConvertUToS, this->getType(c.fType), result, parameter, out); } else if (c.fArguments[0]->fType == *fContext.fInt_Type) { return parameter; @@ -1448,16 +1483,16 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, SkWStream int columns = c.fType.columns(); // FIXME this won't work to create a matrix from another matrix if (arguments.size() == 1) { - // with a single argument, a matrix will have all of its diagonal entries equal to the + // with a single argument, a matrix will have all of its diagonal entries equal to the // argument and its other values equal to zero // FIXME this won't work for int matrices FloatLiteral zero(fContext, Position(), 0); SpvId zeroId = this->writeFloatLiteral(zero); std::vector<SpvId> columnIds; for (int column = 0; column < columns; column++) { - this->writeOpCode(SpvOpCompositeConstruct, 3 + c.fType.rows(), + this->writeOpCode(SpvOpCompositeConstruct, 3 + c.fType.rows(), out); - this->writeWord(this->getType(c.fType.componentType().toCompound(fContext, rows, 1)), + this->writeWord(this->getType(c.fType.componentType().toCompound(fContext, rows, 1)), out); SpvId columnId = this->nextId(); this->writeWord(columnId, out); @@ -1466,7 +1501,7 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, SkWStream this->writeWord(row == column ? arguments[0] : zeroId, out); } } - this->writeOpCode(SpvOpCompositeConstruct, 3 + columns, + this->writeOpCode(SpvOpCompositeConstruct, 3 + columns, out); this->writeWord(this->getType(c.fType), out); this->writeWord(result, out); @@ -1485,8 +1520,8 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, SkWStream ASSERT(c.fArguments[i]->fType.kind() == Type::kScalar_Kind); if (currentCount == 0) { this->writeOpCode(SpvOpCompositeConstruct, 3 + c.fType.rows(), out); - this->writeWord(this->getType(c.fType.componentType().toCompound(fContext, rows, - 1)), + this->writeWord(this->getType(c.fType.componentType().toCompound(fContext, rows, + 1)), out); SpvId id = this->nextId(); this->writeWord(id, out); @@ -1602,7 +1637,7 @@ std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, Sk class PointerLValue : public SPIRVCodeGenerator::LValue { public: - PointerLValue(SPIRVCodeGenerator& gen, SpvId pointer, SpvId type) + PointerLValue(SPIRVCodeGenerator& gen, SpvId pointer, SpvId type) : fGen(gen) , fPointer(pointer) , fType(type) {} @@ -1629,7 +1664,7 @@ private: class SwizzleLValue : public SPIRVCodeGenerator::LValue { public: - SwizzleLValue(SPIRVCodeGenerator& gen, SpvId vecPointer, const std::vector<int>& components, + SwizzleLValue(SPIRVCodeGenerator& gen, SpvId vecPointer, const std::vector<int>& components, const Type& baseType, const Type& swizzleType) : fGen(gen) , fVecPointer(vecPointer) @@ -1659,12 +1694,12 @@ public: virtual void store(SpvId value, SkWStream& out) override { // use OpVectorShuffle to mix and match the vector components. We effectively create // a virtual vector out of the concatenation of the left and right vectors, and then - // select components from this virtual vector to make the result vector. For + // select components from this virtual vector to make the result vector. For // instance, given: // vec3 L = ...; // vec3 R = ...; // L.xz = R.xy; - // we end up with the virtual vector (L.x, L.y, L.z, R.x, R.y, R.z). Then we want + // we end up with the virtual vector (L.x, L.y, L.z, R.x, R.y, R.z). Then we want // our result vector to look like (R.x, L.y, R.y), so we need to select indices // (3, 1, 4). SpvId base = fGen.nextId(); @@ -1682,7 +1717,7 @@ public: // check to see if we are writing this component for (size_t j = 0; j < fComponents.size(); j++) { if (fComponents[j] == i) { - // we're writing to this component, so adjust the offset to pull from + // we're writing to this component, so adjust the offset to pull from // the correct component of the right side instead of preserving the // value from the left offset = (int) (j + fBaseType.columns()); @@ -1702,7 +1737,7 @@ private: const Type& fSwizzleType; }; -std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr, +std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr, SkWStream& out) { switch (expr.fKind) { case Expression::kVariableReference_Kind: { @@ -1711,7 +1746,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const ASSERT(entry != fVariableMap.end()); return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue( *this, - entry->second, + entry->second, this->getType(expr.fType))); } case Expression::kIndex_Kind: // fall through @@ -1719,14 +1754,14 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const std::vector<SpvId> chain = this->getAccessChain(expr, out); SpvId member = this->nextId(); this->writeOpCode(SpvOpAccessChain, (SpvId) (3 + chain.size()), out); - this->writeWord(this->getPointerType(expr.fType, get_storage_class(expr)), out); + this->writeWord(this->getPointerType(expr.fType, get_storage_class(expr)), out); this->writeWord(member, out); for (SpvId idx : chain) { this->writeWord(idx, out); } return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue( *this, - member, + member, this->getType(expr.fType))); } @@ -1739,21 +1774,21 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const IntLiteral index(fContext, Position(), swizzle.fComponents[0]); SpvId member = this->nextId(); this->writeInstruction(SpvOpAccessChain, - this->getPointerType(swizzle.fType, - get_storage_class(*swizzle.fBase)), - member, - base, - this->writeIntLiteral(index), + this->getPointerType(swizzle.fType, + get_storage_class(*swizzle.fBase)), + member, + base, + this->writeIntLiteral(index), out); return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue( *this, - member, + member, this->getType(expr.fType))); } else { return std::unique_ptr<SPIRVCodeGenerator::LValue>(new SwizzleLValue( - *this, - base, - swizzle.fComponents, + *this, + base, + swizzle.fComponents, swizzle.fBase->fType, expr.fType)); } @@ -1761,7 +1796,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const default: // expr isn't actually an lvalue, create a dummy variable for it. This case happens due - // to the need to store values in temporary variables during function calls (see + // to the need to store values in temporary variables during function calls (see // comments in getFunctionType); erroneous uses of rvalues as lvalues should have been // caught by IRGenerator SpvId result = this->nextId(); @@ -1771,7 +1806,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const this->writeInstruction(SpvOpStore, result, this->writeExpression(expr, out), out); return std::unique_ptr<SPIRVCodeGenerator::LValue>(new PointerLValue( *this, - result, + result, this->getType(expr.fType))); } } @@ -1798,8 +1833,8 @@ SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, SkWStream& out) { SpvId result = this->nextId(); size_t count = swizzle.fComponents.size(); if (count == 1) { - this->writeInstruction(SpvOpCompositeExtract, this->getType(swizzle.fType), result, base, - swizzle.fComponents[0], out); + this->writeInstruction(SpvOpCompositeExtract, this->getType(swizzle.fType), result, base, + swizzle.fComponents[0], out); } else { this->writeOpCode(SpvOpVectorShuffle, 5 + (int32_t) count, out); this->writeWord(this->getType(swizzle.fType), out); @@ -1813,9 +1848,9 @@ SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, SkWStream& out) { return result; } -SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType, - const Type& operandType, SpvId lhs, - SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, +SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType, + const Type& operandType, SpvId lhs, + SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt, SpvOp_ ifBool, SkWStream& out) { SpvId result = this->nextId(); if (is_float(fContext, operandType)) { @@ -1887,7 +1922,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWSt // IR allows mismatched types in expressions (e.g. vec2 * float), but they need special handling // in SPIR-V if (b.fLeft->fType != b.fRight->fType) { - if (b.fLeft->fType.kind() == Type::kVector_Kind && + if (b.fLeft->fType.kind() == Type::kVector_Kind && b.fRight->fType.isNumber()) { // promote number to vector SpvId vec = this->nextId(); @@ -1899,7 +1934,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWSt } rhs = vec; operandType = &b.fRight->fType; - } else if (b.fRight->fType.kind() == Type::kVector_Kind && + } else if (b.fRight->fType.kind() == Type::kVector_Kind && b.fLeft->fType.isNumber()) { // promote number to vector SpvId vec = this->nextId(); @@ -1933,11 +1968,11 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWSt } else if (b.fRight->fType.kind() == Type::kMatrix_Kind) { SpvId result = this->nextId(); if (b.fLeft->fType.kind() == Type::kVector_Kind) { - this->writeInstruction(SpvOpVectorTimesMatrix, this->getType(b.fType), result, + this->writeInstruction(SpvOpVectorTimesMatrix, this->getType(b.fType), result, lhs, rhs, out); } else { ASSERT(b.fLeft->fType.kind() == Type::kScalar_Kind); - this->writeInstruction(SpvOpMatrixTimesScalar, this->getType(b.fType), result, rhs, + this->writeInstruction(SpvOpMatrixTimesScalar, this->getType(b.fType), result, rhs, lhs, out); } if (b.fOperator == Token::STAREQ) { @@ -1956,40 +1991,40 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWSt switch (b.fOperator) { case Token::EQEQ: ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdEqual, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdEqual, SpvOpIEqual, SpvOpIEqual, SpvOpLogicalEqual, out); case Token::NEQ: ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdNotEqual, - SpvOpINotEqual, SpvOpINotEqual, SpvOpLogicalNotEqual, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdNotEqual, + SpvOpINotEqual, SpvOpINotEqual, SpvOpLogicalNotEqual, out); case Token::GT: ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, - SpvOpFOrdGreaterThan, SpvOpSGreaterThan, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, + SpvOpFOrdGreaterThan, SpvOpSGreaterThan, SpvOpUGreaterThan, SpvOpUndef, out); case Token::LT: ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdLessThan, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFOrdLessThan, SpvOpSLessThan, SpvOpULessThan, SpvOpUndef, out); case Token::GTEQ: ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, - SpvOpFOrdGreaterThanEqual, SpvOpSGreaterThanEqual, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, + SpvOpFOrdGreaterThanEqual, SpvOpSGreaterThanEqual, SpvOpUGreaterThanEqual, SpvOpUndef, out); case Token::LTEQ: ASSERT(resultType == *fContext.fBool_Type); - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, - SpvOpFOrdLessThanEqual, SpvOpSLessThanEqual, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, + SpvOpFOrdLessThanEqual, SpvOpSLessThanEqual, SpvOpULessThanEqual, SpvOpUndef, out); case Token::PLUS: - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFAdd, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFAdd, SpvOpIAdd, SpvOpIAdd, SpvOpUndef, out); case Token::MINUS: - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFSub, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFSub, SpvOpISub, SpvOpISub, SpvOpUndef, out); case Token::STAR: - if (b.fLeft->fType.kind() == Type::kMatrix_Kind && + if (b.fLeft->fType.kind() == Type::kMatrix_Kind && b.fRight->fType.kind() == Type::kMatrix_Kind) { // matrix multiply SpvId result = this->nextId(); @@ -1997,27 +2032,27 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWSt lhs, rhs, out); return result; } - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFMul, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFMul, SpvOpIMul, SpvOpIMul, SpvOpUndef, out); case Token::SLASH: - return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFDiv, + return this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFDiv, SpvOpSDiv, SpvOpUDiv, SpvOpUndef, out); case Token::PLUSEQ: { - SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFAdd, + SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFAdd, SpvOpIAdd, SpvOpIAdd, SpvOpUndef, out); ASSERT(lvalue); lvalue->store(result, out); return result; } case Token::MINUSEQ: { - SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFSub, + SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFSub, SpvOpISub, SpvOpISub, SpvOpUndef, out); ASSERT(lvalue); lvalue->store(result, out); return result; } case Token::STAREQ: { - if (b.fLeft->fType.kind() == Type::kMatrix_Kind && + if (b.fLeft->fType.kind() == Type::kMatrix_Kind && b.fRight->fType.kind() == Type::kMatrix_Kind) { // matrix multiply SpvId result = this->nextId(); @@ -2027,14 +2062,14 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWSt lvalue->store(result, out); return result; } - SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFMul, + SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFMul, SpvOpIMul, SpvOpIMul, SpvOpUndef, out); ASSERT(lvalue); lvalue->store(result, out); return result; } case Token::SLASHEQ: { - SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFDiv, + SpvId result = this->writeBinaryOperation(resultType, *operandType, lhs, rhs, SpvOpFDiv, SpvOpSDiv, SpvOpUDiv, SpvOpUndef, out); ASSERT(lvalue); lvalue->store(result, out); @@ -2062,7 +2097,7 @@ SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, SkWStream& this->writeInstruction(SpvOpBranch, end, out); this->writeLabel(end, out); SpvId result = this->nextId(); - this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result, falseConstant, + this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result, falseConstant, lhsBlock, rhs, rhsBlock, out); return result; } @@ -2083,7 +2118,7 @@ SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, SkWStream& o this->writeInstruction(SpvOpBranch, end, out); this->writeLabel(end, out); SpvId result = this->nextId(); - this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result, trueConstant, + this->writeInstruction(SpvOpPhi, this->getType(*fContext.fBool_Type), result, trueConstant, lhsBlock, rhs, rhsBlock, out); return result; } @@ -2095,14 +2130,14 @@ SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, SkW SpvId result = this->nextId(); SpvId trueId = this->writeExpression(*t.fIfTrue, out); SpvId falseId = this->writeExpression(*t.fIfFalse, out); - this->writeInstruction(SpvOpSelect, this->getType(t.fType), result, test, trueId, falseId, + this->writeInstruction(SpvOpSelect, this->getType(t.fType), result, test, trueId, falseId, out); return result; } - // was originally using OpPhi to choose the result, but for some reason that is crashing on + // was originally using OpPhi to choose the result, but for some reason that is crashing on // Adreno. Switched to storing the result in a temp variable as glslang does. SpvId var = this->nextId(); - this->writeInstruction(SpvOpVariable, this->getPointerType(t.fType, SpvStorageClassFunction), + this->writeInstruction(SpvOpVariable, this->getPointerType(t.fType, SpvStorageClassFunction), var, SpvStorageClassFunction, fVariableBuffer); SpvId trueLabel = this->nextId(); SpvId falseLabel = this->nextId(); @@ -2152,8 +2187,8 @@ SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, SkWSt case Token::PLUSPLUS: { std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out); SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out); - SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load(out), one, - SpvOpFAdd, SpvOpIAdd, SpvOpIAdd, SpvOpUndef, + SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load(out), one, + SpvOpFAdd, SpvOpIAdd, SpvOpIAdd, SpvOpUndef, out); lv->store(result, out); return result; @@ -2161,8 +2196,8 @@ SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, SkWSt case Token::MINUSMINUS: { std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out); SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out); - SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load(out), one, - SpvOpFSub, SpvOpISub, SpvOpISub, SpvOpUndef, + SpvId result = this->writeBinaryOperation(p.fType, p.fType, lv->load(out), one, + SpvOpFSub, SpvOpISub, SpvOpISub, SpvOpUndef, out); lv->store(result, out); return result; @@ -2191,13 +2226,13 @@ SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, SkW SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out); switch (p.fOperator) { case Token::PLUSPLUS: { - SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, one, SpvOpFAdd, + SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, one, SpvOpFAdd, SpvOpIAdd, SpvOpIAdd, SpvOpUndef, out); lv->store(temp, out); return result; } case Token::MINUSMINUS: { - SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, one, SpvOpFSub, + SpvId temp = this->writeBinaryOperation(p.fType, p.fType, result, one, SpvOpFSub, SpvOpISub, SpvOpISub, SpvOpUndef, out); lv->store(temp, out); return result; @@ -2211,14 +2246,14 @@ SpvId SPIRVCodeGenerator::writeBoolLiteral(const BoolLiteral& b) { if (b.fValue) { if (fBoolTrue == 0) { fBoolTrue = this->nextId(); - this->writeInstruction(SpvOpConstantTrue, this->getType(b.fType), fBoolTrue, + this->writeInstruction(SpvOpConstantTrue, this->getType(b.fType), fBoolTrue, fConstantBuffer); } return fBoolTrue; } else { if (fBoolFalse == 0) { fBoolFalse = this->nextId(); - this->writeInstruction(SpvOpConstantFalse, this->getType(b.fType), fBoolFalse, + this->writeInstruction(SpvOpConstantFalse, this->getType(b.fType), fBoolFalse, fConstantBuffer); } return fBoolFalse; @@ -2230,7 +2265,7 @@ SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) { auto entry = fIntConstants.find(i.fValue); if (entry == fIntConstants.end()) { SpvId result = this->nextId(); - this->writeInstruction(SpvOpConstant, this->getType(i.fType), result, (SpvId) i.fValue, + this->writeInstruction(SpvOpConstant, this->getType(i.fType), result, (SpvId) i.fValue, fConstantBuffer); fIntConstants[i.fValue] = result; return result; @@ -2241,7 +2276,7 @@ SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) { auto entry = fUIntConstants.find(i.fValue); if (entry == fUIntConstants.end()) { SpvId result = this->nextId(); - this->writeInstruction(SpvOpConstant, this->getType(i.fType), result, (SpvId) i.fValue, + this->writeInstruction(SpvOpConstant, this->getType(i.fType), result, (SpvId) i.fValue, fConstantBuffer); fUIntConstants[i.fValue] = result; return result; @@ -2259,7 +2294,7 @@ SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) { uint32_t bits; ASSERT(sizeof(bits) == sizeof(value)); memcpy(&bits, &value, sizeof(bits)); - this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits, + this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits, fConstantBuffer); fFloatConstants[value] = result; return result; @@ -2273,7 +2308,7 @@ SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) { uint64_t bits; ASSERT(sizeof(bits) == sizeof(f.fValue)); memcpy(&bits, &f.fValue, sizeof(bits)); - this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, + this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits & 0xffffffff, bits >> 32, fConstantBuffer); fDoubleConstants[f.fValue] = result; return result; @@ -2284,7 +2319,7 @@ SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) { SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, SkWStream& out) { SpvId result = fFunctionMap[&f]; - this->writeInstruction(SpvOpFunction, this->getType(f.fReturnType), result, + this->writeInstruction(SpvOpFunction, this->getType(f.fReturnType), result, SpvFunctionControlMaskNone, this->getFunctionType(f), out); this->writeInstruction(SpvOpName, result, f.fName.c_str(), fNameBuffer); for (size_t i = 0; i < f.fParameters.size(); i++) { @@ -2316,46 +2351,54 @@ SpvId SPIRVCodeGenerator::writeFunction(const FunctionDefinition& f, SkWStream& void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target) { if (layout.fLocation >= 0) { - this->writeInstruction(SpvOpDecorate, target, SpvDecorationLocation, layout.fLocation, + this->writeInstruction(SpvOpDecorate, target, SpvDecorationLocation, layout.fLocation, fDecorationBuffer); } if (layout.fBinding >= 0) { - this->writeInstruction(SpvOpDecorate, target, SpvDecorationBinding, layout.fBinding, + this->writeInstruction(SpvOpDecorate, target, SpvDecorationBinding, layout.fBinding, fDecorationBuffer); } if (layout.fIndex >= 0) { - this->writeInstruction(SpvOpDecorate, target, SpvDecorationIndex, layout.fIndex, + this->writeInstruction(SpvOpDecorate, target, SpvDecorationIndex, layout.fIndex, fDecorationBuffer); } if (layout.fSet >= 0) { - this->writeInstruction(SpvOpDecorate, target, SpvDecorationDescriptorSet, layout.fSet, + this->writeInstruction(SpvOpDecorate, target, SpvDecorationDescriptorSet, layout.fSet, fDecorationBuffer); } + if (layout.fInputAttachmentIndex >= 0) { + this->writeInstruction(SpvOpDecorate, target, SpvDecorationInputAttachmentIndex, + layout.fInputAttachmentIndex, fDecorationBuffer); + } if (layout.fBuiltin >= 0 && layout.fBuiltin != SK_FRAGCOLOR_BUILTIN) { - this->writeInstruction(SpvOpDecorate, target, SpvDecorationBuiltIn, layout.fBuiltin, + this->writeInstruction(SpvOpDecorate, target, SpvDecorationBuiltIn, layout.fBuiltin, fDecorationBuffer); } } void SPIRVCodeGenerator::writeLayout(const Layout& layout, SpvId target, int member) { if (layout.fLocation >= 0) { - this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationLocation, + this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationLocation, layout.fLocation, fDecorationBuffer); } if (layout.fBinding >= 0) { - this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationBinding, + this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationBinding, layout.fBinding, fDecorationBuffer); } if (layout.fIndex >= 0) { - this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationIndex, + this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationIndex, layout.fIndex, fDecorationBuffer); } if (layout.fSet >= 0) { - this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationDescriptorSet, + this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationDescriptorSet, layout.fSet, fDecorationBuffer); } + if (layout.fInputAttachmentIndex >= 0) { + this->writeInstruction(SpvOpDecorate, target, member, SpvDecorationInputAttachmentIndex, + layout.fInputAttachmentIndex, fDecorationBuffer); + } if (layout.fBuiltin >= 0) { - this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationBuiltIn, + this->writeInstruction(SpvOpMemberDecorate, target, member, SpvDecorationBuiltIn, layout.fBuiltin, fDecorationBuffer); } } @@ -2374,7 +2417,7 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) { } #define BUILTIN_IGNORE 9999 -void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclarations& decl, +void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclarations& decl, SkWStream& out) { for (size_t i = 0; i < decl.fVars.size(); i++) { const VarDeclaration& varDecl = decl.fVars[i]; @@ -2414,9 +2457,9 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio this->writeInstruction(SpvOpVariable, type, id, storageClass, fConstantBuffer); this->writeInstruction(SpvOpName, id, var->fName.c_str(), fNameBuffer); if (var->fType.kind() == Type::kMatrix_Kind) { - this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor, + this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationColMajor, fDecorationBuffer); - this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationMatrixStride, + this->writeInstruction(SpvOpMemberDecorate, id, (SpvId) i, SpvDecorationMatrixStride, (SpvId) var->fType.stride(), fDecorationBuffer); } if (varDecl.fValue) { @@ -2453,7 +2496,7 @@ void SPIRVCodeGenerator::writeStatement(const Statement& s, SkWStream& out) { case Statement::kExpression_Kind: this->writeExpression(*((ExpressionStatement&) s).fExpression, out); break; - case Statement::kReturn_Kind: + case Statement::kReturn_Kind: this->writeReturnStatement((ReturnStatement&) s, out); break; case Statement::kVarDeclarations_Kind: @@ -2553,7 +2596,7 @@ void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, SkWStream& out void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, SkWStream& out) { if (r.fExpression) { - this->writeInstruction(SpvOpReturnValue, this->writeExpression(*r.fExpression, out), + this->writeInstruction(SpvOpReturnValue, this->writeExpression(*r.fExpression, out), out); } else { this->writeInstruction(SpvOpReturn, out); @@ -2583,7 +2626,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, SkWStream& ou } for (size_t i = 0; i < program.fElements.size(); i++) { if (program.fElements[i]->fKind == ProgramElement::kVar_Kind) { - this->writeGlobalVars(program.fKind, ((VarDeclarations&) *program.fElements[i]), + this->writeGlobalVars(program.fKind, ((VarDeclarations&) *program.fElements[i]), body); } } @@ -2601,7 +2644,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, SkWStream& ou ASSERT(main); for (auto entry : fVariableMap) { const Variable* var = entry.first; - if (var->fStorage == Variable::kGlobal_Storage && + if (var->fStorage == Variable::kGlobal_Storage && ((var->fModifiers.fFlags & Modifiers::kIn_Flag) || (var->fModifiers.fFlags & Modifiers::kOut_Flag))) { interfaceVars.push_back(entry.second); @@ -2610,7 +2653,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, SkWStream& ou this->writeCapabilities(out); this->writeInstruction(SpvOpExtInstImport, fGLSLExtendedInstructions, "GLSL.std.450", out); this->writeInstruction(SpvOpMemoryModel, SpvAddressingModelLogical, SpvMemoryModelGLSL450, out); - this->writeOpCode(SpvOpEntryPoint, (SpvId) (3 + (strlen(main->fName.c_str()) + 4) / 4) + + this->writeOpCode(SpvOpEntryPoint, (SpvId) (3 + (strlen(main->fName.c_str()) + 4) / 4) + (int32_t) interfaceVars.size(), out); switch (program.fKind) { case Program::kVertex_Kind: @@ -2626,19 +2669,19 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, SkWStream& ou this->writeWord(var, out); } if (program.fKind == Program::kFragment_Kind) { - this->writeInstruction(SpvOpExecutionMode, - fFunctionMap[main], + this->writeInstruction(SpvOpExecutionMode, + fFunctionMap[main], SpvExecutionModeOriginUpperLeft, out); } for (size_t i = 0; i < program.fElements.size(); i++) { if (program.fElements[i]->fKind == ProgramElement::kExtension_Kind) { - this->writeInstruction(SpvOpSourceExtension, - ((Extension&) *program.fElements[i]).fName.c_str(), + this->writeInstruction(SpvOpSourceExtension, + ((Extension&) *program.fElements[i]).fName.c_str(), out); } } - + write_data(*fNameBuffer.detachAsData(), out); write_data(*fDecorationBuffer.detachAsData(), out); write_data(*fConstantBuffer.detachAsData(), out); diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h index 84c582e53e..b79194500a 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/SkSLSPIRVCodeGenerator.h @@ -51,7 +51,7 @@ public: class LValue { public: virtual ~LValue() {} - + // returns a pointer to the lvalue, if possible. If the lvalue cannot be directly referenced // by a pointer (e.g. vector swizzles), returns 0. virtual SpvId getPointer() = 0; @@ -84,7 +84,8 @@ private: kAtan_SpecialIntrinsic, kTexture_SpecialIntrinsic, kTexture2D_SpecialIntrinsic, - kTextureProj_SpecialIntrinsic + kTextureProj_SpecialIntrinsic, + kSubpassLoad_SpecialIntrinsic, }; void setupIntrinsics(); diff --git a/src/sksl/ast/SkSLASTLayout.h b/src/sksl/ast/SkSLASTLayout.h index cb7f3c175c..a77e8388ed 100644 --- a/src/sksl/ast/SkSLASTLayout.h +++ b/src/sksl/ast/SkSLASTLayout.h @@ -78,13 +78,15 @@ struct ASTLayout : public ASTNode { } // For int parameters, a -1 means no value - ASTLayout(int location, int binding, int index, int set, int builtin, bool originUpperLeft, - bool overrideCoverage, bool blendSupportAllEquations, Format format) + ASTLayout(int location, int binding, int index, int set, int builtin, int inputAttachmentIndex, + bool originUpperLeft, bool overrideCoverage, bool blendSupportAllEquations, + Format format) : fLocation(location) , fBinding(binding) , fIndex(index) , fSet(set) , fBuiltin(builtin) + , fInputAttachmentIndex(inputAttachmentIndex) , fOriginUpperLeft(originUpperLeft) , fOverrideCoverage(overrideCoverage) , fBlendSupportAllEquations(blendSupportAllEquations) @@ -113,6 +115,10 @@ struct ASTLayout : public ASTNode { result += separator + "builtin = " + to_string(fBuiltin); separator = ", "; } + if (fInputAttachmentIndex >= 0) { + result += separator + "input_attachment_index = " + to_string(fBuiltin); + separator = ", "; + } if (fOriginUpperLeft) { result += separator + "origin_upper_left"; separator = ", "; @@ -140,6 +146,7 @@ struct ASTLayout : public ASTNode { const int fIndex; const int fSet; const int fBuiltin; + const int fInputAttachmentIndex; const bool fOriginUpperLeft; const bool fOverrideCoverage; const bool fBlendSupportAllEquations; diff --git a/src/sksl/ir/SkSLConstructor.h b/src/sksl/ir/SkSLConstructor.h index 92f758032b..63c692b88e 100644 --- a/src/sksl/ir/SkSLConstructor.h +++ b/src/sksl/ir/SkSLConstructor.h @@ -4,7 +4,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ - + #ifndef SKSL_CONSTRUCTOR #define SKSL_CONSTRUCTOR @@ -16,7 +16,7 @@ namespace SkSL { * Represents the construction of a compound type, such as "vec2(x, y)". */ struct Constructor : public Expression { - Constructor(Position position, const Type& type, + Constructor(Position position, const Type& type, std::vector<std::unique_ptr<Expression>> arguments) : INHERITED(position, kConstructor_Kind, type) , fArguments(std::move(arguments)) {} diff --git a/src/sksl/ir/SkSLLayout.h b/src/sksl/ir/SkSLLayout.h index 7359262c96..c5753e010c 100644 --- a/src/sksl/ir/SkSLLayout.h +++ b/src/sksl/ir/SkSLLayout.h @@ -22,29 +22,33 @@ struct Layout { , fIndex(layout.fIndex) , fSet(layout.fSet) , fBuiltin(layout.fBuiltin) + , fInputAttachmentIndex(layout.fInputAttachmentIndex) , fOriginUpperLeft(layout.fOriginUpperLeft) , fOverrideCoverage(layout.fOverrideCoverage) , fBlendSupportAllEquations(layout.fBlendSupportAllEquations) , fFormat(layout.fFormat) {} - Layout(int location, int binding, int index, int set, int builtin, bool originUpperLeft, - bool overrideCoverage, bool blendSupportAllEquations, ASTLayout::Format format) + Layout(int location, int binding, int index, int set, int builtin, int inputAttachmentIndex, + bool originUpperLeft, bool overrideCoverage, bool blendSupportAllEquations, + ASTLayout::Format format) : fLocation(location) , fBinding(binding) , fIndex(index) , fSet(set) , fBuiltin(builtin) + , fInputAttachmentIndex(inputAttachmentIndex) , fOriginUpperLeft(originUpperLeft) , fOverrideCoverage(overrideCoverage) , fBlendSupportAllEquations(blendSupportAllEquations) , fFormat(format) {} - Layout() + Layout() : fLocation(-1) , fBinding(-1) , fIndex(-1) , fSet(-1) , fBuiltin(-1) + , fInputAttachmentIndex(-1) , fOriginUpperLeft(false) , fOverrideCoverage(false) , fBlendSupportAllEquations(false) @@ -73,6 +77,10 @@ struct Layout { result += separator + "builtin = " + to_string(fBuiltin); separator = ", "; } + if (fInputAttachmentIndex >= 0) { + result += separator + "input_attachment_index = " + to_string(fBuiltin); + separator = ", "; + } if (fOriginUpperLeft) { result += separator + "origin_upper_left"; separator = ", "; @@ -101,6 +109,7 @@ struct Layout { fIndex == other.fIndex && fSet == other.fSet && fBuiltin == other.fBuiltin && + fInputAttachmentIndex == other.fInputAttachmentIndex && fOriginUpperLeft == other.fOriginUpperLeft && fOverrideCoverage == other.fOverrideCoverage && fBlendSupportAllEquations == other.fBlendSupportAllEquations && @@ -111,13 +120,16 @@ struct Layout { return !(*this == other); } - // everything but builtin is in the GLSL spec; builtin comes from SPIR-V and identifies which - // particular builtin value this object represents. int fLocation; int fBinding; int fIndex; int fSet; + // builtin comes from SPIR-V and identifies which particular builtin value this object + // represents. int fBuiltin; + // input_attachment_index comes from Vulkan/SPIR-V to connect a shader variable to the a + // corresponding attachment on the subpass in which the shader is being used. + int fInputAttachmentIndex; bool fOriginUpperLeft; bool fOverrideCoverage; bool fBlendSupportAllEquations; diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h index 4174c72a33..81ec13ab44 100644 --- a/src/sksl/ir/SkSLType.h +++ b/src/sksl/ir/SkSLType.h @@ -4,7 +4,7 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ - + #ifndef SKIASL_TYPE #define SKIASL_TYPE @@ -51,14 +51,14 @@ public: kOther_Kind }; - // Create an "other" (special) type with the given name. These types cannot be directly + // Create an "other" (special) type with the given name. These types cannot be directly // referenced from user code. Type(SkString name) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kOther_Kind) {} - // Create a generic type which maps to the listed types. As currently implemented, there are - // always exactly four coercion targets, mapping to the scalar, vec2, vec3, and vec4 versions of + // Create a generic type which maps to the listed types. As currently implemented, there are + // always exactly four coercion targets, mapping to the scalar, vec2, vec3, and vec4 versions of // a type. Type(SkString name, std::vector<const Type*> types) : INHERITED(Position(), kType_Kind, std::move(name)) @@ -100,7 +100,7 @@ public: , fTypeKind(kind) , fComponentType(&componentType) , fColumns(columns) - , fRows(1) + , fRows(1) , fDimensions(SpvDim1D) {} // Create a matrix type. @@ -109,12 +109,12 @@ public: , fTypeKind(kMatrix_Kind) , fComponentType(&componentType) , fColumns(columns) - , fRows(rows) + , fRows(rows) , fDimensions(SpvDim1D) {} // Create a sampler type. - Type(SkString name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled, - bool isSampled) + Type(SkString name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled, + bool isSampled) : INHERITED(Position(), kType_Kind, std::move(name)) , fTypeKind(kSampler_Kind) , fDimensions(dimensions) @@ -154,7 +154,7 @@ public: } /** - * Returns true if an instance of this type can be freely coerced (implicitly converted) to + * Returns true if an instance of this type can be freely coerced (implicitly converted) to * another type. */ bool canCoerceTo(const Type& other) const { @@ -164,8 +164,8 @@ public: /** * Determines the "cost" of coercing (implicitly converting) this type to another type. The cost - * is a number with no particular meaning other than that lower costs are preferable to higher - * costs. Returns true if a conversion is possible, false otherwise. The value of the out + * is a number with no particular meaning other than that lower costs are preferable to higher + * costs. Returns true if a conversion is possible, false otherwise. The value of the out * parameter is undefined if false is returned. */ bool determineCoercionCost(const Type& other, int* outCost) const; @@ -181,11 +181,11 @@ public: /** * For matrices and vectors, returns the number of columns (e.g. both mat3 and vec3 return 3). - * For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1. + * For scalars, returns 1. For arrays, returns either the size of the array (if known) or -1. * For all other types, causes an assertion failure. */ int columns() const { - ASSERT(fTypeKind == kScalar_Kind || fTypeKind == kVector_Kind || + ASSERT(fTypeKind == kScalar_Kind || fTypeKind == kVector_Kind || fTypeKind == kMatrix_Kind || fTypeKind == kArray_Kind); return fColumns; } @@ -214,27 +214,27 @@ public: } int dimensions() const { - ASSERT(fTypeKind == kSampler_Kind); + ASSERT(kSampler_Kind == fTypeKind); return fDimensions; } bool isDepth() const { - ASSERT(fTypeKind == kSampler_Kind); + ASSERT(kSampler_Kind == fTypeKind); return fIsDepth; } bool isArrayed() const { - ASSERT(fTypeKind == kSampler_Kind); + ASSERT(kSampler_Kind == fTypeKind); return fIsArrayed; } bool isMultisampled() const { - ASSERT(fTypeKind == kSampler_Kind); + ASSERT(kSampler_Kind == fTypeKind); return fIsMultisampled; } bool isSampled() const { - ASSERT(fTypeKind == kSampler_Kind); + ASSERT(kSampler_Kind == fTypeKind); return fIsSampled; } @@ -320,7 +320,7 @@ public: } /** - * Returns the corresponding vector or matrix type with the specified number of columns and + * Returns the corresponding vector or matrix type with the specified number of columns and * rows. */ const Type& toCompound(const Context& context, int columns, int rows) const; diff --git a/src/sksl/sksl.include b/src/sksl/sksl.include index 83c6aed0dc..d7b632657e 100644 --- a/src/sksl/sksl.include +++ b/src/sksl/sksl.include @@ -286,6 +286,15 @@ $gvec4 texture($gsampler2DRect sampler, vec2 P); float texture(sampler2DRectShadow sampler, vec3 P); float texture($gsamplerCubeArrayShadow sampler, vec4 P, float compare); */ + +// Currently we do not support the generic types of loading subpassInput so we have some explicit +// versions that we currently use +vec4 subpassLoad(subpassInput subpass); +vec4 subpassLoad(subpassInputMS subpass, int sample); +/* +$gvec4 subpassLoad(gsubpassInput subpass); +$gvec4 subpassLoad(gsubpassInputMS subpass, int sample); +*/ ) // split into multiple chunks, as MSVC++ complains if a single string is too long |