Change pipeline stage callbacks to support mangling type names
Structs, enums, and global variables are all going to require name mangling. Move that to a separate virtual on the callback. More importantly, the generator is going to need to do type-name substitution inside the function declaration string, so the contract has shifted: The generator constructs the entire function declaration line (using the mangled name it gets from the new callback), then it calls defineFunction with two strings, and a flag indicating if this is main or not. Bug: skia:10939, skia:11295, skia:11296 Change-Id: I535eee9bfbb2337013b539908fe3d658ec3b2dbd Reviewed-on: https://skia-review.googlesource.com/c/skia/+/368397 Reviewed-by: John Stiles <johnstiles@google.com> Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
0bd5578c31
commit
55761ae5e6
@ -8,7 +8,6 @@
|
||||
#include "src/gpu/GrShaderCaps.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLPipelineStageCodeGenerator.h"
|
||||
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
|
||||
#include "src/sksl/ir/SkSLVarDeclarations.h"
|
||||
#include "src/sksl/ir/SkSLVariable.h"
|
||||
|
||||
@ -34,9 +33,7 @@ bool FuzzSKSL2Pipeline(sk_sp<SkData> bytes) {
|
||||
return decl->var().name();
|
||||
}
|
||||
|
||||
String defineFunction(const SkSL::FunctionDeclaration* decl, String /*body*/) override {
|
||||
return decl->name();
|
||||
}
|
||||
void defineFunction(const char* /*decl*/, const char* /*body*/, bool /*isMain*/) override {}
|
||||
|
||||
String sampleChild(int index, String coords) override {
|
||||
return SkSL::String::printf("sample(%d%s%s)", index, coords.empty() ? "" : ", ",
|
||||
|
@ -71,16 +71,15 @@ public:
|
||||
return String(uniformName);
|
||||
}
|
||||
|
||||
String defineFunction(const SkSL::FunctionDeclaration* decl, String body) override {
|
||||
GrGLSLFPFragmentBuilder* fragBuilder = fArgs.fFragBuilder;
|
||||
if (decl->name() == "main") {
|
||||
fragBuilder->codeAppend(body.c_str());
|
||||
return String("main");
|
||||
String getMangledName(const char* name) override {
|
||||
return String(fArgs.fFragBuilder->getMangledFunctionName(name).c_str());
|
||||
}
|
||||
|
||||
void defineFunction(const char* decl, const char* body, bool isMain) override {
|
||||
if (isMain) {
|
||||
fArgs.fFragBuilder->codeAppend(body);
|
||||
} else {
|
||||
SkString mangledName =
|
||||
fragBuilder->getMangledFunctionName(SkString(decl->name()).c_str());
|
||||
fragBuilder->emitFunction(decl, mangledName.c_str(), body.c_str());
|
||||
return String(mangledName.c_str());
|
||||
fArgs.fFragBuilder->emitFunction(decl, body);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include "src/gpu/glsl/GrGLSLBlend.h"
|
||||
#include "src/gpu/glsl/GrGLSLColorSpaceXformHelper.h"
|
||||
#include "src/gpu/glsl/GrGLSLProgramBuilder.h"
|
||||
#include "src/sksl/ir/SkSLFunctionDeclaration.h"
|
||||
|
||||
GrGLSLShaderBuilder::GrGLSLShaderBuilder(GrGLSLProgramBuilder* program)
|
||||
: fProgramBuilder(program)
|
||||
@ -63,32 +62,6 @@ void GrGLSLShaderBuilder::appendFunctionDecl(GrSLType returnType,
|
||||
this->functions().append(")");
|
||||
}
|
||||
|
||||
void GrGLSLShaderBuilder::appendFunctionDecl(const SkSL::FunctionDeclaration* decl,
|
||||
const char* mangledName) {
|
||||
// This function is similar to decl->description(), but substitutes mangledName, and handles
|
||||
// modifiers on parameters (eg inout).
|
||||
this->functions().appendf("%s %s(", decl->returnType().displayName().c_str(), mangledName);
|
||||
const char* separator = "";
|
||||
for (auto p : decl->parameters()) {
|
||||
// TODO: Handle arrays
|
||||
const char* typeModifier = "";
|
||||
switch (p->modifiers().fFlags & (SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag)) {
|
||||
case SkSL::Modifiers::kOut_Flag:
|
||||
typeModifier = "out ";
|
||||
break;
|
||||
case SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag:
|
||||
typeModifier = "inout ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
this->functions().appendf("%s%s%s %s", separator, typeModifier,
|
||||
p->type().displayName().c_str(), SkString(p->name()).c_str());
|
||||
separator = ", ";
|
||||
}
|
||||
this->functions().append(")");
|
||||
}
|
||||
|
||||
void GrGLSLShaderBuilder::emitFunction(GrSLType returnType,
|
||||
const char* mangledName,
|
||||
SkSpan<const GrShaderVar> args,
|
||||
@ -100,13 +73,10 @@ void GrGLSLShaderBuilder::emitFunction(GrSLType returnType,
|
||||
"}\n\n", body);
|
||||
}
|
||||
|
||||
void GrGLSLShaderBuilder::emitFunction(const SkSL::FunctionDeclaration* decl,
|
||||
const char* mangledName,
|
||||
const char* body) {
|
||||
this->appendFunctionDecl(decl, mangledName);
|
||||
this->functions().appendf(" {\n"
|
||||
void GrGLSLShaderBuilder::emitFunction(const char* declaration, const char* body) {
|
||||
this->functions().appendf("%s {\n"
|
||||
"%s"
|
||||
"}\n\n", body);
|
||||
"}\n\n", declaration, body);
|
||||
}
|
||||
|
||||
void GrGLSLShaderBuilder::emitFunctionPrototype(GrSLType returnType,
|
||||
|
@ -17,10 +17,6 @@
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace SkSL {
|
||||
class FunctionDeclaration;
|
||||
} // namespace SkSL
|
||||
|
||||
class GrGLSLColorSpaceXformHelper;
|
||||
|
||||
/**
|
||||
@ -144,9 +140,7 @@ public:
|
||||
const char* body,
|
||||
bool forceInline = false);
|
||||
|
||||
void emitFunction(const SkSL::FunctionDeclaration* decl,
|
||||
const char* mangledName,
|
||||
const char* body);
|
||||
void emitFunction(const char* declaration, const char* body);
|
||||
|
||||
/**
|
||||
* Combines the various parts of the shader to create a single finalized shader string.
|
||||
@ -184,8 +178,6 @@ protected:
|
||||
SkSpan<const GrShaderVar> args,
|
||||
bool forceInline);
|
||||
|
||||
void appendFunctionDecl(const SkSL::FunctionDeclaration* decl, const char* mangledName);
|
||||
|
||||
/**
|
||||
* Features that should only be enabled internally by the builders.
|
||||
*/
|
||||
|
@ -414,10 +414,10 @@ ResultCode processCommand(std::vector<SkSL::String>& args) {
|
||||
return decl->var().name();
|
||||
}
|
||||
|
||||
String defineFunction(const SkSL::FunctionDeclaration* decl,
|
||||
String body) override {
|
||||
fOutput += (decl->description() + "{" + body + "}");
|
||||
return decl->name();
|
||||
void defineFunction(const char* decl,
|
||||
const char* body,
|
||||
bool /*isMain*/) override {
|
||||
fOutput += String(decl) + "{" + body + "}";
|
||||
}
|
||||
|
||||
String sampleChild(int index, String coords) override {
|
||||
|
@ -56,6 +56,7 @@ private:
|
||||
void write(const String& s);
|
||||
void write(StringFragment s);
|
||||
|
||||
String typeName(const Type& type);
|
||||
void writeType(const Type& type);
|
||||
|
||||
void writeFunction(const FunctionDefinition& f);
|
||||
@ -288,8 +289,36 @@ void PipelineStageCodeGenerator::writeFunction(const FunctionDefinition& f) {
|
||||
fCastReturnsToHalf = false;
|
||||
}
|
||||
|
||||
String fnName = fCallbacks->defineFunction(&f.declaration(), body.fBuffer.str());
|
||||
String fnName =
|
||||
isMain ? "main" : fCallbacks->getMangledName(String(f.declaration().name()).c_str());
|
||||
|
||||
// This is similar to decl->description(), but substitutes a mangled name, and handles
|
||||
// modifiers on parameters (eg inout).
|
||||
const FunctionDeclaration& decl = f.declaration();
|
||||
String declString =
|
||||
String::printf("%s %s(", this->typeName(decl.returnType()).c_str(), fnName.c_str());
|
||||
const char* separator = "";
|
||||
for (auto p : decl.parameters()) {
|
||||
// TODO: Handle arrays
|
||||
const char* typeModifier = "";
|
||||
switch (p->modifiers().fFlags & (SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag)) {
|
||||
case SkSL::Modifiers::kOut_Flag:
|
||||
typeModifier = "out ";
|
||||
break;
|
||||
case SkSL::Modifiers::kIn_Flag | SkSL::Modifiers::kOut_Flag:
|
||||
typeModifier = "inout ";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
declString.appendf("%s%s%s %s", separator, typeModifier, this->typeName(p->type()).c_str(),
|
||||
String(p->name()).c_str());
|
||||
separator = ", ";
|
||||
}
|
||||
declString.append(")");
|
||||
|
||||
fFunctionNames.insert({&f.declaration(), std::move(fnName)});
|
||||
fCallbacks->defineFunction(declString.c_str(), body.fBuffer.str().c_str(), isMain);
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::writeGlobalVarDeclaration(const GlobalVarDeclaration& g) {
|
||||
@ -331,8 +360,12 @@ void PipelineStageCodeGenerator::writeProgramElement(const ProgramElement& e) {
|
||||
}
|
||||
}
|
||||
|
||||
String PipelineStageCodeGenerator::typeName(const Type& type) {
|
||||
return type.name();
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::writeType(const Type& type) {
|
||||
this->write(type.name());
|
||||
this->write(this->typeName(type));
|
||||
}
|
||||
|
||||
void PipelineStageCodeGenerator::writeExpression(const Expression& expr,
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
namespace SkSL {
|
||||
|
||||
class FunctionDeclaration;
|
||||
struct Program;
|
||||
class VarDeclaration;
|
||||
|
||||
@ -22,8 +21,11 @@ namespace PipelineStage {
|
||||
class Callbacks {
|
||||
public:
|
||||
virtual ~Callbacks() = default;
|
||||
|
||||
virtual String getMangledName(const char* name) { return name; }
|
||||
virtual void defineFunction(const char* declaration, const char* body, bool isMain) = 0;
|
||||
|
||||
virtual String declareUniform(const VarDeclaration*) = 0;
|
||||
virtual String defineFunction(const FunctionDeclaration*, String body) = 0;
|
||||
virtual String sampleChild(int index, String coords) = 0;
|
||||
virtual String sampleChildWithMatrix(int index, String matrix) = 0;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user