From 64773e6c9f61fb319f597a8d7dd7ee377d51a43a Mon Sep 17 00:00:00 2001 From: Greg Daniel Date: Tue, 22 Nov 2016 09:44:03 -0500 Subject: Add support for input attachments in SkSL spirv BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5115 Change-Id: I3e03a465a10c9aff62491d0f6e71105d1b650dab Reviewed-on: https://skia-review.googlesource.com/5115 Reviewed-by: Ethan Nicholas Commit-Queue: Greg Daniel --- src/sksl/SkSLSPIRVCodeGenerator.cpp | 343 ++++++++++++++++++++---------------- 1 file changed, 193 insertions(+), 150 deletions(-) (limited to 'src/sksl/SkSLSPIRVCodeGenerator.cpp') 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 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> 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>> lvalues; std::vector 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 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 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& components, + SwizzleLValue(SPIRVCodeGenerator& gen, SpvId vecPointer, const std::vector& 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::getLValue(const Expression& expr, +std::unique_ptr SPIRVCodeGenerator::getLValue(const Expression& expr, SkWStream& out) { switch (expr.fKind) { case Expression::kVariableReference_Kind: { @@ -1711,7 +1746,7 @@ std::unique_ptr SPIRVCodeGenerator::getLValue(const ASSERT(entry != fVariableMap.end()); return std::unique_ptr(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::getLValue(const std::vector 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(new PointerLValue( *this, - member, + member, this->getType(expr.fType))); } @@ -1739,21 +1774,21 @@ std::unique_ptr 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(new PointerLValue( *this, - member, + member, this->getType(expr.fType))); } else { return std::unique_ptr(new SwizzleLValue( - *this, - base, - swizzle.fComponents, + *this, + base, + swizzle.fComponents, swizzle.fBase->fType, expr.fType)); } @@ -1761,7 +1796,7 @@ std::unique_ptr 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::getLValue(const this->writeInstruction(SpvOpStore, result, this->writeExpression(expr, out), out); return std::unique_ptr(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 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 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); -- cgit v1.2.3