blob: 9eb2d5bda97057251a26320593b018ae979f1439 [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 "GLSLANG/ShaderLang.h"
Jamie Madill493f9572018-05-24 19:52:15 -040016#include "common/utilities.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 Madill493f9572018-05-24 19:52:15 -040020#include "libANGLE/Context.h"
21#include "libANGLE/ResourceManager.h"
Jamie Madill53ea9cc2016-05-17 10:12:52 -040022#include "libANGLE/renderer/GLImplFactory.h"
Jamie Madill91445bc2015-09-23 16:47:53 -040023#include "libANGLE/renderer/ShaderImpl.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);
Olli Etuaho107c7242018-03-20 15:45:35 +020038 if (var.active)
Jamie Madill006cbc52015-09-23 16:47:54 -040039 {
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 Shao385b3e02018-03-21 09:43:28 +080077const char *GetShaderTypeString(ShaderType type)
Jiawei Shao881b7bf2017-12-25 11:18:37 +080078{
79 switch (type)
80 {
Jiawei Shao385b3e02018-03-21 09:43:28 +080081 case ShaderType::Vertex:
Jiawei Shao881b7bf2017-12-25 11:18:37 +080082 return "VERTEX";
83
Jiawei Shao385b3e02018-03-21 09:43:28 +080084 case ShaderType::Fragment:
Jiawei Shao881b7bf2017-12-25 11:18:37 +080085 return "FRAGMENT";
86
Jiawei Shao385b3e02018-03-21 09:43:28 +080087 case ShaderType::Compute:
Jiawei Shao881b7bf2017-12-25 11:18:37 +080088 return "COMPUTE";
89
Jiawei Shao385b3e02018-03-21 09:43:28 +080090 case ShaderType::Geometry:
Jiawei Shao881b7bf2017-12-25 11:18:37 +080091 return "GEOMETRY";
92
93 default:
94 UNREACHABLE();
95 return "";
96 }
97}
98
Jiawei Shao385b3e02018-03-21 09:43:28 +080099ShaderState::ShaderState(ShaderType shaderType)
Jamie Madill34ca4f52017-06-13 11:49:39 -0400100 : 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 mGeometryShaderInvocations(1),
Jamie Madill34ca4f52017-06-13 11:49:39 -0400105 mCompileStatus(CompileStatus::NOT_COMPILED)
Jamie Madill91445bc2015-09-23 16:47:53 -0400106{
Martin Radev4c4c8e72016-08-04 12:25:34 +0300107 mLocalSize.fill(-1);
Jamie Madill91445bc2015-09-23 16:47:53 -0400108}
109
Jamie Madill15243d92016-04-26 13:41:35 -0400110ShaderState::~ShaderState()
Jamie Madill91445bc2015-09-23 16:47:53 -0400111{
112}
113
Geoff Lang4ddf5af2016-12-01 14:30:44 -0500114Shader::Shader(ShaderProgramManager *manager,
Jamie Madill7aea7e02016-05-10 10:39:45 -0400115 rx::GLImplFactory *implFactory,
Jamie Madill006cbc52015-09-23 16:47:54 -0400116 const gl::Limitations &rendererLimitations,
Jiawei Shao385b3e02018-03-21 09:43:28 +0800117 ShaderType type,
Jamie Madill006cbc52015-09-23 16:47:54 -0400118 GLuint handle)
Jamie Madill15243d92016-04-26 13:41:35 -0400119 : mState(type),
120 mImplementation(implFactory->createShader(mState)),
Jamie Madill006cbc52015-09-23 16:47:54 -0400121 mRendererLimitations(rendererLimitations),
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700122 mHandle(handle),
Corentin Wallezbc99bb62015-05-14 17:42:20 -0400123 mType(type),
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700124 mRefCount(0),
125 mDeleteStatus(false),
Corentin Wallezbc99bb62015-05-14 17:42:20 -0400126 mResourceManager(manager)
Jamie Madille294bb82014-07-17 14:16:26 -0400127{
Jamie Madill91445bc2015-09-23 16:47:53 -0400128 ASSERT(mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000129}
130
Jamie Madill4928b7c2017-06-20 12:57:39 -0400131void Shader::onDestroy(const gl::Context *context)
132{
Geoff Lang58662082018-05-10 13:41:51 -0400133 mImplementation->destroy(context);
Jamie Madill4928b7c2017-06-20 12:57:39 -0400134 mBoundCompiler.set(context, nullptr);
135 mImplementation.reset(nullptr);
136 delete this;
137}
138
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000139Shader::~Shader()
140{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400141 ASSERT(!mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000142}
143
Geoff Lang70d0f492015-12-10 17:45:46 -0500144void Shader::setLabel(const std::string &label)
145{
Jamie Madill15243d92016-04-26 13:41:35 -0400146 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -0500147}
148
149const std::string &Shader::getLabel() const
150{
Jamie Madill15243d92016-04-26 13:41:35 -0400151 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -0500152}
153
daniel@transgaming.com6c785212010-03-30 03:36:17 +0000154GLuint Shader::getHandle() const
155{
156 return mHandle;
157}
158
shannon.woods%transgaming.com@gtempaccount.com5f339332013-04-13 03:29:02 +0000159void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000160{
Geoff Lang536d7262013-08-26 17:04:20 -0400161 std::ostringstream stream;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162
163 for (int i = 0; i < count; i++)
164 {
Geoff Langf60fab62014-11-24 11:21:20 -0500165 if (length == nullptr || length[i] < 0)
166 {
Jamie Madille7cfb3d2014-12-03 10:58:56 -0500167 stream.write(string[i], strlen(string[i]));
Geoff Langf60fab62014-11-24 11:21:20 -0500168 }
169 else
170 {
171 stream.write(string[i], length[i]);
172 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000173 }
174
Jamie Madill15243d92016-04-26 13:41:35 -0400175 mState.mSource = stream.str();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000176}
177
Jamie Madillbd044ed2017-06-05 12:59:21 -0400178int Shader::getInfoLogLength(const Context *context)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000179{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400180 resolveCompile(context);
Jamie Madill006cbc52015-09-23 16:47:54 -0400181 if (mInfoLog.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400182 {
183 return 0;
184 }
185
Jamie Madill006cbc52015-09-23 16:47:54 -0400186 return (static_cast<int>(mInfoLog.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000187}
188
Jamie Madillbd044ed2017-06-05 12:59:21 -0400189void Shader::getInfoLog(const Context *context, GLsizei bufSize, GLsizei *length, char *infoLog)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000190{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400191 resolveCompile(context);
192
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000193 int index = 0;
194
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000195 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000196 {
Jamie Madill006cbc52015-09-23 16:47:54 -0400197 index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
198 memcpy(infoLog, mInfoLog.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000199
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000200 infoLog[index] = '\0';
201 }
202
203 if (length)
204 {
205 *length = index;
206 }
207}
208
209int Shader::getSourceLength() const
210{
Jamie Madill15243d92016-04-26 13:41:35 -0400211 return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000212}
213
Jamie Madillbd044ed2017-06-05 12:59:21 -0400214int Shader::getTranslatedSourceLength(const Context *context)
zmo@google.coma574f782011-10-03 21:45:23 +0000215{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400216 resolveCompile(context);
217
Jamie Madill15243d92016-04-26 13:41:35 -0400218 if (mState.mTranslatedSource.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400219 {
220 return 0;
221 }
222
Jamie Madill15243d92016-04-26 13:41:35 -0400223 return (static_cast<int>(mState.mTranslatedSource.length()) + 1);
zmo@google.coma574f782011-10-03 21:45:23 +0000224}
225
Jamie Madillbd044ed2017-06-05 12:59:21 -0400226int Shader::getTranslatedSourceWithDebugInfoLength(const Context *context)
Jamie Madill847638a2015-11-20 13:01:41 -0500227{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400228 resolveCompile(context);
229
Geoff Lang58662082018-05-10 13:41:51 -0400230 const std::string &debugInfo = mImplementation->getDebugInfo(context);
Jamie Madill847638a2015-11-20 13:01:41 -0500231 if (debugInfo.empty())
232 {
233 return 0;
234 }
235
236 return (static_cast<int>(debugInfo.length()) + 1);
237}
238
Jamie Madillbd044ed2017-06-05 12:59:21 -0400239// static
240void Shader::GetSourceImpl(const std::string &source,
241 GLsizei bufSize,
242 GLsizei *length,
243 char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000244{
245 int index = 0;
246
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000247 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000248 {
Geoff Lang536d7262013-08-26 17:04:20 -0400249 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
250 memcpy(buffer, source.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000251
zmo@google.coma574f782011-10-03 21:45:23 +0000252 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000253 }
254
255 if (length)
256 {
257 *length = index;
258 }
259}
260
Geoff Lang536d7262013-08-26 17:04:20 -0400261void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000262{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400263 GetSourceImpl(mState.mSource, bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000264}
265
Jamie Madillbd044ed2017-06-05 12:59:21 -0400266void Shader::getTranslatedSource(const Context *context,
267 GLsizei bufSize,
268 GLsizei *length,
269 char *buffer)
zmo@google.coma574f782011-10-03 21:45:23 +0000270{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400271 GetSourceImpl(getTranslatedSource(context), bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000272}
273
Jamie Madillbd044ed2017-06-05 12:59:21 -0400274const std::string &Shader::getTranslatedSource(const Context *context)
Tibor den Ouden97049c62014-10-06 21:39:16 +0200275{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400276 resolveCompile(context);
277 return mState.mTranslatedSource;
278}
279
280void Shader::getTranslatedSourceWithDebugInfo(const Context *context,
281 GLsizei bufSize,
282 GLsizei *length,
283 char *buffer)
284{
285 resolveCompile(context);
Geoff Lang58662082018-05-10 13:41:51 -0400286 const std::string &debugInfo = mImplementation->getDebugInfo(context);
Jamie Madillbd044ed2017-06-05 12:59:21 -0400287 GetSourceImpl(debugInfo, bufSize, length, buffer);
Tibor den Ouden97049c62014-10-06 21:39:16 +0200288}
289
Bryan Bernhart619c8332016-11-09 11:11:41 -0800290void Shader::compile(const Context *context)
Jamie Madillbf9cce22014-07-18 10:33:09 -0400291{
Jamie Madill15243d92016-04-26 13:41:35 -0400292 mState.mTranslatedSource.clear();
Jamie Madill006cbc52015-09-23 16:47:54 -0400293 mInfoLog.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400294 mState.mShaderVersion = 100;
Jiawei Shao3d404882017-10-16 13:30:48 +0800295 mState.mInputVaryings.clear();
296 mState.mOutputVaryings.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400297 mState.mUniforms.clear();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800298 mState.mUniformBlocks.clear();
299 mState.mShaderStorageBlocks.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400300 mState.mActiveAttributes.clear();
301 mState.mActiveOutputVariables.clear();
Martin Radev7cf61662017-07-26 17:10:53 +0300302 mState.mNumViews = -1;
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800303 mState.mGeometryShaderInputPrimitiveType.reset();
304 mState.mGeometryShaderOutputPrimitiveType.reset();
305 mState.mGeometryShaderMaxVertices.reset();
306 mState.mGeometryShaderInvocations = 1;
Jamie Madill91445bc2015-09-23 16:47:53 -0400307
Jamie Madill34ca4f52017-06-13 11:49:39 -0400308 mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
Jamie Madill4928b7c2017-06-20 12:57:39 -0400309 mBoundCompiler.set(context, context->getCompiler());
Jamie Madillbd044ed2017-06-05 12:59:21 -0400310
311 // Cache the compile source and options for compilation. Must be done now, since the source
312 // can change before the link call or another call that resolves the compile.
Jamie Madill006cbc52015-09-23 16:47:54 -0400313
314 std::stringstream sourceStream;
315
Geoff Lang58662082018-05-10 13:41:51 -0400316 mLastCompileOptions = mImplementation->prepareSourceAndReturnOptions(context, &sourceStream,
317 &mLastCompiledSourcePath);
Jamie Madillbd044ed2017-06-05 12:59:21 -0400318 mLastCompileOptions |= (SH_OBJECT_CODE | SH_VARIABLES);
319 mLastCompiledSource = sourceStream.str();
Jamie Madill006cbc52015-09-23 16:47:54 -0400320
Bryan Bernhart619c8332016-11-09 11:11:41 -0800321 // Add default options to WebGL shaders to prevent unexpected behavior during compilation.
322 if (context->getExtensions().webglCompatibility)
323 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400324 mLastCompileOptions |= SH_INIT_GL_POSITION;
325 mLastCompileOptions |= SH_LIMIT_CALL_STACK_DEPTH;
326 mLastCompileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY;
327 mLastCompileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS;
Bryan Bernhart619c8332016-11-09 11:11:41 -0800328 }
329
Jamie Madill006cbc52015-09-23 16:47:54 -0400330 // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
331 // in fragment shaders. Shader compilation will fail. To provide a better error message we can
332 // instruct the compiler to pre-validate.
333 if (mRendererLimitations.shadersRequireIndexedLoopValidation)
334 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400335 mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING;
Jamie Madill006cbc52015-09-23 16:47:54 -0400336 }
Jamie Madillbd044ed2017-06-05 12:59:21 -0400337}
Jamie Madill006cbc52015-09-23 16:47:54 -0400338
Jamie Madillbd044ed2017-06-05 12:59:21 -0400339void Shader::resolveCompile(const Context *context)
340{
Jamie Madill34ca4f52017-06-13 11:49:39 -0400341 if (!mState.compilePending())
Jamie Madilld2c52e32015-10-14 17:07:05 -0400342 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400343 return;
Jamie Madilld2c52e32015-10-14 17:07:05 -0400344 }
345
Jamie Madillbd044ed2017-06-05 12:59:21 -0400346 ASSERT(mBoundCompiler.get());
347 ShHandle compilerHandle = mBoundCompiler->getCompilerHandle(mState.mShaderType);
Jamie Madilld2c52e32015-10-14 17:07:05 -0400348
Jamie Madillbd044ed2017-06-05 12:59:21 -0400349 std::vector<const char *> srcStrings;
Jamie Madill006cbc52015-09-23 16:47:54 -0400350
Jamie Madillbd044ed2017-06-05 12:59:21 -0400351 if (!mLastCompiledSourcePath.empty())
352 {
353 srcStrings.push_back(mLastCompiledSourcePath.c_str());
354 }
355
356 srcStrings.push_back(mLastCompiledSource.c_str());
357
358 if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions))
Jamie Madill006cbc52015-09-23 16:47:54 -0400359 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500360 mInfoLog = sh::GetInfoLog(compilerHandle);
Yuly Novikovd73f8522017-01-13 17:48:57 -0500361 WARN() << std::endl << mInfoLog;
Jamie Madill34ca4f52017-06-13 11:49:39 -0400362 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
Jamie Madill006cbc52015-09-23 16:47:54 -0400363 return;
364 }
365
Jamie Madillacb4b812016-11-07 13:50:29 -0500366 mState.mTranslatedSource = sh::GetObjectCode(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400367
Jamie Madillbd044ed2017-06-05 12:59:21 -0400368#if !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400369 // Prefix translated shader with commented out un-translated shader.
370 // Useful in diagnostics tools which capture the shader source.
371 std::ostringstream shaderStream;
372 shaderStream << "// GLSL\n";
373 shaderStream << "//\n";
374
Geoff Lang9e1bf102017-03-28 15:10:48 -0400375 std::istringstream inputSourceStream(mState.mSource);
376 std::string line;
377 while (std::getline(inputSourceStream, line))
Jamie Madill006cbc52015-09-23 16:47:54 -0400378 {
Geoff Lang9e1bf102017-03-28 15:10:48 -0400379 // Remove null characters from the source line
380 line.erase(std::remove(line.begin(), line.end(), '\0'), line.end());
Jamie Madill006cbc52015-09-23 16:47:54 -0400381
Geoff Langab4be842017-07-18 11:23:07 -0400382 shaderStream << "// " << line << std::endl;
Jamie Madill006cbc52015-09-23 16:47:54 -0400383 }
384 shaderStream << "\n\n";
Jamie Madill15243d92016-04-26 13:41:35 -0400385 shaderStream << mState.mTranslatedSource;
386 mState.mTranslatedSource = shaderStream.str();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400387#endif // !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400388
389 // Gather the shader information
Jamie Madillacb4b812016-11-07 13:50:29 -0500390 mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400391
Jamie Madill493f9572018-05-24 19:52:15 -0400392 mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle));
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800393 mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
394 mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
Jamie Madill006cbc52015-09-23 16:47:54 -0400395
Martin Radev4c4c8e72016-08-04 12:25:34 +0300396 switch (mState.mShaderType)
Jamie Madill006cbc52015-09-23 16:47:54 -0400397 {
Jiawei Shao385b3e02018-03-21 09:43:28 +0800398 case ShaderType::Compute:
Martin Radev4c4c8e72016-08-04 12:25:34 +0300399 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500400 mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle);
Xinghua Cao77a2b4c2018-05-21 17:28:29 +0800401 if (mState.mLocalSize.isDeclared())
402 {
403 angle::CheckedNumeric<uint32_t> checked_local_size_product(mState.mLocalSize[0]);
404 checked_local_size_product *= mState.mLocalSize[1];
405 checked_local_size_product *= mState.mLocalSize[2];
406
407 if (!checked_local_size_product.IsValid())
408 {
409 WARN() << std::endl
410 << "Integer overflow when computing the product of local_size_x, "
411 << "local_size_y and local_size_z.";
412 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
413 return;
414 }
415 if (checked_local_size_product.ValueOrDie() >
416 context->getCaps().maxComputeWorkGroupInvocations)
417 {
418 WARN() << std::endl
419 << "The total number of invocations within a work group exceeds "
420 << "MAX_COMPUTE_WORK_GROUP_INVOCATIONS.";
421 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
422 return;
423 }
424 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300425 break;
426 }
Jiawei Shao385b3e02018-03-21 09:43:28 +0800427 case ShaderType::Vertex:
Martin Radev4c4c8e72016-08-04 12:25:34 +0300428 {
Martin Radev7cf61662017-07-26 17:10:53 +0300429 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800430 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
Olli Etuahoebd6e2d2018-03-23 17:07:55 +0200431 mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
432 mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
Jamie Madill493f9572018-05-24 19:52:15 -0400433 mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
Martin Radev7cf61662017-07-26 17:10:53 +0300434 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300435 break;
436 }
Jiawei Shao385b3e02018-03-21 09:43:28 +0800437 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +0300438 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800439 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300440 // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
Jiawei Shao3d404882017-10-16 13:30:48 +0800441 std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
Martin Radev4c4c8e72016-08-04 12:25:34 +0300442 mState.mActiveOutputVariables =
Jamie Madillacb4b812016-11-07 13:50:29 -0500443 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300444 break;
445 }
Jiawei Shao385b3e02018-03-21 09:43:28 +0800446 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +0800447 {
448 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
449 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
450
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800451 if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
452 {
Jamie Madill493f9572018-05-24 19:52:15 -0400453 mState.mGeometryShaderInputPrimitiveType = FromGLenum<PrimitiveMode>(
454 sh::GetGeometryShaderInputPrimitiveType(compilerHandle));
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800455 }
456 if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle))
457 {
Jamie Madill493f9572018-05-24 19:52:15 -0400458 mState.mGeometryShaderOutputPrimitiveType = FromGLenum<PrimitiveMode>(
459 sh::GetGeometryShaderOutputPrimitiveType(compilerHandle));
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800460 }
461 if (sh::HasValidGeometryShaderMaxVertices(compilerHandle))
462 {
463 mState.mGeometryShaderMaxVertices =
464 sh::GetGeometryShaderMaxVertices(compilerHandle);
465 }
Jiawei Shao89be29a2017-11-06 14:36:45 +0800466 mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
Jiawei Shao89be29a2017-11-06 14:36:45 +0800467 break;
468 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300469 default:
470 UNREACHABLE();
Jamie Madill006cbc52015-09-23 16:47:54 -0400471 }
472
Jamie Madill15243d92016-04-26 13:41:35 -0400473 ASSERT(!mState.mTranslatedSource.empty());
Jamie Madill006cbc52015-09-23 16:47:54 -0400474
Geoff Lang58662082018-05-10 13:41:51 -0400475 bool success = mImplementation->postTranslateCompile(context, mBoundCompiler.get(), &mInfoLog);
Jamie Madill34ca4f52017-06-13 11:49:39 -0400476 mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000477}
478
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000479void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000480{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000481 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482}
483
Jamie Madill6c1f6712017-02-14 19:08:04 -0500484void Shader::release(const Context *context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000485{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000486 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000487
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000488 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000489 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500490 mResourceManager->deleteShader(context, mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000491 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000492}
493
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000494unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000495{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000496 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000497}
498
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000499bool Shader::isFlaggedForDeletion() const
500{
501 return mDeleteStatus;
502}
503
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000504void Shader::flagForDeletion()
505{
506 mDeleteStatus = true;
507}
508
Jamie Madillbd044ed2017-06-05 12:59:21 -0400509bool Shader::isCompiled(const Context *context)
Jamie Madill80a6fc02015-08-21 16:53:16 -0400510{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400511 resolveCompile(context);
Jamie Madill34ca4f52017-06-13 11:49:39 -0400512 return mState.mCompileStatus == CompileStatus::COMPILED;
Jamie Madillbd044ed2017-06-05 12:59:21 -0400513}
514
515int Shader::getShaderVersion(const Context *context)
516{
517 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400518 return mState.mShaderVersion;
Jamie Madill80a6fc02015-08-21 16:53:16 -0400519}
520
Jiawei Shao3d404882017-10-16 13:30:48 +0800521const std::vector<sh::Varying> &Shader::getInputVaryings(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400522{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400523 resolveCompile(context);
Jiawei Shao3d404882017-10-16 13:30:48 +0800524 return mState.getInputVaryings();
525}
526
527const std::vector<sh::Varying> &Shader::getOutputVaryings(const Context *context)
528{
529 resolveCompile(context);
530 return mState.getOutputVaryings();
Jamie Madilld15250e2014-09-03 09:40:44 -0400531}
532
Jamie Madillbd044ed2017-06-05 12:59:21 -0400533const std::vector<sh::Uniform> &Shader::getUniforms(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400534{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400535 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400536 return mState.getUniforms();
Jamie Madilld15250e2014-09-03 09:40:44 -0400537}
538
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800539const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400540{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400541 resolveCompile(context);
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800542 return mState.getUniformBlocks();
543}
544
545const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks(const Context *context)
546{
547 resolveCompile(context);
548 return mState.getShaderStorageBlocks();
Jamie Madilld15250e2014-09-03 09:40:44 -0400549}
550
Jamie Madillbd044ed2017-06-05 12:59:21 -0400551const std::vector<sh::Attribute> &Shader::getActiveAttributes(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400552{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400553 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400554 return mState.getActiveAttributes();
Jamie Madilld15250e2014-09-03 09:40:44 -0400555}
556
Olli Etuahoebd6e2d2018-03-23 17:07:55 +0200557const std::vector<sh::Attribute> &Shader::getAllAttributes(const Context *context)
558{
559 resolveCompile(context);
560 return mState.getAllAttributes();
561}
562
Jamie Madillbd044ed2017-06-05 12:59:21 -0400563const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables(const Context *context)
Jamie Madilld15250e2014-09-03 09:40:44 -0400564{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400565 resolveCompile(context);
Jamie Madill15243d92016-04-26 13:41:35 -0400566 return mState.getActiveOutputVariables();
Jamie Madilld15250e2014-09-03 09:40:44 -0400567}
568
Olli Etuaho855d9642017-05-17 14:05:06 +0300569std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName,
570 const Context *context)
571{
Jiawei Shao3d404882017-10-16 13:30:48 +0800572 // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader.
Jiawei Shao385b3e02018-03-21 09:43:28 +0800573 ASSERT(mState.getShaderType() == ShaderType::Vertex);
Jiawei Shao3d404882017-10-16 13:30:48 +0800574 const auto &varyings = getOutputVaryings(context);
Olli Etuaho855d9642017-05-17 14:05:06 +0300575 auto bracketPos = tfVaryingName.find("[");
576 if (bracketPos != std::string::npos)
577 {
578 auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos);
579 for (const auto &varying : varyings)
580 {
581 if (varying.name == tfVaryingBaseName)
582 {
583 std::string mappedNameWithArrayIndex =
584 varying.mappedName + tfVaryingName.substr(bracketPos);
585 return mappedNameWithArrayIndex;
586 }
587 }
588 }
589 else
590 {
591 for (const auto &varying : varyings)
592 {
593 if (varying.name == tfVaryingName)
594 {
595 return varying.mappedName;
596 }
jchen108225e732017-11-14 16:29:03 +0800597 else if (varying.isStruct())
598 {
599 const auto *field = FindShaderVarField(varying, tfVaryingName);
600 ASSERT(field != nullptr && !field->isStruct() && !field->isArray());
601 return varying.mappedName + "." + field->mappedName;
602 }
Olli Etuaho855d9642017-05-17 14:05:06 +0300603 }
604 }
605 UNREACHABLE();
606 return std::string();
607}
608
Jamie Madillbd044ed2017-06-05 12:59:21 -0400609const sh::WorkGroupSize &Shader::getWorkGroupSize(const Context *context)
610{
611 resolveCompile(context);
612 return mState.mLocalSize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000613}
Jamie Madillbd044ed2017-06-05 12:59:21 -0400614
Martin Radev7cf61662017-07-26 17:10:53 +0300615int Shader::getNumViews(const Context *context)
616{
617 resolveCompile(context);
618 return mState.mNumViews;
619}
620
Jamie Madill493f9572018-05-24 19:52:15 -0400621Optional<PrimitiveMode> Shader::getGeometryShaderInputPrimitiveType(const Context *context)
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800622{
623 resolveCompile(context);
624 return mState.mGeometryShaderInputPrimitiveType;
625}
626
Jamie Madill493f9572018-05-24 19:52:15 -0400627Optional<PrimitiveMode> Shader::getGeometryShaderOutputPrimitiveType(const Context *context)
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800628{
629 resolveCompile(context);
630 return mState.mGeometryShaderOutputPrimitiveType;
631}
632
633int Shader::getGeometryShaderInvocations(const Context *context)
634{
635 resolveCompile(context);
636 return mState.mGeometryShaderInvocations;
637}
638
639Optional<GLint> Shader::getGeometryShaderMaxVertices(const Context *context)
640{
641 resolveCompile(context);
642 return mState.mGeometryShaderMaxVertices;
643}
644
Jamie Madill32447362017-06-28 14:53:52 -0400645const std::string &Shader::getCompilerResourcesString() const
646{
647 ASSERT(mBoundCompiler.get());
648 return mBoundCompiler->getBuiltinResourcesString(mState.mShaderType);
649}
650
Jamie Madillbd044ed2017-06-05 12:59:21 -0400651} // namespace gl