blob: d0255a4428ba16fa642f10a841e69f07c710d1b4 [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"
17#include "libANGLE/Constants.h"
18#include "libANGLE/renderer/Renderer.h"
19#include "libANGLE/renderer/ShaderImpl.h"
20#include "libANGLE/ResourceManager.h"
21
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022namespace gl
23{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024
Jamie Madill91445bc2015-09-23 16:47:53 -040025Shader::Data::Data(GLenum shaderType) : mShaderType(shaderType), mShaderVersion(100)
26{
27}
28
29Shader::Data::~Data()
30{
31}
32
33Shader::Shader(ResourceManager *manager, rx::ImplFactory *implFactory, GLenum type, GLuint handle)
34 : mData(type),
35 mImplementation(implFactory->createShader(&mData)),
Brandon Jonesf05cdee2014-08-27 15:24:07 -070036 mHandle(handle),
Corentin Wallezbc99bb62015-05-14 17:42:20 -040037 mType(type),
Brandon Jonesf05cdee2014-08-27 15:24:07 -070038 mRefCount(0),
39 mDeleteStatus(false),
Corentin Wallezbc99bb62015-05-14 17:42:20 -040040 mCompiled(false),
41 mResourceManager(manager)
Jamie Madille294bb82014-07-17 14:16:26 -040042{
Jamie Madill91445bc2015-09-23 16:47:53 -040043 ASSERT(mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000044}
45
46Shader::~Shader()
47{
Jamie Madill91445bc2015-09-23 16:47:53 -040048 SafeDelete(mImplementation);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000049}
50
daniel@transgaming.com6c785212010-03-30 03:36:17 +000051GLuint Shader::getHandle() const
52{
53 return mHandle;
54}
55
shannon.woods%transgaming.com@gtempaccount.com5f339332013-04-13 03:29:02 +000056void Shader::setSource(GLsizei count, const char *const *string, const GLint *length)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000057{
Geoff Lang536d7262013-08-26 17:04:20 -040058 std::ostringstream stream;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
60 for (int i = 0; i < count; i++)
61 {
Geoff Langf60fab62014-11-24 11:21:20 -050062 if (length == nullptr || length[i] < 0)
63 {
Jamie Madille7cfb3d2014-12-03 10:58:56 -050064 stream.write(string[i], strlen(string[i]));
Geoff Langf60fab62014-11-24 11:21:20 -050065 }
66 else
67 {
68 stream.write(string[i], length[i]);
69 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070 }
71
Geoff Lang536d7262013-08-26 17:04:20 -040072 mSource = stream.str();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000073}
74
daniel@transgaming.comcba50572010-03-28 19:36:09 +000075int Shader::getInfoLogLength() const
76{
Jamie Madill91445bc2015-09-23 16:47:53 -040077 if (mData.mInfoLog.empty())
78 {
79 return 0;
80 }
81
82 return (static_cast<int>(mData.mInfoLog.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000083}
84
Geoff Lang536d7262013-08-26 17:04:20 -040085void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog) const
daniel@transgaming.comcba50572010-03-28 19:36:09 +000086{
87 int index = 0;
88
daniel@transgaming.com807d8c32012-04-04 15:06:04 +000089 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +000090 {
Jamie Madill91445bc2015-09-23 16:47:53 -040091 index = std::min(bufSize - 1, static_cast<GLsizei>(mData.mInfoLog.length()));
92 memcpy(infoLog, mData.mInfoLog.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +000093
daniel@transgaming.comcba50572010-03-28 19:36:09 +000094 infoLog[index] = '\0';
95 }
96
97 if (length)
98 {
99 *length = index;
100 }
101}
102
103int Shader::getSourceLength() const
104{
Cooper Partin4d61f7e2015-08-12 10:56:50 -0700105 return mSource.empty() ? 0 : (static_cast<int>(mSource.length()) + 1);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000106}
107
zmo@google.coma574f782011-10-03 21:45:23 +0000108int Shader::getTranslatedSourceLength() const
109{
Jamie Madill91445bc2015-09-23 16:47:53 -0400110 if (mData.mTranslatedSource.empty())
111 {
112 return 0;
113 }
114
115 return (static_cast<int>(mData.mTranslatedSource.length()) + 1);
zmo@google.coma574f782011-10-03 21:45:23 +0000116}
117
Brandon Jonesf05cdee2014-08-27 15:24:07 -0700118void Shader::getSourceImpl(const std::string &source, GLsizei bufSize, GLsizei *length, char *buffer)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000119{
120 int index = 0;
121
daniel@transgaming.com807d8c32012-04-04 15:06:04 +0000122 if (bufSize > 0)
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000123 {
Geoff Lang536d7262013-08-26 17:04:20 -0400124 index = std::min(bufSize - 1, static_cast<GLsizei>(source.length()));
125 memcpy(buffer, source.c_str(), index);
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000126
zmo@google.coma574f782011-10-03 21:45:23 +0000127 buffer[index] = '\0';
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000128 }
129
130 if (length)
131 {
132 *length = index;
133 }
134}
135
Geoff Lang536d7262013-08-26 17:04:20 -0400136void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000137{
138 getSourceImpl(mSource, bufSize, length, buffer);
139}
140
Geoff Lang536d7262013-08-26 17:04:20 -0400141void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer) const
zmo@google.coma574f782011-10-03 21:45:23 +0000142{
Jamie Madill91445bc2015-09-23 16:47:53 -0400143 getSourceImpl(mData.mTranslatedSource, bufSize, length, buffer);
zmo@google.coma574f782011-10-03 21:45:23 +0000144}
145
Tibor den Ouden97049c62014-10-06 21:39:16 +0200146void Shader::getTranslatedSourceWithDebugInfo(GLsizei bufSize, GLsizei *length, char *buffer) const
147{
Jamie Madill91445bc2015-09-23 16:47:53 -0400148 std::string debugInfo(mImplementation->getDebugInfo());
Tibor den Ouden97049c62014-10-06 21:39:16 +0200149 getSourceImpl(debugInfo, bufSize, length, buffer);
150}
151
Geoff Lang492a7e42014-11-05 13:27:06 -0500152void Shader::compile(Compiler *compiler)
Jamie Madillbf9cce22014-07-18 10:33:09 -0400153{
Jamie Madill91445bc2015-09-23 16:47:53 -0400154 mData.mTranslatedSource.clear();
155 mData.mInfoLog.clear();
156 mData.mShaderVersion = 100;
157 mData.mVaryings.clear();
158 mData.mUniforms.clear();
159 mData.mInterfaceBlocks.clear();
160 mData.mActiveAttributes.clear();
161 mData.mActiveOutputVariables.clear();
162
163 mCompiled = mImplementation->compile(compiler, mSource, 0);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164}
165
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000166void Shader::addRef()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000168 mRefCount++;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169}
170
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000171void Shader::release()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000172{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000173 mRefCount--;
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000174
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000175 if (mRefCount == 0 && mDeleteStatus)
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000176 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000177 mResourceManager->deleteShader(mHandle);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000178 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000179}
180
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000181unsigned int Shader::getRefCount() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000182{
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000183 return mRefCount;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184}
185
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000186bool Shader::isFlaggedForDeletion() const
187{
188 return mDeleteStatus;
189}
190
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191void Shader::flagForDeletion()
192{
193 mDeleteStatus = true;
194}
195
Jamie Madill80a6fc02015-08-21 16:53:16 -0400196int Shader::getShaderVersion() const
197{
Jamie Madill91445bc2015-09-23 16:47:53 -0400198 return mData.mShaderVersion;
Jamie Madill80a6fc02015-08-21 16:53:16 -0400199}
200
Jamie Madill4cff2472015-08-21 16:53:18 -0400201const std::vector<sh::Varying> &Shader::getVaryings() const
Jamie Madilld15250e2014-09-03 09:40:44 -0400202{
Jamie Madill91445bc2015-09-23 16:47:53 -0400203 return mData.getVaryings();
Jamie Madilld15250e2014-09-03 09:40:44 -0400204}
205
206const std::vector<sh::Uniform> &Shader::getUniforms() const
207{
Jamie Madill91445bc2015-09-23 16:47:53 -0400208 return mData.getUniforms();
Jamie Madilld15250e2014-09-03 09:40:44 -0400209}
210
211const std::vector<sh::InterfaceBlock> &Shader::getInterfaceBlocks() const
212{
Jamie Madill91445bc2015-09-23 16:47:53 -0400213 return mData.getInterfaceBlocks();
Jamie Madilld15250e2014-09-03 09:40:44 -0400214}
215
216const std::vector<sh::Attribute> &Shader::getActiveAttributes() const
217{
Jamie Madill91445bc2015-09-23 16:47:53 -0400218 return mData.getActiveAttributes();
Jamie Madilld15250e2014-09-03 09:40:44 -0400219}
220
Jamie Madilla0a9e122015-09-02 15:54:30 -0400221const std::vector<sh::OutputVariable> &Shader::getActiveOutputVariables() const
Jamie Madilld15250e2014-09-03 09:40:44 -0400222{
Jamie Madill91445bc2015-09-23 16:47:53 -0400223 return mData.getActiveOutputVariables();
Jamie Madilld15250e2014-09-03 09:40:44 -0400224}
225
Jamie Madill437d2662014-12-05 14:23:35 -0500226int Shader::getSemanticIndex(const std::string &attributeName) const
227{
228 if (!attributeName.empty())
229 {
Jamie Madill91445bc2015-09-23 16:47:53 -0400230 const auto &activeAttributes = mData.getActiveAttributes();
Jamie Madill437d2662014-12-05 14:23:35 -0500231
232 int semanticIndex = 0;
233 for (size_t attributeIndex = 0; attributeIndex < activeAttributes.size(); attributeIndex++)
234 {
235 const sh::ShaderVariable &attribute = activeAttributes[attributeIndex];
236
237 if (attribute.name == attributeName)
238 {
239 return semanticIndex;
240 }
241
242 semanticIndex += gl::VariableRegisterCount(attribute.type);
243 }
244 }
245
246 return -1;
247}
248
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000249}