aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/sksl/SkSLSPIRVCodeGenerator.cpp
diff options
context:
space:
mode:
authorGravatar Ethan Nicholas <ethannicholas@google.com>2016-12-12 15:33:30 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-13 14:28:53 +0000
commit941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9 (patch)
tree7f0ad6c5b2c3772d2c83be545fe04c53044746bd /src/sksl/SkSLSPIRVCodeGenerator.cpp
parent3dc73f3596d93a89f71b0c7e96d5d63dafeaf378 (diff)
re-land of added sk_FragCoord support to skslc
BUG=skia: Change-Id: Ifac1aa39839058787ad1794200c3dbb93c147a69 Reviewed-on: https://skia-review.googlesource.com/5850 Reviewed-by: Ethan Nicholas <ethannicholas@google.com> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Diffstat (limited to 'src/sksl/SkSLSPIRVCodeGenerator.cpp')
-rw-r--r--src/sksl/SkSLSPIRVCodeGenerator.cpp105
1 files changed, 84 insertions, 21 deletions
diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp
index b2857f44ef..63fe020993 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -994,14 +994,14 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, const MemoryLayout& memor
const Layout& fieldLayout = type.fields()[i].fModifiers.fLayout;
if (fieldLayout.fOffset >= 0) {
if (fieldLayout.fOffset <= (int) offset) {
- fErrors->error(type.fPosition,
- "offset of field '" + type.fields()[i].fName + "' must be at "
- "least " + to_string((int) offset));
+ fErrors.error(type.fPosition,
+ "offset of field '" + type.fields()[i].fName + "' must be at "
+ "least " + to_string((int) offset));
}
if (fieldLayout.fOffset % alignment) {
- fErrors->error(type.fPosition,
- "offset of field '" + type.fields()[i].fName + "' must be a multiple"
- " of " + to_string((int) alignment));
+ fErrors.error(type.fPosition,
+ "offset of field '" + type.fields()[i].fName + "' must be a multiple"
+ " of " + to_string((int) alignment));
}
offset = fieldLayout.fOffset;
} else {
@@ -1847,11 +1847,64 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
}
SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, SkWStream& out) {
+ SpvId result = this->nextId();
auto entry = fVariableMap.find(&ref.fVariable);
ASSERT(entry != fVariableMap.end());
SpvId var = entry->second;
- SpvId result = this->nextId();
this->writeInstruction(SpvOpLoad, this->getType(ref.fVariable.fType), result, var, out);
+ if (ref.fVariable.fModifiers.fLayout.fBuiltin == SK_FRAGCOORD_BUILTIN &&
+ fProgram.fSettings.fFlipY) {
+ // need to remap to a top-left coordinate system
+ if (fRTHeightStructId == (SpvId) -1) {
+ // height variable hasn't been written yet
+ std::shared_ptr<SymbolTable> st(new SymbolTable(fErrors));
+ ASSERT(fRTHeightFieldIndex == (SpvId) -1);
+ std::vector<Type::Field> fields;
+ fields.emplace_back(Modifiers(), SkString(SKSL_RTHEIGHT_NAME),
+ fContext.fFloat_Type.get());
+ SkString name("sksl_synthetic_uniforms");
+ Type intfStruct(Position(), name, fields);
+ Layout layout(-1, -1, 1, -1, -1, -1, -1, false, false, false, Layout::Format::kUnspecified,
+ false);
+ Variable intfVar(Position(), Modifiers(layout, Modifiers::kUniform_Flag), name,
+ intfStruct, Variable::kGlobal_Storage);
+ InterfaceBlock intf(Position(), intfVar, st);
+ fRTHeightStructId = this->writeInterfaceBlock(intf);
+ fRTHeightFieldIndex = 0;
+ }
+ ASSERT(fRTHeightFieldIndex != (SpvId) -1);
+ // write vec4(gl_FragCoord.x, u_skRTHeight - gl_FragCoord.y, 0.0, 1.0)
+ SpvId xId = this->nextId();
+ this->writeInstruction(SpvOpCompositeExtract, this->getType(*fContext.fFloat_Type), xId,
+ result, 0, out);
+ IntLiteral fieldIndex(fContext, Position(), fRTHeightFieldIndex);
+ SpvId fieldIndexId = this->writeIntLiteral(fieldIndex);
+ SpvId heightRead = this->nextId();
+ this->writeOpCode(SpvOpAccessChain, 5, out);
+ this->writeWord(this->getPointerType(*fContext.fFloat_Type, SpvStorageClassUniform), out);
+ this->writeWord(heightRead, out);
+ this->writeWord(fRTHeightStructId, out);
+ this->writeWord(fieldIndexId, out);
+ SpvId rawYId = this->nextId();
+ this->writeInstruction(SpvOpCompositeExtract, this->getType(*fContext.fFloat_Type), rawYId,
+ result, 1, out);
+ SpvId flippedYId = this->nextId();
+ this->writeInstruction(SpvOpFSub, this->getType(*fContext.fFloat_Type), flippedYId,
+ heightRead, rawYId, out);
+ FloatLiteral zero(fContext, Position(), 0.0);
+ SpvId zeroId = writeFloatLiteral(zero);
+ FloatLiteral one(fContext, Position(), 1.0);
+ SpvId oneId = writeFloatLiteral(one);
+ SpvId flipped = this->nextId();
+ this->writeOpCode(SpvOpCompositeConstruct, 7, out);
+ this->writeWord(this->getType(*fContext.fVec4_Type), out);
+ this->writeWord(flipped, out);
+ this->writeWord(xId, out);
+ this->writeWord(flippedYId, out);
+ this->writeWord(zeroId, out);
+ this->writeWord(oneId, out);
+ return flipped;
+ }
return result;
}
@@ -2442,12 +2495,22 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
MemoryLayout layout = intf.fVariable.fModifiers.fLayout.fPushConstant ?
MemoryLayout(MemoryLayout::k430_Standard) :
fDefaultLayout;
- SpvId type = this->getType(intf.fVariable.fType, layout);
SpvId result = this->nextId();
- this->writeInstruction(SpvOpDecorate, type, SpvDecorationBlock, fDecorationBuffer);
+ const Type* type = &intf.fVariable.fType;
+ if (fProgram.fInputs.fRTHeight) {
+ ASSERT(fRTHeightStructId == (SpvId) -1);
+ ASSERT(fRTHeightFieldIndex == (SpvId) -1);
+ std::vector<Type::Field> fields = type->fields();
+ fRTHeightStructId = result;
+ fRTHeightFieldIndex = fields.size();
+ fields.emplace_back(Modifiers(), SkString(SKSL_RTHEIGHT_NAME), fContext.fFloat_Type.get());
+ type = new Type(type->fPosition, type->name(), fields);
+ }
+ SpvId typeId = this->getType(*type, layout);
+ this->writeInstruction(SpvOpDecorate, typeId, SpvDecorationBlock, fDecorationBuffer);
SpvStorageClass_ storageClass = get_storage_class(intf.fVariable.fModifiers);
SpvId ptrType = this->nextId();
- this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, type, fConstantBuffer);
+ this->writeInstruction(SpvOpTypePointer, ptrType, storageClass, typeId, fConstantBuffer);
this->writeInstruction(SpvOpVariable, ptrType, result, storageClass, fConstantBuffer);
this->writeLayout(intf.fVariable.fModifiers.fLayout, result);
fVariableMap[&intf.fVariable] = result;
@@ -2734,6 +2797,7 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, SkWStream& ou
}
}
+ write_data(*fExtraGlobalsBuffer.detachAsData(), out);
write_data(*fNameBuffer.detachAsData(), out);
write_data(*fDecorationBuffer.detachAsData(), out);
write_data(*fConstantBuffer.detachAsData(), out);
@@ -2741,18 +2805,17 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, SkWStream& ou
write_data(*body.detachAsData(), out);
}
-void SPIRVCodeGenerator::generateCode(const Program& program, ErrorReporter& errors,
- SkWStream& out) {
- fErrors = &errors;
- this->writeWord(SpvMagicNumber, out);
- this->writeWord(SpvVersion, out);
- this->writeWord(SKSL_MAGIC, out);
+bool SPIRVCodeGenerator::generateCode() {
+ ASSERT(!fErrors.errorCount());
+ this->writeWord(SpvMagicNumber, *fOut);
+ this->writeWord(SpvVersion, *fOut);
+ this->writeWord(SKSL_MAGIC, *fOut);
SkDynamicMemoryWStream buffer;
- this->writeInstructions(program, buffer);
- this->writeWord(fIdCount, out);
- this->writeWord(0, out); // reserved, always zero
- write_data(*buffer.detachAsData(), out);
- fErrors = nullptr;
+ this->writeInstructions(fProgram, buffer);
+ this->writeWord(fIdCount, *fOut);
+ this->writeWord(0, *fOut); // reserved, always zero
+ write_data(*buffer.detachAsData(), *fOut);
+ return 0 == fErrors.errorCount();
}
}