aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl/SkSLSPIRVCodeGenerator.cpp
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2016-11-22 09:44:03 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-22 15:31:02 +0000
commit64773e6c9f61fb319f597a8d7dd7ee377d51a43a (patch)
treee8ceb0267585ec660844e85d2869d01cf2e3c855 /src/sksl/SkSLSPIRVCodeGenerator.cpp
parent71fecc32b1b4f71ef3c6467b1f5e0b55c2a12428 (diff)
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 <ethannicholas@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
Diffstat (limited to 'src/sksl/SkSLSPIRVCodeGenerator.cpp')
-rw-r--r--src/sksl/SkSLSPIRVCodeGenerator.cpp343
1 files changed, 193 insertions, 150 deletions
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);