diff options
author | Ethan Nicholas <ethannicholas@google.com> | 2016-12-12 15:33:30 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-13 14:28:53 +0000 |
commit | 941e7e2c9567ab1d8a3b2d1b0e3db71ee5eb75c9 (patch) | |
tree | 7f0ad6c5b2c3772d2c83be545fe04c53044746bd /src/sksl/SkSLSPIRVCodeGenerator.cpp | |
parent | 3dc73f3596d93a89f71b0c7e96d5d63dafeaf378 (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.cpp | 105 |
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(); } } |