diff --git a/src/sksl/SkSLContext.h b/src/sksl/SkSLContext.h index a9ebe9db06..53e5ea0954 100644 --- a/src/sksl/SkSLContext.h +++ b/src/sksl/SkSLContext.h @@ -71,7 +71,8 @@ public: , fSampler1DArray_Type(new Type(String("sampler1DArray"))) , fSampler2DArray_Type(new Type(String("sampler2DArray"))) , fSamplerCubeArray_Type(new Type(String("samplerCubeArray"))) - , fSamplerBuffer_Type(new Type(String("samplerBuffer"))) + , fSamplerBuffer_Type(new Type(String("samplerBuffer"), SpvDimBuffer, false, false, false, + true)) , fSampler2DMS_Type(new Type(String("sampler2DMS"))) , fSampler2DMSArray_Type(new Type(String("sampler2DMSArray"))) , fSampler1DShadow_Type(new Type(String("sampler1DShadow"))) diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index 24f3d91993..1cbd1274fc 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -64,12 +64,12 @@ void SPIRVCodeGenerator::setupIntrinsics() { fIntrinsicMap[String("determinant")] = ALL_GLSL(Determinant); fIntrinsicMap[String("matrixInverse")] = ALL_GLSL(MatrixInverse); fIntrinsicMap[String("mod")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpFMod, - SpvOpSMod, SpvOpUMod, SpvOpUndef); + SpvOpSMod, SpvOpUMod, SpvOpUndef); fIntrinsicMap[String("min")] = BY_TYPE_GLSL(FMin, SMin, UMin); fIntrinsicMap[String("max")] = BY_TYPE_GLSL(FMax, SMax, UMax); fIntrinsicMap[String("clamp")] = BY_TYPE_GLSL(FClamp, SClamp, UClamp); fIntrinsicMap[String("dot")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDot, - SpvOpUndef, SpvOpUndef, SpvOpUndef); + SpvOpUndef, SpvOpUndef, SpvOpUndef); fIntrinsicMap[String("mix")] = ALL_GLSL(FMix); fIntrinsicMap[String("step")] = ALL_GLSL(Step); fIntrinsicMap[String("smoothstep")] = ALL_GLSL(SmoothStep); @@ -95,44 +95,44 @@ void SPIRVCodeGenerator::setupIntrinsics() { fIntrinsicMap[String("findLSB")] = ALL_GLSL(FindILsb); fIntrinsicMap[String("findMSB")] = BY_TYPE_GLSL(FindSMsb, FindSMsb, FindUMsb); fIntrinsicMap[String("dFdx")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdx, - SpvOpUndef, SpvOpUndef, SpvOpUndef); + SpvOpUndef, SpvOpUndef, SpvOpUndef); fIntrinsicMap[String("dFdy")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdy, - SpvOpUndef, SpvOpUndef, SpvOpUndef); + SpvOpUndef, SpvOpUndef, SpvOpUndef); fIntrinsicMap[String("dFdy")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdy, - SpvOpUndef, SpvOpUndef, SpvOpUndef); + SpvOpUndef, SpvOpUndef, SpvOpUndef); fIntrinsicMap[String("texture")] = SPECIAL(Texture); - + fIntrinsicMap[String("texelFetch")] = SPECIAL(TexelFetch); fIntrinsicMap[String("subpassLoad")] = SPECIAL(SubpassLoad); fIntrinsicMap[String("any")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, - SpvOpUndef, SpvOpUndef, SpvOpAny); + SpvOpUndef, SpvOpUndef, SpvOpAny); fIntrinsicMap[String("all")] = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, - SpvOpUndef, SpvOpUndef, SpvOpAll); + SpvOpUndef, SpvOpUndef, SpvOpAll); fIntrinsicMap[String("equal")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpFOrdEqual, SpvOpIEqual, - SpvOpIEqual, SpvOpLogicalEqual); + SpvOpFOrdEqual, SpvOpIEqual, + SpvOpIEqual, SpvOpLogicalEqual); fIntrinsicMap[String("notEqual")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpFOrdNotEqual, SpvOpINotEqual, - SpvOpINotEqual, - SpvOpLogicalNotEqual); + SpvOpFOrdNotEqual, SpvOpINotEqual, + SpvOpINotEqual, + SpvOpLogicalNotEqual); fIntrinsicMap[String("lessThan")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpSLessThan, SpvOpULessThan, - SpvOpFOrdLessThan, SpvOpUndef); + SpvOpSLessThan, SpvOpULessThan, + SpvOpFOrdLessThan, SpvOpUndef); fIntrinsicMap[String("lessThanEqual")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpSLessThanEqual, - SpvOpULessThanEqual, - SpvOpFOrdLessThanEqual, - SpvOpUndef); + SpvOpSLessThanEqual, + SpvOpULessThanEqual, + SpvOpFOrdLessThanEqual, + SpvOpUndef); fIntrinsicMap[String("greaterThan")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpSGreaterThan, - SpvOpUGreaterThan, - SpvOpFOrdGreaterThan, - SpvOpUndef); + SpvOpSGreaterThan, + SpvOpUGreaterThan, + SpvOpFOrdGreaterThan, + SpvOpUndef); fIntrinsicMap[String("greaterThanEqual")] = std::make_tuple(kSPIRV_IntrinsicKind, - SpvOpSGreaterThanEqual, - SpvOpUGreaterThanEqual, - SpvOpFOrdGreaterThanEqual, - SpvOpUndef); + SpvOpSGreaterThanEqual, + SpvOpUGreaterThanEqual, + SpvOpFOrdGreaterThanEqual, + SpvOpUndef); // interpolateAt* not yet supported... } @@ -1091,11 +1091,15 @@ SpvId SPIRVCodeGenerator::getType(const Type& type, const MemoryLayout& layout) if (SpvDimSubpassData != type.dimensions()) { image = this->nextId(); } + if (SpvDimBuffer == type.dimensions()) { + fCapabilities |= (((uint64_t) 1) << SpvCapabilitySampledBuffer); + } this->writeInstruction(SpvOpTypeImage, image, this->getType(*fContext.fFloat_Type, layout), type.dimensions(), type.isDepth(), type.isArrayed(), type.isMultisampled(), type.isSampled() ? 1 : 2, SpvImageFormatUnknown, fConstantBuffer); + fImageTypeMap[key] = image; if (SpvDimSubpassData != type.dimensions()) { this->writeInstruction(SpvOpTypeSampledImage, result, image, fConstantBuffer); } @@ -1114,6 +1118,14 @@ SpvId SPIRVCodeGenerator::getType(const Type& type, const MemoryLayout& layout) return entry->second; } +SpvId SPIRVCodeGenerator::getImageType(const Type& type) { + ASSERT(type.kind() == Type::kSampler_Kind); + this->getType(type); + String key = type.name() + to_string((int) fDefaultLayout.fStd); + ASSERT(fImageTypeMap.find(key) != fImageTypeMap.end()); + return fImageTypeMap[key]; +} + SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) { String key = function.fReturnType.description() + "("; String separator; @@ -1295,7 +1307,51 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn for (SpvId id : arguments) { this->writeWord(id, out); } - return result; + break; + } + case kSubpassLoad_SpecialIntrinsic: { + SpvId img = this->writeExpression(*c.fArguments[0], out); + std::vector> args; + args.emplace_back(new FloatLiteral(fContext, Position(), 0.0)); + args.emplace_back(new FloatLiteral(fContext, Position(), 0.0)); + Constructor ctor(Position(), *fContext.fVec2_Type, std::move(args)); + SpvId coords = this->writeConstantVector(ctor); + if (1 == c.fArguments.size()) { + this->writeInstruction(SpvOpImageRead, + this->getType(c.fType), + result, + img, + coords, + out); + } else { + ASSERT(2 == c.fArguments.size()); + SpvId sample = this->writeExpression(*c.fArguments[1], out); + this->writeInstruction(SpvOpImageRead, + this->getType(c.fType), + result, + img, + coords, + SpvImageOperandsSampleMask, + sample, + out); + } + break; + } + case kTexelFetch_SpecialIntrinsic: { + ASSERT(c.fArguments.size() == 2); + SpvId image = this->nextId(); + this->writeInstruction(SpvOpImage, + this->getImageType(c.fArguments[0]->fType), + image, + this->writeExpression(*c.fArguments[0], out), + out); + this->writeInstruction(SpvOpImageFetch, + this->getType(c.fType), + result, + image, + this->writeExpression(*c.fArguments[1], out), + out); + break; } case kTexture_SpecialIntrinsic: { SpvOp_ op = SpvOpImageSampleImplicitLod; @@ -1342,34 +1398,6 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn } break; } - case kSubpassLoad_SpecialIntrinsic: { - SpvId img = this->writeExpression(*c.fArguments[0], out); - std::vector> args; - args.emplace_back(new FloatLiteral(fContext, Position(), 0.0)); - args.emplace_back(new FloatLiteral(fContext, Position(), 0.0)); - Constructor ctor(Position(), *fContext.fVec2_Type, std::move(args)); - SpvId coords = this->writeConstantVector(ctor); - if (1 == c.fArguments.size()) { - this->writeInstruction(SpvOpImageRead, - this->getType(c.fType), - result, - img, - coords, - out); - } else { - ASSERT(2 == c.fArguments.size()); - SpvId sample = this->writeExpression(*c.fArguments[1], out); - this->writeInstruction(SpvOpImageRead, - this->getType(c.fType), - result, - img, - coords, - SpvImageOperandsSampleMask, - sample, - out); - } - break; - } } return result; } diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h index 84a4c1ff6a..a3439059b3 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/SkSLSPIRVCodeGenerator.h @@ -89,8 +89,9 @@ private: enum SpecialIntrinsic { kAtan_SpecialIntrinsic, - kTexture_SpecialIntrinsic, kSubpassLoad_SpecialIntrinsic, + kTexelFetch_SpecialIntrinsic, + kTexture_SpecialIntrinsic, }; void setupIntrinsics(); @@ -101,6 +102,8 @@ private: SpvId getType(const Type& type, const MemoryLayout& layout); + SpvId getImageType(const Type& type); + SpvId getFunctionType(const FunctionDeclaration& function); SpvId getPointerType(const Type& type, SpvStorageClass_ storageClass); @@ -276,6 +279,7 @@ private: std::unordered_map fFunctionMap; std::unordered_map fVariableMap; std::unordered_map fInterfaceBlockMap; + std::unordered_map fImageTypeMap; std::unordered_map fTypeMap; StringStream fCapabilitiesBuffer; StringStream fGlobalInitializersBuffer; diff --git a/src/sksl/sksl.include b/src/sksl/sksl.include index 3d730d4f9d..18a55169b8 100644 --- a/src/sksl/sksl.include +++ b/src/sksl/sksl.include @@ -345,9 +345,10 @@ float textureOffset(sampler1DArrayShadow sampler, vec3 P, int offset); float textureOffset(sampler1DArrayShadow sampler, vec3 P, int offset, float bias); float textureOffset(sampler2DArrayShadow sampler, vec4 P, ivec2 offset); */ +vec4 texelFetch(samplerBuffer sampler, int P); + $gvec4 texelFetch($gsampler1D sampler, int P, int lod); $gvec4 texelFetch($gsampler2D sampler, ivec2 P, int lod); -$gvec4 texelFetch($gsamplerBuffer sampler, int P); $gvec4 texelFetch($gsampler2DRect sampler, ivec2 P); /* $gvec4 texelFetch($gsampler3D sampler, ivec3 P, int lod);