blob: 8c303aad50fc1c39830b95b17f17355545240d1b [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"
12#include "libANGLE/renderer/Renderer.h"
13#include "libANGLE/renderer/ShaderImpl.h"
14#include "libANGLE/Constants.h"
15#include "libANGLE/ResourceManager.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000016
Geoff Lang0b7eef72014-06-12 14:10:47 -040017#include "common/utilities.h"
18
19#include "GLSLANG/ShaderLang.h"
20
21#include <sstream>
22
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000023namespace gl
24{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025
Brandon Jonesf05cdee2014-08-27 15:24:07 -070026Shader::Shader(ResourceManager *manager, rx::ShaderImpl *impl, GLenum type, GLuint handle)
27 : mShader(impl),
Brandon Jonesf05cdee2014-08-27 15:24:07 -070028 mHandle(handle),
Corentin Wallezbc99bb62015-05-14 17:42:20 -040029 mType(type),
Brandon Jonesf05cdee2014-08-27 15:24:07 -070030 mRefCount(0),
31 mDeleteStatus(false),
Corentin Wallezbc99bb62015-05-14 17:42:20 -040032 mCompiled(false),
33 mResourceManager(manager)
Jamie Madille294bb82014-07-17 14:16:26 -040034{
Jamie Madilld15250e2014-09-03 09:40:44 -040035 ASSERT(impl);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000036}
37
38Shader::~Shader()
39{
Geoff Langfc532b92014-10-21 10:24:16 -040040 SafeDelete(mShader);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000041}
42
daniel@transgaming.com6c785212010-03-30 03:36:17 +000043GLuint Shader::getHandle() const
44{
45 return mHandle;
46}
47
shannon.woods%transgaming.com@gtempaccount.com5f339332013-04-13 03:29:02 +000048void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000049{
Geoff Lang536d7262013-08-26 17:04:20 -040050 std::ostringstream stream;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000051
52 for (int i = 0; i < count; i++)
53 {
Geoff Langf60fab62014-11-24 11:21:20 -050054 if (length == nullptr || length[i] < 0)
55 {
Jamie Madille7cfb3d2014-12-03 10:58:56 -050056 stream.write(string[i], strlen(string[i]));
Geoff Langf60fab62014-11-24 11:21:20 -050057 }
58 else
59 {
60 stream.write(string[i], length[i]);
61 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000062 }
63
Geoff Lang536d7262013-08-26 17:04:20 -040064 mSource = stream.str();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000065}
66
daniel@transgaming.comcba50572010-03-28 19:36:09 +000067int Shader::getInfoLogLength() const
68{
Brandon Jonesf05cdee2014-08-27 15:24:07 -070069 return mShader->getInfoLog().empty() ? 0 : (mShader->getInfoLog().length() + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000070}
71
Geoff Lang536d7262013-08-26 17:04:20 -040072void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
daniel@transgaming.comcba50572010-03-28 19:36:09 +000073{
74 int index = 0;
75
daniel@transgaming.com807d8c32012-04-04 15:06:04 +000076 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +000077 {
Brandon Jonesf05cdee2014-08-27 15:24:07 -070078 index = std::min(bufSize - 1, static_cast<GLsizei>(mShader->getInfoLog().length()));
79 memcpy(infoLog, mShader->getInfoLog().c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000080
daniel@transgaming.comcba50572010-03-28 19:36:09 +000081 infoLog[index] = '\0';
82 }
83
84 if (length)
85 {
86 *length = index;
87 }
88}
89
90int Shader::getSourceLength() const
91{
Geoff Lang536d7262013-08-26 17:04:20 -040092 return mSource.empty() ? 0 : (mSource.length() + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000093}
94
zmo@google.coma574f782011-10-03 21:45:23 +000095int Shader::getTranslatedSourceLength() const
96{
Brandon Jonesf05cdee2014-08-27 15:24:07 -070097 return mShader->getTranslatedSource().empty() ? 0 : (mShader->getTranslatedSource().length() + 1);
zmo@google.coma574f782011-10-03 21:45:23 +000098}
99
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700100void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000101{
102 int index = 0;
103
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000104 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000105 {
Geoff Lang536d7262013-08-26 17:04:20 -0400106 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
107 memcpy(buffer, source.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000108
zmo@google.coma574f782011-10-03 21:45:23 +0000109 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000110 }
111
112 if (length)
113 {
114 *length = index;
115 }
116}
117
Geoff Lang536d7262013-08-26 17:04:20 -0400118void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000119{
120 getSourceImpl(mSource, bufSize, length, buffer);
121}
122
Geoff Lang536d7262013-08-26 17:04:20 -0400123void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000124{
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700125 getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000126}
127
Tibor den Ouden97049c62014-10-06 21:39:16 +0200128void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const
129{
130 std::string debugInfo(mShader->getDebugInfo());
131 getSourceImpl(debugInfo, bufSize, length, buffer);
132}
133
Geoff Lang492a7e42014-11-05 13:27:06 -0500134void Shader::compile(Compiler *compiler)
Jamie Madillbf9cce22014-07-18 10:33:09 -0400135{
Geoff Lang492a7e42014-11-05 13:27:06 -0500136 mCompiled = mShader->compile(compiler, mSource);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137}
138
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000139void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000141 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000142}
143
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000144void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000145{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000146 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000147
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000148 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000149 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000150 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000151 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152}
153
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000154unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000155{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000156 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157}
158
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000159bool Shader::isFlaggedForDeletion() const
160{
161 return mDeleteStatus;
162}
163
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164void Shader::flagForDeletion()
165{
166 mDeleteStatus = true;
167}
168
Jamie Madilld15250e2014-09-03 09:40:44 -0400169const std::vector<gl::PackedVarying> &Shader::getVaryings() const
170{
171 return mShader->getVaryings();
172}
173
174const std::vector<sh::Uniform> &Shader::getUniforms() const
175{
176 return mShader->getUniforms();
177}
178
179const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
180{
181 return mShader->getInterfaceBlocks();
182}
183
184const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
185{
186 return mShader->getActiveAttributes();
187}
188
189const std::vector<sh::Attribute> &Shader::getActiveOutputVariables() const
190{
191 return mShader->getActiveOutputVariables();
192}
193
194std::vector<gl::PackedVarying> &Shader::getVaryings()
195{
196 return mShader->getVaryings();
197}
198
199std::vector<sh::Uniform> &Shader::getUniforms()
200{
201 return mShader->getUniforms();
202}
203
204std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks()
205{
206 return mShader->getInterfaceBlocks();
207}
208
209std::vector<sh::Attribute> &Shader::getActiveAttributes()
210{
211 return mShader->getActiveAttributes();
212}
213
214std::vector<sh::Attribute> &Shader::getActiveOutputVariables()
215{
216 return mShader->getActiveOutputVariables();
217}
218
Jamie Madill437d2662014-12-05 14:23:35 -0500219
220int Shader::getSemanticIndex(const std::string &attributeName) const
221{
222 if (!attributeName.empty())
223 {
224 const auto &activeAttributes = mShader->getActiveAttributes();
225
226 int semanticIndex = 0;
227 for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
228 {
229 const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
230
231 if (attribute.name == attributeName)
232 {
233 return semanticIndex;
234 }
235
236 semanticIndex += gl::VariableRegisterCount(attribute.type);
237 }
238 }
239
240 return -1;
241}
242
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000243}