blob: 992016eafdefa60c6e727a09975c6b5dd954a93b [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 Nicholas11d53972016-11-28 11:23:23 -05007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_IRGENERATOR
9#define SKSL_IRGENERATOR
10
John Stilesddefaee2020-08-11 15:13:26 -040011#include <unordered_map>
John Stilesb8e010c2020-08-11 18:05:39 -040012#include <unordered_set>
Ethan Nicholasdb80f692019-11-22 14:06:12 -050013
Ethan Nicholasdaed2592021-03-04 14:30:25 -050014#include "include/private/SkSLModifiers.h"
Ethan Nicholas24c17722021-03-09 13:10:59 -050015#include "include/private/SkSLStatement.h"
John Stiles45990502021-02-16 10:55:27 -050016#include "src/sksl/SkSLOperators.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050017#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 Kleinc0bd9f92019-04-23 12:05:21 -050022#include "src/sksl/ir/SkSLModifiersDeclaration.h"
23#include "src/sksl/ir/SkSLProgram.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050024#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"
ethannicholasb3058bd2016-07-01 08:22:01 -070029
30namespace SkSL {
31
Ethan Nicholas95046142021-01-07 10:57:27 -050032namespace dsl {
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -050033 class DSLCore;
Ethan Nicholasdf93db92021-10-04 15:35:59 -040034 class DSLExpression;
Ethan Nicholas1ff76092021-01-28 10:02:43 -050035 class DSLFunction;
Ethan Nicholasdf93db92021-10-04 15:35:59 -040036 class DSLGlobalVar;
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -050037 class DSLVar;
Ethan Nicholas95046142021-01-07 10:57:27 -050038 class DSLWriter;
39}
40
Brian Osmanbe0b3b72021-01-06 14:27:35 -050041class ExternalFunction;
Ethan Nicholas1e9f7f32020-10-08 05:28:32 -040042class FunctionCall;
John Stilesdc75a972020-11-25 16:24:55 -050043class StructDefinition;
Brian Osman3d87e9f2020-10-08 11:50:22 -040044struct ParsedModule;
Ethan Nicholascb0f4092019-04-19 11:26:50 -040045struct Swizzle;
46
ethannicholasb3058bd2016-07-01 08:22:01 -070047/**
Ethan Nicholas11d53972016-11-28 11:23:23 -050048 * Performs semantic analysis on an abstract syntax tree (AST) and produces the corresponding
ethannicholasb3058bd2016-07-01 08:22:01 -070049 * (unoptimized) intermediate representation (IR).
50 */
51class IRGenerator {
52public:
John Stilesc1a98b82021-02-24 13:35:02 -050053 IRGenerator(const Context* context);
ethannicholasb3058bd2016-07-01 08:22:01 -070054
Brian Osman88cda172020-10-09 12:05:16 -040055 struct IRBundle {
56 std::vector<std::unique_ptr<ProgramElement>> fElements;
Brian Osman133724c2020-10-28 14:14:39 -040057 std::vector<const ProgramElement*> fSharedElements;
Brian Osman88cda172020-10-09 12:05:16 -040058 std::shared_ptr<SymbolTable> fSymbolTable;
59 Program::Inputs fInputs;
60 };
61
62 /**
John Stilesaecf8d52021-05-14 12:15:01 -040063 * If externalFunctions is supplied, those values are registered in the symbol table of the
Brian Osman88cda172020-10-09 12:05:16 -040064 * Program, but ownership is *not* transferred. It is up to the caller to keep them alive.
65 */
Brian Osmanbe0b3b72021-01-06 14:27:35 -050066 IRBundle convertProgram(
Brian Osmanbe0b3b72021-01-06 14:27:35 -050067 const ParsedModule& base,
68 bool isBuiltinCode,
Ethan Nicholas6823b502021-06-15 11:42:07 -040069 skstd::string_view text);
ethannicholasb3058bd2016-07-01 08:22:01 -070070
John Stilesd1204642021-02-17 16:30:02 -050071 const Program::Settings& settings() const { return fContext.fConfig->fSettings; }
72 ProgramKind programKind() const { return fContext.fConfig->fKind; }
Brian Osman88cda172020-10-09 12:05:16 -040073
Ethan Nicholas39f6da42021-08-23 13:10:07 -040074 ErrorReporter& errorReporter() const { return *fContext.fErrors; }
John Stilesdc8ec312021-01-11 11:05:21 -050075
Ethan Nicholasba9a04f2020-11-06 09:28:04 -050076 std::shared_ptr<SymbolTable>& symbolTable() {
77 return fSymbolTable;
78 }
79
80 void setSymbolTable(std::shared_ptr<SymbolTable>& symbolTable) {
81 fSymbolTable = symbolTable;
82 }
83
Ethan Nicholas371f6e12021-05-04 14:30:02 -040084 static void CheckModifiers(const Context& context,
Ethan Nicholas89cfde12021-09-27 11:20:34 -040085 int line,
Ethan Nicholas371f6e12021-05-04 14:30:02 -040086 const Modifiers& modifiers,
87 int permittedModifierFlags,
88 int permittedLayoutFlags);
89
Ethan Nicholas89cfde12021-09-27 11:20:34 -040090 std::unique_ptr<Expression> convertIdentifier(int line, skstd::string_view identifier);
Ethan Nicholas722cb672021-05-06 10:47:06 -040091
Ethan Nicholas494eb3e2021-08-27 19:17:01 -040092 bool haveRTAdjustInterfaceBlock() { return fRTAdjustInterfaceBlock != nullptr; }
93
94 int getRTAdjustFieldIndex() { return fRTAdjustFieldIndex; }
95
Ethan Nicholas86a43402017-01-19 13:32:00 -050096 const Context& fContext;
Ethan Nicholas941e7e22016-12-12 15:33:30 -050097
ethannicholasb3058bd2016-07-01 08:22:01 -070098private:
Ethan Nicholas8b3dd342021-03-23 12:32:56 -040099 void start(const ParsedModule& base,
Ethan Nicholas8b3dd342021-03-23 12:32:56 -0400100 std::vector<std::unique_ptr<ProgramElement>>* elements,
101 std::vector<const ProgramElement*>* sharedElements);
102
103 IRGenerator::IRBundle finish();
104
Ethan Nicholas89cfde12021-09-27 11:20:34 -0400105 void checkVarDeclaration(int line,
Brian Osmana654faa2021-02-26 11:52:59 -0500106 const Modifiers& modifiers,
107 const Type* baseType,
Ethan Nicholas489e5522021-01-20 10:53:11 -0500108 Variable::Storage storage);
Ethan Nicholas89cfde12021-09-27 11:20:34 -0400109 std::unique_ptr<Variable> convertVar(int line, const Modifiers& modifiers,
Ethan Nicholas962dec42021-06-10 13:06:39 -0400110 const Type* baseType, skstd::string_view name,
111 bool isArray, std::unique_ptr<Expression> arraySize,
Ethan Nicholasbd974002021-02-22 16:20:06 -0500112 Variable::Storage storage);
113 std::unique_ptr<Statement> convertVarDeclaration(std::unique_ptr<Variable> var,
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -0400114 std::unique_ptr<Expression> value,
115 bool addToSymbolTable = true);
Ethan Nicholas89cfde12021-09-27 11:20:34 -0400116 std::unique_ptr<Statement> convertVarDeclaration(int line, const Modifiers& modifiers,
Ethan Nicholas962dec42021-06-10 13:06:39 -0400117 const Type* baseType, skstd::string_view name,
Ethan Nicholas489e5522021-01-20 10:53:11 -0500118 bool isArray,
119 std::unique_ptr<Expression> arraySize,
120 std::unique_ptr<Expression> value,
121 Variable::Storage storage);
Ethan Nicholas494eb3e2021-08-27 19:17:01 -0400122 void scanInterfaceBlock(SkSL::InterfaceBlock& intf);
John Stiles3b204892021-08-27 17:35:35 -0400123 /** Appends sk_Position fixup to the bottom of main() if this is a vertex program. */
124 void appendRTAdjustFixupToVertexMain(const FunctionDeclaration& decl, Block* body);
ethannicholasb3058bd2016-07-01 08:22:01 -0700125
Brian Osman818fd6d2020-12-30 15:06:22 -0500126 // 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 Stilesca107c92021-02-19 09:54:44 -0500129 return fContext.fConfig->strictES2Mode();
Brian Osman818fd6d2020-12-30 15:06:22 -0500130 }
131
John Stilesbb2ef922021-07-26 08:32:07 -0400132 bool isRuntimeEffect() const {
John Stilesaddccaf2021-08-02 19:03:30 -0400133 return ProgramConfig::IsRuntimeEffect(fContext.fConfig->fKind);
John Stilesbb2ef922021-07-26 08:32:07 -0400134 }
135
John Stilesc1a98b82021-02-24 13:35:02 -0500136 const ShaderCapsClass& caps() const {
137 return fContext.fCaps;
138 }
139
John Stilesf2872e62021-05-04 11:38:43 -0400140 ModifiersPool& modifiersPool() const {
John Stiles10d39d92021-05-04 16:13:14 -0400141 return *fContext.fModifiersPool;
John Stilesf2872e62021-05-04 11:38:43 -0400142 }
143
Brian Osman88cda172020-10-09 12:05:16 -0400144 Program::Inputs fInputs;
Brian Osman88cda172020-10-09 12:05:16 -0400145
Brian Osman88cda172020-10-09 12:05:16 -0400146 std::shared_ptr<SymbolTable> fSymbolTable = nullptr;
Brian Osman02bc5222021-01-28 11:00:20 -0500147 std::unordered_set<const Type*> fDefinedStructs;
Brian Osman88cda172020-10-09 12:05:16 -0400148 std::vector<std::unique_ptr<ProgramElement>>* fProgramElements = nullptr;
Brian Osman133724c2020-10-28 14:14:39 -0400149 std::vector<const ProgramElement*>* fSharedElements = nullptr;
Brian Osman88cda172020-10-09 12:05:16 -0400150 const Variable* fRTAdjust = nullptr;
151 const Variable* fRTAdjustInterfaceBlock = nullptr;
Robert Phillipsfe8da172018-01-24 14:52:02 +0000152 int fRTAdjustFieldIndex;
ethannicholasb3058bd2016-07-01 08:22:01 -0700153
154 friend class AutoSymbolTable;
ethannicholas22f939e2016-10-13 13:25:34 -0700155 friend class AutoLoopLevel;
Ethan Nicholasaf197692017-02-27 13:26:45 -0500156 friend class AutoSwitchLevel;
John Stilesd1c4dac2020-08-11 18:50:50 -0400157 friend class AutoDisableInline;
ethannicholasb3058bd2016-07-01 08:22:01 -0700158 friend class Compiler;
Ethan Nicholasdd2fdea2021-07-20 15:23:04 -0400159 friend class DSLParser;
Ethan Nicholasc8452722021-10-07 10:47:32 -0400160 friend class ThreadContext;
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500161 friend class dsl::DSLCore;
Ethan Nicholasdf93db92021-10-04 15:35:59 -0400162 friend class dsl::DSLExpression;
Ethan Nicholas1ff76092021-01-28 10:02:43 -0500163 friend class dsl::DSLFunction;
Ethan Nicholasdf93db92021-10-04 15:35:59 -0400164 friend class dsl::DSLGlobalVar;
Ethan Nicholasd6b6f3e2021-01-22 15:18:25 -0500165 friend class dsl::DSLVar;
Ethan Nicholas95046142021-01-07 10:57:27 -0500166 friend class dsl::DSLWriter;
ethannicholasb3058bd2016-07-01 08:22:01 -0700167};
168
John Stilesa6841be2020-08-06 14:11:56 -0400169} // namespace SkSL
ethannicholasb3058bd2016-07-01 08:22:01 -0700170
171#endif