690b6f3a92
There is now PipelineStage::ConvertProgram, which takes a collection of callbacks, and processes an entire program. For program objects that may need name mangling, the callbacks return the new name, which is recorded and used for future references to that object (eg uniforms & functions). The callbacks let the FP inject new elements programmatically: - Declare uniforms and get handles - Emit child functions - Invoke child processors for calls to sample() In a follow-up CL, we can add an skslc `.rte -> .sksl` mode, where the callbacks just emit the description() of the relevant element. We can also follow the same pattern to emit declarations of types (structs, enums), and global variables. Change-Id: I81df68a2f41bcb48f866d37af3b77ad43e880236 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/367058 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
67 lines
2.2 KiB
C++
67 lines
2.2 KiB
C++
/*
|
|
* Copyright 2019 Google, LLC
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#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"
|
|
|
|
#include "fuzz/Fuzz.h"
|
|
|
|
bool FuzzSKSL2Pipeline(sk_sp<SkData> bytes) {
|
|
sk_sp<GrShaderCaps> caps = SkSL::ShaderCapsFactory::Default();
|
|
SkSL::Compiler compiler(caps.get());
|
|
SkSL::Program::Settings settings;
|
|
std::unique_ptr<SkSL::Program> program = compiler.convertProgram(
|
|
SkSL::Program::kRuntimeEffect_Kind,
|
|
SkSL::String((const char*) bytes->data(),
|
|
bytes->size()),
|
|
settings);
|
|
if (!program) {
|
|
return false;
|
|
}
|
|
|
|
class Callbacks : public SkSL::PipelineStage::Callbacks {
|
|
using String = SkSL::String;
|
|
|
|
String declareUniform(const SkSL::VarDeclaration* decl) override {
|
|
return decl->var().name();
|
|
}
|
|
|
|
String defineFunction(const SkSL::FunctionDeclaration* decl, String /*body*/) override {
|
|
return decl->name();
|
|
}
|
|
|
|
String sampleChild(int index, String coords) override {
|
|
return SkSL::String::printf("sample(%d%s%s)", index, coords.empty() ? "" : ", ",
|
|
coords.c_str());
|
|
}
|
|
|
|
String sampleChildWithMatrix(int index, String matrix) override {
|
|
return SkSL::String::printf("sample(%d%s%s)", index, matrix.empty() ? "" : ", ",
|
|
matrix.c_str());
|
|
}
|
|
};
|
|
|
|
Callbacks callbacks;
|
|
SkSL::PipelineStage::ConvertProgram(*program, "coords", &callbacks);
|
|
return true;
|
|
}
|
|
|
|
#if defined(SK_BUILD_FOR_LIBFUZZER)
|
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|
if (size > 3000) {
|
|
return 0;
|
|
}
|
|
auto bytes = SkData::MakeWithoutCopy(data, size);
|
|
FuzzSKSL2Pipeline(bytes);
|
|
return 0;
|
|
}
|
|
#endif
|