Add new sksl-precompile binary to tools.
This binary will be compiled when the gn flag `skia_compile_modules` is set. sksl-precompile will replace for skslc for module precompilation in a followup. Change-Id: I217127169b091f97c2e4d11e0deb655ceac84425 Bug: skia:13164 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/527838 Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com> Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
2a04ac3ee1
commit
156952dc7b
24
BUILD.gn
24
BUILD.gn
@ -628,6 +628,30 @@ if (skia_lex) {
|
||||
}
|
||||
}
|
||||
|
||||
# Build sksl-precompile when the compile-modules flag is set.
|
||||
# TODO(skia:13164): skslc is still in charge of module compilation for now
|
||||
if (skia_compile_modules) {
|
||||
skia_executable("sksl-precompile") {
|
||||
defines = [
|
||||
"SKSL_STANDALONE",
|
||||
"SK_DISABLE_TRACING",
|
||||
]
|
||||
sources = skslc_deps
|
||||
sources += [ "tools/sksl-precompile/SkSLPrecompile.cpp" ]
|
||||
libs = []
|
||||
if (is_win) {
|
||||
sources += [ "src/ports/SkOSFile_win.cpp" ]
|
||||
} else {
|
||||
sources += [ "src/ports/SkOSFile_posix.cpp" ]
|
||||
libs += [ "dl" ]
|
||||
}
|
||||
sources += skia_sksl_sources
|
||||
sources += skia_sksl_gpu_sources
|
||||
include_dirs = [ "." ]
|
||||
deps = [ ":run_sksllex" ]
|
||||
}
|
||||
}
|
||||
|
||||
# `Compile SkSL Tests` relies on skslc.
|
||||
if (skia_compile_sksl_tests) {
|
||||
skia_executable("skslc") {
|
||||
|
@ -10,6 +10,7 @@ is_skia_dev_build = is_skia_standalone && !is_official_build
|
||||
|
||||
declare_args() {
|
||||
skia_android_serial = ""
|
||||
skia_compile_modules = false
|
||||
skia_compile_sksl_tests = false
|
||||
skia_enable_api_available_macro = true
|
||||
skia_enable_android_utils = is_skia_dev_build
|
||||
|
@ -136,6 +136,7 @@ def compile_fn(api, checkout_root, out_dir):
|
||||
|
||||
if 'CheckGeneratedFiles' in extra_tokens:
|
||||
compiler = 'Clang'
|
||||
args['skia_compile_modules'] = 'true'
|
||||
args['skia_compile_sksl_tests'] = 'true'
|
||||
args['skia_generate_workarounds'] = 'true'
|
||||
|
||||
|
@ -66,7 +66,7 @@
|
||||
"[START_DIR]/cache/work/skia/bin/gn",
|
||||
"gen",
|
||||
"[START_DIR]/cache/work/skia/out/Housekeeper-PerCommit-CheckGeneratedFiles/Release",
|
||||
"--args=cc=\"[START_DIR]/clang_linux/bin/clang\" cc_wrapper=\"[START_DIR]/ccache_linux/bin/ccache\" cxx=\"[START_DIR]/clang_linux/bin/clang++\" extra_cflags=[\"-B[START_DIR]/clang_linux/bin\", \"-DPLACEHOLDER_clang_linux_version=42\"] extra_ldflags=[\"-B[START_DIR]/clang_linux/bin\", \"-fuse-ld=lld\", \"-L[START_DIR]/clang_linux/lib\"] is_debug=false skia_compile_sksl_tests=true skia_generate_workarounds=true werror=true"
|
||||
"--args=cc=\"[START_DIR]/clang_linux/bin/clang\" cc_wrapper=\"[START_DIR]/ccache_linux/bin/ccache\" cxx=\"[START_DIR]/clang_linux/bin/clang++\" extra_cflags=[\"-B[START_DIR]/clang_linux/bin\", \"-DPLACEHOLDER_clang_linux_version=42\"] extra_ldflags=[\"-B[START_DIR]/clang_linux/bin\", \"-fuse-ld=lld\", \"-L[START_DIR]/clang_linux/lib\"] is_debug=false skia_compile_modules=true skia_compile_sksl_tests=true skia_generate_workarounds=true werror=true"
|
||||
],
|
||||
"cwd": "[START_DIR]/cache/work/skia",
|
||||
"env": {
|
||||
|
@ -271,7 +271,7 @@
|
||||
"[START_DIR]/cache/work/skia/bin/gn",
|
||||
"gen",
|
||||
"[START_DIR]/build/out/Release",
|
||||
"--args=cc=\"[START_DIR]/clang_linux/bin/clang\" cc_wrapper=\"[START_DIR]/ccache_linux/bin/ccache\" cxx=\"[START_DIR]/clang_linux/bin/clang++\" extra_cflags=[\"-B[START_DIR]/clang_linux/bin\", \"-DPLACEHOLDER_clang_linux_version=42\"] extra_ldflags=[\"-B[START_DIR]/clang_linux/bin\", \"-fuse-ld=lld\", \"-L[START_DIR]/clang_linux/lib\"] is_debug=false skia_compile_sksl_tests=true skia_generate_workarounds=true werror=true"
|
||||
"--args=cc=\"[START_DIR]/clang_linux/bin/clang\" cc_wrapper=\"[START_DIR]/ccache_linux/bin/ccache\" cxx=\"[START_DIR]/clang_linux/bin/clang++\" extra_cflags=[\"-B[START_DIR]/clang_linux/bin\", \"-DPLACEHOLDER_clang_linux_version=42\"] extra_ldflags=[\"-B[START_DIR]/clang_linux/bin\", \"-fuse-ld=lld\", \"-L[START_DIR]/clang_linux/lib\"] is_debug=false skia_compile_modules=true skia_compile_sksl_tests=true skia_generate_workarounds=true werror=true"
|
||||
],
|
||||
"cwd": "[START_DIR]/cache/work/skia",
|
||||
"env": {
|
||||
|
24
tools/sksl-precompile/BUILD.bazel
Normal file
24
tools/sksl-precompile/BUILD.bazel
Normal file
@ -0,0 +1,24 @@
|
||||
load("//bazel:macros.bzl", "generated_cc_atom")
|
||||
|
||||
generated_cc_atom(
|
||||
name = "SkSLPrecompile_src",
|
||||
srcs = ["SkSLPrecompile.cpp"],
|
||||
visibility = ["//:__subpackages__"],
|
||||
deps = [
|
||||
"//include/core:SkGraphics_hdr",
|
||||
"//include/core:SkStream_hdr",
|
||||
"//include/private:SkStringView_hdr",
|
||||
"//src/core:SkCpu_hdr",
|
||||
"//src/core:SkOpts_hdr",
|
||||
"//src/opts:SkChecksum_opts_hdr",
|
||||
"//src/opts:SkVM_opts_hdr",
|
||||
"//src/sksl:SkSLCompiler_hdr",
|
||||
"//src/sksl:SkSLDehydrator_hdr",
|
||||
"//src/sksl:SkSLFileOutputStream_hdr",
|
||||
"//src/sksl:SkSLStringStream_hdr",
|
||||
"//src/sksl:SkSLUtil_hdr",
|
||||
"//src/sksl/ir:SkSLUnresolvedFunction_hdr",
|
||||
"//src/sksl/ir:SkSLVarDeclarations_hdr",
|
||||
"//src/utils:SkShaderUtils_hdr",
|
||||
],
|
||||
)
|
149
tools/sksl-precompile/SkSLPrecompile.cpp
Normal file
149
tools/sksl-precompile/SkSLPrecompile.cpp
Normal file
@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2022 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#define SK_OPTS_NS sksl_precompile_standalone
|
||||
#include "include/core/SkGraphics.h"
|
||||
#include "include/core/SkStream.h"
|
||||
#include "include/private/SkStringView.h"
|
||||
#include "src/core/SkCpu.h"
|
||||
#include "src/core/SkOpts.h"
|
||||
#include "src/opts/SkChecksum_opts.h"
|
||||
#include "src/opts/SkVM_opts.h"
|
||||
#include "src/sksl/SkSLCompiler.h"
|
||||
#include "src/sksl/SkSLDehydrator.h"
|
||||
#include "src/sksl/SkSLFileOutputStream.h"
|
||||
#include "src/sksl/SkSLStringStream.h"
|
||||
#include "src/sksl/SkSLUtil.h"
|
||||
#include "src/sksl/ir/SkSLUnresolvedFunction.h"
|
||||
#include "src/sksl/ir/SkSLVarDeclarations.h"
|
||||
#include "src/utils/SkShaderUtils.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <limits.h>
|
||||
#include <optional>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void SkDebugf(const char format[], ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vfprintf(stderr, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
namespace SkOpts {
|
||||
decltype(hash_fn) hash_fn = sksl_precompile_standalone::hash_fn;
|
||||
decltype(interpret_skvm) interpret_skvm;
|
||||
}
|
||||
|
||||
enum class ResultCode {
|
||||
kSuccess = 0,
|
||||
kCompileError = 1,
|
||||
kInputError = 2,
|
||||
kOutputError = 3,
|
||||
};
|
||||
|
||||
// Given the path to a file (e.g. src/gpu/effects/GrFooFragmentProcessor.fp) and the expected
|
||||
// filename prefix and suffix (e.g. "Gr" and ".fp"), returns the "base name" of the
|
||||
// file (in this case, 'FooFragmentProcessor'). If no match, returns the empty string.
|
||||
static std::string base_name(const std::string& fpPath, const char* prefix, const char* suffix) {
|
||||
std::string result;
|
||||
const char* end = &*fpPath.end();
|
||||
const char* fileName = end;
|
||||
// back up until we find a slash
|
||||
while (fileName != fpPath && '/' != *(fileName - 1) && '\\' != *(fileName - 1)) {
|
||||
--fileName;
|
||||
}
|
||||
if (!strncmp(fileName, prefix, strlen(prefix)) &&
|
||||
!strncmp(end - strlen(suffix), suffix, strlen(suffix))) {
|
||||
result.append(fileName + strlen(prefix), end - fileName - strlen(prefix) - strlen(suffix));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays a usage banner; used when the command line arguments don't make sense.
|
||||
*/
|
||||
static void show_usage() {
|
||||
printf("usage: sksl-precompile <output> <input>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle a single input.
|
||||
*/
|
||||
ResultCode processCommand(const std::vector<std::string>& paths) {
|
||||
if (paths.size() != 2) {
|
||||
show_usage();
|
||||
return ResultCode::kInputError;
|
||||
}
|
||||
|
||||
const std::string& outputPath = paths[0];
|
||||
const std::string& inputPath = paths[1];
|
||||
SkSL::ProgramKind kind = SkSL::ProgramKind::kFragment;
|
||||
|
||||
std::ifstream in(inputPath);
|
||||
std::string text((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
|
||||
if (in.rdstate()) {
|
||||
printf("error reading '%s'\n", inputPath.c_str());
|
||||
return ResultCode::kInputError;
|
||||
}
|
||||
|
||||
SkSL::Program::Settings settings;
|
||||
auto standaloneCaps = SkSL::ShaderCapsFactory::Standalone();
|
||||
const SkSL::ShaderCaps* caps = standaloneCaps.get();
|
||||
|
||||
// This tells the compiler where the rt-flip uniform will live should it be required. For
|
||||
// testing purposes we don't care where that is, but the compiler will report an error if we
|
||||
// leave them at their default invalid values, or if the offset overlaps another uniform.
|
||||
settings.fRTFlipOffset = 16384;
|
||||
settings.fRTFlipSet = 0;
|
||||
settings.fRTFlipBinding = 0;
|
||||
|
||||
// Load in the input file as a module.
|
||||
SkSL::FileOutputStream out(outputPath.c_str());
|
||||
SkSL::Compiler compiler(caps);
|
||||
if (!out.isValid()) {
|
||||
printf("error writing '%s'\n", outputPath.c_str());
|
||||
return ResultCode::kOutputError;
|
||||
}
|
||||
SkSL::LoadedModule module =
|
||||
compiler.loadModule(kind, SkSL::Compiler::MakeModulePath(inputPath.c_str()),
|
||||
/*base=*/nullptr, /*dehydrate=*/true);
|
||||
|
||||
// Dehydrate the input file into a buffer.
|
||||
SkSL::Dehydrator dehydrator;
|
||||
dehydrator.write(*module.fSymbols);
|
||||
dehydrator.write(module.fElements);
|
||||
std::string baseName = base_name(inputPath, "", ".sksl");
|
||||
SkSL::StringStream buffer;
|
||||
dehydrator.finish(buffer);
|
||||
const std::string& data = buffer.str();
|
||||
|
||||
// Emit the dehydrated data into our output file.
|
||||
out.printf("static uint8_t SKSL_INCLUDE_%s[] = {", baseName.c_str());
|
||||
for (size_t i = 0; i < data.length(); ++i) {
|
||||
out.printf("%s%d,", dehydrator.prefixAtOffset(i), uint8_t(data[i]));
|
||||
}
|
||||
out.printf("};\n");
|
||||
out.printf("static constexpr size_t SKSL_INCLUDE_%s_LENGTH = sizeof(SKSL_INCLUDE_%s);\n",
|
||||
baseName.c_str(), baseName.c_str());
|
||||
if (!out.close()) {
|
||||
printf("error writing '%s'\n", outputPath.c_str());
|
||||
return ResultCode::kOutputError;
|
||||
}
|
||||
|
||||
return ResultCode::kSuccess;
|
||||
}
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
std::vector<std::string> args;
|
||||
for (int index=1; index<argc; ++index) {
|
||||
args.push_back(argv[index]);
|
||||
}
|
||||
|
||||
return (int)processCommand(args);
|
||||
}
|
Loading…
Reference in New Issue
Block a user