Reland "Fixed some GrSkSLFP limitations."
This is a reland of 190157bff2
Original change's description:
> Fixed some GrSkSLFP limitations.
>
> This makes it possible to pass more types as uniforms / inputs and fixes an
> issue with non-main functions calling other non-main functions.
>
> Change-Id: I6b5623b3c967d8219b992a455cc68bb0a29706b8
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255300
> Reviewed-by: Brian Osman <brianosman@google.com>
> Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Change-Id: Icc06cd54abb7acc83415915e16ca64c3eb6b943b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/255779
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
This commit is contained in:
parent
119ac6d1b7
commit
fc671ad888
@ -76,6 +76,12 @@ const SkSL::Program* GrSkSLFPFactory::getSpecialization(const SkSL::String& key,
|
||||
bool v = *(((bool*) inputs) + offset);
|
||||
inputMap.insert(std::make_pair(name, SkSL::Program::Settings::Value(v)));
|
||||
offset += sizeof(bool);
|
||||
} else if (&v->fType == fCompiler.context().fFloat2_Type.get() ||
|
||||
&v->fType == fCompiler.context().fHalf2_Type.get()) {
|
||||
offset = SkAlign4(offset) + sizeof(float) * 2;
|
||||
} else if (&v->fType == fCompiler.context().fFloat3_Type.get() ||
|
||||
&v->fType == fCompiler.context().fHalf3_Type.get()) {
|
||||
offset = SkAlign4(offset) + sizeof(float) * 3;
|
||||
} else if (&v->fType == fCompiler.context().fFloat4_Type.get() ||
|
||||
&v->fType == fCompiler.context().fHalf4_Type.get()) {
|
||||
offset = SkAlign4(offset) + sizeof(float) * 4;
|
||||
@ -103,6 +109,10 @@ static SkSL::Layout::CType get_ctype(const SkSL::Context& context, const SkSL::V
|
||||
if (result == SkSL::Layout::CType::kDefault) {
|
||||
if (&v.fType == context.fFloat_Type.get()) {
|
||||
result = SkSL::Layout::CType::kFloat;
|
||||
} else if (&v.fType == context.fFloat2_Type.get()) {
|
||||
result = SkSL::Layout::CType::kFloat2;
|
||||
} else if (&v.fType == context.fFloat3_Type.get()) {
|
||||
result = SkSL::Layout::CType::kFloat3;
|
||||
} else if (&v.fType == context.fFloat4_Type.get()) {
|
||||
result = SkSL::Layout::CType::kSkRect;
|
||||
} else if (&v.fType == context.fHalf4_Type.get()) {
|
||||
@ -139,10 +149,22 @@ public:
|
||||
return kFloat2_GrSLType;
|
||||
} else if (type == *fContext.fHalf2_Type) {
|
||||
return kHalf2_GrSLType;
|
||||
} else if (type == *fContext.fFloat3_Type) {
|
||||
return kFloat3_GrSLType;
|
||||
} else if (type == *fContext.fHalf3_Type) {
|
||||
return kHalf3_GrSLType;
|
||||
} else if (type == *fContext.fFloat4_Type) {
|
||||
return kFloat4_GrSLType;
|
||||
} else if (type == *fContext.fHalf4_Type) {
|
||||
return kHalf4_GrSLType;
|
||||
} else if (type == *fContext.fFloat2x2_Type) {
|
||||
return kFloat2x2_GrSLType;
|
||||
} else if (type == *fContext.fHalf2x2_Type) {
|
||||
return kHalf2x2_GrSLType;
|
||||
} else if (type == *fContext.fFloat3x3_Type) {
|
||||
return kFloat3x3_GrSLType;
|
||||
} else if (type == *fContext.fHalf3x3_Type) {
|
||||
return kHalf3x3_GrSLType;
|
||||
} else if (type == *fContext.fFloat4x4_Type) {
|
||||
return kFloat4x4_GrSLType;
|
||||
} else if (type == *fContext.fHalf4x4_Type) {
|
||||
@ -156,6 +178,64 @@ public:
|
||||
SK_ABORT("unsupported uniform type");
|
||||
}
|
||||
|
||||
SkSL::String expandFormatArgs(const SkSL::String& raw,
|
||||
const EmitArgs& args,
|
||||
const std::vector<SkSL::Compiler::FormatArg> formatArgs,
|
||||
const char* coordsName,
|
||||
const std::vector<SkString>& childNames) {
|
||||
SkSL::String result;
|
||||
int substringStartIndex = 0;
|
||||
int formatArgIndex = 0;
|
||||
for (size_t i = 0; i < raw.length(); ++i) {
|
||||
char c = raw[i];
|
||||
if (c == '%') {
|
||||
result += SkSL::StringFragment(raw.c_str() + substringStartIndex,
|
||||
i - substringStartIndex);
|
||||
++i;
|
||||
c = raw[i];
|
||||
switch (c) {
|
||||
case 's': {
|
||||
const SkSL::Compiler::FormatArg& arg = formatArgs[formatArgIndex++];
|
||||
switch (arg.fKind) {
|
||||
case SkSL::Compiler::FormatArg::Kind::kInput:
|
||||
result += args.fInputColor;
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kOutput:
|
||||
result += args.fOutputColor;
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kCoordX:
|
||||
result += coordsName;
|
||||
result += ".x";
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kCoordY:
|
||||
result += coordsName;
|
||||
result += ".y";
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kUniform:
|
||||
result += args.fUniformHandler->getUniformCStr(
|
||||
fUniformHandles[arg.fIndex]);
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
|
||||
result += childNames[arg.fIndex].c_str();
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kFunctionName:
|
||||
SkASSERT((int) fFunctionNames.size() > arg.fIndex);
|
||||
result += fFunctionNames[arg.fIndex].c_str();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result += c;
|
||||
}
|
||||
substringStartIndex = i + 1;
|
||||
}
|
||||
}
|
||||
result += SkSL::StringFragment(raw.c_str() + substringStartIndex,
|
||||
raw.length() - substringStartIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
void emitCode(EmitArgs& args) override {
|
||||
for (const auto& v : fInAndUniformVars) {
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag && v->fType !=
|
||||
@ -167,69 +247,27 @@ public:
|
||||
}
|
||||
}
|
||||
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
|
||||
for (const auto& f : fFunctions) {
|
||||
fFunctionNames.emplace_back();
|
||||
fragBuilder->emitFunction(f.fReturnType,
|
||||
f.fName.c_str(),
|
||||
f.fParameters.size(),
|
||||
f.fParameters.data(),
|
||||
f.fBody.c_str(),
|
||||
&fFunctionNames.back());
|
||||
}
|
||||
SkString coords = args.fTransformedCoords.count()
|
||||
? fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint)
|
||||
: SkString("sk_FragCoord");
|
||||
std::vector<SkString> childNames;
|
||||
for (int i = 0; i < this->numChildProcessors(); ++i) {
|
||||
childNames.push_back(SkStringPrintf("_child%d", i));
|
||||
this->invokeChild(i, &childNames[i], args);
|
||||
}
|
||||
int substringStartIndex = 0;
|
||||
int formatArgIndex = 0;
|
||||
SkString coords = args.fTransformedCoords.count()
|
||||
? fragBuilder->ensureCoords2D(args.fTransformedCoords[0].fVaryingPoint)
|
||||
: SkString("sk_FragCoord");
|
||||
for (size_t i = 0; i < fGLSL.length(); ++i) {
|
||||
char c = fGLSL[i];
|
||||
if (c == '%') {
|
||||
fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
|
||||
i - substringStartIndex);
|
||||
++i;
|
||||
c = fGLSL[i];
|
||||
switch (c) {
|
||||
case 's': {
|
||||
SkSL::Compiler::FormatArg& arg = fFormatArgs[formatArgIndex++];
|
||||
switch (arg.fKind) {
|
||||
case SkSL::Compiler::FormatArg::Kind::kInput:
|
||||
fragBuilder->codeAppend(args.fInputColor);
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kOutput:
|
||||
fragBuilder->codeAppend(args.fOutputColor);
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kCoordX:
|
||||
fragBuilder->codeAppendf("%s.x", coords.c_str());
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kCoordY:
|
||||
fragBuilder->codeAppendf("%s.y", coords.c_str());
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kUniform:
|
||||
fragBuilder->codeAppend(args.fUniformHandler->getUniformCStr(
|
||||
fUniformHandles[arg.fIndex]));
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kChildProcessor:
|
||||
fragBuilder->codeAppend(childNames[arg.fIndex].c_str());
|
||||
break;
|
||||
case SkSL::Compiler::FormatArg::Kind::kFunctionName:
|
||||
fragBuilder->codeAppend(fFunctionNames[arg.fIndex].c_str());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fragBuilder->codeAppendf("%c", c);
|
||||
}
|
||||
substringStartIndex = i + 1;
|
||||
}
|
||||
for (const auto& f : fFunctions) {
|
||||
fFunctionNames.emplace_back();
|
||||
SkSL::String body = this->expandFormatArgs(f.fBody.c_str(), args, f.fFormatArgs,
|
||||
coords.c_str(), childNames);
|
||||
fragBuilder->emitFunction(f.fReturnType,
|
||||
f.fName.c_str(),
|
||||
f.fParameters.size(),
|
||||
f.fParameters.data(),
|
||||
body.c_str(),
|
||||
&fFunctionNames.back());
|
||||
}
|
||||
fragBuilder->codeAppend(fGLSL.c_str() + substringStartIndex,
|
||||
fGLSL.length() - substringStartIndex);
|
||||
fragBuilder->codeAppend(this->expandFormatArgs(fGLSL.c_str(), args, fFormatArgs,
|
||||
coords.c_str(), childNames).c_str());
|
||||
}
|
||||
|
||||
void onSetData(const GrGLSLProgramDataManager& pdman,
|
||||
@ -250,6 +288,30 @@ public:
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SkSL::Layout::CType::kFloat2: {
|
||||
offset = SkAlign4(offset);
|
||||
float f1 = *(float*) (inputs + offset);
|
||||
offset += sizeof(float);
|
||||
float f2 = *(float*) (inputs + offset);
|
||||
offset += sizeof(float);
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
|
||||
pdman.set2f(fUniformHandles[uniformIndex++], f1, f2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SkSL::Layout::CType::kFloat3: {
|
||||
offset = SkAlign4(offset);
|
||||
float f1 = *(float*) (inputs + offset);
|
||||
offset += sizeof(float);
|
||||
float f2 = *(float*) (inputs + offset);
|
||||
offset += sizeof(float);
|
||||
float f3 = *(float*) (inputs + offset);
|
||||
offset += sizeof(float);
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kUniform_Flag) {
|
||||
pdman.set3f(fUniformHandles[uniformIndex++], f1, f2, f3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SkSL::Layout::CType::kSkPMColor4f:
|
||||
case SkSL::Layout::CType::kSkRect: {
|
||||
offset = SkAlign4(offset);
|
||||
@ -398,6 +460,19 @@ GrGLSLFragmentProcessor* GrSkSLFP::onCreateGLSLInstance() const {
|
||||
formatArgs, functions);
|
||||
}
|
||||
|
||||
static void copy_floats_key(char* inputs, GrProcessorKeyBuilder* b, bool isIn, int count,
|
||||
size_t* offset, SkSL::String* key) {
|
||||
if (isIn) {
|
||||
for (size_t i = 0; i < sizeof(float) * count; ++i) {
|
||||
(*key) += inputs[*offset + i];
|
||||
b->add32(*(int32_t*) (inputs + *offset));
|
||||
(*offset) += sizeof(float);
|
||||
}
|
||||
} else {
|
||||
(*offset) += sizeof(float) * count;
|
||||
}
|
||||
}
|
||||
|
||||
void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
GrProcessorKeyBuilder* b) const {
|
||||
this->createFactory();
|
||||
@ -441,24 +516,19 @@ void GrSkSLFP::onGetGLSLProcessorKey(const GrShaderCaps& caps,
|
||||
offset += sizeof(float);
|
||||
break;
|
||||
}
|
||||
case SkSL::Layout::CType::kFloat2:
|
||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 2,
|
||||
&offset, &fKey);
|
||||
break;
|
||||
case SkSL::Layout::CType::kFloat3:
|
||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 3,
|
||||
&offset, &fKey);
|
||||
break;
|
||||
case SkSL::Layout::CType::kSkPMColor:
|
||||
case SkSL::Layout::CType::kSkPMColor4f:
|
||||
case SkSL::Layout::CType::kSkRect:
|
||||
if (v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag) {
|
||||
for (size_t i = 0; i < sizeof(float) * 4; ++i) {
|
||||
fKey += inputs[offset + i];
|
||||
}
|
||||
b->add32(*(int32_t*) (inputs + offset));
|
||||
offset += sizeof(float);
|
||||
b->add32(*(int32_t*) (inputs + offset));
|
||||
offset += sizeof(float);
|
||||
b->add32(*(int32_t*) (inputs + offset));
|
||||
offset += sizeof(float);
|
||||
b->add32(*(int32_t*) (inputs + offset));
|
||||
offset += sizeof(float);
|
||||
} else {
|
||||
offset += sizeof(float) * 4;
|
||||
}
|
||||
copy_floats_key(inputs, b, v->fModifiers.fFlags & SkSL::Modifiers::kIn_Flag, 4,
|
||||
&offset, &fKey);
|
||||
break;
|
||||
default:
|
||||
// unsupported input var type
|
||||
|
@ -102,6 +102,7 @@ public:
|
||||
SkString fName;
|
||||
std::vector<GrShaderVar> fParameters;
|
||||
SkString fBody;
|
||||
std::vector<Compiler::FormatArg> fFormatArgs;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -215,6 +215,10 @@ static GrSLType glsltype(const Context& context, const Type& type) {
|
||||
return GrSLType::kFloat2_GrSLType;
|
||||
} else if (type == *context.fHalf2_Type) {
|
||||
return GrSLType::kHalf2_GrSLType;
|
||||
} else if (type == *context.fFloat3_Type) {
|
||||
return GrSLType::kFloat3_GrSLType;
|
||||
} else if (type == *context.fHalf3_Type) {
|
||||
return GrSLType::kHalf3_GrSLType;
|
||||
} else if (type == *context.fFloat4_Type) {
|
||||
return GrSLType::kFloat4_GrSLType;
|
||||
} else if (type == *context.fHalf4_Type) {
|
||||
@ -262,6 +266,7 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
}
|
||||
fOut = oldOut;
|
||||
result.fBody = buffer.str();
|
||||
result.fFormatArgs = std::move(*fFormatArgs);
|
||||
fFunctions->push_back(result);
|
||||
}
|
||||
}
|
||||
|
@ -82,6 +82,9 @@ struct Layout {
|
||||
kDefault,
|
||||
kBool,
|
||||
kFloat,
|
||||
kFloat2,
|
||||
kFloat3,
|
||||
kFloat4,
|
||||
kInt32,
|
||||
kSkRect,
|
||||
kSkIRect,
|
||||
|
Loading…
Reference in New Issue
Block a user