From 6403b0e29055b8573eab20b5cb586c07785a2435 Mon Sep 17 00:00:00 2001 From: Timothy Liang Date: Thu, 17 May 2018 10:40:04 -0400 Subject: added basic texturing to metal sksl backend Bug: skia: Change-Id: I2e70efe53f5c2fb208979cc89be9c3c841944a48 Reviewed-on: https://skia-review.googlesource.com/128844 Reviewed-by: Ethan Nicholas Commit-Queue: Timothy Liang --- src/sksl/SkSLMetalCodeGenerator.cpp | 70 +++++++++++++++++++++++++++++++++++++ src/sksl/SkSLMetalCodeGenerator.h | 18 +++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) (limited to 'src/sksl') diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp index 99cfb5b6c6..b8fdc1c193 100644 --- a/src/sksl/SkSLMetalCodeGenerator.cpp +++ b/src/sksl/SkSLMetalCodeGenerator.cpp @@ -17,6 +17,14 @@ namespace SkSL { +void MetalCodeGenerator::setupIntrinsics(){ +#define SPECIAL(x) std::make_tuple(kSpecial_IntrinsicKind, k ## x ## _SpecialIntrinsic, \ + k ## x ## _SpecialIntrinsic, k ## x ## _SpecialIntrinsic, \ + k ## x ## _SpecialIntrinsic) + + fIntrinsicMap[String("texture")] = SPECIAL(Texture); +} + void MetalCodeGenerator::write(const char* s) { if (!s[0]) { return; @@ -132,7 +140,31 @@ void MetalCodeGenerator::writeExpression(const Expression& expr, Precedence pare } } +void MetalCodeGenerator::writeIntrinsicCall(const FunctionCall& c) { + auto intrinsic = fIntrinsicMap.find(c.fFunction.fName); + ASSERT(intrinsic != fIntrinsicMap.end()); + int32_t intrinsicId = 0; + if (c.fArguments.size() > 0) { + if (std::get<0>(intrinsic->second) == kSpecial_IntrinsicKind) { + intrinsicId = std::get<1>(intrinsic->second); + } + } else { + intrinsicId = std::get<1>(intrinsic->second); + } + switch (std::get<0>(intrinsic->second)) { + case kSpecial_IntrinsicKind: + return this->writeSpecialIntrinsic(c, (SpecialIntrinsic) intrinsicId); + default: + ABORT("unsupported intrinsic kind"); + } +} + void MetalCodeGenerator::writeFunctionCall(const FunctionCall& c) { + const auto& entry = fIntrinsicMap.find(c.fFunction.fName); + if (entry != fIntrinsicMap.end()) { + this->writeIntrinsicCall(c); + return; + } if (c.fFunction.fBuiltin && "atan" == c.fFunction.fName && 2 == c.fArguments.size()) { this->write("atan2"); } else { @@ -166,6 +198,18 @@ void MetalCodeGenerator::writeFunctionCall(const FunctionCall& c) { this->write(")"); } +void MetalCodeGenerator::writeSpecialIntrinsic(const FunctionCall & c, SpecialIntrinsic kind) { + switch (kind) { + case kTexture_SpecialIntrinsic: + this->write("_colorMap.sample($colorSampler, "); + this->writeExpression(*c.fArguments[1], kSequence_Precedence); + this->write(".xy)"); // FIXME - dimension checking + break; + default: + ABORT("unsupported special intrinsic kind"); + } +} + void MetalCodeGenerator::writeConstructor(const Constructor& c) { this->writeType(c.fType); this->write("("); @@ -202,6 +246,9 @@ void MetalCodeGenerator::writeVariableReference(const VariableReference& ref) { case SK_FRAGCOLOR_BUILTIN: this->write("sk_FragColor"); break; + case SK_FRAGCOORD_BUILTIN: + this->writeFragCoord(); + break; default: if (Variable::kGlobal_Storage == ref.fVariable.fStorage) { if (ref.fVariable.fModifiers.fFlags & Modifiers::kIn_Flag) { @@ -390,6 +437,7 @@ void MetalCodeGenerator::writeSetting(const Setting& s) { } void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) { + bool needColorSampler = false; const char* separator = ""; if ("main" == f.fDeclaration.fName) { switch (fProgram.fKind) { @@ -407,6 +455,21 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) { this->write(", constant Uniforms& _uniforms [[buffer(" + to_string(fUniformBuffer) + ")]]"); } + for (const auto& e : fProgram) { + if (ProgramElement::kVar_Kind == e.fKind) { + VarDeclarations& decls = (VarDeclarations&) e; + if (!decls.fVars.size()) { + continue; + } + for(const auto& stmt: decls.fVars){ + VarDeclaration& var = (VarDeclaration&) *stmt; + if(var.fVar->fType == *fContext.fSampler2D_Type){ + needColorSampler = true; + this->write(", texture2d _colorMap [[texture(TextureIndexColor)]]"); + } // FIXME may require textureindexcolor field, hardcoded for now + } + } + } separator = ", "; } else { this->writeType(f.fDeclaration.fReturnType); @@ -454,6 +517,10 @@ void MetalCodeGenerator::writeFunction(const FunctionDefinition& f) { ASSERT(!fProgram.fSettings.fFragColorIsInOut); if ("main" == f.fDeclaration.fName) { + if (needColorSampler) { + this->writeLine(" constexpr sampler " + "$colorSampler(mip_filter::linear, mag_filter::linear, min_filter::linear);"); + } switch (fProgram.fKind) { case Program::kFragment_Kind: this->writeLine(" half4 sk_FragColor;"); @@ -547,6 +614,9 @@ void MetalCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool ASSERT(global); continue; } + if (var.fVar->fType == *fContext.fSampler2D_Type){ + continue; // FIXME - temporarily ignoring global sampler2Ds + } if (wroteType) { this->write(", "); } else { diff --git a/src/sksl/SkSLMetalCodeGenerator.h b/src/sksl/SkSLMetalCodeGenerator.h index 3eccbf0909..6f8933c381 100644 --- a/src/sksl/SkSLMetalCodeGenerator.h +++ b/src/sksl/SkSLMetalCodeGenerator.h @@ -77,7 +77,9 @@ public: OutputStream* out) : INHERITED(program, errors, out) , fLineEnding("\n") - , fContext(*context) {} + , fContext(*context) { + this->setupIntrinsics(); + } bool generateCode() override; @@ -88,6 +90,16 @@ protected: static constexpr Requirements kOutputs_Requirement = 1 << 1; static constexpr Requirements kUniforms_Requirement = 1 << 2; + enum IntrinsicKind { + kSpecial_IntrinsicKind + }; + + enum SpecialIntrinsic { + kTexture_SpecialIntrinsic, + }; + + void setupIntrinsics(); + void write(const char* s); void writeLine(); @@ -142,6 +154,8 @@ protected: void writeFunctionCall(const FunctionCall& c); + void writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind); + void writeConstructor(const Constructor& c); void writeFieldAccess(const FieldAccess& f); @@ -194,6 +208,8 @@ protected: Requirements requirements(const Statement& e); + typedef std::tuple Intrinsic; + std::unordered_map fIntrinsicMap; const char* fLineEnding; const Context& fContext; StringStream fHeader; -- cgit v1.2.3