sksl SPIR-V sampledBuffer support

Bug: skia:
Change-Id: I9bf936857b61d3bb5a165f7a11e53d25069b53c2
Reviewed-on: https://skia-review.googlesource.com/15192
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
Ethan Nicholas 2017-05-03 11:03:44 -04:00 committed by Skia Commit-Bot
parent 581e69865e
commit 0187ae6584
4 changed files with 93 additions and 59 deletions

View File

@ -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")))

View File

@ -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<std::unique_ptr<Expression>> 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<std::unique_ptr<Expression>> 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;
}

View File

@ -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<const FunctionDeclaration*, SpvId> fFunctionMap;
std::unordered_map<const Variable*, SpvId> fVariableMap;
std::unordered_map<const Variable*, int32_t> fInterfaceBlockMap;
std::unordered_map<String, SpvId> fImageTypeMap;
std::unordered_map<String, SpvId> fTypeMap;
StringStream fCapabilitiesBuffer;
StringStream fGlobalInitializersBuffer;

View File

@ -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);