blob: 9bfda09a64710312d4e5f94f52ce62e7cb280538 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
Geoff Lang48dcae72014-02-05 16:28:24 -05002// 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// Program.cpp: Implements the gl::Program class. Implements GL program objects
8// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
9
shannon.woods@transgaming.comd2811d62013-02-28 23:11:19 +000010#include "libGLESv2/Program.h"
apatrick@chromium.orgea09f9b2012-06-08 00:45:32 +000011#include "libGLESv2/ProgramBinary.h"
shannon.woods@transgaming.com486d9e92013-02-28 23:15:41 +000012#include "libGLESv2/ResourceManager.h"
Brandon Jonesc9610c52014-08-25 17:02:59 -070013#include "libGLESv2/renderer/Renderer.h"
daniel@transgaming.com87891f72011-06-01 15:28:35 +000014
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000015namespace gl
16{
apatrick@chromium.org253b8d22012-06-22 19:27:21 +000017const char * const g_fakepath = "C:\\fakepath";
18
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +000019AttributeBindings::AttributeBindings()
20{
21}
22
23AttributeBindings::~AttributeBindings()
24{
apatrick@chromium.org9a30b092012-06-06 20:21:55 +000025}
26
apatrick@chromium.org253b8d22012-06-22 19:27:21 +000027InfoLog::InfoLog() : mInfoLog(NULL)
28{
29}
30
31InfoLog::~InfoLog()
32{
33 delete[] mInfoLog;
34}
35
36
37int InfoLog::getLength() const
38{
39 if (!mInfoLog)
40 {
41 return 0;
42 }
43 else
44 {
45 return strlen(mInfoLog) + 1;
46 }
47}
48
49void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog)
50{
51 int index = 0;
52
53 if (bufSize > 0)
54 {
55 if (mInfoLog)
56 {
57 index = std::min(bufSize - 1, (int)strlen(mInfoLog));
58 memcpy(infoLog, mInfoLog, index);
59 }
60
61 infoLog[index] = '\0';
62 }
63
64 if (length)
65 {
66 *length = index;
67 }
68}
69
70// append a santized message to the program info log.
71// The D3D compiler includes a fake file path in some of the warning or error
72// messages, so lets remove all occurrences of this fake file path from the log.
73void InfoLog::appendSanitized(const char *message)
74{
75 std::string msg(message);
76
77 size_t found;
78 do
79 {
80 found = msg.find(g_fakepath);
81 if (found != std::string::npos)
82 {
83 msg.erase(found, strlen(g_fakepath));
84 }
85 }
86 while (found != std::string::npos);
87
shannon.woods@transgaming.come16e6512013-02-28 23:19:02 +000088 append("%s", msg.c_str());
apatrick@chromium.org253b8d22012-06-22 19:27:21 +000089}
90
91void InfoLog::append(const char *format, ...)
92{
93 if (!format)
94 {
95 return;
96 }
97
apatrick@chromium.org253b8d22012-06-22 19:27:21 +000098 va_list vararg;
99 va_start(vararg, format);
Jamie Madilld4505052014-02-24 15:26:49 -0500100 size_t infoLength = vsnprintf(NULL, 0, format, vararg);
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000101 va_end(vararg);
102
Jamie Madilld4505052014-02-24 15:26:49 -0500103 char *logPointer = NULL;
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000104
105 if (!mInfoLog)
106 {
shannon.woods@transgaming.come16e6512013-02-28 23:19:02 +0000107 mInfoLog = new char[infoLength + 2];
Jamie Madilld4505052014-02-24 15:26:49 -0500108 logPointer = mInfoLog;
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000109 }
110 else
111 {
Jamie Madilld4505052014-02-24 15:26:49 -0500112 size_t currentlogLength = strlen(mInfoLog);
113 char *newLog = new char[currentlogLength + infoLength + 2];
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000114 strcpy(newLog, mInfoLog);
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000115
116 delete[] mInfoLog;
117 mInfoLog = newLog;
Jamie Madilld4505052014-02-24 15:26:49 -0500118
119 logPointer = mInfoLog + currentlogLength;
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000120 }
Jamie Madilld4505052014-02-24 15:26:49 -0500121
122 va_start(vararg, format);
123 vsnprintf(logPointer, infoLength, format, vararg);
124 va_end(vararg);
125
126 logPointer[infoLength] = 0;
127 strcpy(logPointer + infoLength, "\n");
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000128}
129
130void InfoLog::reset()
131{
132 if (mInfoLog)
133 {
134 delete [] mInfoLog;
135 mInfoLog = NULL;
136 }
137}
138
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000139Program::Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000140{
141 mFragmentShader = NULL;
142 mVertexShader = NULL;
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000143 mProgramBinary.set(NULL);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144 mDeleteStatus = false;
daniel@transgaming.com716056c2012-07-24 18:38:59 +0000145 mLinked = false;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000146 mRefCount = 0;
daniel@transgaming.com70062c92012-11-28 19:32:30 +0000147 mRenderer = renderer;
shannonwoods@chromium.org70eb1ea2013-05-30 00:07:20 +0000148
149 resetUniformBlockBindings();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150}
151
152Program::~Program()
153{
154 unlink(true);
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000155
156 if (mVertexShader != NULL)
157 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000158 mVertexShader->release();
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000159 }
160
161 if (mFragmentShader != NULL)
162 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000163 mFragmentShader->release();
daniel@transgaming.com71cd8682010-04-29 03:35:25 +0000164 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000165}
166
167bool Program::attachShader(Shader *shader)
168{
169 if (shader->getType() == GL_VERTEX_SHADER)
170 {
171 if (mVertexShader)
172 {
173 return false;
174 }
175
Brandon Jones71620962014-08-20 14:04:59 -0700176 mVertexShader = shader;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000177 mVertexShader->addRef();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000178 }
179 else if (shader->getType() == GL_FRAGMENT_SHADER)
180 {
181 if (mFragmentShader)
182 {
183 return false;
184 }
185
Brandon Jones71620962014-08-20 14:04:59 -0700186 mFragmentShader = shader;
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000187 mFragmentShader->addRef();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000188 }
189 else UNREACHABLE();
190
191 return true;
192}
193
194bool Program::detachShader(Shader *shader)
195{
196 if (shader->getType() == GL_VERTEX_SHADER)
197 {
198 if (mVertexShader != shader)
199 {
200 return false;
201 }
202
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000203 mVertexShader->release();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204 mVertexShader = NULL;
205 }
206 else if (shader->getType() == GL_FRAGMENT_SHADER)
207 {
208 if (mFragmentShader != shader)
209 {
210 return false;
211 }
212
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000213 mFragmentShader->release();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000214 mFragmentShader = NULL;
215 }
216 else UNREACHABLE();
217
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218 return true;
219}
220
daniel@transgaming.comcba50572010-03-28 19:36:09 +0000221int Program::getAttachedShadersCount() const
222{
223 return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
224}
225
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000226void AttributeBindings::bindAttributeLocation(GLuint index, const char *name)
227{
228 if (index < MAX_VERTEX_ATTRIBS)
229 {
230 for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
231 {
232 mAttributeBinding[i].erase(name);
233 }
234
235 mAttributeBinding[index].insert(name);
236 }
apatrick@chromium.org9a30b092012-06-06 20:21:55 +0000237}
238
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000239void Program::bindAttributeLocation(GLuint index, const char *name)
240{
apatrick@chromium.org9a30b092012-06-06 20:21:55 +0000241 mAttributeBindings.bindAttributeLocation(index, name);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000242}
243
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
245// compiling them into binaries, determining the attribute mappings, and collecting
246// a list of uniforms
Brandon Jones43a53e22014-08-28 16:23:22 -0700247bool Program::link(const Caps &caps)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000248{
249 unlink(false);
250
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000251 mInfoLog.reset();
shannonwoods@chromium.org70eb1ea2013-05-30 00:07:20 +0000252 resetUniformBlockBindings();
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000253
Brandon Jonesc9610c52014-08-25 17:02:59 -0700254 mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
Geoff Lang48dcae72014-02-05 16:28:24 -0500255 mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
Brandon Jones43a53e22014-08-28 16:23:22 -0700256 mTransformFeedbackVaryings, mTransformFeedbackBufferMode, caps);
daniel@transgaming.com4c962bf2012-07-24 18:37:02 +0000257
daniel@transgaming.com716056c2012-07-24 18:38:59 +0000258 return mLinked;
apatrick@chromium.org9a30b092012-06-06 20:21:55 +0000259}
260
apatrick@chromium.org9a30b092012-06-06 20:21:55 +0000261int AttributeBindings::getAttributeBinding(const std::string &name) const
daniel@transgaming.comb4ff1f82010-04-22 13:35:18 +0000262{
263 for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
264 {
265 if (mAttributeBinding[location].find(name) != mAttributeBinding[location].end())
266 {
267 return location;
268 }
269 }
270
271 return -1;
272}
273
daniel@transgaming.comaa5e59b2011-10-04 18:43:12 +0000274// Returns the program object to an unlinked state, before re-linking, or at destruction
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275void Program::unlink(bool destroy)
276{
277 if (destroy) // Object being destructed
278 {
279 if (mFragmentShader)
280 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000281 mFragmentShader->release();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000282 mFragmentShader = NULL;
283 }
284
285 if (mVertexShader)
286 {
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000287 mVertexShader->release();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000288 mVertexShader = NULL;
289 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000290 }
291
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000292 mProgramBinary.set(NULL);
daniel@transgaming.com716056c2012-07-24 18:38:59 +0000293 mLinked = false;
294}
295
296bool Program::isLinked()
297{
298 return mLinked;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000299}
300
Geoff Lang48dcae72014-02-05 16:28:24 -0500301ProgramBinary* Program::getProgramBinary() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000302{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000303 return mProgramBinary.get();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304}
305
Geoff Lang900013c2014-07-07 11:32:19 -0400306bool Program::setProgramBinary(GLenum binaryFormat, const void *binary, GLsizei length)
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +0000307{
308 unlink(false);
apatrick@chromium.org90080e32012-07-09 22:15:33 +0000309
310 mInfoLog.reset();
311
Brandon Jonesc9610c52014-08-25 17:02:59 -0700312 mProgramBinary.set(new ProgramBinary(mRenderer->createProgram()));
Geoff Lang900013c2014-07-07 11:32:19 -0400313 mLinked = mProgramBinary->load(mInfoLog, binaryFormat, binary, length);
Brandon Jonesc9610c52014-08-25 17:02:59 -0700314
daniel@transgaming.com716056c2012-07-24 18:38:59 +0000315 if (!mLinked)
apatrick@chromium.org90080e32012-07-09 22:15:33 +0000316 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000317 mProgramBinary.set(NULL);
apatrick@chromium.org90080e32012-07-09 22:15:33 +0000318 }
daniel@transgaming.com4c962bf2012-07-24 18:37:02 +0000319
daniel@transgaming.com716056c2012-07-24 18:38:59 +0000320 return mLinked;
apatrick@chromium.org3ce8dbc2012-06-08 17:52:30 +0000321}
322
daniel@transgaming.comda13f3e2010-07-28 19:20:56 +0000323void Program::release()
324{
325 mRefCount--;
326
327 if (mRefCount == 0 && mDeleteStatus)
328 {
329 mResourceManager->deleteProgram(mHandle);
330 }
331}
332
333void Program::addRef()
334{
335 mRefCount++;
336}
337
338unsigned int Program::getRefCount() const
339{
340 return mRefCount;
341}
342
apatrick@chromium.org90080e32012-07-09 22:15:33 +0000343GLint Program::getProgramBinaryLength() const
344{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000345 ProgramBinary *programBinary = mProgramBinary.get();
346 if (programBinary)
apatrick@chromium.org90080e32012-07-09 22:15:33 +0000347 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000348 return programBinary->getLength();
apatrick@chromium.org90080e32012-07-09 22:15:33 +0000349 }
350 else
351 {
352 return 0;
353 }
354}
355
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000356int Program::getInfoLogLength() const
357{
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000358 return mInfoLog.getLength();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000359}
360
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000361void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
362{
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000363 return mInfoLog.getLog(bufSize, length, infoLog);
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000364}
365
daniel@transgaming.com6c785212010-03-30 03:36:17 +0000366void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
367{
368 int total = 0;
369
370 if (mVertexShader)
371 {
372 if (total < maxCount)
373 {
374 shaders[total] = mVertexShader->getHandle();
375 }
376
377 total++;
378 }
379
380 if (mFragmentShader)
381 {
382 if (total < maxCount)
383 {
384 shaders[total] = mFragmentShader->getHandle();
385 }
386
387 total++;
388 }
389
390 if (count)
391 {
392 *count = total;
393 }
394}
395
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000396void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
397{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000398 ProgramBinary *programBinary = getProgramBinary();
399 if (programBinary)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000400 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000401 programBinary->getActiveAttribute(index, bufsize, length, size, type, name);
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000402 }
403 else
404 {
405 if (bufsize > 0)
406 {
407 name[0] = '\0';
408 }
409
410 if (length)
411 {
412 *length = 0;
413 }
414
415 *type = GL_NONE;
416 *size = 1;
417 }
418}
419
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000420GLint Program::getActiveAttributeCount()
421{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000422 ProgramBinary *programBinary = getProgramBinary();
423 if (programBinary)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000424 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000425 return programBinary->getActiveAttributeCount();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000426 }
427 else
428 {
429 return 0;
430 }
431}
432
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000433GLint Program::getActiveAttributeMaxLength()
434{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000435 ProgramBinary *programBinary = getProgramBinary();
436 if (programBinary)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000437 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000438 return programBinary->getActiveAttributeMaxLength();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000439 }
440 else
441 {
442 return 0;
443 }
444}
445
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000446void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
447{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000448 ProgramBinary *programBinary = getProgramBinary();
449 if (programBinary)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000450 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000451 return programBinary->getActiveUniform(index, bufsize, length, size, type, name);
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000452 }
453 else
454 {
455 if (bufsize > 0)
456 {
457 name[0] = '\0';
458 }
459
460 if (length)
461 {
462 *length = 0;
463 }
464
465 *size = 0;
466 *type = GL_NONE;
467 }
468}
469
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000470GLint Program::getActiveUniformCount()
471{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000472 ProgramBinary *programBinary = getProgramBinary();
473 if (programBinary)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000474 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000475 return programBinary->getActiveUniformCount();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000476 }
477 else
478 {
479 return 0;
480 }
481}
482
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000483GLint Program::getActiveUniformMaxLength()
484{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000485 ProgramBinary *programBinary = getProgramBinary();
486 if (programBinary)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000487 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000488 return programBinary->getActiveUniformMaxLength();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000489 }
490 else
491 {
492 return 0;
493 }
494}
495
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000496void Program::flagForDeletion()
497{
498 mDeleteStatus = true;
499}
500
501bool Program::isFlaggedForDeletion() const
502{
503 return mDeleteStatus;
504}
daniel@transgaming.com86a7a132010-04-29 03:32:32 +0000505
Brandon Jones43a53e22014-08-28 16:23:22 -0700506void Program::validate(const Caps &caps)
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000507{
508 mInfoLog.reset();
509
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000510 ProgramBinary *programBinary = getProgramBinary();
511 if (isLinked() && programBinary)
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000512 {
Brandon Jones43a53e22014-08-28 16:23:22 -0700513 programBinary->validate(mInfoLog, caps);
apatrick@chromium.org253b8d22012-06-22 19:27:21 +0000514 }
515 else
516 {
517 mInfoLog.append("Program has not been successfully linked.");
518 }
519}
520
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000521bool Program::isValidated() const
522{
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000523 ProgramBinary *programBinary = mProgramBinary.get();
524 if (programBinary)
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000525 {
daniel@transgaming.com989c1c82012-07-24 18:40:38 +0000526 return programBinary->isValidated();
apatrick@chromium.orge2a59bb2012-06-07 21:09:53 +0000527 }
528 else
529 {
530 return false;
531 }
532}
533
shannonwoods@chromium.orge684b582013-05-30 00:07:42 +0000534GLint Program::getActiveUniformBlockCount()
535{
536 ProgramBinary *programBinary = getProgramBinary();
537 if (programBinary)
538 {
539 return static_cast<GLint>(programBinary->getActiveUniformBlockCount());
540 }
541 else
542 {
543 return 0;
544 }
545}
546
547GLint Program::getActiveUniformBlockMaxLength()
548{
549 ProgramBinary *programBinary = getProgramBinary();
550 if (programBinary)
551 {
552 return static_cast<GLint>(programBinary->getActiveUniformBlockMaxLength());
553 }
554 else
555 {
556 return 0;
557 }
558}
559
shannonwoods@chromium.org70eb1ea2013-05-30 00:07:20 +0000560void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
561{
562 mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
563}
564
565GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
566{
567 return mUniformBlockBindings[uniformBlockIndex];
568}
569
570void Program::resetUniformBlockBindings()
571{
572 for (unsigned int blockId = 0; blockId < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; blockId++)
573 {
574 mUniformBlockBindings[blockId] = 0;
575 }
576}
577
Geoff Lang48dcae72014-02-05 16:28:24 -0500578void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
579{
580 mTransformFeedbackVaryings.resize(count);
581 for (GLsizei i = 0; i < count; i++)
582 {
583 mTransformFeedbackVaryings[i] = varyings[i];
584 }
585
586 mTransformFeedbackBufferMode = bufferMode;
587}
588
589void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
590{
591 ProgramBinary *programBinary = getProgramBinary();
592 if (programBinary && index < programBinary->getTransformFeedbackVaryingCount())
593 {
594 const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(index);
595 GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
596 if (length)
597 {
598 *length = lastNameIdx;
599 }
600 if (size)
601 {
602 *size = varying.size;
603 }
604 if (type)
605 {
606 *type = varying.type;
607 }
608 if (name)
609 {
610 memcpy(name, varying.name.c_str(), lastNameIdx);
611 name[lastNameIdx] = '\0';
612 }
613 }
614}
615
Geoff Lang1b6edcb2014-02-03 14:27:56 -0500616GLsizei Program::getTransformFeedbackVaryingCount() const
617{
Geoff Lang48dcae72014-02-05 16:28:24 -0500618 ProgramBinary *programBinary = getProgramBinary();
619 if (programBinary)
620 {
621 return static_cast<GLsizei>(programBinary->getTransformFeedbackVaryingCount());
622 }
623 else
624 {
625 return 0;
626 }
Geoff Lang1b6edcb2014-02-03 14:27:56 -0500627}
628
629GLsizei Program::getTransformFeedbackVaryingMaxLength() const
630{
Geoff Lang48dcae72014-02-05 16:28:24 -0500631 ProgramBinary *programBinary = getProgramBinary();
632 if (programBinary)
633 {
634 GLsizei maxSize = 0;
635 for (size_t i = 0; i < programBinary->getTransformFeedbackVaryingCount(); i++)
636 {
637 const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(i);
638 maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
639 }
640
641 return maxSize;
642 }
643 else
644 {
645 return 0;
646 }
Geoff Lang1b6edcb2014-02-03 14:27:56 -0500647}
648
649GLenum Program::getTransformFeedbackBufferMode() const
650{
Geoff Lang48dcae72014-02-05 16:28:24 -0500651 ProgramBinary *programBinary = getProgramBinary();
652 if (programBinary)
653 {
654 return programBinary->getTransformFeedbackBufferMode();
655 }
656 else
657 {
658 return mTransformFeedbackBufferMode;
659 }
Geoff Lang1b6edcb2014-02-03 14:27:56 -0500660}
661
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000662}