ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2016 Google Inc. |
| 3 | * |
| 4 | * Use of this source code is governed by a BSD-style license that can be |
| 5 | * found in the LICENSE file. |
| 6 | */ |
Ethan Nicholas | 11d5397 | 2016-11-28 11:23:23 -0500 | [diff] [blame] | 7 | |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 8 | #ifndef SKSL_IRGENERATOR |
| 9 | #define SKSL_IRGENERATOR |
| 10 | |
John Stiles | ddefaee | 2020-08-11 15:13:26 -0400 | [diff] [blame] | 11 | #include <unordered_map> |
John Stiles | b8e010c | 2020-08-11 18:05:39 -0400 | [diff] [blame] | 12 | #include <unordered_set> |
Ethan Nicholas | db80f69 | 2019-11-22 14:06:12 -0500 | [diff] [blame] | 13 | |
Ethan Nicholas | daed259 | 2021-03-04 14:30:25 -0500 | [diff] [blame] | 14 | #include "include/private/SkSLModifiers.h" |
Ethan Nicholas | 24c1772 | 2021-03-09 13:10:59 -0500 | [diff] [blame] | 15 | #include "include/private/SkSLStatement.h" |
John Stiles | 4599050 | 2021-02-16 10:55:27 -0500 | [diff] [blame] | 16 | #include "src/sksl/SkSLOperators.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 17 | #include "src/sksl/ir/SkSLBlock.h" |
| 18 | #include "src/sksl/ir/SkSLExpression.h" |
| 19 | #include "src/sksl/ir/SkSLExtension.h" |
| 20 | #include "src/sksl/ir/SkSLFunctionDefinition.h" |
| 21 | #include "src/sksl/ir/SkSLInterfaceBlock.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 22 | #include "src/sksl/ir/SkSLModifiersDeclaration.h" |
| 23 | #include "src/sksl/ir/SkSLProgram.h" |
Mike Klein | c0bd9f9 | 2019-04-23 12:05:21 -0500 | [diff] [blame] | 24 | #include "src/sksl/ir/SkSLSymbolTable.h" |
| 25 | #include "src/sksl/ir/SkSLType.h" |
| 26 | #include "src/sksl/ir/SkSLTypeReference.h" |
| 27 | #include "src/sksl/ir/SkSLVarDeclarations.h" |
| 28 | #include "src/sksl/ir/SkSLVariableReference.h" |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 29 | |
| 30 | namespace SkSL { |
| 31 | |
Ethan Nicholas | 9504614 | 2021-01-07 10:57:27 -0500 | [diff] [blame] | 32 | namespace dsl { |
Ethan Nicholas | d6b6f3e | 2021-01-22 15:18:25 -0500 | [diff] [blame] | 33 | class DSLCore; |
Ethan Nicholas | df93db9 | 2021-10-04 15:35:59 -0400 | [diff] [blame] | 34 | class DSLExpression; |
Ethan Nicholas | 1ff7609 | 2021-01-28 10:02:43 -0500 | [diff] [blame] | 35 | class DSLFunction; |
Ethan Nicholas | df93db9 | 2021-10-04 15:35:59 -0400 | [diff] [blame] | 36 | class DSLGlobalVar; |
Ethan Nicholas | d6b6f3e | 2021-01-22 15:18:25 -0500 | [diff] [blame] | 37 | class DSLVar; |
Ethan Nicholas | 9504614 | 2021-01-07 10:57:27 -0500 | [diff] [blame] | 38 | class DSLWriter; |
| 39 | } |
| 40 | |
Brian Osman | be0b3b7 | 2021-01-06 14:27:35 -0500 | [diff] [blame] | 41 | class ExternalFunction; |
Ethan Nicholas | 1e9f7f3 | 2020-10-08 05:28:32 -0400 | [diff] [blame] | 42 | class FunctionCall; |
John Stiles | dc75a97 | 2020-11-25 16:24:55 -0500 | [diff] [blame] | 43 | class StructDefinition; |
Brian Osman | 3d87e9f | 2020-10-08 11:50:22 -0400 | [diff] [blame] | 44 | struct ParsedModule; |
Ethan Nicholas | cb0f409 | 2019-04-19 11:26:50 -0400 | [diff] [blame] | 45 | struct Swizzle; |
| 46 | |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 47 | /** |
Ethan Nicholas | 11d5397 | 2016-11-28 11:23:23 -0500 | [diff] [blame] | 48 | * Performs semantic analysis on an abstract syntax tree (AST) and produces the corresponding |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 49 | * (unoptimized) intermediate representation (IR). |
| 50 | */ |
| 51 | class IRGenerator { |
| 52 | public: |
John Stiles | c1a98b8 | 2021-02-24 13:35:02 -0500 | [diff] [blame] | 53 | IRGenerator(const Context* context); |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 54 | |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 55 | struct IRBundle { |
| 56 | std::vector<std::unique_ptr<ProgramElement>> fElements; |
Brian Osman | 133724c | 2020-10-28 14:14:39 -0400 | [diff] [blame] | 57 | std::vector<const ProgramElement*> fSharedElements; |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 58 | std::shared_ptr<SymbolTable> fSymbolTable; |
| 59 | Program::Inputs fInputs; |
| 60 | }; |
| 61 | |
| 62 | /** |
John Stiles | aecf8d5 | 2021-05-14 12:15:01 -0400 | [diff] [blame] | 63 | * If externalFunctions is supplied, those values are registered in the symbol table of the |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 64 | * Program, but ownership is *not* transferred. It is up to the caller to keep them alive. |
| 65 | */ |
Brian Osman | be0b3b7 | 2021-01-06 14:27:35 -0500 | [diff] [blame] | 66 | IRBundle convertProgram( |
Brian Osman | be0b3b7 | 2021-01-06 14:27:35 -0500 | [diff] [blame] | 67 | const ParsedModule& base, |
| 68 | bool isBuiltinCode, |
Ethan Nicholas | 6823b50 | 2021-06-15 11:42:07 -0400 | [diff] [blame] | 69 | skstd::string_view text); |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 70 | |
John Stiles | d120464 | 2021-02-17 16:30:02 -0500 | [diff] [blame] | 71 | const Program::Settings& settings() const { return fContext.fConfig->fSettings; } |
| 72 | ProgramKind programKind() const { return fContext.fConfig->fKind; } |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 73 | |
Ethan Nicholas | 39f6da4 | 2021-08-23 13:10:07 -0400 | [diff] [blame] | 74 | ErrorReporter& errorReporter() const { return *fContext.fErrors; } |
John Stiles | dc8ec31 | 2021-01-11 11:05:21 -0500 | [diff] [blame] | 75 | |
Ethan Nicholas | ba9a04f | 2020-11-06 09:28:04 -0500 | [diff] [blame] | 76 | std::shared_ptr<SymbolTable>& symbolTable() { |
| 77 | return fSymbolTable; |
| 78 | } |
| 79 | |
| 80 | void setSymbolTable(std::shared_ptr<SymbolTable>& symbolTable) { |
| 81 | fSymbolTable = symbolTable; |
| 82 | } |
| 83 | |
Ethan Nicholas | 371f6e1 | 2021-05-04 14:30:02 -0400 | [diff] [blame] | 84 | static void CheckModifiers(const Context& context, |
Ethan Nicholas | 89cfde1 | 2021-09-27 11:20:34 -0400 | [diff] [blame] | 85 | int line, |
Ethan Nicholas | 371f6e1 | 2021-05-04 14:30:02 -0400 | [diff] [blame] | 86 | const Modifiers& modifiers, |
| 87 | int permittedModifierFlags, |
| 88 | int permittedLayoutFlags); |
| 89 | |
Ethan Nicholas | 89cfde1 | 2021-09-27 11:20:34 -0400 | [diff] [blame] | 90 | std::unique_ptr<Expression> convertIdentifier(int line, skstd::string_view identifier); |
Ethan Nicholas | 722cb67 | 2021-05-06 10:47:06 -0400 | [diff] [blame] | 91 | |
Ethan Nicholas | 494eb3e | 2021-08-27 19:17:01 -0400 | [diff] [blame] | 92 | bool haveRTAdjustInterfaceBlock() { return fRTAdjustInterfaceBlock != nullptr; } |
| 93 | |
| 94 | int getRTAdjustFieldIndex() { return fRTAdjustFieldIndex; } |
| 95 | |
Ethan Nicholas | 86a4340 | 2017-01-19 13:32:00 -0500 | [diff] [blame] | 96 | const Context& fContext; |
Ethan Nicholas | 941e7e2 | 2016-12-12 15:33:30 -0500 | [diff] [blame] | 97 | |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 98 | private: |
Ethan Nicholas | 8b3dd34 | 2021-03-23 12:32:56 -0400 | [diff] [blame] | 99 | void start(const ParsedModule& base, |
Ethan Nicholas | 8b3dd34 | 2021-03-23 12:32:56 -0400 | [diff] [blame] | 100 | std::vector<std::unique_ptr<ProgramElement>>* elements, |
| 101 | std::vector<const ProgramElement*>* sharedElements); |
| 102 | |
| 103 | IRGenerator::IRBundle finish(); |
| 104 | |
Ethan Nicholas | 89cfde1 | 2021-09-27 11:20:34 -0400 | [diff] [blame] | 105 | void checkVarDeclaration(int line, |
Brian Osman | a654faa | 2021-02-26 11:52:59 -0500 | [diff] [blame] | 106 | const Modifiers& modifiers, |
| 107 | const Type* baseType, |
Ethan Nicholas | 489e552 | 2021-01-20 10:53:11 -0500 | [diff] [blame] | 108 | Variable::Storage storage); |
Ethan Nicholas | 89cfde1 | 2021-09-27 11:20:34 -0400 | [diff] [blame] | 109 | std::unique_ptr<Variable> convertVar(int line, const Modifiers& modifiers, |
Ethan Nicholas | 962dec4 | 2021-06-10 13:06:39 -0400 | [diff] [blame] | 110 | const Type* baseType, skstd::string_view name, |
| 111 | bool isArray, std::unique_ptr<Expression> arraySize, |
Ethan Nicholas | bd97400 | 2021-02-22 16:20:06 -0500 | [diff] [blame] | 112 | Variable::Storage storage); |
| 113 | std::unique_ptr<Statement> convertVarDeclaration(std::unique_ptr<Variable> var, |
Ethan Nicholas | dd2fdea | 2021-07-20 15:23:04 -0400 | [diff] [blame] | 114 | std::unique_ptr<Expression> value, |
| 115 | bool addToSymbolTable = true); |
Ethan Nicholas | 89cfde1 | 2021-09-27 11:20:34 -0400 | [diff] [blame] | 116 | std::unique_ptr<Statement> convertVarDeclaration(int line, const Modifiers& modifiers, |
Ethan Nicholas | 962dec4 | 2021-06-10 13:06:39 -0400 | [diff] [blame] | 117 | const Type* baseType, skstd::string_view name, |
Ethan Nicholas | 489e552 | 2021-01-20 10:53:11 -0500 | [diff] [blame] | 118 | bool isArray, |
| 119 | std::unique_ptr<Expression> arraySize, |
| 120 | std::unique_ptr<Expression> value, |
| 121 | Variable::Storage storage); |
Ethan Nicholas | 494eb3e | 2021-08-27 19:17:01 -0400 | [diff] [blame] | 122 | void scanInterfaceBlock(SkSL::InterfaceBlock& intf); |
John Stiles | 3b20489 | 2021-08-27 17:35:35 -0400 | [diff] [blame] | 123 | /** Appends sk_Position fixup to the bottom of main() if this is a vertex program. */ |
| 124 | void appendRTAdjustFixupToVertexMain(const FunctionDeclaration& decl, Block* body); |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 125 | |
Brian Osman | 818fd6d | 2020-12-30 15:06:22 -0500 | [diff] [blame] | 126 | // Runtime effects (and the interpreter, which uses the same CPU runtime) require adherence to |
| 127 | // the strict rules from The OpenGL ES Shading Language Version 1.00. (Including Appendix A). |
| 128 | bool strictES2Mode() const { |
John Stiles | ca107c9 | 2021-02-19 09:54:44 -0500 | [diff] [blame] | 129 | return fContext.fConfig->strictES2Mode(); |
Brian Osman | 818fd6d | 2020-12-30 15:06:22 -0500 | [diff] [blame] | 130 | } |
| 131 | |
John Stiles | bb2ef92 | 2021-07-26 08:32:07 -0400 | [diff] [blame] | 132 | bool isRuntimeEffect() const { |
John Stiles | addccaf | 2021-08-02 19:03:30 -0400 | [diff] [blame] | 133 | return ProgramConfig::IsRuntimeEffect(fContext.fConfig->fKind); |
John Stiles | bb2ef92 | 2021-07-26 08:32:07 -0400 | [diff] [blame] | 134 | } |
| 135 | |
John Stiles | c1a98b8 | 2021-02-24 13:35:02 -0500 | [diff] [blame] | 136 | const ShaderCapsClass& caps() const { |
| 137 | return fContext.fCaps; |
| 138 | } |
| 139 | |
John Stiles | f2872e6 | 2021-05-04 11:38:43 -0400 | [diff] [blame] | 140 | ModifiersPool& modifiersPool() const { |
John Stiles | 10d39d9 | 2021-05-04 16:13:14 -0400 | [diff] [blame] | 141 | return *fContext.fModifiersPool; |
John Stiles | f2872e6 | 2021-05-04 11:38:43 -0400 | [diff] [blame] | 142 | } |
| 143 | |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 144 | Program::Inputs fInputs; |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 145 | |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 146 | std::shared_ptr<SymbolTable> fSymbolTable = nullptr; |
Brian Osman | 02bc522 | 2021-01-28 11:00:20 -0500 | [diff] [blame] | 147 | std::unordered_set<const Type*> fDefinedStructs; |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 148 | std::vector<std::unique_ptr<ProgramElement>>* fProgramElements = nullptr; |
Brian Osman | 133724c | 2020-10-28 14:14:39 -0400 | [diff] [blame] | 149 | std::vector<const ProgramElement*>* fSharedElements = nullptr; |
Brian Osman | 88cda17 | 2020-10-09 12:05:16 -0400 | [diff] [blame] | 150 | const Variable* fRTAdjust = nullptr; |
| 151 | const Variable* fRTAdjustInterfaceBlock = nullptr; |
Robert Phillips | fe8da17 | 2018-01-24 14:52:02 +0000 | [diff] [blame] | 152 | int fRTAdjustFieldIndex; |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 153 | |
| 154 | friend class AutoSymbolTable; |
ethannicholas | 22f939e | 2016-10-13 13:25:34 -0700 | [diff] [blame] | 155 | friend class AutoLoopLevel; |
Ethan Nicholas | af19769 | 2017-02-27 13:26:45 -0500 | [diff] [blame] | 156 | friend class AutoSwitchLevel; |
John Stiles | d1c4dac | 2020-08-11 18:50:50 -0400 | [diff] [blame] | 157 | friend class AutoDisableInline; |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 158 | friend class Compiler; |
Ethan Nicholas | dd2fdea | 2021-07-20 15:23:04 -0400 | [diff] [blame] | 159 | friend class DSLParser; |
Ethan Nicholas | c845272 | 2021-10-07 10:47:32 -0400 | [diff] [blame] | 160 | friend class ThreadContext; |
Ethan Nicholas | d6b6f3e | 2021-01-22 15:18:25 -0500 | [diff] [blame] | 161 | friend class dsl::DSLCore; |
Ethan Nicholas | df93db9 | 2021-10-04 15:35:59 -0400 | [diff] [blame] | 162 | friend class dsl::DSLExpression; |
Ethan Nicholas | 1ff7609 | 2021-01-28 10:02:43 -0500 | [diff] [blame] | 163 | friend class dsl::DSLFunction; |
Ethan Nicholas | df93db9 | 2021-10-04 15:35:59 -0400 | [diff] [blame] | 164 | friend class dsl::DSLGlobalVar; |
Ethan Nicholas | d6b6f3e | 2021-01-22 15:18:25 -0500 | [diff] [blame] | 165 | friend class dsl::DSLVar; |
Ethan Nicholas | 9504614 | 2021-01-07 10:57:27 -0500 | [diff] [blame] | 166 | friend class dsl::DSLWriter; |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 167 | }; |
| 168 | |
John Stiles | a6841be | 2020-08-06 14:11:56 -0400 | [diff] [blame] | 169 | } // namespace SkSL |
ethannicholas | b3058bd | 2016-07-01 08:22:01 -0700 | [diff] [blame] | 170 | |
| 171 | #endif |