blob: acb981b6e74cd553d5f37a7782f25f5060514bfa [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2013 TransGaming Inc.
4//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#ifndef COMPILER_OUTPUTASM_H_
13#define COMPILER_OUTPUTASM_H_
14
15#include "intermediate.h"
16#include "ParseHelper.h"
17#include "Shader/PixelShader.hpp"
18#include "Shader/VertexShader.hpp"
19
John Bauman66b8ab22014-05-06 15:57:45 -040020#include <list>
21#include <set>
22#include <map>
23
Nicolas Capens14ee7622014-10-28 23:48:41 -040024namespace es2
John Bauman66b8ab22014-05-06 15:57:45 -040025{
26 class Shader;
27}
28
Nicolas Capenseafa0222015-01-26 00:23:01 -050029typedef unsigned int GLenum;
30
Nicolas Capens5597eef2015-01-22 09:33:04 -050031namespace glsl
John Bauman66b8ab22014-05-06 15:57:45 -040032{
33 struct Uniform
34 {
Alexis Hetu5228d3c2015-07-22 16:37:02 -040035 Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int offset, int blockId);
John Bauman66b8ab22014-05-06 15:57:45 -040036
37 GLenum type;
John Baumand4ae8632014-05-06 16:18:33 -040038 GLenum precision;
John Bauman66b8ab22014-05-06 15:57:45 -040039 std::string name;
40 int arraySize;
41
42 int registerIndex;
Alexis Hetu5228d3c2015-07-22 16:37:02 -040043 int offset;
Alexis Hetub938c3c2015-07-06 15:03:42 -040044
45 int blockId;
John Bauman66b8ab22014-05-06 15:57:45 -040046 };
47
48 typedef std::vector<Uniform> ActiveUniforms;
49
Alexis Hetub938c3c2015-07-06 15:03:42 -040050 struct UniformBlock
51 {
52 UniformBlock(const std::string& name, const std::string& instanceName, unsigned int dataSize, unsigned int arraySize,
53 TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId);
54
55 const std::string& getName() const { return (instanceName.length() > 0) ? instanceName : name; }
56
57 std::string name;
58 std::string instanceName;
59 unsigned int dataSize;
60 unsigned int arraySize;
61 TLayoutBlockStorage layout;
62 bool isRowMajorLayout;
63 std::vector<int> fields;
64
65 int registerIndex;
66
67 int blockId;
68 };
69
70 typedef std::vector<UniformBlock> ActiveUniformBlocks;
71
John Bauman66b8ab22014-05-06 15:57:45 -040072 struct Attribute
73 {
74 Attribute();
Alexis Hetu910b6b62015-07-16 11:12:38 -040075 Attribute(GLenum type, const std::string &name, int arraySize, int location, int registerIndex);
John Bauman66b8ab22014-05-06 15:57:45 -040076
77 GLenum type;
78 std::string name;
79 int arraySize;
Alexis Hetu910b6b62015-07-16 11:12:38 -040080 int location;
John Bauman66b8ab22014-05-06 15:57:45 -040081
82 int registerIndex;
83 };
84
Nicolas Capens68754bf2015-01-22 09:31:59 -050085 typedef std::vector<Attribute> ActiveAttributes;
86
87 struct Varying
88 {
89 Varying(GLenum type, const std::string &name, int arraySize, int reg = -1, int col = -1)
90 : type(type), name(name), arraySize(arraySize), reg(reg), col(col)
91 {
92 }
93
94 bool isArray() const
95 {
96 return arraySize >= 1;
97 }
98
99 int size() const // Unify with es2::Uniform?
100 {
101 return arraySize > 0 ? arraySize : 1;
102 }
103
104 GLenum type;
105 std::string name;
106 int arraySize;
107
108 int reg; // First varying register, assigned during link
109 int col; // First register element, assigned during link
110 };
111
112 typedef std::list<Varying> VaryingList;
113
114 class Shader
115 {
116 friend class OutputASM;
117 public:
Ping-Hao Wu6dbd5fe2015-03-20 13:21:28 -0700118 virtual ~Shader() {};
Nicolas Capens68754bf2015-01-22 09:31:59 -0500119 virtual sw::Shader *getShader() const = 0;
120 virtual sw::PixelShader *getPixelShader() const;
121 virtual sw::VertexShader *getVertexShader() const;
122
123 protected:
124 VaryingList varyings;
125 ActiveUniforms activeUniforms;
126 ActiveAttributes activeAttributes;
Alexis Hetub938c3c2015-07-06 15:03:42 -0400127 ActiveUniformBlocks activeUniformBlocks;
Nicolas Capens68754bf2015-01-22 09:31:59 -0500128 };
129
John Bauman66b8ab22014-05-06 15:57:45 -0400130 struct Function
131 {
132 Function(int label, const char *name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)
133 {
134 }
135
136 Function(int label, const TString &name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)
137 {
138 }
139
140 int label;
141 TString name;
142 TIntermSequence *arg;
143 TIntermTyped *ret;
144 };
145
146 typedef sw::Shader::Instruction Instruction;
John Bauman66b8ab22014-05-06 15:57:45 -0400147
148 class Temporary;
149
150 class OutputASM : public TIntermTraverser
151 {
152 public:
Nicolas Capens68754bf2015-01-22 09:31:59 -0500153 explicit OutputASM(TParseContext &context, Shader *shaderObject);
John Bauman66b8ab22014-05-06 15:57:45 -0400154 ~OutputASM();
155
156 void output();
157
158 void freeTemporary(Temporary *temporary);
159
John Baumand4ae8632014-05-06 16:18:33 -0400160 private:
John Bauman66b8ab22014-05-06 15:57:45 -0400161 enum Scope
162 {
163 GLOBAL,
164 FUNCTION
165 };
166
167 void emitShader(Scope scope);
168
169 // Visit AST nodes and output their code to the body stream
170 virtual void visitSymbol(TIntermSymbol*);
171 virtual bool visitBinary(Visit visit, TIntermBinary*);
172 virtual bool visitUnary(Visit visit, TIntermUnary*);
173 virtual bool visitSelection(Visit visit, TIntermSelection*);
174 virtual bool visitAggregate(Visit visit, TIntermAggregate*);
175 virtual bool visitLoop(Visit visit, TIntermLoop*);
176 virtual bool visitBranch(Visit visit, TIntermBranch*);
177
Alexis Hetu02a2bb82015-08-20 14:10:33 -0400178 sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;
Alexis Hetuc3d95f32015-09-23 12:27:32 -0400179 Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, int index = 0);
Nicolas Capens20608662014-06-12 14:05:19 -0400180 Instruction *emitCast(TIntermTyped *dst, TIntermTyped *src);
John Baumand4ae8632014-05-06 16:18:33 -0400181 void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0);
John Bauman66b8ab22014-05-06 15:57:45 -0400182 void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);
183 void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
Alexis Hetuc3d95f32015-09-23 12:27:32 -0400184 void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);
John Bauman66b8ab22014-05-06 15:57:45 -0400185 void argument(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);
186 void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
Alexis Hetu1763eeb2014-11-20 10:47:04 -0500187 void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
John Bauman66b8ab22014-05-06 15:57:45 -0400188 int lvalue(sw::Shader::DestinationParameter &dst, Temporary &address, TIntermTyped *node);
189 sw::Shader::ParameterType registerType(TIntermTyped *operand);
190 int registerIndex(TIntermTyped *operand);
191 int writeMask(TIntermTyped *destination, int index = 0);
Nicolas Capens059bece2014-05-06 16:44:23 -0400192 int readSwizzle(TIntermTyped *argument, int size);
John Bauman66b8ab22014-05-06 15:57:45 -0400193 bool trivial(TIntermTyped *expression, int budget); // Fast to compute and no side effects
194 int cost(TIntermNode *expression, int budget);
Nicolas Capens014b9a62014-10-15 10:28:29 -0400195 const Function *findFunction(const TString &name);
John Bauman66b8ab22014-05-06 15:57:45 -0400196
197 int temporaryRegister(TIntermTyped *temporary);
198 int varyingRegister(TIntermTyped *varying);
199 void declareVarying(TIntermTyped *varying, int reg);
200 int uniformRegister(TIntermTyped *uniform);
201 int attributeRegister(TIntermTyped *attribute);
Alexis Hetuf14891d2015-11-20 11:46:41 -0500202 int fragmentOutputRegister(TIntermTyped *fragmentOutput);
John Bauman66b8ab22014-05-06 15:57:45 -0400203 int samplerRegister(TIntermTyped *sampler);
Nicolas Capenscdd29242015-02-12 15:27:55 -0500204 int samplerRegister(TIntermSymbol *sampler);
John Bauman66b8ab22014-05-06 15:57:45 -0400205
206 typedef std::vector<TIntermTyped*> VariableArray;
207
208 int lookup(VariableArray &list, TIntermTyped *variable);
209 int allocate(VariableArray &list, TIntermTyped *variable);
210 void free(VariableArray &list, TIntermTyped *variable);
211
Alexis Hetu5228d3c2015-07-22 16:37:02 -0400212 void declareUniform(const TType &type, const TString &name, int registerIndex, int offset = 0, int blockId = -1);
John Bauman66b8ab22014-05-06 15:57:45 -0400213 GLenum glVariableType(const TType &type);
John Baumand4ae8632014-05-06 16:18:33 -0400214 GLenum glVariablePrecision(const TType &type);
John Bauman66b8ab22014-05-06 15:57:45 -0400215
216 static int dim(TIntermNode *v);
217 static int dim2(TIntermNode *m);
John Baumand4ae8632014-05-06 16:18:33 -0400218 static unsigned int loopCount(TIntermLoop *node);
Alexis Hetu5b5d5622014-11-24 16:22:57 -0500219 static bool isSamplerRegister(TIntermTyped *operand);
Nicolas Capenscdd29242015-02-12 15:27:55 -0500220 static bool isSamplerRegister(const TType &type);
John Bauman66b8ab22014-05-06 15:57:45 -0400221
Nicolas Capens68754bf2015-01-22 09:31:59 -0500222 Shader *const shaderObject;
John Bauman66b8ab22014-05-06 15:57:45 -0400223 sw::Shader *shader;
224 sw::PixelShader *pixelShader;
225 sw::VertexShader *vertexShader;
226
227 VariableArray temporaries;
228 VariableArray uniforms;
229 VariableArray varyings;
230 VariableArray attributes;
231 VariableArray samplers;
Alexis Hetuf14891d2015-11-20 11:46:41 -0500232 VariableArray fragmentOutputs;
John Bauman66b8ab22014-05-06 15:57:45 -0400233
234 Scope emitScope;
235 Scope currentScope;
236
237 int currentFunction;
238 std::vector<Function> functionArray;
239
Alexis Hetua82b58e2014-11-13 16:43:44 -0500240 TQualifier outputQualifier;
241
John Bauman66b8ab22014-05-06 15:57:45 -0400242 TParseContext &mContext;
243 };
John Baumand4ae8632014-05-06 16:18:33 -0400244
245 // Checks whether a loop can run for a variable number of iterations
246 class DetectLoopDiscontinuity : public TIntermTraverser
247 {
248 public:
249 bool traverse(TIntermNode *node);
250
251 private:
252 bool visitBranch(Visit visit, TIntermBranch *node);
253 bool visitLoop(Visit visit, TIntermLoop *loop);
254 bool visitAggregate(Visit visit, TIntermAggregate *node);
255
256 int loopDepth;
257 bool loopDiscontinuity;
258 };
John Bauman66b8ab22014-05-06 15:57:45 -0400259}
260
261#endif // COMPILER_OUTPUTASM_H_