blob: c3232ce14a7ab3f42d4be8008a6561a8a9316e56 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Geoff Langcec35902014-04-16 10:52:36 -04002// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// Shader.cpp: Implements the gl::Shader class and its derived classes
8// VertexShader and FragmentShader. Implements GL shader objects and related
9// functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
10
Geoff Lang2b5420c2014-11-19 14:20:15 -050011#include "libANGLE/Shader.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040012
13#include <sstream>
14
Jamie Madill91445bc2015-09-23 16:47:53 -040015#include "common/utilities.h"
16#include "GLSLANG/ShaderLang.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040017#include "libANGLE/Caps.h"
Jamie Madill006cbc52015-09-23 16:47:54 -040018#include "libANGLE/Compiler.h"
Jamie Madill91445bc2015-09-23 16:47:53 -040019#include "libANGLE/Constants.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040020#include "libANGLE/renderer/GLImplFactory.h"
Jamie Madill91445bc2015-09-23 16:47:53 -040021#include "libANGLE/renderer/ShaderImpl.h"
22#include "libANGLE/ResourceManager.h"
Bryan Bernhart619c8332016-11-09 11:11:41 -080023#include "libANGLE/Context.h"
Jamie Madill91445bc2015-09-23 16:47:53 -040024
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025namespace gl
26{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027
Jamie Madill006cbc52015-09-23 16:47:54 -040028namespace
29{
30template <typename VarT>
31std::vector<VarT> GetActiveShaderVariables(const std::vector<VarT> *variableList)
32{
33 ASSERT(variableList);
34 std::vector<VarT> result;
35 for (size_t varIndex = 0; varIndex < variableList->size(); varIndex++)
36 {
37 const VarT &var = variableList->at(varIndex);
38 if (var.staticUse)
39 {
40 result.push_back(var);
41 }
42 }
43 return result;
44}
45
46template <typename VarT>
47const std::vector<VarT> &GetShaderVariables(const std::vector<VarT> *variableList)
48{
49 ASSERT(variableList);
50 return *variableList;
51}
52
Jamie Madill9fc36822015-11-18 13:08:07 -050053} // anonymous namespace
54
Jamie Madill006cbc52015-09-23 16:47:54 -040055// true if varying x has a higher priority in packing than y
Jamie Madill55c25d02015-11-18 13:08:08 -050056bool CompareShaderVar(const sh::ShaderVariable &x, const sh::ShaderVariable &y)
Jamie Madill006cbc52015-09-23 16:47:54 -040057{
58 if (x.type == y.type)
59 {
60 return x.arraySize > y.arraySize;
61 }
62
63 // Special case for handling structs: we sort these to the end of the list
Jamie Madillf00f7ff2017-08-31 14:39:15 -040064 if (x.type == GL_NONE)
Jamie Madill006cbc52015-09-23 16:47:54 -040065 {
66 return false;
67 }
68
Jamie Madillf00f7ff2017-08-31 14:39:15 -040069 if (y.type == GL_NONE)
Jamie Madill006cbc52015-09-23 16:47:54 -040070 {
71 return true;
72 }
73
74 return gl::VariableSortOrder(x.type) < gl::VariableSortOrder(y.type);
75}
76
Jamie Madill34ca4f52017-06-13 11:49:39 -040077ShaderState::ShaderState(GLenum shaderType)
78 : mLabel(),
79 mShaderType(shaderType),
80 mShaderVersion(100),
Martin Radev7cf61662017-07-26 17:10:53 +030081 mNumViews(-1),
Jamie Madill34ca4f52017-06-13 11:49:39 -040082 mCompileStatus(CompileStatus::NOT_COMPILED)
Jamie Madill91445bc2015-09-23 16:47:53 -040083{
Martin Radev4c4c8e72016-08-04 12:25:34 +030084 mLocalSize.fill(-1);
Jamie Madill91445bc2015-09-23 16:47:53 -040085}
86
Jamie Madill15243d92016-04-26 13:41:35 -040087ShaderState::~ShaderState()
Jamie Madill91445bc2015-09-23 16:47:53 -040088{
89}
90
Geoff Lang4ddf5af2016-12-01 14:30:44 -050091Shader::Shader(ShaderProgramManager *manager,
Jamie Madill7aea7e02016-05-10 10:39:45 -040092 rx::GLImplFactory *implFactory,
Jamie Madill006cbc52015-09-23 16:47:54 -040093 const gl::Limitations &rendererLimitations,
94 GLenum type,
95 GLuint handle)
Jamie Madill15243d92016-04-26 13:41:35 -040096 : mState(type),
97 mImplementation(implFactory->createShader(mState)),
Jamie Madill006cbc52015-09-23 16:47:54 -040098 mRendererLimitations(rendererLimitations),
Brandon Jonesf05cdee2014-08-27 15:24:07 -070099 mHandle(handle),
Corentin Wallezbc99bb62015-05-14 17:42:20 -0400100 mType(type),
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700101 mRefCount(0),
102 mDeleteStatus(false),
Corentin Wallezbc99bb62015-05-14 17:42:20 -0400103 mResourceManager(manager)
Jamie Madille294bb82014-07-17 14:16:26 -0400104{
Jamie Madill91445bc2015-09-23 16:47:53 -0400105 ASSERT(mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106}
107
Jamie Madill4928b7c2017-06-20 12:57:39 -0400108void Shader::onDestroy(const gl::Context *context)
109{
110 mBoundCompiler.set(context, nullptr);
111 mImplementation.reset(nullptr);
112 delete this;
113}
114
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115Shader::~Shader()
116{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400117 ASSERT(!mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000118}
119
Geoff Lang70d0f492015-12-10 17:45:46 -0500120void Shader::setLabel(const std::string &label)
121{
Jamie Madill15243d92016-04-26 13:41:35 -0400122 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -0500123}
124
125const std::string &Shader::getLabel() const
126{
Jamie Madill15243d92016-04-26 13:41:35 -0400127 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -0500128}
129
daniel@transgaming.com6c785212010-03-30 03:36:17 +0000130GLuint Shader::getHandle() const
131{
132 return mHandle;
133}
134
shannon.woods%transgaming.com@gtempaccount.com5f339332013-04-13 03:29:02 +0000135void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000136{
Geoff Lang536d7262013-08-26 17:04:20 -0400137 std::ostringstream stream;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138
139 for (int i = 0; i < count; i++)
140 {
Geoff Langf60fab62014-11-24 11:21:20 -0500141 if (length == nullptr || length[i] < 0)
142 {
Jamie Madille7cfb3d2014-12-03 10:58:56 -0500143 stream.write(string[i], strlen(string[i]));
Geoff Langf60fab62014-11-24 11:21:20 -0500144 }
145 else
146 {
147 stream.write(string[i], length[i]);
148 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149 }
150
Jamie Madill15243d92016-04-26 13:41:35 -0400151 mState.mSource = stream.str();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152}
153
Jamie Madillbd044ed2017-06-05 12:59:21 -0400154int Shader::getInfoLogLength(const Context *context)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000155{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400156 resolveCompile(context);
Jamie Madill006cbc52015-09-23 16:47:54 -0400157 if (mInfoLog.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400158 {
159 return 0;
160 }
161
Jamie Madill006cbc52015-09-23 16:47:54 -0400162 return (static_cast<int>(mInfoLog.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000163}
164
Jamie Madillbd044ed2017-06-05 12:59:21 -0400165void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000166{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400167 resolveCompile(context);
168
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000169 int index = 0;
170
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000171 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000172 {
Jamie Madill006cbc52015-09-23 16:47:54 -0400173 index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
174 memcpy(infoLog, mInfoLog.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000175
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000176 infoLog[index] = '\0';
177 }
178
179 if (length)
180 {
181 *length = index;
182 }
183}
184
185int Shader::getSourceLength() const
186{
Jamie Madill15243d92016-04-26 13:41:35 -0400187 return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000188}
189
Jamie Madillbd044ed2017-06-05 12:59:21 -0400190int Shader::getTranslatedSourceLength(const Context *context)
zmo@google.coma574f782011-10-03 21:45:23 +0000191{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400192 resolveCompile(context);
193
Jamie Madill15243d92016-04-26 13:41:35 -0400194 if (mState.mTranslatedSource.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400195 {
196 return 0;
197 }
198
Jamie Madill15243d92016-04-26 13:41:35 -0400199 return (static_cast<int>(mState.mTranslatedSource.length()) + 1);
zmo@google.coma574f782011-10-03 21:45:23 +0000200}
201
Jamie Madillbd044ed2017-06-05 12:59:21 -0400202int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context)
Jamie Madill847638a2015-11-20 13:01:41 -0500203{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400204 resolveCompile(context);
205
Jamie Madill847638a2015-11-20 13:01:41 -0500206 const std::string &debugInfo = mImplementation->getDebugInfo();
207 if (debugInfo.empty())
208 {
209 return 0;
210 }
211
212 return (static_cast<int>(debugInfo.length()) + 1);
213}
214
Jamie Madillbd044ed2017-06-05 12:59:21 -0400215// static
216void Shader::GetSourceImpl(const std::string &source,
217 GLsizei bufSize,
218 GLsizei *length,
219 char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000220{
221 int index = 0;
222
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000223 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000224 {
Geoff Lang536d7262013-08-26 17:04:20 -0400225 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
226 memcpy(buffer, source.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000227
zmo@google.coma574f782011-10-03 21:45:23 +0000228 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000229 }
230
231 if (length)
232 {
233 *length = index;
234 }
235}
236
Geoff Lang536d7262013-08-26 17:04:20 -0400237void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000238{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400239 GetSourceImpl(mState.mSource, bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000240}
241
Jamie Madillbd044ed2017-06-05 12:59:21 -0400242void Shader::getTranslatedSource(const Context *context,
243 GLsizei bufSize,
244 GLsizei *length,
245 char *buffer)
zmo@google.coma574f782011-10-03 21:45:23 +0000246{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400247 GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000248}
249
Jamie Madillbd044ed2017-06-05 12:59:21 -0400250const std::string &Shader::getTranslatedSource(const Context *context)
Tibor den Ouden97049c62014-10-06 21:39:16 +0200251{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400252 resolveCompile(context);
253 return mState.mTranslatedSource;
254}
255
256void Shader::getTranslatedSourceWithDebugInfo(const Context *context,
257 GLsizei bufSize,
258 GLsizei *length,
259 char *buffer)
260{
261 resolveCompile(context);
Jamie Madill847638a2015-11-20 13:01:41 -0500262 const std::string &debugInfo = mImplementation->getDebugInfo();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400263 GetSourceImpl(debugInfo, bufSize, length, buffer);
Tibor den Ouden97049c62014-10-06 21:39:16 +0200264}
265
Bryan Bernhart619c8332016-11-09 11:11:41 -0800266void Shader::compile(const Context *context)
Jamie Madillbf9cce22014-07-18 10:33:09 -0400267{
Jamie Madill15243d92016-04-26 13:41:35 -0400268 mState.mTranslatedSource.clear();
Jamie Madill006cbc52015-09-23 16:47:54 -0400269 mInfoLog.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400270 mState.mShaderVersion = 100;
Jiawei Shao3d404882017-10-16 13:30:48 +0800271 mState.mInputVaryings.clear();
272 mState.mOutputVaryings.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400273 mState.mUniforms.clear();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800274 mState.mUniformBlocks.clear();
275 mState.mShaderStorageBlocks.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400276 mState.mActiveAttributes.clear();
277 mState.mActiveOutputVariables.clear();
Martin Radev7cf61662017-07-26 17:10:53 +0300278 mState.mNumViews = -1;
Jamie Madill91445bc2015-09-23 16:47:53 -0400279
Jamie Madill34ca4f52017-06-13 11:49:39 -0400280 mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
Jamie Madill4928b7c2017-06-20 12:57:39 -0400281 mBoundCompiler.set(context, context->getCompiler());
Jamie Madillbd044ed2017-06-05 12:59:21 -0400282
283 // Cache the compile source and options for compilation. Must be done now, since the source
284 // can change before the link call or another call that resolves the compile.
Jamie Madill006cbc52015-09-23 16:47:54 -0400285
286 std::stringstream sourceStream;
287
Jamie Madillbd044ed2017-06-05 12:59:21 -0400288 mLastCompileOptions =
289 mImplementation->prepareSourceAndReturnOptions(&sourceStream, &mLastCompiledSourcePath);
290 mLastCompileOptions |= (SH_OBJECT_CODE | SH_VARIABLES);
291 mLastCompiledSource = sourceStream.str();
Jamie Madill006cbc52015-09-23 16:47:54 -0400292
Bryan Bernhart619c8332016-11-09 11:11:41 -0800293 // Add default options to WebGL shaders to prevent unexpected behavior during compilation.
294 if (context->getExtensions().webglCompatibility)
295 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400296 mLastCompileOptions |= SH_INIT_GL_POSITION;
297 mLastCompileOptions |= SH_LIMIT_CALL_STACK_DEPTH;
298 mLastCompileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY;
299 mLastCompileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS;
Bryan Bernhart619c8332016-11-09 11:11:41 -0800300 }
301
Jamie Madill006cbc52015-09-23 16:47:54 -0400302 // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
303 // in fragment shaders. Shader compilation will fail. To provide a better error message we can
304 // instruct the compiler to pre-validate.
305 if (mRendererLimitations.shadersRequireIndexedLoopValidation)
306 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400307 mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING;
Jamie Madill006cbc52015-09-23 16:47:54 -0400308 }
Jamie Madillbd044ed2017-06-05 12:59:21 -0400309}
Jamie Madill006cbc52015-09-23 16:47:54 -0400310
Jamie Madillbd044ed2017-06-05 12:59:21 -0400311void Shader::resolveCompile(const Context *context)
312{
Jamie Madill34ca4f52017-06-13 11:49:39 -0400313 if (!mState.compilePending())
Jamie Madilld2c52e32015-10-14 17:07:05 -0400314 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400315 return;
Jamie Madilld2c52e32015-10-14 17:07:05 -0400316 }
317
Jamie Madillbd044ed2017-06-05 12:59:21 -0400318 ASSERT(mBoundCompiler.get());
319 ShHandle compilerHandle = mBoundCompiler->getCompilerHandle(mState.mShaderType);
Jamie Madilld2c52e32015-10-14 17:07:05 -0400320
Jamie Madillbd044ed2017-06-05 12:59:21 -0400321 std::vector<const char *> srcStrings;
Jamie Madill006cbc52015-09-23 16:47:54 -0400322
Jamie Madillbd044ed2017-06-05 12:59:21 -0400323 if (!mLastCompiledSourcePath.empty())
324 {
325 srcStrings.push_back(mLastCompiledSourcePath.c_str());
326 }
327
328 srcStrings.push_back(mLastCompiledSource.c_str());
329
330 if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions))
Jamie Madill006cbc52015-09-23 16:47:54 -0400331 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500332 mInfoLog = sh::GetInfoLog(compilerHandle);
Yuly Novikovd73f8522017-01-13 17:48:57 -0500333 WARN() << std::endl << mInfoLog;
Jamie Madill34ca4f52017-06-13 11:49:39 -0400334 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
Jamie Madill006cbc52015-09-23 16:47:54 -0400335 return;
336 }
337
Jamie Madillacb4b812016-11-07 13:50:29 -0500338 mState.mTranslatedSource = sh::GetObjectCode(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400339
Jamie Madillbd044ed2017-06-05 12:59:21 -0400340#if !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400341 // Prefix translated shader with commented out un-translated shader.
342 // Useful in diagnostics tools which capture the shader source.
343 std::ostringstream shaderStream;
344 shaderStream << "// GLSL\n";
345 shaderStream << "//\n";
346
Geoff Lang9e1bf102017-03-28 15:10:48 -0400347 std::istringstream inputSourceStream(mState.mSource);
348 std::string line;
349 while (std::getline(inputSourceStream, line))
Jamie Madill006cbc52015-09-23 16:47:54 -0400350 {
Geoff Lang9e1bf102017-03-28 15:10:48 -0400351 // Remove null characters from the source line
352 line.erase(std::remove(line.begin(), line.end(), '\0'), line.end());
Jamie Madill006cbc52015-09-23 16:47:54 -0400353
Geoff Langab4be842017-07-18 11:23:07 -0400354 shaderStream << "// " << line << std::endl;
Jamie Madill006cbc52015-09-23 16:47:54 -0400355 }
356 shaderStream << "\n\n";
Jamie Madill15243d92016-04-26 13:41:35 -0400357 shaderStream << mState.mTranslatedSource;
358 mState.mTranslatedSource = shaderStream.str();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400359#endif // !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400360
361 // Gather the shader information
Jamie Madillacb4b812016-11-07 13:50:29 -0500362 mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400363
Jamie Madillacb4b812016-11-07 13:50:29 -0500364 mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle));
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800365 mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
366 mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
Jamie Madill006cbc52015-09-23 16:47:54 -0400367
Martin Radev4c4c8e72016-08-04 12:25:34 +0300368 switch (mState.mShaderType)
Jamie Madill006cbc52015-09-23 16:47:54 -0400369 {
Martin Radev4c4c8e72016-08-04 12:25:34 +0300370 case GL_COMPUTE_SHADER:
371 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500372 mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle);
Martin Radev4c4c8e72016-08-04 12:25:34 +0300373 break;
374 }
375 case GL_VERTEX_SHADER:
376 {
Martin Radev7cf61662017-07-26 17:10:53 +0300377 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800378 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
Martin Radev7cf61662017-07-26 17:10:53 +0300379 mState.mActiveAttributes =
380 GetActiveShaderVariables(sh::GetAttributes(compilerHandle));
381 mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
382 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300383 break;
384 }
385 case GL_FRAGMENT_SHADER:
386 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800387 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300388 // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
Jiawei Shao3d404882017-10-16 13:30:48 +0800389 std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
Martin Radev4c4c8e72016-08-04 12:25:34 +0300390 mState.mActiveOutputVariables =
Jamie Madillacb4b812016-11-07 13:50:29 -0500391 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300392 break;
393 }
394 default:
395 UNREACHABLE();
Jamie Madill006cbc52015-09-23 16:47:54 -0400396 }
397
Jamie Madill15243d92016-04-26 13:41:35 -0400398 ASSERT(!mState.mTranslatedSource.empty());
Jamie Madill006cbc52015-09-23 16:47:54 -0400399
Jamie Madillbd044ed2017-06-05 12:59:21 -0400400 bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog);
Jamie Madill34ca4f52017-06-13 11:49:39 -0400401 mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000402}
403
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000404void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000405{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000406 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000407}
408
Jamie Madill6c1f6712017-02-14 19:08:04 -0500409void Shader::release(const Context *context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000410{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000411 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000412
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000413 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000414 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500415 mResourceManager->deleteShader(context, mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000416 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000417}
418
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000419unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000420{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000421 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000422}
423
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000424bool Shader::isFlaggedForDeletion() const
425{
426 return mDeleteStatus;
427}
428
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000429void Shader::flagForDeletion()
430{
431 mDeleteStatus = true;
432}
433
Jamie Madillbd044ed2017-06-05 12:59:21 -0400434bool Shader::isCompiled(const Context *context)
Jamie Madill80a6fc02015-08-21 16:53:16 -0400435{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400436 resolveCompile(context);
Jamie Madill34ca4f52017-06-13 11:49:39 -0400437 return mState.mCompileStatus == CompileStatus::COMPILED;
Jamie Madillbd044ed2017-06-05 12:59:21 -0400438}
439
440int Shader::getShaderVersion(const Context *context)
441{
442 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400443 return mState.mShaderVersion;
Jamie Madill80a6fc02015-08-21 16:53:16 -0400444}
445
Jiawei Shao3d404882017-10-16 13:30:48 +0800446const std::vector<sh::Varying> &Shader::getInputVaryings(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400447{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400448 resolveCompile(context);
Jiawei Shao3d404882017-10-16 13:30:48 +0800449 return mState.getInputVaryings();
450}
451
452const std::vector<sh::Varying> &Shader::getOutputVaryings(const Context *context)
453{
454 resolveCompile(context);
455 return mState.getOutputVaryings();
Jamie Madilld15250e2014-09-03 09:40:44 -0400456}
457
Jamie Madillbd044ed2017-06-05 12:59:21 -0400458const std::vector<sh::Uniform> &Shader::getUniforms(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400459{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400460 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400461 return mState.getUniforms();
Jamie Madilld15250e2014-09-03 09:40:44 -0400462}
463
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800464const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400465{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400466 resolveCompile(context);
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800467 return mState.getUniformBlocks();
468}
469
470const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks(const Context *context)
471{
472 resolveCompile(context);
473 return mState.getShaderStorageBlocks();
Jamie Madilld15250e2014-09-03 09:40:44 -0400474}
475
Jamie Madillbd044ed2017-06-05 12:59:21 -0400476const std::vector<sh::Attribute> &Shader::getActiveAttributes(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400477{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400478 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400479 return mState.getActiveAttributes();
Jamie Madilld15250e2014-09-03 09:40:44 -0400480}
481
Jamie Madillbd044ed2017-06-05 12:59:21 -0400482const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400483{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400484 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400485 return mState.getActiveOutputVariables();
Jamie Madilld15250e2014-09-03 09:40:44 -0400486}
487
Olli Etuaho855d9642017-05-17 14:05:06 +0300488std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
489 const Context *context)
490{
Jiawei Shao3d404882017-10-16 13:30:48 +0800491 // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader.
492 ASSERT(mState.getShaderType() == GL_VERTEX_SHADER);
493 const auto &varyings = getOutputVaryings(context);
Olli Etuaho855d9642017-05-17 14:05:06 +0300494 auto bracketPos = tfVaryingName.find("[");
495 if (bracketPos != std::string::npos)
496 {
497 auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos);
498 for (const auto &varying : varyings)
499 {
500 if (varying.name == tfVaryingBaseName)
501 {
502 std::string mappedNameWithArrayIndex =
503 varying.mappedName + tfVaryingName.substr(bracketPos);
504 return mappedNameWithArrayIndex;
505 }
506 }
507 }
508 else
509 {
510 for (const auto &varying : varyings)
511 {
512 if (varying.name == tfVaryingName)
513 {
514 return varying.mappedName;
515 }
516 }
517 }
518 UNREACHABLE();
519 return std::string();
520}
521
Jamie Madillbd044ed2017-06-05 12:59:21 -0400522const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
523{
524 resolveCompile(context);
525 return mState.mLocalSize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000526}
Jamie Madillbd044ed2017-06-05 12:59:21 -0400527
Martin Radev7cf61662017-07-26 17:10:53 +0300528int Shader::getNumViews(const Context *context)
529{
530 resolveCompile(context);
531 return mState.mNumViews;
532}
533
Jamie Madill32447362017-06-28 14:53:52 -0400534const std::string &Shader::getCompilerResourcesString() const
535{
536 ASSERT(mBoundCompiler.get());
537 return mBoundCompiler->getBuiltinResourcesString(mState.mShaderType);
538}
539
Jamie Madillbd044ed2017-06-05 12:59:21 -0400540} // namespace gl