blob: d732b4097ad43082b80d22ad9a645c444c96cb3c [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 {
Olli Etuaho465835d2017-09-26 13:34:10 +030060 return x.getArraySizeProduct() > y.getArraySizeProduct();
Jamie Madill006cbc52015-09-23 16:47:54 -040061 }
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
Jiawei Shao881b7bf2017-12-25 11:18:37 +080077const char *GetShaderTypeString(GLenum type)
78{
79 switch (type)
80 {
81 case GL_VERTEX_SHADER:
82 return "VERTEX";
83
84 case GL_FRAGMENT_SHADER:
85 return "FRAGMENT";
86
87 case GL_COMPUTE_SHADER:
88 return "COMPUTE";
89
90 case GL_GEOMETRY_SHADER_EXT:
91 return "GEOMETRY";
92
93 default:
94 UNREACHABLE();
95 return "";
96 }
97}
98
Jamie Madill34ca4f52017-06-13 11:49:39 -040099ShaderState::ShaderState(GLenum shaderType)
100 : mLabel(),
101 mShaderType(shaderType),
102 mShaderVersion(100),
Martin Radev7cf61662017-07-26 17:10:53 +0300103 mNumViews(-1),
Jiawei Shao89be29a2017-11-06 14:36:45 +0800104 mGeometryShaderInputPrimitiveType(GL_INVALID_VALUE),
105 mGeometryShaderOutputPrimitiveType(GL_INVALID_VALUE),
106 mGeometryShaderInvocations(1),
107 mGeometryShaderMaxVertices(-1),
Jamie Madill34ca4f52017-06-13 11:49:39 -0400108 mCompileStatus(CompileStatus::NOT_COMPILED)
Jamie Madill91445bc2015-09-23 16:47:53 -0400109{
Martin Radev4c4c8e72016-08-04 12:25:34 +0300110 mLocalSize.fill(-1);
Jamie Madill91445bc2015-09-23 16:47:53 -0400111}
112
Jamie Madill15243d92016-04-26 13:41:35 -0400113ShaderState::~ShaderState()
Jamie Madill91445bc2015-09-23 16:47:53 -0400114{
115}
116
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500117Shader::Shader(ShaderProgramManager *manager,
Jamie Madill7aea7e02016-05-10 10:39:45 -0400118 rx::GLImplFactory *implFactory,
Jamie Madill006cbc52015-09-23 16:47:54 -0400119 const gl::Limitations &rendererLimitations,
120 GLenum type,
121 GLuint handle)
Jamie Madill15243d92016-04-26 13:41:35 -0400122 : mState(type),
123 mImplementation(implFactory->createShader(mState)),
Jamie Madill006cbc52015-09-23 16:47:54 -0400124 mRendererLimitations(rendererLimitations),
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700125 mHandle(handle),
Corentin Wallezbc99bb62015-05-14 17:42:20 -0400126 mType(type),
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700127 mRefCount(0),
128 mDeleteStatus(false),
Corentin Wallezbc99bb62015-05-14 17:42:20 -0400129 mResourceManager(manager)
Jamie Madille294bb82014-07-17 14:16:26 -0400130{
Jamie Madill91445bc2015-09-23 16:47:53 -0400131 ASSERT(mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000132}
133
Jamie Madill4928b7c2017-06-20 12:57:39 -0400134void Shader::onDestroy(const gl::Context *context)
135{
136 mBoundCompiler.set(context, nullptr);
137 mImplementation.reset(nullptr);
138 delete this;
139}
140
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000141Shader::~Shader()
142{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400143 ASSERT(!mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144}
145
Geoff Lang70d0f492015-12-10 17:45:46 -0500146void Shader::setLabel(const std::string &label)
147{
Jamie Madill15243d92016-04-26 13:41:35 -0400148 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -0500149}
150
151const std::string &Shader::getLabel() const
152{
Jamie Madill15243d92016-04-26 13:41:35 -0400153 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -0500154}
155
daniel@transgaming.com6c785212010-03-30 03:36:17 +0000156GLuint Shader::getHandle() const
157{
158 return mHandle;
159}
160
shannon.woods%transgaming.com@gtempaccount.com5f339332013-04-13 03:29:02 +0000161void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162{
Geoff Lang536d7262013-08-26 17:04:20 -0400163 std::ostringstream stream;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164
165 for (int i = 0; i < count; i++)
166 {
Geoff Langf60fab62014-11-24 11:21:20 -0500167 if (length == nullptr || length[i] < 0)
168 {
Jamie Madille7cfb3d2014-12-03 10:58:56 -0500169 stream.write(string[i], strlen(string[i]));
Geoff Langf60fab62014-11-24 11:21:20 -0500170 }
171 else
172 {
173 stream.write(string[i], length[i]);
174 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000175 }
176
Jamie Madill15243d92016-04-26 13:41:35 -0400177 mState.mSource = stream.str();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178}
179
Jamie Madillbd044ed2017-06-05 12:59:21 -0400180int Shader::getInfoLogLength(const Context *context)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000181{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400182 resolveCompile(context);
Jamie Madill006cbc52015-09-23 16:47:54 -0400183 if (mInfoLog.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400184 {
185 return 0;
186 }
187
Jamie Madill006cbc52015-09-23 16:47:54 -0400188 return (static_cast<int>(mInfoLog.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000189}
190
Jamie Madillbd044ed2017-06-05 12:59:21 -0400191void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000192{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400193 resolveCompile(context);
194
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000195 int index = 0;
196
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000197 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000198 {
Jamie Madill006cbc52015-09-23 16:47:54 -0400199 index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
200 memcpy(infoLog, mInfoLog.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000201
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000202 infoLog[index] = '\0';
203 }
204
205 if (length)
206 {
207 *length = index;
208 }
209}
210
211int Shader::getSourceLength() const
212{
Jamie Madill15243d92016-04-26 13:41:35 -0400213 return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000214}
215
Jamie Madillbd044ed2017-06-05 12:59:21 -0400216int Shader::getTranslatedSourceLength(const Context *context)
zmo@google.coma574f782011-10-03 21:45:23 +0000217{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400218 resolveCompile(context);
219
Jamie Madill15243d92016-04-26 13:41:35 -0400220 if (mState.mTranslatedSource.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400221 {
222 return 0;
223 }
224
Jamie Madill15243d92016-04-26 13:41:35 -0400225 return (static_cast<int>(mState.mTranslatedSource.length()) + 1);
zmo@google.coma574f782011-10-03 21:45:23 +0000226}
227
Jamie Madillbd044ed2017-06-05 12:59:21 -0400228int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context)
Jamie Madill847638a2015-11-20 13:01:41 -0500229{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400230 resolveCompile(context);
231
Jamie Madill847638a2015-11-20 13:01:41 -0500232 const std::string &debugInfo = mImplementation->getDebugInfo();
233 if (debugInfo.empty())
234 {
235 return 0;
236 }
237
238 return (static_cast<int>(debugInfo.length()) + 1);
239}
240
Jamie Madillbd044ed2017-06-05 12:59:21 -0400241// static
242void Shader::GetSourceImpl(const std::string &source,
243 GLsizei bufSize,
244 GLsizei *length,
245 char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000246{
247 int index = 0;
248
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000249 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000250 {
Geoff Lang536d7262013-08-26 17:04:20 -0400251 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
252 memcpy(buffer, source.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000253
zmo@google.coma574f782011-10-03 21:45:23 +0000254 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000255 }
256
257 if (length)
258 {
259 *length = index;
260 }
261}
262
Geoff Lang536d7262013-08-26 17:04:20 -0400263void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000264{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400265 GetSourceImpl(mState.mSource, bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000266}
267
Jamie Madillbd044ed2017-06-05 12:59:21 -0400268void Shader::getTranslatedSource(const Context *context,
269 GLsizei bufSize,
270 GLsizei *length,
271 char *buffer)
zmo@google.coma574f782011-10-03 21:45:23 +0000272{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400273 GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000274}
275
Jamie Madillbd044ed2017-06-05 12:59:21 -0400276const std::string &Shader::getTranslatedSource(const Context *context)
Tibor den Ouden97049c62014-10-06 21:39:16 +0200277{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400278 resolveCompile(context);
279 return mState.mTranslatedSource;
280}
281
282void Shader::getTranslatedSourceWithDebugInfo(const Context *context,
283 GLsizei bufSize,
284 GLsizei *length,
285 char *buffer)
286{
287 resolveCompile(context);
Jamie Madill847638a2015-11-20 13:01:41 -0500288 const std::string &debugInfo = mImplementation->getDebugInfo();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400289 GetSourceImpl(debugInfo, bufSize, length, buffer);
Tibor den Ouden97049c62014-10-06 21:39:16 +0200290}
291
Bryan Bernhart619c8332016-11-09 11:11:41 -0800292void Shader::compile(const Context *context)
Jamie Madillbf9cce22014-07-18 10:33:09 -0400293{
Jamie Madill15243d92016-04-26 13:41:35 -0400294 mState.mTranslatedSource.clear();
Jamie Madill006cbc52015-09-23 16:47:54 -0400295 mInfoLog.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400296 mState.mShaderVersion = 100;
Jiawei Shao3d404882017-10-16 13:30:48 +0800297 mState.mInputVaryings.clear();
298 mState.mOutputVaryings.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400299 mState.mUniforms.clear();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800300 mState.mUniformBlocks.clear();
301 mState.mShaderStorageBlocks.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400302 mState.mActiveAttributes.clear();
303 mState.mActiveOutputVariables.clear();
Martin Radev7cf61662017-07-26 17:10:53 +0300304 mState.mNumViews = -1;
Jiawei Shao89be29a2017-11-06 14:36:45 +0800305 mState.mGeometryShaderInputPrimitiveType = GL_INVALID_VALUE;
306 mState.mGeometryShaderOutputPrimitiveType = GL_INVALID_VALUE;
307 mState.mGeometryShaderInvocations = 1;
308 mState.mGeometryShaderMaxVertices = -1;
Jamie Madill91445bc2015-09-23 16:47:53 -0400309
Jamie Madill34ca4f52017-06-13 11:49:39 -0400310 mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
Jamie Madill4928b7c2017-06-20 12:57:39 -0400311 mBoundCompiler.set(context, context->getCompiler());
Jamie Madillbd044ed2017-06-05 12:59:21 -0400312
313 // Cache the compile source and options for compilation. Must be done now, since the source
314 // can change before the link call or another call that resolves the compile.
Jamie Madill006cbc52015-09-23 16:47:54 -0400315
316 std::stringstream sourceStream;
317
Jamie Madillbd044ed2017-06-05 12:59:21 -0400318 mLastCompileOptions =
319 mImplementation->prepareSourceAndReturnOptions(&sourceStream, &mLastCompiledSourcePath);
320 mLastCompileOptions |= (SH_OBJECT_CODE | SH_VARIABLES);
321 mLastCompiledSource = sourceStream.str();
Jamie Madill006cbc52015-09-23 16:47:54 -0400322
Bryan Bernhart619c8332016-11-09 11:11:41 -0800323 // Add default options to WebGL shaders to prevent unexpected behavior during compilation.
324 if (context->getExtensions().webglCompatibility)
325 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400326 mLastCompileOptions |= SH_INIT_GL_POSITION;
327 mLastCompileOptions |= SH_LIMIT_CALL_STACK_DEPTH;
328 mLastCompileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY;
329 mLastCompileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS;
Bryan Bernhart619c8332016-11-09 11:11:41 -0800330 }
331
Jamie Madill006cbc52015-09-23 16:47:54 -0400332 // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
333 // in fragment shaders. Shader compilation will fail. To provide a better error message we can
334 // instruct the compiler to pre-validate.
335 if (mRendererLimitations.shadersRequireIndexedLoopValidation)
336 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400337 mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING;
Jamie Madill006cbc52015-09-23 16:47:54 -0400338 }
Jamie Madillbd044ed2017-06-05 12:59:21 -0400339}
Jamie Madill006cbc52015-09-23 16:47:54 -0400340
Jamie Madillbd044ed2017-06-05 12:59:21 -0400341void Shader::resolveCompile(const Context *context)
342{
Jamie Madill34ca4f52017-06-13 11:49:39 -0400343 if (!mState.compilePending())
Jamie Madilld2c52e32015-10-14 17:07:05 -0400344 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400345 return;
Jamie Madilld2c52e32015-10-14 17:07:05 -0400346 }
347
Jamie Madillbd044ed2017-06-05 12:59:21 -0400348 ASSERT(mBoundCompiler.get());
349 ShHandle compilerHandle = mBoundCompiler->getCompilerHandle(mState.mShaderType);
Jamie Madilld2c52e32015-10-14 17:07:05 -0400350
Jamie Madillbd044ed2017-06-05 12:59:21 -0400351 std::vector<const char *> srcStrings;
Jamie Madill006cbc52015-09-23 16:47:54 -0400352
Jamie Madillbd044ed2017-06-05 12:59:21 -0400353 if (!mLastCompiledSourcePath.empty())
354 {
355 srcStrings.push_back(mLastCompiledSourcePath.c_str());
356 }
357
358 srcStrings.push_back(mLastCompiledSource.c_str());
359
360 if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions))
Jamie Madill006cbc52015-09-23 16:47:54 -0400361 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500362 mInfoLog = sh::GetInfoLog(compilerHandle);
Yuly Novikovd73f8522017-01-13 17:48:57 -0500363 WARN() << std::endl << mInfoLog;
Jamie Madill34ca4f52017-06-13 11:49:39 -0400364 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
Jamie Madill006cbc52015-09-23 16:47:54 -0400365 return;
366 }
367
Jamie Madillacb4b812016-11-07 13:50:29 -0500368 mState.mTranslatedSource = sh::GetObjectCode(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400369
Jamie Madillbd044ed2017-06-05 12:59:21 -0400370#if !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400371 // Prefix translated shader with commented out un-translated shader.
372 // Useful in diagnostics tools which capture the shader source.
373 std::ostringstream shaderStream;
374 shaderStream << "// GLSL\n";
375 shaderStream << "//\n";
376
Geoff Lang9e1bf102017-03-28 15:10:48 -0400377 std::istringstream inputSourceStream(mState.mSource);
378 std::string line;
379 while (std::getline(inputSourceStream, line))
Jamie Madill006cbc52015-09-23 16:47:54 -0400380 {
Geoff Lang9e1bf102017-03-28 15:10:48 -0400381 // Remove null characters from the source line
382 line.erase(std::remove(line.begin(), line.end(), '\0'), line.end());
Jamie Madill006cbc52015-09-23 16:47:54 -0400383
Geoff Langab4be842017-07-18 11:23:07 -0400384 shaderStream << "// " << line << std::endl;
Jamie Madill006cbc52015-09-23 16:47:54 -0400385 }
386 shaderStream << "\n\n";
Jamie Madill15243d92016-04-26 13:41:35 -0400387 shaderStream << mState.mTranslatedSource;
388 mState.mTranslatedSource = shaderStream.str();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400389#endif // !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400390
391 // Gather the shader information
Jamie Madillacb4b812016-11-07 13:50:29 -0500392 mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400393
Jamie Madillacb4b812016-11-07 13:50:29 -0500394 mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle));
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800395 mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
396 mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
Jamie Madill006cbc52015-09-23 16:47:54 -0400397
Martin Radev4c4c8e72016-08-04 12:25:34 +0300398 switch (mState.mShaderType)
Jamie Madill006cbc52015-09-23 16:47:54 -0400399 {
Martin Radev4c4c8e72016-08-04 12:25:34 +0300400 case GL_COMPUTE_SHADER:
401 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500402 mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle);
Martin Radev4c4c8e72016-08-04 12:25:34 +0300403 break;
404 }
405 case GL_VERTEX_SHADER:
406 {
Martin Radev7cf61662017-07-26 17:10:53 +0300407 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800408 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
Martin Radev7cf61662017-07-26 17:10:53 +0300409 mState.mActiveAttributes =
410 GetActiveShaderVariables(sh::GetAttributes(compilerHandle));
411 mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
412 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300413 break;
414 }
415 case GL_FRAGMENT_SHADER:
416 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800417 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300418 // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
Jiawei Shao3d404882017-10-16 13:30:48 +0800419 std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
Martin Radev4c4c8e72016-08-04 12:25:34 +0300420 mState.mActiveOutputVariables =
Jamie Madillacb4b812016-11-07 13:50:29 -0500421 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300422 break;
423 }
Jiawei Shao89be29a2017-11-06 14:36:45 +0800424 case GL_GEOMETRY_SHADER_EXT:
425 {
426 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
427 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
428
429 mState.mGeometryShaderInputPrimitiveType =
430 sh::GetGeometryShaderInputPrimitiveType(compilerHandle);
431 mState.mGeometryShaderOutputPrimitiveType =
432 sh::GetGeometryShaderOutputPrimitiveType(compilerHandle);
433 mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
434 mState.mGeometryShaderMaxVertices = sh::GetGeometryShaderMaxVertices(compilerHandle);
435 break;
436 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300437 default:
438 UNREACHABLE();
Jamie Madill006cbc52015-09-23 16:47:54 -0400439 }
440
Jamie Madill15243d92016-04-26 13:41:35 -0400441 ASSERT(!mState.mTranslatedSource.empty());
Jamie Madill006cbc52015-09-23 16:47:54 -0400442
Jamie Madillbd044ed2017-06-05 12:59:21 -0400443 bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog);
Jamie Madill34ca4f52017-06-13 11:49:39 -0400444 mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000445}
446
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000447void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000448{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000449 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000450}
451
Jamie Madill6c1f6712017-02-14 19:08:04 -0500452void Shader::release(const Context *context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000453{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000454 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000455
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000456 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000457 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500458 mResourceManager->deleteShader(context, mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000459 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000460}
461
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000462unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000463{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000464 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000465}
466
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000467bool Shader::isFlaggedForDeletion() const
468{
469 return mDeleteStatus;
470}
471
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000472void Shader::flagForDeletion()
473{
474 mDeleteStatus = true;
475}
476
Jamie Madillbd044ed2017-06-05 12:59:21 -0400477bool Shader::isCompiled(const Context *context)
Jamie Madill80a6fc02015-08-21 16:53:16 -0400478{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400479 resolveCompile(context);
Jamie Madill34ca4f52017-06-13 11:49:39 -0400480 return mState.mCompileStatus == CompileStatus::COMPILED;
Jamie Madillbd044ed2017-06-05 12:59:21 -0400481}
482
483int Shader::getShaderVersion(const Context *context)
484{
485 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400486 return mState.mShaderVersion;
Jamie Madill80a6fc02015-08-21 16:53:16 -0400487}
488
Jiawei Shao3d404882017-10-16 13:30:48 +0800489const std::vector<sh::Varying> &Shader::getInputVaryings(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400490{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400491 resolveCompile(context);
Jiawei Shao3d404882017-10-16 13:30:48 +0800492 return mState.getInputVaryings();
493}
494
495const std::vector<sh::Varying> &Shader::getOutputVaryings(const Context *context)
496{
497 resolveCompile(context);
498 return mState.getOutputVaryings();
Jamie Madilld15250e2014-09-03 09:40:44 -0400499}
500
Jamie Madillbd044ed2017-06-05 12:59:21 -0400501const std::vector<sh::Uniform> &Shader::getUniforms(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400502{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400503 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400504 return mState.getUniforms();
Jamie Madilld15250e2014-09-03 09:40:44 -0400505}
506
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800507const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400508{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400509 resolveCompile(context);
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800510 return mState.getUniformBlocks();
511}
512
513const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks(const Context *context)
514{
515 resolveCompile(context);
516 return mState.getShaderStorageBlocks();
Jamie Madilld15250e2014-09-03 09:40:44 -0400517}
518
Jamie Madillbd044ed2017-06-05 12:59:21 -0400519const std::vector<sh::Attribute> &Shader::getActiveAttributes(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400520{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400521 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400522 return mState.getActiveAttributes();
Jamie Madilld15250e2014-09-03 09:40:44 -0400523}
524
Jamie Madillbd044ed2017-06-05 12:59:21 -0400525const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400526{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400527 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400528 return mState.getActiveOutputVariables();
Jamie Madilld15250e2014-09-03 09:40:44 -0400529}
530
Olli Etuaho855d9642017-05-17 14:05:06 +0300531std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
532 const Context *context)
533{
Jiawei Shao3d404882017-10-16 13:30:48 +0800534 // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader.
535 ASSERT(mState.getShaderType() == GL_VERTEX_SHADER);
536 const auto &varyings = getOutputVaryings(context);
Olli Etuaho855d9642017-05-17 14:05:06 +0300537 auto bracketPos = tfVaryingName.find("[");
538 if (bracketPos != std::string::npos)
539 {
540 auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos);
541 for (const auto &varying : varyings)
542 {
543 if (varying.name == tfVaryingBaseName)
544 {
545 std::string mappedNameWithArrayIndex =
546 varying.mappedName + tfVaryingName.substr(bracketPos);
547 return mappedNameWithArrayIndex;
548 }
549 }
550 }
551 else
552 {
553 for (const auto &varying : varyings)
554 {
555 if (varying.name == tfVaryingName)
556 {
557 return varying.mappedName;
558 }
jchen108225e732017-11-14 16:29:03 +0800559 else if (varying.isStruct())
560 {
561 const auto *field = FindShaderVarField(varying, tfVaryingName);
562 ASSERT(field != nullptr && !field->isStruct() && !field->isArray());
563 return varying.mappedName + "." + field->mappedName;
564 }
Olli Etuaho855d9642017-05-17 14:05:06 +0300565 }
566 }
567 UNREACHABLE();
568 return std::string();
569}
570
Jamie Madillbd044ed2017-06-05 12:59:21 -0400571const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
572{
573 resolveCompile(context);
574 return mState.mLocalSize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000575}
Jamie Madillbd044ed2017-06-05 12:59:21 -0400576
Martin Radev7cf61662017-07-26 17:10:53 +0300577int Shader::getNumViews(const Context *context)
578{
579 resolveCompile(context);
580 return mState.mNumViews;
581}
582
Jamie Madill32447362017-06-28 14:53:52 -0400583const std::string &Shader::getCompilerResourcesString() const
584{
585 ASSERT(mBoundCompiler.get());
586 return mBoundCompiler->getBuiltinResourcesString(mState.mShaderType);
587}
588
Jamie Madillbd044ed2017-06-05 12:59:21 -0400589} // namespace gl