blob: 27735ec86c56bfd71a297ed4c55b394e9fb46d67 [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{
Cooper Partin4d61f7e2015-08-12 10:56:50 -070069 return mShader->getInfoLog().empty() ? 0
70 : (static_cast<int>(mShader->getInfoLog().length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000071}
72
Geoff Lang536d7262013-08-26 17:04:20 -040073void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
daniel@transgaming.comcba50572010-03-28 19:36:09 +000074{
75 int index = 0;
76
daniel@transgaming.com807d8c32012-04-04 15:06:04 +000077 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +000078 {
Brandon Jonesf05cdee2014-08-27 15:24:07 -070079 index = std::min(bufSize - 1, static_cast<GLsizei>(mShader->getInfoLog().length()));
80 memcpy(infoLog, mShader->getInfoLog().c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000081
daniel@transgaming.comcba50572010-03-28 19:36:09 +000082 infoLog[index] = '\0';
83 }
84
85 if (length)
86 {
87 *length = index;
88 }
89}
90
91int Shader::getSourceLength() const
92{
Cooper Partin4d61f7e2015-08-12 10:56:50 -070093 return mSource.empty() ? 0 : (static_cast<int>(mSource.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000094}
95
zmo@google.coma574f782011-10-03 21:45:23 +000096int Shader::getTranslatedSourceLength() const
97{
Cooper Partin4d61f7e2015-08-12 10:56:50 -070098 return mShader->getTranslatedSource().empty()
99 ? 0
100 : (static_cast<int>(mShader->getTranslatedSource().length()) + 1);
zmo@google.coma574f782011-10-03 21:45:23 +0000101}
102
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700103void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000104{
105 int index = 0;
106
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000107 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000108 {
Geoff Lang536d7262013-08-26 17:04:20 -0400109 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
110 memcpy(buffer, source.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000111
zmo@google.coma574f782011-10-03 21:45:23 +0000112 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000113 }
114
115 if (length)
116 {
117 *length = index;
118 }
119}
120
Geoff Lang536d7262013-08-26 17:04:20 -0400121void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000122{
123 getSourceImpl(mSource, bufSize, length, buffer);
124}
125
Geoff Lang536d7262013-08-26 17:04:20 -0400126void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000127{
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700128 getSourceImpl(mShader->getTranslatedSource(), bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000129}
130
Tibor den Ouden97049c62014-10-06 21:39:16 +0200131void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const
132{
133 std::string debugInfo(mShader->getDebugInfo());
134 getSourceImpl(debugInfo, bufSize, length, buffer);
135}
136
Geoff Lang492a7e42014-11-05 13:27:06 -0500137void Shader::compile(Compiler *compiler)
Jamie Madillbf9cce22014-07-18 10:33:09 -0400138{
Geoff Lang492a7e42014-11-05 13:27:06 -0500139 mCompiled = mShader->compile(compiler, mSource);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140}
141
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000142void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000144 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000145}
146
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000147void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000148{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000149 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000150
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000151 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000152 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000153 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000154 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000155}
156
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000157unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000158{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000159 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000160}
161
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000162bool Shader::isFlaggedForDeletion() const
163{
164 return mDeleteStatus;
165}
166
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167void Shader::flagForDeletion()
168{
169 mDeleteStatus = true;
170}
171
Jamie Madill80a6fc02015-08-21 16:53:16 -0400172int Shader::getShaderVersion() const
173{
174 return mShader->getShaderVersion();
175}
176
Jamie Madilld15250e2014-09-03 09:40:44 -0400177const std::vector<gl::PackedVarying> &Shader::getVaryings() const
178{
179 return mShader->getVaryings();
180}
181
182const std::vector<sh::Uniform> &Shader::getUniforms() const
183{
184 return mShader->getUniforms();
185}
186
187const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
188{
189 return mShader->getInterfaceBlocks();
190}
191
192const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
193{
194 return mShader->getActiveAttributes();
195}
196
197const std::vector<sh::Attribute> &Shader::getActiveOutputVariables() const
198{
199 return mShader->getActiveOutputVariables();
200}
201
202std::vector<gl::PackedVarying> &Shader::getVaryings()
203{
204 return mShader->getVaryings();
205}
206
207std::vector<sh::Uniform> &Shader::getUniforms()
208{
209 return mShader->getUniforms();
210}
211
212std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks()
213{
214 return mShader->getInterfaceBlocks();
215}
216
217std::vector<sh::Attribute> &Shader::getActiveAttributes()
218{
219 return mShader->getActiveAttributes();
220}
221
222std::vector<sh::Attribute> &Shader::getActiveOutputVariables()
223{
224 return mShader->getActiveOutputVariables();
225}
226
Jamie Madill437d2662014-12-05 14:23:35 -0500227
228int Shader::getSemanticIndex(const std::string &attributeName) const
229{
230 if (!attributeName.empty())
231 {
232 const auto &activeAttributes = mShader->getActiveAttributes();
233
234 int semanticIndex = 0;
235 for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
236 {
237 const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
238
239 if (attribute.name == attributeName)
240 {
241 return semanticIndex;
242 }
243
244 semanticIndex += gl::VariableRegisterCount(attribute.type);
245 }
246 }
247
248 return -1;
249}
250
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000251}