Handle a single input.
513 {
514 std::optional<bool> honorSettings;
515 std::vector<std::string> paths;
516 for (
size_t i = 1; i <
args.size(); ++i) {
517 const std::string& arg =
args[i];
518 if (arg == "--settings") {
519 if (!
set_flag(&honorSettings,
"settings",
true)) {
521 }
522 } else if (arg == "--nosettings") {
523 if (!
set_flag(&honorSettings,
"settings",
false)) {
525 }
527 paths.push_back(arg);
528 } else {
531 }
532 }
533 if (paths.size() != 2) {
536 }
537
538 if (!honorSettings.has_value()) {
539 honorSettings = true;
540 }
541
542 const std::string& inputPath = paths[0];
543 const std::string& outputPath = paths[1];
561 } else {
562 printf(
"input filename must end in '.vert', '.frag', '.mvert', '.mfrag', '.compute', "
563 "'.rtb', '.rtcf', '.rts' or '.sksl'\n");
565 }
566
567 std::ifstream in(inputPath);
568 std::string
text((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
569 if (in.rdstate()) {
570 printf(
"error reading '%s'\n", inputPath.c_str());
572 }
573
576 std::unique_ptr<SkSL::DebugTracePriv> debugTrace;
577 if (*honorSettings) {
580 }
581 }
582
583
584
585
589
590 auto emitCompileError = [&](const char* errorText) {
591
593 errorStream.writeText("### Compilation failed:\n\n");
594 errorStream.writeText(errorText);
595 errorStream.close();
596
597 puts(errorText);
598 };
599
600 auto compileProgram = [&](
const auto& writeFn) ->
ResultCode {
603 if (!
out.isValid()) {
604 printf(
"error writing '%s'\n", outputPath.c_str());
606 }
607 std::unique_ptr<SkSL::Program> program =
compiler.convertProgram(kind,
text, settings);
608 if (!program || !writeFn(
compiler, caps, *program, out)) {
610 emitCompileError(
compiler.errorText().c_str());
612 }
614 printf(
"error writing '%s'\n", outputPath.c_str());
616 }
618 };
619
620 auto compileProgramAsRuntimeShader = [&](
const auto& writeFn) ->
ResultCode {
622 emitCompileError("Runtime shaders do not support vertex programs\n");
624 }
626
628 }
629 return compileProgram(writeFn);
630 };
631
638 });
642 return compileProgram(
647
650 return false;
651 }
652
653 spvtools::SpirvTools
tools(SPV_ENV_VULKAN_1_0);
654 const std::string& spirv(assembly.
str());
655 std::string disassembly;
656 uint32_t
options = spvtools::SpirvTools::kDefaultDisassembleOption;
657 options |= SPV_BINARY_TO_TEXT_OPTION_INDENT;
658 if (!
tools.Disassemble((
const uint32_t*)spirv.data(),
659 spirv.size() / 4,
660 &disassembly,
662 return false;
663 }
664
665 out.write(disassembly.data(), disassembly.size());
666 return true;
667 });
669 return compileProgram(
675 return compileProgram(
681 return compileProgram(
687 return compileProgram(
701 compiler.errorReporter().
error({},
"code has no entrypoint");
702 return false;
703 }
704 bool wantTraceOps = (debugTrace != nullptr);
706 program, *
main->definition(), &skrpDebugTrace, wantTraceOps);
707 if (!rasterProg) {
708 compiler.errorReporter().error({},
"code is not supported");
709 return false;
710 }
712 return true;
713 });
720 public:
722 return std::string(
name) +
"_0";
723 }
724
727 return std::string(decl->
var()->
name());
728 }
729
730 void defineFunction(
const char* decl,
const char* body,
bool )
override {
731 fOutput += std::string(decl) + '{' + body + '}';
732 }
733
735
736 void defineStruct(
const char* definition)
override { fOutput += definition; }
737
738 void declareGlobal(
const char* declaration)
override { fOutput += declaration; }
739
740 std::string
sampleShader(
int index, std::string coords)
override {
741 return "child_" + std::to_string(index) + ".eval(" + coords + ')';
742 }
743
745 return "child_" + std::to_string(index) +
".eval(" +
color +
')';
746 }
747
748 std::string
sampleBlender(
int index, std::string src, std::string dst)
override {
749 return "child_" + std::to_string(index) +
".eval(" +
src +
", " +
dst +
')';
750 }
751
753 return "toLinearSrgb(" +
color +
')';
754 }
756 return "fromLinearSrgb(" +
color +
')';
757 }
758
759 std::string fOutput;
760 };
761
762
763
764
765
766
767
768
769
770
771
772 Callbacks callbacks;
774 "_canvasColor", &callbacks);
776 return true;
777 });
778 } else {
779 printf(
"expected output path to end with one of: .glsl, .html, .metal, .hlsl, .wgsl, "
780 ".spirv, .asm.vert, .asm.frag, .asm.comp, .skrp, .stage (got '%s')\n",
781 outputPath.c_str());
783 }
785}
virtual std::string sampleShader(int index, std::string coords)=0
virtual std::string sampleBlender(int index, std::string src, std::string dst)=0
virtual void defineStruct(const char *definition)=0
virtual void declareFunction(const char *declaration)=0
virtual std::string toLinearSrgb(std::string color)=0
virtual void declareGlobal(const char *declaration)=0
virtual std::string sampleColorFilter(int index, std::string color)=0
virtual std::string fromLinearSrgb(std::string color)=0
virtual void defineFunction(const char *declaration, const char *body, bool isMain)=0
virtual std::string declareUniform(const VarDeclaration *)=0
virtual std::string getMangledName(const char *name)
static const ShaderCaps * Standalone()
const std::string & str() const
std::string_view name() const
std::string description() const override
const uint8_t uint32_t uint32_t GError ** error
void ConvertProgram(const Program &program, const char *sampleCoords, const char *inputColor, const char *destColor, Callbacks *callbacks)
bool ToSPIRV(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToWGSL(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToGLSL(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToMetal(Program &program, const ShaderCaps *caps, OutputStream &out)
bool ToHLSL(Program &program, const ShaderCaps *caps, OutputStream &out)
std::unique_ptr< RP::Program > MakeRasterPipelineProgram(const SkSL::Program &program, const FunctionDefinition &function, DebugTracePriv *debugTrace, bool writeTraceOps)
std::string PrettyPrint(const std::string &string)
const myers::Point & get(const myers::Segment &)
constexpr bool starts_with(std::string_view str, std::string_view prefix)
const FunctionDeclaration * getFunction(const char *functionName) const
static std::unique_ptr< SkWStream > as_SkWStream(SkSL::OutputStream &s)
static bool set_flag(std::optional< bool > *flag, const char *name, bool value)
static bool detect_shader_settings(const std::string &text, SkSL::ProgramSettings *settings, const SkSL::ShaderCaps **caps, std::unique_ptr< SkSL::DebugTracePriv > *debugTrace)