diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2019-04-22 11:23:28 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2019-04-22 15:28:40 +0000 |
commit | 8f92cc67adbbd03732c8a3239d29d787f36c3243 (patch) | |
tree | a567cc86eca25f48afd6d2e0e27ee3e25ee0070a | |
parent | ec62a21fd704efd36ab0f019c00c654ad1cefa68 (diff) | |
download | skia-8f92cc67adbbd03732c8a3239d29d787f36c3243.tar.gz |
Revert "Revert "added more SPIR-V RelaxedPrecision decorations""
This reverts commit 5155e09d146665be078494247092fa990d5ae4a7.
No-Tree-Checks: true
No-Try: true
No-Presubmit: true
Bug: b/131080966
Change-Id: Ie2df5d64a0f4f76806f3edc9c934ec81d16ee128
Reviewed-On: https://skia-review.googlesource.com/c/skia/+/208678
Reviewed-By: Greg Daniel <egdaniel@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/209416
-rw-r--r-- | src/sksl/SkSLSPIRVCodeGenerator.cpp | 123 | ||||
-rw-r--r-- | src/sksl/SkSLSPIRVCodeGenerator.h | 45 |
2 files changed, 126 insertions, 42 deletions
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index 27787bbc62..bc79fa4550 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -389,18 +389,19 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor } size_t offset = 0; for (int32_t i = 0; i < (int32_t) type.fields().size(); i++) { - size_t size = memoryLayout.size(*type.fields()[i].fType); - size_t alignment = memoryLayout.alignment(*type.fields()[i].fType); - const Layout& fieldLayout = type.fields()[i].fModifiers.fLayout; + const Type::Field& field = type.fields()[i]; + size_t size = memoryLayout.size(*field.fType); + size_t alignment = memoryLayout.alignment(*field.fType); + const Layout& fieldLayout = field.fModifiers.fLayout; if (fieldLayout.fOffset >= 0) { if (fieldLayout.fOffset < (int) offset) { fErrors.error(type.fOffset, - "offset of field '" + type.fields()[i].fName + "' must be at " + "offset of field '" + field.fName + "' must be at " "least " + to_string((int) offset)); } if (fieldLayout.fOffset % alignment) { fErrors.error(type.fOffset, - "offset of field '" + type.fields()[i].fName + "' must be a multiple" + "offset of field '" + field.fName + "' must be a multiple" " of " + to_string((int) alignment)); } offset = fieldLayout.fOffset; @@ -410,21 +411,25 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor offset += alignment - mod; } } - this->writeInstruction(SpvOpMemberName, resultId, i, type.fields()[i].fName, fNameBuffer); + this->writeInstruction(SpvOpMemberName, resultId, i, field.fName, fNameBuffer); this->writeLayout(fieldLayout, resultId, i); - if (type.fields()[i].fModifiers.fLayout.fBuiltin < 0) { + if (field.fModifiers.fLayout.fBuiltin < 0) { this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, SpvDecorationOffset, (SpvId) offset, fDecorationBuffer); } - if (type.fields()[i].fType->kind() == Type::kMatrix_Kind) { + if (field.fType->kind() == Type::kMatrix_Kind) { this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationColMajor, fDecorationBuffer); this->writeInstruction(SpvOpMemberDecorate, resultId, i, SpvDecorationMatrixStride, - (SpvId) memoryLayout.stride(*type.fields()[i].fType), + (SpvId) memoryLayout.stride(*field.fType), fDecorationBuffer); } + if (!field.fType->highPrecision()) { + this->writeInstruction(SpvOpMemberDecorate, resultId, (SpvId) i, + SpvDecorationRelaxedPrecision, fDecorationBuffer); + } offset += size; - Type::Kind kind = type.fields()[i].fType->kind(); + Type::Kind kind = field.fType->kind(); if ((kind == Type::kArray_Kind || kind == Type::kStruct_Kind) && offset % alignment != 0) { offset += alignment - offset % alignment; } @@ -763,6 +768,7 @@ std::vector<SpvId> SPIRVCodeGenerator::vectorize( for (int i = 0; i < vectorSize; i++) { this->writeWord(raw, out); } + this->writePrecisionModifier(a->fType, vector); result.push_back(vector); } else { result.push_back(raw); @@ -1132,6 +1138,7 @@ void SPIRVCodeGenerator::writeUniformScaleMatrix(SpvId id, SpvId diagonal, const for (int row = 0; row < type.columns(); row++) { this->writeWord(row == column ? diagonal : zeroId, out); } + this->writePrecisionModifier(type, columnId); } this->writeOpCode(SpvOpCompositeConstruct, 3 + type.columns(), out); @@ -1140,6 +1147,7 @@ void SPIRVCodeGenerator::writeUniformScaleMatrix(SpvId id, SpvId diagonal, const for (SpvId id : columnIds) { this->writeWord(id, out); } + this->writePrecisionModifier(type, id); } void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcType, @@ -1170,6 +1178,7 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp // we're still inside the src matrix, copy the column SpvId srcColumn = this->nextId(); this->writeInstruction(SpvOpCompositeExtract, srcColumnType, srcColumn, src, i, out); + this->writePrecisionModifier(dstType, srcColumn); SpvId dstColumn; if (srcType.rows() == dstType.rows()) { // columns are equal size, don't need to do anything @@ -1186,6 +1195,7 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp for (int i = 0; i < delta; ++i) { this->writeWord(zeroId, out); } + this->writePrecisionModifier(dstType, dstColumn); } else { // dst column is smaller, need to swizzle the src column @@ -1199,6 +1209,7 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp for (int i = 0; i < count; i++) { this->writeWord(i, out); } + this->writePrecisionModifier(dstType, dstColumn); } columns[i] = dstColumn; } else { @@ -1211,6 +1222,7 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp for (int i = 0; i < dstType.rows(); ++i) { this->writeWord(zeroId, out); } + this->writePrecisionModifier(dstType, zeroColumn); } columns[i] = zeroColumn; } @@ -1221,6 +1233,30 @@ void SPIRVCodeGenerator::writeMatrixCopy(SpvId id, SpvId src, const Type& srcTyp for (int i = 0; i < dstType.columns(); i++) { this->writeWord(columns[i], out); } + this->writePrecisionModifier(dstType, id); +} + +void SPIRVCodeGenerator::addColumnEntry(SpvId columnType, Precision precision, + std::vector<SpvId>* currentColumn, + std::vector<SpvId>* columnIds, + int* currentCount, int rows, SpvId entry, + OutputStream& out) { + SkASSERT(*currentCount < rows); + ++(*currentCount); + currentColumn->push_back(entry); + if (*currentCount == rows) { + *currentCount = 0; + this->writeOpCode(SpvOpCompositeConstruct, 3 + currentColumn->size(), out); + this->writeWord(columnType, out); + SpvId columnId = this->nextId(); + this->writeWord(columnId, out); + columnIds->push_back(columnId); + for (SpvId id : *currentColumn) { + this->writeWord(id, out); + } + currentColumn->clear(); + this->writePrecisionModifier(precision, columnId); + } } SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStream& out) { @@ -1255,11 +1291,13 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStr this->writeInstruction(SpvOpCompositeConstruct, this->getType(c.fType), result, column1, column2, out); } else { + SpvId columnType = this->getType(c.fType.componentType().toCompound(fContext, rows, 1)); std::vector<SpvId> columnIds; // ids of vectors and scalars we have written to the current column so far std::vector<SpvId> currentColumn; // the total number of scalars represented by currentColumn's entries int currentCount = 0; + Precision precision = c.fType.highPrecision() ? Precision::kHigh : Precision::kLow; for (size_t i = 0; i < arguments.size(); i++) { if (c.fArguments[i]->fType.kind() == Type::kVector_Kind && c.fArguments[i]->fType.columns() == c.fType.rows()) { @@ -1268,14 +1306,16 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStr columnIds.push_back(arguments[i]); } else { if (c.fArguments[i]->fType.columns() == 1) { - currentColumn.push_back(arguments[i]); + this->addColumnEntry(columnType, precision, ¤tColumn, &columnIds, + ¤tCount, rows, arguments[i], out); } else { SpvId componentType = this->getType(c.fArguments[i]->fType.componentType()); for (int j = 0; j < c.fArguments[i]->fType.columns(); ++j) { SpvId swizzle = this->nextId(); this->writeInstruction(SpvOpCompositeExtract, componentType, swizzle, arguments[i], j, out); - currentColumn.push_back(swizzle); + this->addColumnEntry(columnType, precision, ¤tColumn, &columnIds, + ¤tCount, rows, swizzle, out); } } currentCount += c.fArguments[i]->fType.columns(); @@ -1304,6 +1344,7 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, OutputStr this->writeWord(id, out); } } + this->writePrecisionModifier(c.fType, result); return result; } @@ -2517,55 +2558,61 @@ SpvId SPIRVCodeGenerator::writeBoolLiteral(const BoolLiteral& b) { } SpvId SPIRVCodeGenerator::writeIntLiteral(const IntLiteral& i) { + ConstantType type; if (i.fType == *fContext.fInt_Type) { - 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, - fConstantBuffer); - fIntConstants[i.fValue] = result; - return result; - } - return entry->second; - } else { - SkASSERT(i.fType == *fContext.fUInt_Type); - 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, - fConstantBuffer); - fUIntConstants[i.fValue] = result; - return result; - } - return entry->second; + type = ConstantType::kInt; + } else if (i.fType == *fContext.fUInt_Type) { + type = ConstantType::kUInt; + } else if (i.fType == *fContext.fShort_Type) { + type = ConstantType::kShort; + } else if (i.fType == *fContext.fUShort_Type) { + type = ConstantType::kUShort; + } + std::pair<ConstantValue, ConstantType> key(i.fValue, type); + auto entry = fNumberConstants.find(key); + if (entry == fNumberConstants.end()) { + SpvId result = this->nextId(); + this->writeInstruction(SpvOpConstant, this->getType(i.fType), result, (SpvId) i.fValue, + fConstantBuffer); + fNumberConstants[key] = result; + return result; } + return entry->second; } SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) { if (f.fType != *fContext.fDouble_Type) { + ConstantType type; + if (f.fType == *fContext.fHalf_Type) { + type = ConstantType::kHalf; + } else { + type = ConstantType::kFloat; + } float value = (float) f.fValue; - auto entry = fFloatConstants.find(value); - if (entry == fFloatConstants.end()) { + std::pair<ConstantValue, ConstantType> key(f.fValue, type); + auto entry = fNumberConstants.find(key); + if (entry == fNumberConstants.end()) { SpvId result = this->nextId(); uint32_t bits; SkASSERT(sizeof(bits) == sizeof(value)); memcpy(&bits, &value, sizeof(bits)); this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits, fConstantBuffer); - fFloatConstants[value] = result; + fNumberConstants[key] = result; return result; } return entry->second; } else { - auto entry = fDoubleConstants.find(f.fValue); - if (entry == fDoubleConstants.end()) { + std::pair<ConstantValue, ConstantType> key(f.fValue, ConstantType::kDouble); + auto entry = fNumberConstants.find(key); + if (entry == fNumberConstants.end()) { SpvId result = this->nextId(); uint64_t bits; SkASSERT(sizeof(bits) == sizeof(f.fValue)); memcpy(&bits, &f.fValue, sizeof(bits)); this->writeInstruction(SpvOpConstant, this->getType(f.fType), result, bits & 0xffffffff, bits >> 32, fConstantBuffer); - fDoubleConstants[f.fValue] = result; + fNumberConstants[key] = result; return result; } return entry->second; diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h index 422c0e7b0a..26560d5c69 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/SkSLSPIRVCodeGenerator.h @@ -42,6 +42,42 @@ #include "ir/SkSLWhileStatement.h" #include "spirv.h" +union ConstantValue { + ConstantValue(int64_t i) + : fInt(i) {} + + ConstantValue(double d) + : fDouble(d) {} + + bool operator==(const ConstantValue& other) const { + return fInt == other.fInt; + } + + int64_t fInt; + double fDouble; +}; + +enum class ConstantType { + kInt, + kUInt, + kShort, + kUShort, + kFloat, + kDouble, + kHalf, +}; + +namespace std { + +template <> +struct hash<std::pair<ConstantValue, ConstantType>> { + size_t operator()(const std::pair<ConstantValue, ConstantType>& key) const { + return key.first.fInt ^ (int) key.second; + } +}; + +} + namespace SkSL { #define kLast_Capability SpvCapabilityMultiViewport @@ -199,6 +235,10 @@ private: void writeMatrixCopy(SpvId id, SpvId src, const Type& srcType, const Type& dstType, OutputStream& out); + void addColumnEntry(SpvId columnType, Precision precision, std::vector<SpvId>* currentColumn, + std::vector<SpvId>* columnIds, int* currentCount, int rows, SpvId entry, + OutputStream& out); + SpvId writeMatrixConstructor(const Constructor& c, OutputStream& out); SpvId writeVectorConstructor(const Constructor& c, OutputStream& out); @@ -340,10 +380,7 @@ private: SpvId fBoolTrue; SpvId fBoolFalse; - std::unordered_map<int64_t, SpvId> fIntConstants; - std::unordered_map<uint64_t, SpvId> fUIntConstants; - std::unordered_map<float, SpvId> fFloatConstants; - std::unordered_map<double, SpvId> fDoubleConstants; + std::unordered_map<std::pair<ConstantValue, ConstantType>, SpvId> fNumberConstants; // The constant float2(0, 1), used in swizzling SpvId fConstantZeroOneVector = 0; bool fSetupFragPosition; |