1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // ShaderGL.cpp: Implements the class methods for ShaderGL.
8
9 #include "libANGLE/renderer/gl/ShaderGL.h"
10
11 #include "common/debug.h"
12 #include "libANGLE/Compiler.h"
13 #include "libANGLE/Context.h"
14 #include "libANGLE/renderer/ContextImpl.h"
15 #include "libANGLE/renderer/gl/ContextGL.h"
16 #include "libANGLE/renderer/gl/FunctionsGL.h"
17 #include "libANGLE/trace.h"
18 #include "platform/autogen/FeaturesGL_autogen.h"
19
20 #include <iostream>
21
22 namespace rx
23 {
24 namespace
25 {
26 class ShaderTranslateTaskGL final : public ShaderTranslateTask
27 {
28 public:
ShaderTranslateTaskGL(const FunctionsGL * functions,GLuint shaderID,bool hasNativeParallelCompile)29 ShaderTranslateTaskGL(const FunctionsGL *functions,
30 GLuint shaderID,
31 bool hasNativeParallelCompile)
32 : mFunctions(functions),
33 mShaderID(shaderID),
34 mHasNativeParallelCompile(hasNativeParallelCompile)
35 {}
36 ~ShaderTranslateTaskGL() override = default;
37
postTranslate(ShHandle compiler,const gl::CompiledShaderState & compiledState)38 void postTranslate(ShHandle compiler, const gl::CompiledShaderState &compiledState) override
39 {
40 startCompile(compiledState);
41 }
42
load(const gl::CompiledShaderState & compiledState)43 void load(const gl::CompiledShaderState &compiledState) override
44 {
45 startCompile(compiledState);
46 }
47
isCompilingInternally()48 bool isCompilingInternally() override
49 {
50 if (!mHasNativeParallelCompile)
51 {
52 return false;
53 }
54
55 GLint status = GL_FALSE;
56 mFunctions->getShaderiv(mShaderID, GL_COMPLETION_STATUS, &status);
57 return status != GL_TRUE;
58 }
59
getResult(std::string & infoLog)60 angle::Result getResult(std::string &infoLog) override
61 {
62 // Check for compile errors from the native driver
63 GLint compileStatus = GL_FALSE;
64 mFunctions->getShaderiv(mShaderID, GL_COMPILE_STATUS, &compileStatus);
65 if (compileStatus != GL_FALSE)
66 {
67 return angle::Result::Continue;
68 }
69
70 // Compilation failed, put the error into the info log
71 GLint infoLogLength = 0;
72 mFunctions->getShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
73
74 // Info log length includes the null terminator, so 1 means that the info log is an empty
75 // string.
76 if (infoLogLength > 1)
77 {
78 std::vector<char> buf(infoLogLength);
79 mFunctions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]);
80
81 infoLog += buf.data();
82 }
83 else
84 {
85 WARN() << std::endl << "Shader compilation failed with no info log.";
86 }
87
88 return angle::Result::Stop;
89 }
90
91 private:
startCompile(const gl::CompiledShaderState & compiledState)92 void startCompile(const gl::CompiledShaderState &compiledState)
93 {
94 const char *source = compiledState.translatedSource.c_str();
95 mFunctions->shaderSource(mShaderID, 1, &source, nullptr);
96 mFunctions->compileShader(mShaderID);
97 }
98
99 const FunctionsGL *mFunctions;
100 GLuint mShaderID;
101 bool mHasNativeParallelCompile;
102 };
103 } // anonymous namespace
104
ShaderGL(const gl::ShaderState & data,GLuint shaderID)105 ShaderGL::ShaderGL(const gl::ShaderState &data, GLuint shaderID)
106 : ShaderImpl(data), mShaderID(shaderID)
107 {}
108
~ShaderGL()109 ShaderGL::~ShaderGL()
110 {
111 ASSERT(mShaderID == 0);
112 }
113
onDestroy(const gl::Context * context)114 void ShaderGL::onDestroy(const gl::Context *context)
115 {
116 const FunctionsGL *functions = GetFunctionsGL(context);
117
118 functions->deleteShader(mShaderID);
119 mShaderID = 0;
120 }
121
compile(const gl::Context * context,ShCompileOptions * options)122 std::shared_ptr<ShaderTranslateTask> ShaderGL::compile(const gl::Context *context,
123 ShCompileOptions *options)
124 {
125 ContextGL *contextGL = GetImplAs<ContextGL>(context);
126 const FunctionsGL *functions = GetFunctionsGL(context);
127
128 options->initGLPosition = true;
129
130 bool isWebGL = context->isWebGL();
131 if (isWebGL && mState.getShaderType() != gl::ShaderType::Compute)
132 {
133 options->initOutputVariables = true;
134 }
135
136 if (isWebGL && !context->getState().getEnableFeature(GL_TEXTURE_RECTANGLE_ANGLE))
137 {
138 options->disableARBTextureRectangle = true;
139 }
140
141 const angle::FeaturesGL &features = GetFeaturesGL(context);
142
143 if (features.initFragmentOutputVariables.enabled)
144 {
145 options->initFragmentOutputVariables = true;
146 }
147
148 if (features.doWhileGLSLCausesGPUHang.enabled)
149 {
150 options->rewriteDoWhileLoops = true;
151 }
152
153 if (features.emulateAbsIntFunction.enabled)
154 {
155 options->emulateAbsIntFunction = true;
156 }
157
158 if (features.addAndTrueToLoopCondition.enabled)
159 {
160 options->addAndTrueToLoopCondition = true;
161 }
162
163 if (features.emulateIsnanFloat.enabled)
164 {
165 options->emulateIsnanFloatFunction = true;
166 }
167
168 if (features.emulateAtan2Float.enabled)
169 {
170 options->emulateAtan2FloatFunction = true;
171 }
172
173 if (features.useUnusedBlocksWithStandardOrSharedLayout.enabled)
174 {
175 options->useUnusedStandardSharedBlocks = true;
176 }
177
178 if (features.removeInvariantAndCentroidForESSL3.enabled)
179 {
180 options->removeInvariantAndCentroidForESSL3 = true;
181 }
182
183 if (features.rewriteFloatUnaryMinusOperator.enabled)
184 {
185 options->rewriteFloatUnaryMinusOperator = true;
186 }
187
188 if (!features.dontInitializeUninitializedLocals.enabled)
189 {
190 options->initializeUninitializedLocals = true;
191 }
192
193 if (features.clampPointSize.enabled)
194 {
195 options->clampPointSize = true;
196 }
197
198 if (features.dontUseLoopsToInitializeVariables.enabled)
199 {
200 options->dontUseLoopsToInitializeVariables = true;
201 }
202
203 if (features.clampFragDepth.enabled)
204 {
205 options->clampFragDepth = true;
206 }
207
208 if (features.rewriteRepeatedAssignToSwizzled.enabled)
209 {
210 options->rewriteRepeatedAssignToSwizzled = true;
211 }
212
213 if (features.preTransformTextureCubeGradDerivatives.enabled)
214 {
215 options->preTransformTextureCubeGradDerivatives = true;
216 }
217
218 if (contextGL->getMultiviewImplementationType() ==
219 MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2)
220 {
221 options->initializeBuiltinsForInstancedMultiview = true;
222 options->selectViewInNvGLSLVertexShader = true;
223 }
224
225 if (features.clampArrayAccess.enabled || isWebGL)
226 {
227 options->clampIndirectArrayBounds = true;
228 }
229
230 if (features.vertexIDDoesNotIncludeBaseVertex.enabled)
231 {
232 options->addBaseVertexToVertexID = true;
233 }
234
235 if (features.unfoldShortCircuits.enabled)
236 {
237 options->unfoldShortCircuit = true;
238 }
239
240 if (features.removeDynamicIndexingOfSwizzledVector.enabled)
241 {
242 options->removeDynamicIndexingOfSwizzledVector = true;
243 }
244
245 if (features.preAddTexelFetchOffsets.enabled)
246 {
247 options->rewriteTexelFetchOffsetToTexelFetch = true;
248 }
249
250 if (features.regenerateStructNames.enabled)
251 {
252 options->regenerateStructNames = true;
253 }
254
255 if (features.rewriteRowMajorMatrices.enabled)
256 {
257 options->rewriteRowMajorMatrices = true;
258 }
259
260 if (features.passHighpToPackUnormSnormBuiltins.enabled)
261 {
262 options->passHighpToPackUnormSnormBuiltins = true;
263 }
264
265 if (features.emulateClipDistanceState.enabled)
266 {
267 options->emulateClipDistanceState = true;
268 }
269
270 if (features.emulateClipOrigin.enabled)
271 {
272 options->emulateClipOrigin = true;
273 }
274
275 if (features.scalarizeVecAndMatConstructorArgs.enabled)
276 {
277 options->scalarizeVecAndMatConstructorArgs = true;
278 }
279
280 if (features.explicitFragmentLocations.enabled)
281 {
282 options->explicitFragmentLocations = true;
283 }
284
285 if (contextGL->getNativeExtensions().shaderPixelLocalStorageANGLE)
286 {
287 options->pls = contextGL->getNativePixelLocalStorageOptions();
288 }
289
290 return std::shared_ptr<ShaderTranslateTask>(
291 new ShaderTranslateTaskGL(functions, mShaderID, contextGL->hasNativeParallelCompile()));
292 }
293
load(const gl::Context * context,gl::BinaryInputStream * stream)294 std::shared_ptr<ShaderTranslateTask> ShaderGL::load(const gl::Context *context,
295 gl::BinaryInputStream *stream)
296 {
297 ContextGL *contextGL = GetImplAs<ContextGL>(context);
298 const FunctionsGL *functions = GetFunctionsGL(context);
299
300 return std::shared_ptr<ShaderTranslateTask>(
301 new ShaderTranslateTaskGL(functions, mShaderID, contextGL->hasNativeParallelCompile()));
302 }
303
getDebugInfo() const304 std::string ShaderGL::getDebugInfo() const
305 {
306 return mState.getCompiledState()->translatedSource;
307 }
308
getShaderID() const309 GLuint ShaderGL::getShaderID() const
310 {
311 return mShaderID;
312 }
313
314 } // namespace rx
315