blob: a2697da28a529e187659910056a808992573e0de [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),
jchen103fd614d2018-08-13 12:21:58 +0800126 mResourceManager(manager),
127 mCurrentMaxComputeWorkGroupInvocations(0u)
Jamie Madille294bb82014-07-17 14:16:26 -0400128{
Jamie Madill91445bc2015-09-23 16:47:53 -0400129 ASSERT(mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000130}
131
Jamie Madill4928b7c2017-06-20 12:57:39 -0400132void Shader::onDestroy(const gl::Context *context)
133{
jchen103fd614d2018-08-13 12:21:58 +0800134 mImplementation->destroy();
Jamie Madill4928b7c2017-06-20 12:57:39 -0400135 mBoundCompiler.set(context, nullptr);
136 mImplementation.reset(nullptr);
137 delete this;
138}
139
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140Shader::~Shader()
141{
Jamie Madill4928b7c2017-06-20 12:57:39 -0400142 ASSERT(!mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143}
144
Geoff Lang70d0f492015-12-10 17:45:46 -0500145void Shader::setLabel(const std::string &label)
146{
Jamie Madill15243d92016-04-26 13:41:35 -0400147 mState.mLabel = label;
Geoff Lang70d0f492015-12-10 17:45:46 -0500148}
149
150const std::string &Shader::getLabel() const
151{
Jamie Madill15243d92016-04-26 13:41:35 -0400152 return mState.mLabel;
Geoff Lang70d0f492015-12-10 17:45:46 -0500153}
154
daniel@transgaming.com6c785212010-03-30 03:36:17 +0000155GLuint Shader::getHandle() const
156{
157 return mHandle;
158}
159
shannon.woods%transgaming.com@gtempaccount.com5f339332013-04-13 03:29:02 +0000160void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000161{
Geoff Lang536d7262013-08-26 17:04:20 -0400162 std::ostringstream stream;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000163
164 for (int i = 0; i < count; i++)
165 {
Geoff Langf60fab62014-11-24 11:21:20 -0500166 if (length == nullptr || length[i] < 0)
167 {
Jamie Madille7cfb3d2014-12-03 10:58:56 -0500168 stream.write(string[i], strlen(string[i]));
Geoff Langf60fab62014-11-24 11:21:20 -0500169 }
170 else
171 {
172 stream.write(string[i], length[i]);
173 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000174 }
175
Jamie Madill15243d92016-04-26 13:41:35 -0400176 mState.mSource = stream.str();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000177}
178
jchen103fd614d2018-08-13 12:21:58 +0800179int Shader::getInfoLogLength()
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000180{
jchen103fd614d2018-08-13 12:21:58 +0800181 resolveCompile();
Jamie Madill006cbc52015-09-23 16:47:54 -0400182 if (mInfoLog.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400183 {
184 return 0;
185 }
186
Jamie Madill006cbc52015-09-23 16:47:54 -0400187 return (static_cast<int>(mInfoLog.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000188}
189
jchen103fd614d2018-08-13 12:21:58 +0800190void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000191{
jchen103fd614d2018-08-13 12:21:58 +0800192 resolveCompile();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400193
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000194 int index = 0;
195
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000196 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000197 {
Jamie Madill006cbc52015-09-23 16:47:54 -0400198 index = std::min(bufSize - 1, static_cast<GLsizei>(mInfoLog.length()));
199 memcpy(infoLog, mInfoLog.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000200
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000201 infoLog[index] = '\0';
202 }
203
204 if (length)
205 {
206 *length = index;
207 }
208}
209
210int Shader::getSourceLength() const
211{
Jamie Madill15243d92016-04-26 13:41:35 -0400212 return mState.mSource.empty() ? 0 : (static_cast<int>(mState.mSource.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000213}
214
jchen103fd614d2018-08-13 12:21:58 +0800215int Shader::getTranslatedSourceLength()
zmo@google.coma574f782011-10-03 21:45:23 +0000216{
jchen103fd614d2018-08-13 12:21:58 +0800217 resolveCompile();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400218
Jamie Madill15243d92016-04-26 13:41:35 -0400219 if (mState.mTranslatedSource.empty())
Jamie Madill91445bc2015-09-23 16:47:53 -0400220 {
221 return 0;
222 }
223
Jamie Madill15243d92016-04-26 13:41:35 -0400224 return (static_cast<int>(mState.mTranslatedSource.length()) + 1);
zmo@google.coma574f782011-10-03 21:45:23 +0000225}
226
jchen103fd614d2018-08-13 12:21:58 +0800227int Shader::getTranslatedSourceWithDebugInfoLength()
Jamie Madill847638a2015-11-20 13:01:41 -0500228{
jchen103fd614d2018-08-13 12:21:58 +0800229 resolveCompile();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400230
jchen103fd614d2018-08-13 12:21:58 +0800231 const std::string &debugInfo = mImplementation->getDebugInfo();
Jamie Madill847638a2015-11-20 13:01:41 -0500232 if (debugInfo.empty())
233 {
234 return 0;
235 }
236
237 return (static_cast<int>(debugInfo.length()) + 1);
238}
239
Jamie Madillbd044ed2017-06-05 12:59:21 -0400240// static
241void Shader::GetSourceImpl(const std::string &source,
242 GLsizei bufSize,
243 GLsizei *length,
244 char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000245{
246 int index = 0;
247
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000248 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000249 {
Geoff Lang536d7262013-08-26 17:04:20 -0400250 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
251 memcpy(buffer, source.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000252
zmo@google.coma574f782011-10-03 21:45:23 +0000253 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000254 }
255
256 if (length)
257 {
258 *length = index;
259 }
260}
261
Geoff Lang536d7262013-08-26 17:04:20 -0400262void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000263{
Jamie Madillbd044ed2017-06-05 12:59:21 -0400264 GetSourceImpl(mState.mSource, bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000265}
266
jchen103fd614d2018-08-13 12:21:58 +0800267void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
zmo@google.coma574f782011-10-03 21:45:23 +0000268{
jchen103fd614d2018-08-13 12:21:58 +0800269 GetSourceImpl(getTranslatedSource(), bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000270}
271
jchen103fd614d2018-08-13 12:21:58 +0800272const std::string &Shader::getTranslatedSource()
Tibor den Ouden97049c62014-10-06 21:39:16 +0200273{
jchen103fd614d2018-08-13 12:21:58 +0800274 resolveCompile();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400275 return mState.mTranslatedSource;
276}
277
jchen103fd614d2018-08-13 12:21:58 +0800278void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer)
Jamie Madillbd044ed2017-06-05 12:59:21 -0400279{
jchen103fd614d2018-08-13 12:21:58 +0800280 resolveCompile();
281 const std::string &debugInfo = mImplementation->getDebugInfo();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400282 GetSourceImpl(debugInfo, bufSize, length, buffer);
Tibor den Ouden97049c62014-10-06 21:39:16 +0200283}
284
Bryan Bernhart619c8332016-11-09 11:11:41 -0800285void Shader::compile(const Context *context)
Jamie Madillbf9cce22014-07-18 10:33:09 -0400286{
Jamie Madill15243d92016-04-26 13:41:35 -0400287 mState.mTranslatedSource.clear();
Jamie Madill006cbc52015-09-23 16:47:54 -0400288 mInfoLog.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400289 mState.mShaderVersion = 100;
Jiawei Shao3d404882017-10-16 13:30:48 +0800290 mState.mInputVaryings.clear();
291 mState.mOutputVaryings.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400292 mState.mUniforms.clear();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800293 mState.mUniformBlocks.clear();
294 mState.mShaderStorageBlocks.clear();
Jamie Madill15243d92016-04-26 13:41:35 -0400295 mState.mActiveAttributes.clear();
296 mState.mActiveOutputVariables.clear();
Martin Radev7cf61662017-07-26 17:10:53 +0300297 mState.mNumViews = -1;
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800298 mState.mGeometryShaderInputPrimitiveType.reset();
299 mState.mGeometryShaderOutputPrimitiveType.reset();
300 mState.mGeometryShaderMaxVertices.reset();
301 mState.mGeometryShaderInvocations = 1;
Jamie Madill91445bc2015-09-23 16:47:53 -0400302
Jamie Madill34ca4f52017-06-13 11:49:39 -0400303 mState.mCompileStatus = CompileStatus::COMPILE_REQUESTED;
Jamie Madill4928b7c2017-06-20 12:57:39 -0400304 mBoundCompiler.set(context, context->getCompiler());
Jamie Madillbd044ed2017-06-05 12:59:21 -0400305
306 // Cache the compile source and options for compilation. Must be done now, since the source
307 // can change before the link call or another call that resolves the compile.
Jamie Madill006cbc52015-09-23 16:47:54 -0400308
309 std::stringstream sourceStream;
310
Geoff Lang58662082018-05-10 13:41:51 -0400311 mLastCompileOptions = mImplementation->prepareSourceAndReturnOptions(context, &sourceStream,
312 &mLastCompiledSourcePath);
Jamie Madillbd044ed2017-06-05 12:59:21 -0400313 mLastCompileOptions |= (SH_OBJECT_CODE | SH_VARIABLES);
314 mLastCompiledSource = sourceStream.str();
Jamie Madill006cbc52015-09-23 16:47:54 -0400315
Bryan Bernhart619c8332016-11-09 11:11:41 -0800316 // Add default options to WebGL shaders to prevent unexpected behavior during compilation.
317 if (context->getExtensions().webglCompatibility)
318 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400319 mLastCompileOptions |= SH_INIT_GL_POSITION;
320 mLastCompileOptions |= SH_LIMIT_CALL_STACK_DEPTH;
321 mLastCompileOptions |= SH_LIMIT_EXPRESSION_COMPLEXITY;
322 mLastCompileOptions |= SH_ENFORCE_PACKING_RESTRICTIONS;
Bryan Bernhart619c8332016-11-09 11:11:41 -0800323 }
324
Jamie Madill006cbc52015-09-23 16:47:54 -0400325 // Some targets (eg D3D11 Feature Level 9_3 and below) do not support non-constant loop indexes
326 // in fragment shaders. Shader compilation will fail. To provide a better error message we can
327 // instruct the compiler to pre-validate.
328 if (mRendererLimitations.shadersRequireIndexedLoopValidation)
329 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400330 mLastCompileOptions |= SH_VALIDATE_LOOP_INDEXING;
Jamie Madill006cbc52015-09-23 16:47:54 -0400331 }
jchen103fd614d2018-08-13 12:21:58 +0800332
333 mCurrentMaxComputeWorkGroupInvocations = context->getCaps().maxComputeWorkGroupInvocations;
Jamie Madillbd044ed2017-06-05 12:59:21 -0400334}
Jamie Madill006cbc52015-09-23 16:47:54 -0400335
jchen103fd614d2018-08-13 12:21:58 +0800336void Shader::resolveCompile()
Jamie Madillbd044ed2017-06-05 12:59:21 -0400337{
Jamie Madill34ca4f52017-06-13 11:49:39 -0400338 if (!mState.compilePending())
Jamie Madilld2c52e32015-10-14 17:07:05 -0400339 {
Jamie Madillbd044ed2017-06-05 12:59:21 -0400340 return;
Jamie Madilld2c52e32015-10-14 17:07:05 -0400341 }
342
Jamie Madillbd044ed2017-06-05 12:59:21 -0400343 ASSERT(mBoundCompiler.get());
344 ShHandle compilerHandle = mBoundCompiler->getCompilerHandle(mState.mShaderType);
Jamie Madilld2c52e32015-10-14 17:07:05 -0400345
Jamie Madillbd044ed2017-06-05 12:59:21 -0400346 std::vector<const char *> srcStrings;
Jamie Madill006cbc52015-09-23 16:47:54 -0400347
Jamie Madillbd044ed2017-06-05 12:59:21 -0400348 if (!mLastCompiledSourcePath.empty())
349 {
350 srcStrings.push_back(mLastCompiledSourcePath.c_str());
351 }
352
353 srcStrings.push_back(mLastCompiledSource.c_str());
354
355 if (!sh::Compile(compilerHandle, &srcStrings[0], srcStrings.size(), mLastCompileOptions))
Jamie Madill006cbc52015-09-23 16:47:54 -0400356 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500357 mInfoLog = sh::GetInfoLog(compilerHandle);
Yuly Novikovd73f8522017-01-13 17:48:57 -0500358 WARN() << std::endl << mInfoLog;
Jamie Madill34ca4f52017-06-13 11:49:39 -0400359 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
Jamie Madill006cbc52015-09-23 16:47:54 -0400360 return;
361 }
362
Jamie Madillacb4b812016-11-07 13:50:29 -0500363 mState.mTranslatedSource = sh::GetObjectCode(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400364
Jamie Madillbd044ed2017-06-05 12:59:21 -0400365#if !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400366 // Prefix translated shader with commented out un-translated shader.
367 // Useful in diagnostics tools which capture the shader source.
368 std::ostringstream shaderStream;
369 shaderStream << "// GLSL\n";
370 shaderStream << "//\n";
371
Geoff Lang9e1bf102017-03-28 15:10:48 -0400372 std::istringstream inputSourceStream(mState.mSource);
373 std::string line;
374 while (std::getline(inputSourceStream, line))
Jamie Madill006cbc52015-09-23 16:47:54 -0400375 {
Geoff Lang9e1bf102017-03-28 15:10:48 -0400376 // Remove null characters from the source line
377 line.erase(std::remove(line.begin(), line.end(), '\0'), line.end());
Jamie Madill006cbc52015-09-23 16:47:54 -0400378
Geoff Langab4be842017-07-18 11:23:07 -0400379 shaderStream << "// " << line << std::endl;
Jamie Madill006cbc52015-09-23 16:47:54 -0400380 }
381 shaderStream << "\n\n";
Jamie Madill15243d92016-04-26 13:41:35 -0400382 shaderStream << mState.mTranslatedSource;
383 mState.mTranslatedSource = shaderStream.str();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400384#endif // !defined(NDEBUG)
Jamie Madill006cbc52015-09-23 16:47:54 -0400385
386 // Gather the shader information
Jamie Madillacb4b812016-11-07 13:50:29 -0500387 mState.mShaderVersion = sh::GetShaderVersion(compilerHandle);
Jamie Madill006cbc52015-09-23 16:47:54 -0400388
Jamie Madill493f9572018-05-24 19:52:15 -0400389 mState.mUniforms = GetShaderVariables(sh::GetUniforms(compilerHandle));
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800390 mState.mUniformBlocks = GetShaderVariables(sh::GetUniformBlocks(compilerHandle));
391 mState.mShaderStorageBlocks = GetShaderVariables(sh::GetShaderStorageBlocks(compilerHandle));
Jamie Madill006cbc52015-09-23 16:47:54 -0400392
Martin Radev4c4c8e72016-08-04 12:25:34 +0300393 switch (mState.mShaderType)
Jamie Madill006cbc52015-09-23 16:47:54 -0400394 {
Jiawei Shao385b3e02018-03-21 09:43:28 +0800395 case ShaderType::Compute:
Martin Radev4c4c8e72016-08-04 12:25:34 +0300396 {
Jamie Madillacb4b812016-11-07 13:50:29 -0500397 mState.mLocalSize = sh::GetComputeShaderLocalGroupSize(compilerHandle);
Xinghua Cao77a2b4c2018-05-21 17:28:29 +0800398 if (mState.mLocalSize.isDeclared())
399 {
400 angle::CheckedNumeric<uint32_t> checked_local_size_product(mState.mLocalSize[0]);
401 checked_local_size_product *= mState.mLocalSize[1];
402 checked_local_size_product *= mState.mLocalSize[2];
403
404 if (!checked_local_size_product.IsValid())
405 {
406 WARN() << std::endl
407 << "Integer overflow when computing the product of local_size_x, "
408 << "local_size_y and local_size_z.";
409 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
410 return;
411 }
412 if (checked_local_size_product.ValueOrDie() >
jchen103fd614d2018-08-13 12:21:58 +0800413 mCurrentMaxComputeWorkGroupInvocations)
Xinghua Cao77a2b4c2018-05-21 17:28:29 +0800414 {
415 WARN() << std::endl
416 << "The total number of invocations within a work group exceeds "
417 << "MAX_COMPUTE_WORK_GROUP_INVOCATIONS.";
418 mState.mCompileStatus = CompileStatus::NOT_COMPILED;
419 return;
420 }
421 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300422 break;
423 }
Jiawei Shao385b3e02018-03-21 09:43:28 +0800424 case ShaderType::Vertex:
Martin Radev4c4c8e72016-08-04 12:25:34 +0300425 {
Martin Radev7cf61662017-07-26 17:10:53 +0300426 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800427 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
Olli Etuahoebd6e2d2018-03-23 17:07:55 +0200428 mState.mAllAttributes = GetShaderVariables(sh::GetAttributes(compilerHandle));
429 mState.mActiveAttributes = GetActiveShaderVariables(&mState.mAllAttributes);
Jamie Madill493f9572018-05-24 19:52:15 -0400430 mState.mNumViews = sh::GetVertexShaderNumViews(compilerHandle);
Martin Radev7cf61662017-07-26 17:10:53 +0300431 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300432 break;
433 }
Jiawei Shao385b3e02018-03-21 09:43:28 +0800434 case ShaderType::Fragment:
Martin Radev4c4c8e72016-08-04 12:25:34 +0300435 {
Jiawei Shao3d404882017-10-16 13:30:48 +0800436 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300437 // TODO(jmadill): Figure out why we only sort in the FS, and if we need to.
Jiawei Shao3d404882017-10-16 13:30:48 +0800438 std::sort(mState.mInputVaryings.begin(), mState.mInputVaryings.end(), CompareShaderVar);
Martin Radev4c4c8e72016-08-04 12:25:34 +0300439 mState.mActiveOutputVariables =
Jamie Madillacb4b812016-11-07 13:50:29 -0500440 GetActiveShaderVariables(sh::GetOutputVariables(compilerHandle));
Martin Radev4c4c8e72016-08-04 12:25:34 +0300441 break;
442 }
Jiawei Shao385b3e02018-03-21 09:43:28 +0800443 case ShaderType::Geometry:
Jiawei Shao89be29a2017-11-06 14:36:45 +0800444 {
445 mState.mInputVaryings = GetShaderVariables(sh::GetInputVaryings(compilerHandle));
446 mState.mOutputVaryings = GetShaderVariables(sh::GetOutputVaryings(compilerHandle));
447
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800448 if (sh::HasValidGeometryShaderInputPrimitiveType(compilerHandle))
449 {
Jamie Madill493f9572018-05-24 19:52:15 -0400450 mState.mGeometryShaderInputPrimitiveType = FromGLenum<PrimitiveMode>(
451 sh::GetGeometryShaderInputPrimitiveType(compilerHandle));
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800452 }
453 if (sh::HasValidGeometryShaderOutputPrimitiveType(compilerHandle))
454 {
Jamie Madill493f9572018-05-24 19:52:15 -0400455 mState.mGeometryShaderOutputPrimitiveType = FromGLenum<PrimitiveMode>(
456 sh::GetGeometryShaderOutputPrimitiveType(compilerHandle));
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800457 }
458 if (sh::HasValidGeometryShaderMaxVertices(compilerHandle))
459 {
460 mState.mGeometryShaderMaxVertices =
461 sh::GetGeometryShaderMaxVertices(compilerHandle);
462 }
Jiawei Shao89be29a2017-11-06 14:36:45 +0800463 mState.mGeometryShaderInvocations = sh::GetGeometryShaderInvocations(compilerHandle);
Jiawei Shao89be29a2017-11-06 14:36:45 +0800464 break;
465 }
Martin Radev4c4c8e72016-08-04 12:25:34 +0300466 default:
467 UNREACHABLE();
Jamie Madill006cbc52015-09-23 16:47:54 -0400468 }
469
Jamie Madill15243d92016-04-26 13:41:35 -0400470 ASSERT(!mState.mTranslatedSource.empty());
Jamie Madill006cbc52015-09-23 16:47:54 -0400471
jchen103fd614d2018-08-13 12:21:58 +0800472 bool success = mImplementation->postTranslateCompile(mBoundCompiler.get(), &mInfoLog);
Jamie Madill34ca4f52017-06-13 11:49:39 -0400473 mState.mCompileStatus = success ? CompileStatus::COMPILED : CompileStatus::NOT_COMPILED;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000474}
475
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000476void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000477{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000478 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000479}
480
Jamie Madill6c1f6712017-02-14 19:08:04 -0500481void Shader::release(const Context *context)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000483 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000484
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000485 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000486 {
Jamie Madill6c1f6712017-02-14 19:08:04 -0500487 mResourceManager->deleteShader(context, mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000488 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000489}
490
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000491unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000492{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000493 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000494}
495
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000496bool Shader::isFlaggedForDeletion() const
497{
498 return mDeleteStatus;
499}
500
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000501void Shader::flagForDeletion()
502{
503 mDeleteStatus = true;
504}
505
jchen103fd614d2018-08-13 12:21:58 +0800506bool Shader::isCompiled()
Jamie Madill80a6fc02015-08-21 16:53:16 -0400507{
jchen103fd614d2018-08-13 12:21:58 +0800508 resolveCompile();
Jamie Madill34ca4f52017-06-13 11:49:39 -0400509 return mState.mCompileStatus == CompileStatus::COMPILED;
Jamie Madillbd044ed2017-06-05 12:59:21 -0400510}
511
jchen103fd614d2018-08-13 12:21:58 +0800512int Shader::getShaderVersion()
Jamie Madillbd044ed2017-06-05 12:59:21 -0400513{
jchen103fd614d2018-08-13 12:21:58 +0800514 resolveCompile();
Jamie Madill15243d92016-04-26 13:41:35 -0400515 return mState.mShaderVersion;
Jamie Madill80a6fc02015-08-21 16:53:16 -0400516}
517
jchen103fd614d2018-08-13 12:21:58 +0800518const std::vector<sh::Varying> &Shader::getInputVaryings()
Jamie Madilld15250e2014-09-03 09:40:44 -0400519{
jchen103fd614d2018-08-13 12:21:58 +0800520 resolveCompile();
Jiawei Shao3d404882017-10-16 13:30:48 +0800521 return mState.getInputVaryings();
522}
523
jchen103fd614d2018-08-13 12:21:58 +0800524const std::vector<sh::Varying> &Shader::getOutputVaryings()
Jiawei Shao3d404882017-10-16 13:30:48 +0800525{
jchen103fd614d2018-08-13 12:21:58 +0800526 resolveCompile();
Jiawei Shao3d404882017-10-16 13:30:48 +0800527 return mState.getOutputVaryings();
Jamie Madilld15250e2014-09-03 09:40:44 -0400528}
529
jchen103fd614d2018-08-13 12:21:58 +0800530const std::vector<sh::Uniform> &Shader::getUniforms()
Jamie Madilld15250e2014-09-03 09:40:44 -0400531{
jchen103fd614d2018-08-13 12:21:58 +0800532 resolveCompile();
Jamie Madill15243d92016-04-26 13:41:35 -0400533 return mState.getUniforms();
Jamie Madilld15250e2014-09-03 09:40:44 -0400534}
535
jchen103fd614d2018-08-13 12:21:58 +0800536const std::vector<sh::InterfaceBlock> &Shader::getUniformBlocks()
Jamie Madilld15250e2014-09-03 09:40:44 -0400537{
jchen103fd614d2018-08-13 12:21:58 +0800538 resolveCompile();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800539 return mState.getUniformBlocks();
540}
541
jchen103fd614d2018-08-13 12:21:58 +0800542const std::vector<sh::InterfaceBlock> &Shader::getShaderStorageBlocks()
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800543{
jchen103fd614d2018-08-13 12:21:58 +0800544 resolveCompile();
Jiajia Qin9b11ea42017-07-11 16:50:08 +0800545 return mState.getShaderStorageBlocks();
Jamie Madilld15250e2014-09-03 09:40:44 -0400546}
547
jchen103fd614d2018-08-13 12:21:58 +0800548const std::vector<sh::Attribute> &Shader::getActiveAttributes()
Jamie Madilld15250e2014-09-03 09:40:44 -0400549{
jchen103fd614d2018-08-13 12:21:58 +0800550 resolveCompile();
Jamie Madill15243d92016-04-26 13:41:35 -0400551 return mState.getActiveAttributes();
Jamie Madilld15250e2014-09-03 09:40:44 -0400552}
553
jchen103fd614d2018-08-13 12:21:58 +0800554const std::vector<sh::Attribute> &Shader::getAllAttributes()
Olli Etuahoebd6e2d2018-03-23 17:07:55 +0200555{
jchen103fd614d2018-08-13 12:21:58 +0800556 resolveCompile();
Olli Etuahoebd6e2d2018-03-23 17:07:55 +0200557 return mState.getAllAttributes();
558}
559
jchen103fd614d2018-08-13 12:21:58 +0800560const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables()
Jamie Madilld15250e2014-09-03 09:40:44 -0400561{
jchen103fd614d2018-08-13 12:21:58 +0800562 resolveCompile();
Jamie Madill15243d92016-04-26 13:41:35 -0400563 return mState.getActiveOutputVariables();
Jamie Madilld15250e2014-09-03 09:40:44 -0400564}
565
jchen103fd614d2018-08-13 12:21:58 +0800566std::string Shader::getTransformFeedbackVaryingMappedName(const std::string &tfVaryingName)
Olli Etuaho855d9642017-05-17 14:05:06 +0300567{
Jiawei Shao3d404882017-10-16 13:30:48 +0800568 // TODO(jiawei.shao@intel.com): support transform feedback on geometry shader.
Jiawei Shao385b3e02018-03-21 09:43:28 +0800569 ASSERT(mState.getShaderType() == ShaderType::Vertex);
jchen103fd614d2018-08-13 12:21:58 +0800570 const auto &varyings = getOutputVaryings();
Olli Etuaho855d9642017-05-17 14:05:06 +0300571 auto bracketPos = tfVaryingName.find("[");
572 if (bracketPos != std::string::npos)
573 {
574 auto tfVaryingBaseName = tfVaryingName.substr(0, bracketPos);
575 for (const auto &varying : varyings)
576 {
577 if (varying.name == tfVaryingBaseName)
578 {
579 std::string mappedNameWithArrayIndex =
580 varying.mappedName + tfVaryingName.substr(bracketPos);
581 return mappedNameWithArrayIndex;
582 }
583 }
584 }
585 else
586 {
587 for (const auto &varying : varyings)
588 {
589 if (varying.name == tfVaryingName)
590 {
591 return varying.mappedName;
592 }
jchen108225e732017-11-14 16:29:03 +0800593 else if (varying.isStruct())
594 {
595 const auto *field = FindShaderVarField(varying, tfVaryingName);
596 ASSERT(field != nullptr && !field->isStruct() && !field->isArray());
597 return varying.mappedName + "." + field->mappedName;
598 }
Olli Etuaho855d9642017-05-17 14:05:06 +0300599 }
600 }
601 UNREACHABLE();
602 return std::string();
603}
604
jchen103fd614d2018-08-13 12:21:58 +0800605const sh::WorkGroupSize &Shader::getWorkGroupSize()
Jamie Madillbd044ed2017-06-05 12:59:21 -0400606{
jchen103fd614d2018-08-13 12:21:58 +0800607 resolveCompile();
Jamie Madillbd044ed2017-06-05 12:59:21 -0400608 return mState.mLocalSize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000609}
Jamie Madillbd044ed2017-06-05 12:59:21 -0400610
jchen103fd614d2018-08-13 12:21:58 +0800611int Shader::getNumViews()
Martin Radev7cf61662017-07-26 17:10:53 +0300612{
jchen103fd614d2018-08-13 12:21:58 +0800613 resolveCompile();
Martin Radev7cf61662017-07-26 17:10:53 +0300614 return mState.mNumViews;
615}
616
jchen103fd614d2018-08-13 12:21:58 +0800617Optional<PrimitiveMode> Shader::getGeometryShaderInputPrimitiveType()
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800618{
jchen103fd614d2018-08-13 12:21:58 +0800619 resolveCompile();
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800620 return mState.mGeometryShaderInputPrimitiveType;
621}
622
jchen103fd614d2018-08-13 12:21:58 +0800623Optional<PrimitiveMode> Shader::getGeometryShaderOutputPrimitiveType()
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800624{
jchen103fd614d2018-08-13 12:21:58 +0800625 resolveCompile();
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800626 return mState.mGeometryShaderOutputPrimitiveType;
627}
628
jchen103fd614d2018-08-13 12:21:58 +0800629int Shader::getGeometryShaderInvocations()
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800630{
jchen103fd614d2018-08-13 12:21:58 +0800631 resolveCompile();
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800632 return mState.mGeometryShaderInvocations;
633}
634
jchen103fd614d2018-08-13 12:21:58 +0800635Optional<GLint> Shader::getGeometryShaderMaxVertices()
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800636{
jchen103fd614d2018-08-13 12:21:58 +0800637 resolveCompile();
Jiawei Shao4ed05da2018-02-02 14:26:15 +0800638 return mState.mGeometryShaderMaxVertices;
639}
640
Jamie Madill32447362017-06-28 14:53:52 -0400641const std::string &Shader::getCompilerResourcesString() const
642{
643 ASSERT(mBoundCompiler.get());
644 return mBoundCompiler->getBuiltinResourcesString(mState.mShaderType);
645}
646
Jamie Madillbd044ed2017-06-05 12:59:21 -0400647} // namespace gl