blob: ab16fe51060d256a7ae0d1c6e563ae77c2ca890c [file] [log] [blame]
Geoff Langf9a6f082015-01-22 13:32:49 -05001//
2// Copyright 2015 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7// ProgramGL.cpp: Implements the class methods for ProgramGL.
8
9#include "libANGLE/renderer/gl/ProgramGL.h"
10
11#include "common/debug.h"
Geoff Lang5ed74cf2015-04-14 13:57:07 -040012#include "common/utilities.h"
Geoff Langb1f435e2015-02-20 10:01:01 -050013#include "libANGLE/renderer/gl/FunctionsGL.h"
14#include "libANGLE/renderer/gl/ShaderGL.h"
15#include "libANGLE/renderer/gl/StateManagerGL.h"
Geoff Langf9a6f082015-01-22 13:32:49 -050016
17namespace rx
18{
19
Geoff Langb1f435e2015-02-20 10:01:01 -050020ProgramGL::ProgramGL(const FunctionsGL *functions, StateManagerGL *stateManager)
21 : ProgramImpl(),
22 mFunctions(functions),
23 mStateManager(stateManager),
24 mProgramID(0)
25{
26 ASSERT(mFunctions);
27 ASSERT(mStateManager);
28}
Geoff Langf9a6f082015-01-22 13:32:49 -050029
30ProgramGL::~ProgramGL()
Geoff Langb1f435e2015-02-20 10:01:01 -050031{
32 if (mProgramID != 0)
33 {
34 mFunctions->deleteProgram(mProgramID);
35 mProgramID = 0;
36 }
37}
Geoff Langf9a6f082015-01-22 13:32:49 -050038
39bool ProgramGL::usesPointSize() const
40{
41 UNIMPLEMENTED();
42 return bool();
43}
44
45int ProgramGL::getShaderVersion() const
46{
47 UNIMPLEMENTED();
48 return int();
49}
50
51GLenum ProgramGL::getTransformFeedbackBufferMode() const
52{
53 UNIMPLEMENTED();
54 return GLenum();
55}
56
57GLenum ProgramGL::getBinaryFormat()
58{
59 UNIMPLEMENTED();
60 return GLenum();
61}
62
63LinkResult ProgramGL::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
64{
65 UNIMPLEMENTED();
66 return LinkResult(false, gl::Error(GL_INVALID_OPERATION));
67}
68
69gl::Error ProgramGL::save(gl::BinaryOutputStream *stream)
70{
71 UNIMPLEMENTED();
72 return gl::Error(GL_INVALID_OPERATION);
73}
74
75LinkResult ProgramGL::link(const gl::Data &data, gl::InfoLog &infoLog,
76 gl::Shader *fragmentShader, gl::Shader *vertexShader,
77 const std::vector<std::string> &transformFeedbackVaryings,
78 GLenum transformFeedbackBufferMode,
79 int *registers, std::vector<gl::LinkedVarying> *linkedVaryings,
80 std::map<int, gl::VariableLocation> *outputVariables)
81{
Geoff Langb1f435e2015-02-20 10:01:01 -050082 // Reset the program state, delete the current program if one exists
83 reset();
84
85 ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(vertexShader);
86 ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(fragmentShader);
87
88 // Generate a new program, make sure one doesn't already exist
89 ASSERT(mProgramID == 0);
90 mProgramID = mFunctions->createProgram();
91
92 // Attach the shaders
93 mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
94 mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
95
96 // TODO: bind attribute locations?
97
98 // Link and verify
99 mFunctions->linkProgram(mProgramID);
100
101 GLint linkStatus = GL_FALSE;
102 mFunctions->getProgramiv(mProgramID, GL_LINK_STATUS, &linkStatus);
103 ASSERT(linkStatus == GL_TRUE);
104 if (linkStatus == GL_FALSE)
105 {
106 // Linking failed, put the error into the info log
107 GLint infoLogLength = 0;
108 mFunctions->getProgramiv(mProgramID, GL_INFO_LOG_LENGTH, &infoLogLength);
109
110 std::vector<char> buf(infoLogLength);
111 mFunctions->getProgramInfoLog(mProgramID, infoLogLength, nullptr, &buf[0]);
112
113 mFunctions->deleteProgram(mProgramID);
114 mProgramID = 0;
115
116 infoLog.append(&buf[0]);
117 TRACE("\n%s", &buf[0]);
118
119 // TODO, return GL_OUT_OF_MEMORY or just fail the link? This is an unexpected case
120 return LinkResult(false, gl::Error(GL_NO_ERROR));
121 }
122
123 // Query the uniform information
124 // TODO: A lot of this logic should be done at the gl::Program level
125 GLint activeUniformMaxLength = 0;
126 mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformMaxLength);
127
128 std::vector<GLchar> uniformNameBuffer(activeUniformMaxLength);
129
130 GLint uniformCount = 0;
131 mFunctions->getProgramiv(mProgramID, GL_ACTIVE_UNIFORMS, &uniformCount);
132 for (GLint i = 0; i < uniformCount; i++)
133 {
134 GLsizei uniformNameLength = 0;
135 GLint uniformSize = 0;
136 GLenum uniformType = GL_NONE;
137 mFunctions->getActiveUniform(mProgramID, i, uniformNameBuffer.size(), &uniformNameLength, &uniformSize, &uniformType, &uniformNameBuffer[0]);
138
Geoff Lang5ed74cf2015-04-14 13:57:07 -0400139 std::string uniformName = gl::ParseUniformName(std::string(&uniformNameBuffer[0], uniformNameLength), nullptr);
140
141 for (size_t arrayIndex = 0; arrayIndex < static_cast<size_t>(uniformSize); arrayIndex++)
142 {
143 std::string locationName = uniformName;
144 if (uniformSize > 1)
145 {
146 locationName += "[" + Str(arrayIndex) + "]";
147 }
148
149 GLint location = mFunctions->getUniformLocation(mProgramID, locationName.c_str());
150 if (location >= 0)
151 {
152 // Make sure the uniform index array is large enough
153 if (static_cast<size_t>(location) >= mUniformIndex.size())
154 {
155 mUniformIndex.resize(location + 1);
156 }
157
158 mUniformIndex[location] = gl::VariableLocation(uniformName, arrayIndex, static_cast<unsigned int>(mUniforms.size()));
159 }
160 }
161
162 // ANGLE uses 0 to identify an non-array uniform.
163 unsigned int arraySize = (uniformSize > 1) ? static_cast<unsigned int>(uniformSize) : 0;
Geoff Langb1f435e2015-02-20 10:01:01 -0500164
165 // TODO: determine uniform precision
Geoff Lang5ed74cf2015-04-14 13:57:07 -0400166 mUniforms.push_back(new gl::LinkedUniform(uniformType, GL_NONE, uniformName, arraySize, -1, sh::BlockMemberInfo::getDefaultBlockInfo()));
Geoff Langb1f435e2015-02-20 10:01:01 -0500167 }
168
169 // Query the attribute information
170 GLint activeAttributeMaxLength = 0;
171 mFunctions->getProgramiv(mProgramID, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttributeMaxLength);
172
173 std::vector<GLchar> attributeNameBuffer(activeAttributeMaxLength);
174
175 GLint attributeCount = 0;
176 mFunctions->getProgramiv(mProgramID, GL_ACTIVE_ATTRIBUTES, &attributeCount);
177 for (GLint i = 0; i < attributeCount; i++)
178 {
179 GLsizei attributeNameLength = 0;
180 GLint attributeSize = 0;
181 GLenum attributeType = GL_NONE;
182 mFunctions->getActiveAttrib(mProgramID, i, attributeNameBuffer.size(), &attributeNameLength, &attributeSize, &attributeType, &attributeNameBuffer[0]);
183
184 std::string attributeName(&attributeNameBuffer[0], attributeNameLength);
185
186 mShaderAttributes[i].type = attributeType;
187 // TODO: determine attribute precision
188 mShaderAttributes[i].precision = GL_NONE;
189 mShaderAttributes[i].name = attributeName;
190 mShaderAttributes[i].arraySize = attributeSize;
191 mShaderAttributes[i].location = i;
192 }
193
194 return LinkResult(true, gl::Error(GL_NO_ERROR));
Geoff Langf9a6f082015-01-22 13:32:49 -0500195}
196
197void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
198{
Geoff Lang63cbace2015-02-26 10:03:12 -0500199 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500200 mFunctions->uniform1fv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500201}
202
203void ProgramGL::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
204{
Geoff Lang63cbace2015-02-26 10:03:12 -0500205 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500206 mFunctions->uniform2fv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500207}
208
209void ProgramGL::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
210{
Geoff Lang63cbace2015-02-26 10:03:12 -0500211 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500212 mFunctions->uniform3fv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500213}
214
215void ProgramGL::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
216{
Geoff Lang63cbace2015-02-26 10:03:12 -0500217 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500218 mFunctions->uniform4fv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500219}
220
221void ProgramGL::setUniform1iv(GLint location, GLsizei count, const GLint *v)
222{
Geoff Lang63cbace2015-02-26 10:03:12 -0500223 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500224 mFunctions->uniform1iv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500225}
226
227void ProgramGL::setUniform2iv(GLint location, GLsizei count, const GLint *v)
228{
Geoff Lang63cbace2015-02-26 10:03:12 -0500229 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500230 mFunctions->uniform2iv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500231}
232
233void ProgramGL::setUniform3iv(GLint location, GLsizei count, const GLint *v)
234{
Geoff Lang63cbace2015-02-26 10:03:12 -0500235 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500236 mFunctions->uniform3iv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500237}
238
239void ProgramGL::setUniform4iv(GLint location, GLsizei count, const GLint *v)
240{
Geoff Lang63cbace2015-02-26 10:03:12 -0500241 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500242 mFunctions->uniform4iv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500243}
244
245void ProgramGL::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
246{
Geoff Lang63cbace2015-02-26 10:03:12 -0500247 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500248 mFunctions->uniform1uiv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500249}
250
251void ProgramGL::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
252{
Geoff Lang63cbace2015-02-26 10:03:12 -0500253 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500254 mFunctions->uniform2uiv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500255}
256
257void ProgramGL::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
258{
Geoff Lang63cbace2015-02-26 10:03:12 -0500259 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500260 mFunctions->uniform3uiv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500261}
262
263void ProgramGL::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
264{
Geoff Lang63cbace2015-02-26 10:03:12 -0500265 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500266 mFunctions->uniform4uiv(location, count, v);
Geoff Langf9a6f082015-01-22 13:32:49 -0500267}
268
269void ProgramGL::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
270{
Geoff Lang63cbace2015-02-26 10:03:12 -0500271 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500272 mFunctions->uniformMatrix2fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500273}
274
275void ProgramGL::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
276{
Geoff Lang63cbace2015-02-26 10:03:12 -0500277 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500278 mFunctions->uniformMatrix3fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500279}
280
281void ProgramGL::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
282{
Geoff Lang63cbace2015-02-26 10:03:12 -0500283 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500284 mFunctions->uniformMatrix4fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500285}
286
287void ProgramGL::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
288{
Geoff Lang63cbace2015-02-26 10:03:12 -0500289 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500290 mFunctions->uniformMatrix2x3fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500291}
292
293void ProgramGL::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
294{
Geoff Lang63cbace2015-02-26 10:03:12 -0500295 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500296 mFunctions->uniformMatrix3x2fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500297}
298
299void ProgramGL::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
300{
Geoff Lang63cbace2015-02-26 10:03:12 -0500301 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500302 mFunctions->uniformMatrix2x4fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500303}
304
305void ProgramGL::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
306{
Geoff Lang63cbace2015-02-26 10:03:12 -0500307 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500308 mFunctions->uniformMatrix4x2fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500309}
310
311void ProgramGL::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
312{
Geoff Lang63cbace2015-02-26 10:03:12 -0500313 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500314 mFunctions->uniformMatrix3x4fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500315}
316
317void ProgramGL::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
318{
Geoff Lang63cbace2015-02-26 10:03:12 -0500319 mStateManager->useProgram(mProgramID);
Geoff Langb1f435e2015-02-20 10:01:01 -0500320 mFunctions->uniformMatrix4x3fv(location, count, transpose, value);
Geoff Langf9a6f082015-01-22 13:32:49 -0500321}
322
323void ProgramGL::getUniformfv(GLint location, GLfloat *params)
324{
Geoff Langb1f435e2015-02-20 10:01:01 -0500325 mFunctions->getUniformfv(mProgramID, location, params);
Geoff Langf9a6f082015-01-22 13:32:49 -0500326}
327
328void ProgramGL::getUniformiv(GLint location, GLint *params)
329{
Geoff Langb1f435e2015-02-20 10:01:01 -0500330 mFunctions->getUniformiv(mProgramID, location, params);
Geoff Langf9a6f082015-01-22 13:32:49 -0500331}
332
333void ProgramGL::getUniformuiv(GLint location, GLuint *params)
334{
Geoff Langb1f435e2015-02-20 10:01:01 -0500335 mFunctions->getUniformuiv(mProgramID, location, params);
Geoff Langf9a6f082015-01-22 13:32:49 -0500336}
337
338GLint ProgramGL::getSamplerMapping(gl::SamplerType type, unsigned int samplerIndex, const gl::Caps &caps) const
339{
340 UNIMPLEMENTED();
341 return GLint();
342}
343
344GLenum ProgramGL::getSamplerTextureType(gl::SamplerType type, unsigned int samplerIndex) const
345{
346 UNIMPLEMENTED();
347 return GLenum();
348}
349
350GLint ProgramGL::getUsedSamplerRange(gl::SamplerType type) const
351{
352 UNIMPLEMENTED();
353 return GLint();
354}
355
356void ProgramGL::updateSamplerMapping()
357{
358 UNIMPLEMENTED();
359}
360
361bool ProgramGL::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
362{
Geoff Lang35d315c2015-03-31 12:48:54 -0400363 //UNIMPLEMENTED();
Geoff Langb1f435e2015-02-20 10:01:01 -0500364 return true;
Geoff Langf9a6f082015-01-22 13:32:49 -0500365}
366
367LinkResult ProgramGL::compileProgramExecutables(gl::InfoLog &infoLog, gl::Shader *fragmentShader, gl::Shader *vertexShader,
368 int registers)
369{
Geoff Langb1f435e2015-02-20 10:01:01 -0500370 //UNIMPLEMENTED();
371 return LinkResult(true, gl::Error(GL_NO_ERROR));
Geoff Langf9a6f082015-01-22 13:32:49 -0500372}
373
374bool ProgramGL::linkUniforms(gl::InfoLog &infoLog, const gl::Shader &vertexShader, const gl::Shader &fragmentShader,
375 const gl::Caps &caps)
376{
Geoff Langb1f435e2015-02-20 10:01:01 -0500377 //UNIMPLEMENTED();
378 return true;
Geoff Langf9a6f082015-01-22 13:32:49 -0500379}
380
381bool ProgramGL::defineUniformBlock(gl::InfoLog &infoLog, const gl::Shader &shader, const sh::InterfaceBlock &interfaceBlock,
382 const gl::Caps &caps)
383{
384 UNIMPLEMENTED();
385 return bool();
386}
387
388gl::Error ProgramGL::applyUniforms()
389{
390 UNIMPLEMENTED();
391 return gl::Error(GL_INVALID_OPERATION);
392}
393
Gregoire Payen de La Garanderie68694e92015-03-24 14:03:37 +0000394gl::Error ProgramGL::applyUniformBuffers(const gl::Data &data, GLuint uniformBlockBindings[])
Geoff Langf9a6f082015-01-22 13:32:49 -0500395{
396 UNIMPLEMENTED();
397 return gl::Error(GL_INVALID_OPERATION);
398}
399
400bool ProgramGL::assignUniformBlockRegister(gl::InfoLog &infoLog, gl::UniformBlock *uniformBlock, GLenum shader,
401 unsigned int registerIndex, const gl::Caps &caps)
402{
403 UNIMPLEMENTED();
404 return bool();
405}
406
Geoff Langb1f435e2015-02-20 10:01:01 -0500407void ProgramGL::reset()
408{
409 ProgramImpl::reset();
410
411 if (mProgramID)
412 {
413 mFunctions->deleteProgram(mProgramID);
414 mProgramID = 0;
415 }
416}
417
418GLuint ProgramGL::getProgramID() const
419{
420 return mProgramID;
421}
422
Geoff Langf9a6f082015-01-22 13:32:49 -0500423}