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/FunctionsGL.h"
16 #include "libANGLE/renderer/gl/RendererGL.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 const char *source = compiledState.translatedSource.c_str();
41 mFunctions->shaderSource(mShaderID, 1, &source, nullptr);
42 mFunctions->compileShader(mShaderID);
43 }
44
isCompilingInternally()45 bool isCompilingInternally() override
46 {
47 if (!mHasNativeParallelCompile)
48 {
49 return false;
50 }
51
52 GLint status = GL_FALSE;
53 mFunctions->getShaderiv(mShaderID, GL_COMPLETION_STATUS, &status);
54 return status != GL_TRUE;
55 }
56
getResult(std::string & infoLog)57 angle::Result getResult(std::string &infoLog) override
58 {
59 // Check for compile errors from the native driver
60 GLint compileStatus = GL_FALSE;
61 mFunctions->getShaderiv(mShaderID, GL_COMPILE_STATUS, &compileStatus);
62 if (compileStatus != GL_FALSE)
63 {
64 return angle::Result::Continue;
65 }
66
67 // Compilation failed, put the error into the info log
68 GLint infoLogLength = 0;
69 mFunctions->getShaderiv(mShaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
70
71 // Info log length includes the null terminator, so 1 means that the info log is an empty
72 // string.
73 if (infoLogLength > 1)
74 {
75 std::vector<char> buf(infoLogLength);
76 mFunctions->getShaderInfoLog(mShaderID, infoLogLength, nullptr, &buf[0]);
77
78 infoLog += buf.data();
79 }
80 else
81 {
82 WARN() << std::endl << "Shader compilation failed with no info log.";
83 }
84
85 return angle::Result::Stop;
86 }
87
88 private:
89 const FunctionsGL *mFunctions;
90 GLuint mShaderID;
91 bool mHasNativeParallelCompile;
92 };
93 } // anonymous namespace
94
ShaderGL(const gl::ShaderState & data,GLuint shaderID,MultiviewImplementationTypeGL multiviewImplementationType,const std::shared_ptr<RendererGL> & renderer)95 ShaderGL::ShaderGL(const gl::ShaderState &data,
96 GLuint shaderID,
97 MultiviewImplementationTypeGL multiviewImplementationType,
98 const std::shared_ptr<RendererGL> &renderer)
99 : ShaderImpl(data),
100 mShaderID(shaderID),
101 mMultiviewImplementationType(multiviewImplementationType),
102 mRenderer(renderer)
103 {}
104
~ShaderGL()105 ShaderGL::~ShaderGL()
106 {
107 ASSERT(mShaderID == 0);
108 }
109
destroy()110 void ShaderGL::destroy()
111 {
112 mRenderer->getFunctions()->deleteShader(mShaderID);
113 mShaderID = 0;
114 }
115
compile(const gl::Context * context,ShCompileOptions * options)116 std::shared_ptr<ShaderTranslateTask> ShaderGL::compile(const gl::Context *context,
117 ShCompileOptions *options)
118 {
119 options->initGLPosition = true;
120
121 bool isWebGL = context->isWebGL();
122 if (isWebGL && mState.getShaderType() != gl::ShaderType::Compute)
123 {
124 options->initOutputVariables = true;
125 }
126
127 if (isWebGL && !context->getState().getEnableFeature(GL_TEXTURE_RECTANGLE_ANGLE))
128 {
129 options->disableARBTextureRectangle = true;
130 }
131
132 const angle::FeaturesGL &features = GetFeaturesGL(context);
133
134 if (features.initFragmentOutputVariables.enabled)
135 {
136 options->initFragmentOutputVariables = true;
137 }
138
139 if (features.doWhileGLSLCausesGPUHang.enabled)
140 {
141 options->rewriteDoWhileLoops = true;
142 }
143
144 if (features.emulateAbsIntFunction.enabled)
145 {
146 options->emulateAbsIntFunction = true;
147 }
148
149 if (features.addAndTrueToLoopCondition.enabled)
150 {
151 options->addAndTrueToLoopCondition = true;
152 }
153
154 if (features.emulateIsnanFloat.enabled)
155 {
156 options->emulateIsnanFloatFunction = true;
157 }
158
159 if (features.emulateAtan2Float.enabled)
160 {
161 options->emulateAtan2FloatFunction = true;
162 }
163
164 if (features.useUnusedBlocksWithStandardOrSharedLayout.enabled)
165 {
166 options->useUnusedStandardSharedBlocks = true;
167 }
168
169 if (features.removeInvariantAndCentroidForESSL3.enabled)
170 {
171 options->removeInvariantAndCentroidForESSL3 = true;
172 }
173
174 if (features.rewriteFloatUnaryMinusOperator.enabled)
175 {
176 options->rewriteFloatUnaryMinusOperator = true;
177 }
178
179 if (!features.dontInitializeUninitializedLocals.enabled)
180 {
181 options->initializeUninitializedLocals = true;
182 }
183
184 if (features.clampPointSize.enabled)
185 {
186 options->clampPointSize = true;
187 }
188
189 if (features.dontUseLoopsToInitializeVariables.enabled)
190 {
191 options->dontUseLoopsToInitializeVariables = true;
192 }
193
194 if (features.clampFragDepth.enabled)
195 {
196 options->clampFragDepth = true;
197 }
198
199 if (features.rewriteRepeatedAssignToSwizzled.enabled)
200 {
201 options->rewriteRepeatedAssignToSwizzled = true;
202 }
203
204 if (features.preTransformTextureCubeGradDerivatives.enabled)
205 {
206 options->preTransformTextureCubeGradDerivatives = true;
207 }
208
209 if (mMultiviewImplementationType == MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2)
210 {
211 options->initializeBuiltinsForInstancedMultiview = true;
212 options->selectViewInNvGLSLVertexShader = true;
213 }
214
215 if (features.clampArrayAccess.enabled || isWebGL)
216 {
217 options->clampIndirectArrayBounds = true;
218 }
219
220 if (features.vertexIDDoesNotIncludeBaseVertex.enabled)
221 {
222 options->addBaseVertexToVertexID = true;
223 }
224
225 if (features.unfoldShortCircuits.enabled)
226 {
227 options->unfoldShortCircuit = true;
228 }
229
230 if (features.removeDynamicIndexingOfSwizzledVector.enabled)
231 {
232 options->removeDynamicIndexingOfSwizzledVector = true;
233 }
234
235 if (features.preAddTexelFetchOffsets.enabled)
236 {
237 options->rewriteTexelFetchOffsetToTexelFetch = true;
238 }
239
240 if (features.regenerateStructNames.enabled)
241 {
242 options->regenerateStructNames = true;
243 }
244
245 if (features.rewriteRowMajorMatrices.enabled)
246 {
247 options->rewriteRowMajorMatrices = true;
248 }
249
250 if (features.passHighpToPackUnormSnormBuiltins.enabled)
251 {
252 options->passHighpToPackUnormSnormBuiltins = true;
253 }
254
255 if (features.emulateClipDistanceState.enabled)
256 {
257 options->emulateClipDistanceState = true;
258 }
259
260 if (features.emulateClipOrigin.enabled)
261 {
262 options->emulateClipOrigin = true;
263 }
264
265 if (features.scalarizeVecAndMatConstructorArgs.enabled)
266 {
267 options->scalarizeVecAndMatConstructorArgs = true;
268 }
269
270 if (features.explicitFragmentLocations.enabled)
271 {
272 options->explicitFragmentLocations = true;
273 }
274
275 if (mRenderer->getNativeExtensions().shaderPixelLocalStorageANGLE)
276 {
277 options->pls = mRenderer->getNativePixelLocalStorageOptions();
278 }
279
280 return std::shared_ptr<ShaderTranslateTask>(new ShaderTranslateTaskGL(
281 mRenderer->getFunctions(), mShaderID, mRenderer->hasNativeParallelCompile()));
282 }
283
getDebugInfo() const284 std::string ShaderGL::getDebugInfo() const
285 {
286 return mState.getCompiledState()->translatedSource;
287 }
288
getShaderID() const289 GLuint ShaderGL::getShaderID() const
290 {
291 return mShaderID;
292 }
293
294 } // namespace rx
295