aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Nicholas <ethannicholas@google.com>2019-04-22 11:23:28 -0400
committerSkia Commit-Bot <skia-commit-bot@chromium.org>2019-04-22 15:28:40 +0000
commit8f92cc67adbbd03732c8a3239d29d787f36c3243 (patch)
treea567cc86eca25f48afd6d2e0e27ee3e25ee0070a
parentec62a21fd704efd36ab0f019c00c654ad1cefa68 (diff)
downloadskia-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.cpp123
-rw-r--r--src/sksl/SkSLSPIRVCodeGenerator.h45
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, &currentColumn, &columnIds,
+ &currentCount, 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, &currentColumn, &columnIds,
+ &currentCount, 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;