Home | History | Annotate | Download | only in libGLESv2
      1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //    http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 // Program.cpp: Implements the Program class. Implements GL program objects
     16 // and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.
     17 
     18 #include "Program.h"
     19 
     20 #include "main.h"
     21 #include "Buffer.h"
     22 #include "Shader.h"
     23 #include "TransformFeedback.h"
     24 #include "utilities.h"
     25 #include "common/debug.h"
     26 #include "Shader/PixelShader.hpp"
     27 #include "Shader/VertexShader.hpp"
     28 
     29 #include <algorithm>
     30 #include <string>
     31 #include <stdlib.h>
     32 
     33 namespace es2
     34 {
     35 	unsigned int Program::currentSerial = 1;
     36 
     37 	std::string str(int i)
     38 	{
     39 		char buffer[20];
     40 		sprintf(buffer, "%d", i);
     41 		return buffer;
     42 	}
     43 
     44 	Uniform::BlockInfo::BlockInfo(const glsl::Uniform& uniform, int blockIndex)
     45 	{
     46 		if(blockIndex >= 0)
     47 		{
     48 			index = blockIndex;
     49 			offset = uniform.blockInfo.offset;
     50 			arrayStride = uniform.blockInfo.arrayStride;
     51 			matrixStride = uniform.blockInfo.matrixStride;
     52 			isRowMajorMatrix = uniform.blockInfo.isRowMajorMatrix;
     53 		}
     54 	}
     55 
     56 	Uniform::Uniform(const glsl::Uniform &uniform, const BlockInfo &blockInfo)
     57 	 : type(uniform.type), precision(uniform.precision), name(uniform.name),
     58 	   arraySize(uniform.arraySize), blockInfo(blockInfo), fields(uniform.fields)
     59 	{
     60 		if((blockInfo.index == -1) && uniform.fields.empty())
     61 		{
     62 			size_t bytes = UniformTypeSize(type) * size();
     63 			data = new unsigned char[bytes];
     64 			memset(data, 0, bytes);
     65 		}
     66 	}
     67 
     68 	Uniform::~Uniform()
     69 	{
     70 		delete[] data;
     71 	}
     72 
     73 	bool Uniform::isArray() const
     74 	{
     75 		return arraySize >= 1;
     76 	}
     77 
     78 	int Uniform::size() const
     79 	{
     80 		return arraySize > 0 ? arraySize : 1;
     81 	}
     82 
     83 	int Uniform::registerCount() const
     84 	{
     85 		return size() * VariableRegisterCount(type);
     86 	}
     87 
     88 	UniformBlock::UniformBlock(const std::string &name, unsigned int elementIndex, unsigned int dataSize, std::vector<unsigned int> memberUniformIndexes) :
     89 		name(name), elementIndex(elementIndex), dataSize(dataSize), memberUniformIndexes(memberUniformIndexes), psRegisterIndex(GL_INVALID_INDEX), vsRegisterIndex(GL_INVALID_INDEX)
     90 	{
     91 	}
     92 
     93 	void UniformBlock::setRegisterIndex(GLenum shader, unsigned int registerIndex)
     94 	{
     95 		switch(shader)
     96 		{
     97 		case GL_VERTEX_SHADER:
     98 			vsRegisterIndex = registerIndex;
     99 			break;
    100 		case GL_FRAGMENT_SHADER:
    101 			psRegisterIndex = registerIndex;
    102 			break;
    103 		default:
    104 			UNREACHABLE(shader);
    105 		}
    106 	}
    107 
    108 	bool UniformBlock::isArrayElement() const
    109 	{
    110 		return elementIndex != GL_INVALID_INDEX;
    111 	}
    112 
    113 	bool UniformBlock::isReferencedByVertexShader() const
    114 	{
    115 		return vsRegisterIndex != GL_INVALID_INDEX;
    116 	}
    117 
    118 	bool UniformBlock::isReferencedByFragmentShader() const
    119 	{
    120 		return psRegisterIndex != GL_INVALID_INDEX;
    121 	}
    122 
    123 	UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index)
    124 	{
    125 	}
    126 
    127 	LinkedVarying::LinkedVarying()
    128 	{
    129 	}
    130 
    131 	LinkedVarying::LinkedVarying(const std::string &name, GLenum type, GLsizei size, int reg, int col)
    132 	 : name(name), type(type), size(size), reg(reg), col(col)
    133 	{
    134 	}
    135 
    136 	Program::Program(ResourceManager *manager, GLuint handle) : serial(issueSerial()), resourceManager(manager), handle(handle)
    137 	{
    138 		fragmentShader = 0;
    139 		vertexShader = 0;
    140 		pixelBinary = 0;
    141 		vertexBinary = 0;
    142 
    143 		transformFeedbackBufferMode = GL_INTERLEAVED_ATTRIBS;
    144 		totalLinkedVaryingsComponents = 0;
    145 
    146 		infoLog = 0;
    147 		validated = false;
    148 
    149 		resetUniformBlockBindings();
    150 		unlink();
    151 
    152 		orphaned = false;
    153 		retrievableBinary = false;
    154 		referenceCount = 0;
    155 	}
    156 
    157 	Program::~Program()
    158 	{
    159 		unlink();
    160 
    161 		if(vertexShader)
    162 		{
    163 			vertexShader->release();
    164 		}
    165 
    166 		if(fragmentShader)
    167 		{
    168 			fragmentShader->release();
    169 		}
    170 	}
    171 
    172 	bool Program::attachShader(Shader *shader)
    173 	{
    174 		if(shader->getType() == GL_VERTEX_SHADER)
    175 		{
    176 			if(vertexShader)
    177 			{
    178 				return false;
    179 			}
    180 
    181 			vertexShader = (VertexShader*)shader;
    182 			vertexShader->addRef();
    183 		}
    184 		else if(shader->getType() == GL_FRAGMENT_SHADER)
    185 		{
    186 			if(fragmentShader)
    187 			{
    188 				return false;
    189 			}
    190 
    191 			fragmentShader = (FragmentShader*)shader;
    192 			fragmentShader->addRef();
    193 		}
    194 		else UNREACHABLE(shader->getType());
    195 
    196 		return true;
    197 	}
    198 
    199 	bool Program::detachShader(Shader *shader)
    200 	{
    201 		if(shader->getType() == GL_VERTEX_SHADER)
    202 		{
    203 			if(vertexShader != shader)
    204 			{
    205 				return false;
    206 			}
    207 
    208 			vertexShader->release();
    209 			vertexShader = 0;
    210 		}
    211 		else if(shader->getType() == GL_FRAGMENT_SHADER)
    212 		{
    213 			if(fragmentShader != shader)
    214 			{
    215 				return false;
    216 			}
    217 
    218 			fragmentShader->release();
    219 			fragmentShader = 0;
    220 		}
    221 		else UNREACHABLE(shader->getType());
    222 
    223 		return true;
    224 	}
    225 
    226 	int Program::getAttachedShadersCount() const
    227 	{
    228 		return (vertexShader ? 1 : 0) + (fragmentShader ? 1 : 0);
    229 	}
    230 
    231 	sw::PixelShader *Program::getPixelShader()
    232 	{
    233 		return pixelBinary;
    234 	}
    235 
    236 	sw::VertexShader *Program::getVertexShader()
    237 	{
    238 		return vertexBinary;
    239 	}
    240 
    241 	GLint Program::getFragDataLocation(const GLchar *name)
    242 	{
    243 		if(name && linked)
    244 		{
    245 			std::string baseName(name);
    246 			unsigned int subscript = GL_INVALID_INDEX;
    247 			baseName = ParseUniformName(baseName, &subscript);
    248 			for(auto const &varying : fragmentShader->varyings)
    249 			{
    250 				if(varying.qualifier == EvqFragmentOut)
    251 				{
    252 					if(varying.name == baseName)
    253 					{
    254 						ASSERT(varying.registerIndex >= 0);
    255 
    256 						if(subscript == GL_INVALID_INDEX)   // No subscript
    257 						{
    258 							return varying.registerIndex;
    259 						}
    260 
    261 						int rowCount = VariableRowCount(varying.type);
    262 						int colCount = VariableColumnCount(varying.type);
    263 
    264 						return varying.registerIndex + (rowCount > 1 ? colCount * subscript : subscript);
    265 					}
    266 				}
    267 			}
    268 		}
    269 
    270 		return -1;
    271 	}
    272 
    273 	void Program::bindAttributeLocation(GLuint index, const char *name)
    274 	{
    275 		attributeBinding[name] = index;
    276 	}
    277 
    278 	GLint Program::getAttributeLocation(const char *name)
    279 	{
    280 		return name ? getAttributeLocation(std::string(name)) : -1;
    281 	}
    282 
    283 	int Program::getAttributeStream(int attributeIndex)
    284 	{
    285 		ASSERT(attributeIndex >= 0 && attributeIndex < MAX_VERTEX_ATTRIBS);
    286 
    287 		return attributeStream[attributeIndex];
    288 	}
    289 
    290 	// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader)
    291 	GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
    292 	{
    293 		GLint logicalTextureUnit = -1;
    294 
    295 		switch(type)
    296 		{
    297 		case sw::SAMPLER_PIXEL:
    298 			ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
    299 
    300 			if(samplersPS[samplerIndex].active)
    301 			{
    302 				logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
    303 			}
    304 			break;
    305 		case sw::SAMPLER_VERTEX:
    306 			ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
    307 
    308 			if(samplersVS[samplerIndex].active)
    309 			{
    310 				logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
    311 			}
    312 			break;
    313 		default: UNREACHABLE(type);
    314 		}
    315 
    316 		if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
    317 		{
    318 			return logicalTextureUnit;
    319 		}
    320 
    321 		return -1;
    322 	}
    323 
    324 	// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
    325 	TextureType Program::getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex)
    326 	{
    327 		switch(type)
    328 		{
    329 		case sw::SAMPLER_PIXEL:
    330 			ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
    331 			ASSERT(samplersPS[samplerIndex].active);
    332 			return samplersPS[samplerIndex].textureType;
    333 		case sw::SAMPLER_VERTEX:
    334 			ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
    335 			ASSERT(samplersVS[samplerIndex].active);
    336 			return samplersVS[samplerIndex].textureType;
    337 		default: UNREACHABLE(type);
    338 		}
    339 
    340 		return TEXTURE_2D;
    341 	}
    342 
    343 	Uniform *Program::getUniform(const std::string &name) const
    344 	{
    345 		unsigned int subscript = GL_INVALID_INDEX;
    346 		std::string baseName = es2::ParseUniformName(name, &subscript);
    347 
    348 		for(size_t index = 0; index < uniforms.size(); index++)
    349 		{
    350 			if(uniforms[index]->name == baseName)
    351 			{
    352 				return uniforms[index];
    353 			}
    354 		}
    355 
    356 		return nullptr;
    357 	}
    358 
    359 	GLint Program::getUniformLocation(const std::string &name) const
    360 	{
    361 		unsigned int subscript = GL_INVALID_INDEX;
    362 		std::string baseName = es2::ParseUniformName(name, &subscript);
    363 
    364 		for(size_t location = 0; location < uniformIndex.size(); location++)
    365 		{
    366 			if(uniformIndex[location].name == baseName)
    367 			{
    368 				const unsigned int index = uniformIndex[location].index;
    369 
    370 				if(index != GL_INVALID_INDEX)
    371 				{
    372 					if(subscript == GL_INVALID_INDEX)
    373 					{
    374 						return (GLint)location;
    375 					}
    376 					else if(uniforms[index]->isArray())
    377 					{
    378 						if(uniformIndex[location].element == subscript)
    379 						{
    380 							return (GLint)location;
    381 						}
    382 					}
    383 				}
    384 			}
    385 		}
    386 
    387 		return -1;
    388 	}
    389 
    390 	GLuint Program::getUniformIndex(const std::string &name) const
    391 	{
    392 		unsigned int subscript = GL_INVALID_INDEX;
    393 		std::string baseName = es2::ParseUniformName(name, &subscript);
    394 
    395 		// The app is not allowed to specify array indices other than 0 for arrays of basic types
    396 		if(subscript != 0 && subscript != GL_INVALID_INDEX)
    397 		{
    398 			return GL_INVALID_INDEX;
    399 		}
    400 
    401 		size_t numUniforms = uniforms.size();
    402 		for(GLuint index = 0; index < numUniforms; index++)
    403 		{
    404 			if(uniforms[index]->name == baseName)
    405 			{
    406 				if(uniforms[index]->isArray() || subscript == GL_INVALID_INDEX)
    407 				{
    408 					return index;
    409 				}
    410 			}
    411 		}
    412 
    413 		return GL_INVALID_INDEX;
    414 	}
    415 
    416 	void Program::getActiveUniformBlockiv(GLuint uniformBlockIndex, GLenum pname, GLint *params) const
    417 	{
    418 		ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
    419 
    420 		const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
    421 
    422 		switch(pname)
    423 		{
    424 		case GL_UNIFORM_BLOCK_DATA_SIZE:
    425 			*params = static_cast<GLint>(uniformBlock.dataSize);
    426 			break;
    427 		case GL_UNIFORM_BLOCK_NAME_LENGTH:
    428 			*params = static_cast<GLint>(uniformBlock.name.size() + 1 + (uniformBlock.isArrayElement() ? 3 : 0));
    429 			break;
    430 		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
    431 			*params = static_cast<GLint>(uniformBlock.memberUniformIndexes.size());
    432 			break;
    433 		case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
    434 			{
    435 				for(unsigned int blockMemberIndex = 0; blockMemberIndex < uniformBlock.memberUniformIndexes.size(); blockMemberIndex++)
    436 				{
    437 					params[blockMemberIndex] = static_cast<GLint>(uniformBlock.memberUniformIndexes[blockMemberIndex]);
    438 				}
    439 			}
    440 			break;
    441 		case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
    442 			*params = static_cast<GLint>(uniformBlock.isReferencedByVertexShader());
    443 			break;
    444 		case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
    445 			*params = static_cast<GLint>(uniformBlock.isReferencedByFragmentShader());
    446 			break;
    447 		default: UNREACHABLE(pname);
    448 		}
    449 	}
    450 
    451 	GLuint Program::getUniformBlockIndex(const std::string &name) const
    452 	{
    453 		unsigned int subscript = GL_INVALID_INDEX;
    454 		std::string baseName = es2::ParseUniformName(name, &subscript);
    455 
    456 		size_t numUniformBlocks = getActiveUniformBlockCount();
    457 		for(GLuint blockIndex = 0; blockIndex < numUniformBlocks; blockIndex++)
    458 		{
    459 			const UniformBlock &uniformBlock = *uniformBlocks[blockIndex];
    460 			if(uniformBlock.name == baseName)
    461 			{
    462 				const bool arrayElementZero = (subscript == GL_INVALID_INDEX && uniformBlock.elementIndex == 0);
    463 				if(subscript == uniformBlock.elementIndex || arrayElementZero)
    464 				{
    465 					return blockIndex;
    466 				}
    467 			}
    468 		}
    469 
    470 		return GL_INVALID_INDEX;
    471 	}
    472 
    473 	void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
    474 	{
    475 		ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
    476 
    477 		uniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
    478 	}
    479 
    480 	GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
    481 	{
    482 		ASSERT(uniformBlockIndex < getActiveUniformBlockCount());
    483 
    484 		return uniformBlockBindings[uniformBlockIndex];
    485 	}
    486 
    487 	void Program::resetUniformBlockBindings()
    488 	{
    489 		for(unsigned int blockId = 0; blockId < MAX_UNIFORM_BUFFER_BINDINGS; blockId++)
    490 		{
    491 			uniformBlockBindings[blockId] = 0;
    492 		}
    493 	}
    494 
    495 	bool Program::setUniformfv(GLint location, GLsizei count, const GLfloat *v, int numElements)
    496 	{
    497 		ASSERT(numElements >= 1 && numElements <= 4);
    498 
    499 		static GLenum floatType[] = { GL_FLOAT, GL_FLOAT_VEC2, GL_FLOAT_VEC3, GL_FLOAT_VEC4 };
    500 		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
    501 
    502 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    503 		{
    504 			return false;
    505 		}
    506 
    507 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    508 		targetUniform->dirty = true;
    509 
    510 		int size = targetUniform->size();
    511 
    512 		if(size == 1 && count > 1)
    513 		{
    514 			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
    515 		}
    516 
    517 		count = std::min(size - (int)uniformIndex[location].element, count);
    518 
    519 		int index = numElements - 1;
    520 		if(targetUniform->type == floatType[index])
    521 		{
    522 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat)* numElements,
    523 				   v, numElements * sizeof(GLfloat) * count);
    524 		}
    525 		else if(targetUniform->type == boolType[index])
    526 		{
    527 			GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * numElements;
    528 
    529 			for(int i = 0; i < count * numElements; i++)
    530 			{
    531 				boolParams[i] = (v[i] == 0.0f) ? GL_FALSE : GL_TRUE;
    532 			}
    533 		}
    534 		else
    535 		{
    536 			return false;
    537 		}
    538 
    539 		return true;
    540 	}
    541 
    542 	bool Program::setUniform1fv(GLint location, GLsizei count, const GLfloat* v)
    543 	{
    544 		return setUniformfv(location, count, v, 1);
    545 	}
    546 
    547 	bool Program::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
    548 	{
    549 		return setUniformfv(location, count, v, 2);
    550 	}
    551 
    552 	bool Program::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
    553 	{
    554 		return setUniformfv(location, count, v, 3);
    555 	}
    556 
    557 	bool Program::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
    558 	{
    559 		return setUniformfv(location, count, v, 4);
    560 	}
    561 
    562 	bool Program::setUniformMatrixfv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value, GLenum type)
    563 	{
    564 		int numElements;
    565 		switch(type)
    566 		{
    567 		case GL_FLOAT_MAT2:
    568 			numElements = 4;
    569 			break;
    570 		case GL_FLOAT_MAT2x3:
    571 		case GL_FLOAT_MAT3x2:
    572 			numElements = 6;
    573 			break;
    574 		case GL_FLOAT_MAT2x4:
    575 		case GL_FLOAT_MAT4x2:
    576 			numElements = 8;
    577 			break;
    578 		case GL_FLOAT_MAT3:
    579 			numElements = 9;
    580 			break;
    581 		case GL_FLOAT_MAT3x4:
    582 		case GL_FLOAT_MAT4x3:
    583 			numElements = 12;
    584 			break;
    585 		case GL_FLOAT_MAT4:
    586 			numElements = 16;
    587 			break;
    588 		default:
    589 			return false;
    590 		}
    591 
    592 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    593 		{
    594 			return false;
    595 		}
    596 
    597 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    598 		targetUniform->dirty = true;
    599 
    600 		if(targetUniform->type != type)
    601 		{
    602 			return false;
    603 		}
    604 
    605 		int size = targetUniform->size();
    606 
    607 		if(size == 1 && count > 1)
    608 		{
    609 			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
    610 		}
    611 
    612 		count = std::min(size - (int)uniformIndex[location].element, count);
    613 
    614 		GLfloat* dst = reinterpret_cast<GLfloat*>(targetUniform->data + uniformIndex[location].element * sizeof(GLfloat) * numElements);
    615 
    616 		if(transpose == GL_FALSE)
    617 		{
    618 			memcpy(dst, value, numElements * sizeof(GLfloat) * count);
    619 		}
    620 		else
    621 		{
    622 			const int rowSize = VariableRowCount(type);
    623 			const int colSize = VariableColumnCount(type);
    624 			for(int n = 0; n < count; ++n)
    625 			{
    626 				for(int i = 0; i < colSize; ++i)
    627 				{
    628 					for(int j = 0; j < rowSize; ++j)
    629 					{
    630 						dst[i * rowSize + j] = value[j * colSize + i];
    631 					}
    632 				}
    633 				dst += numElements;
    634 				value += numElements;
    635 			}
    636 		}
    637 
    638 
    639 		return true;
    640 	}
    641 
    642 	bool Program::setUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    643 	{
    644 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2);
    645 	}
    646 
    647 	bool Program::setUniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    648 	{
    649 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x3);
    650 	}
    651 
    652 	bool Program::setUniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    653 	{
    654 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT2x4);
    655 	}
    656 
    657 	bool Program::setUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    658 	{
    659 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3);
    660 	}
    661 
    662 	bool Program::setUniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    663 	{
    664 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x2);
    665 	}
    666 
    667 	bool Program::setUniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    668 	{
    669 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT3x4);
    670 	}
    671 
    672 	bool Program::setUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    673 	{
    674 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4);
    675 	}
    676 
    677 	bool Program::setUniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    678 	{
    679 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x2);
    680 	}
    681 
    682 	bool Program::setUniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value)
    683 	{
    684 		return setUniformMatrixfv(location, count, transpose, value, GL_FLOAT_MAT4x3);
    685 	}
    686 
    687 	bool Program::setUniform1iv(GLint location, GLsizei count, const GLint *v)
    688 	{
    689 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    690 		{
    691 			return false;
    692 		}
    693 
    694 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    695 		targetUniform->dirty = true;
    696 
    697 		int size = targetUniform->size();
    698 
    699 		if(size == 1 && count > 1)
    700 		{
    701 			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
    702 		}
    703 
    704 		count = std::min(size - (int)uniformIndex[location].element, count);
    705 
    706 		if(targetUniform->type == GL_INT || IsSamplerUniform(targetUniform->type))
    707 		{
    708 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint),
    709 				   v, sizeof(GLint) * count);
    710 		}
    711 		else if(targetUniform->type == GL_BOOL)
    712 		{
    713 			GLboolean *boolParams = new GLboolean[count];
    714 
    715 			for(int i = 0; i < count; i++)
    716 			{
    717 				if(v[i] == 0)
    718 				{
    719 					boolParams[i] = GL_FALSE;
    720 				}
    721 				else
    722 				{
    723 					boolParams[i] = GL_TRUE;
    724 				}
    725 			}
    726 
    727 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
    728 				   boolParams, sizeof(GLboolean) * count);
    729 
    730 			delete[] boolParams;
    731 		}
    732 		else
    733 		{
    734 			return false;
    735 		}
    736 
    737 		return true;
    738 	}
    739 
    740 	bool Program::setUniformiv(GLint location, GLsizei count, const GLint *v, int numElements)
    741 	{
    742 		static GLenum intType[] = { GL_INT, GL_INT_VEC2, GL_INT_VEC3, GL_INT_VEC4 };
    743 		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
    744 
    745 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    746 		{
    747 			return false;
    748 		}
    749 
    750 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    751 		targetUniform->dirty = true;
    752 
    753 		int size = targetUniform->size();
    754 
    755 		if(size == 1 && count > 1)
    756 		{
    757 			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
    758 		}
    759 
    760 		count = std::min(size - (int)uniformIndex[location].element, count);
    761 
    762 		int index = numElements - 1;
    763 		if(targetUniform->type == intType[index])
    764 		{
    765 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLint)* numElements,
    766 				   v, numElements * sizeof(GLint)* count);
    767 		}
    768 		else if(targetUniform->type == boolType[index])
    769 		{
    770 			GLboolean *boolParams = new GLboolean[count * numElements];
    771 
    772 			for(int i = 0; i < count * numElements; i++)
    773 			{
    774 				boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
    775 			}
    776 
    777 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
    778 				   boolParams, numElements * sizeof(GLboolean)* count);
    779 
    780 			delete[] boolParams;
    781 		}
    782 		else
    783 		{
    784 			return false;
    785 		}
    786 
    787 		return true;
    788 	}
    789 
    790 	bool Program::setUniform2iv(GLint location, GLsizei count, const GLint *v)
    791 	{
    792 		return setUniformiv(location, count, v, 2);
    793 	}
    794 
    795 	bool Program::setUniform3iv(GLint location, GLsizei count, const GLint *v)
    796 	{
    797 		return setUniformiv(location, count, v, 3);
    798 	}
    799 
    800 	bool Program::setUniform4iv(GLint location, GLsizei count, const GLint *v)
    801 	{
    802 		return setUniformiv(location, count, v, 4);
    803 	}
    804 
    805 	bool Program::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
    806 	{
    807 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    808 		{
    809 			return false;
    810 		}
    811 
    812 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    813 		targetUniform->dirty = true;
    814 
    815 		int size = targetUniform->size();
    816 
    817 		if(size == 1 && count > 1)
    818 		{
    819 			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
    820 		}
    821 
    822 		count = std::min(size - (int)uniformIndex[location].element, count);
    823 
    824 		if(targetUniform->type == GL_UNSIGNED_INT)
    825 		{
    826 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint),
    827 				   v, sizeof(GLuint)* count);
    828 		}
    829 		else if(targetUniform->type == GL_BOOL)
    830 		{
    831 			GLboolean *boolParams = new GLboolean[count];
    832 
    833 			for(int i = 0; i < count; i++)
    834 			{
    835 				if(v[i] == 0)
    836 				{
    837 					boolParams[i] = GL_FALSE;
    838 				}
    839 				else
    840 				{
    841 					boolParams[i] = GL_TRUE;
    842 				}
    843 			}
    844 
    845 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean),
    846 				   boolParams, sizeof(GLboolean)* count);
    847 
    848 			delete[] boolParams;
    849 		}
    850 		else
    851 		{
    852 			return false;
    853 		}
    854 
    855 		return true;
    856 	}
    857 
    858 	bool Program::setUniformuiv(GLint location, GLsizei count, const GLuint *v, int numElements)
    859 	{
    860 		static GLenum uintType[] = { GL_UNSIGNED_INT, GL_UNSIGNED_INT_VEC2, GL_UNSIGNED_INT_VEC3, GL_UNSIGNED_INT_VEC4 };
    861 		static GLenum boolType[] = { GL_BOOL, GL_BOOL_VEC2, GL_BOOL_VEC3, GL_BOOL_VEC4 };
    862 
    863 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    864 		{
    865 			return false;
    866 		}
    867 
    868 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    869 		targetUniform->dirty = true;
    870 
    871 		int size = targetUniform->size();
    872 
    873 		if(size == 1 && count > 1)
    874 		{
    875 			return false;   // Attempting to write an array to a non-array uniform is an INVALID_OPERATION
    876 		}
    877 
    878 		count = std::min(size - (int)uniformIndex[location].element, count);
    879 
    880 		int index = numElements - 1;
    881 		if(targetUniform->type == uintType[index])
    882 		{
    883 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLuint)* numElements,
    884 				   v, numElements * sizeof(GLuint)* count);
    885 		}
    886 		else if(targetUniform->type == boolType[index])
    887 		{
    888 			GLboolean *boolParams = new GLboolean[count * numElements];
    889 
    890 			for(int i = 0; i < count * numElements; i++)
    891 			{
    892 				boolParams[i] = (v[i] == 0) ? GL_FALSE : GL_TRUE;
    893 			}
    894 
    895 			memcpy(targetUniform->data + uniformIndex[location].element * sizeof(GLboolean)* numElements,
    896 				   boolParams, numElements * sizeof(GLboolean)* count);
    897 
    898 			delete[] boolParams;
    899 		}
    900 		else
    901 		{
    902 			return false;
    903 		}
    904 
    905 		return true;
    906 	}
    907 
    908 	bool Program::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
    909 	{
    910 		return setUniformuiv(location, count, v, 2);
    911 	}
    912 
    913 	bool Program::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
    914 	{
    915 		return setUniformuiv(location, count, v, 3);
    916 	}
    917 
    918 	bool Program::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
    919 	{
    920 		return setUniformuiv(location, count, v, 4);
    921 	}
    922 
    923 	bool Program::getUniformfv(GLint location, GLsizei *bufSize, GLfloat *params)
    924 	{
    925 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    926 		{
    927 			return false;
    928 		}
    929 
    930 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    931 		unsigned int count = UniformComponentCount(targetUniform->type);
    932 
    933 		// Sized query - ensure the provided buffer is large enough
    934 		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLfloat))
    935 		{
    936 			return false;
    937 		}
    938 
    939 		switch(UniformComponentType(targetUniform->type))
    940 		{
    941 		case GL_BOOL:
    942 			{
    943 				GLboolean *boolParams = (GLboolean*)targetUniform->data + uniformIndex[location].element * count;
    944 
    945 				for(unsigned int i = 0; i < count; i++)
    946 				{
    947 					params[i] = (boolParams[i] == GL_FALSE) ? 0.0f : 1.0f;
    948 				}
    949 			}
    950 			break;
    951 		case GL_FLOAT:
    952 			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLfloat),
    953 				   count * sizeof(GLfloat));
    954 			break;
    955 		case GL_INT:
    956 			{
    957 				GLint *intParams = (GLint*)targetUniform->data + uniformIndex[location].element * count;
    958 
    959 				for(unsigned int i = 0; i < count; i++)
    960 				{
    961 					params[i] = (float)intParams[i];
    962 				}
    963 			}
    964 			break;
    965 		case GL_UNSIGNED_INT:
    966 			{
    967 				GLuint *uintParams = (GLuint*)targetUniform->data + uniformIndex[location].element * count;
    968 
    969 				for(unsigned int i = 0; i < count; i++)
    970 				{
    971 					params[i] = (float)uintParams[i];
    972 				}
    973 			}
    974 			break;
    975 		default: UNREACHABLE(targetUniform->type);
    976 		}
    977 
    978 		return true;
    979 	}
    980 
    981 	bool Program::getUniformiv(GLint location, GLsizei *bufSize, GLint *params)
    982 	{
    983 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
    984 		{
    985 			return false;
    986 		}
    987 
    988 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
    989 		unsigned int count = UniformComponentCount(targetUniform->type);
    990 
    991 		// Sized query - ensure the provided buffer is large enough
    992 		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLint))
    993 		{
    994 			return false;
    995 		}
    996 
    997 		switch(UniformComponentType(targetUniform->type))
    998 		{
    999 		case GL_BOOL:
   1000 			{
   1001 				GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
   1002 
   1003 				for(unsigned int i = 0; i < count; i++)
   1004 				{
   1005 					params[i] = (GLint)boolParams[i];
   1006 				}
   1007 			}
   1008 			break;
   1009 		case GL_FLOAT:
   1010 			{
   1011 				GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
   1012 
   1013 				for(unsigned int i = 0; i < count; i++)
   1014 				{
   1015 					params[i] = (GLint)floatParams[i];
   1016 				}
   1017 			}
   1018 			break;
   1019 		case GL_INT:
   1020 		case GL_UNSIGNED_INT:
   1021 			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLint),
   1022 				   count * sizeof(GLint));
   1023 			break;
   1024 		default: UNREACHABLE(targetUniform->type);
   1025 		}
   1026 
   1027 		return true;
   1028 	}
   1029 
   1030 	bool Program::getUniformuiv(GLint location, GLsizei *bufSize, GLuint *params)
   1031 	{
   1032 		if(location < 0 || location >= (int)uniformIndex.size() || (uniformIndex[location].index == GL_INVALID_INDEX))
   1033 		{
   1034 			return false;
   1035 		}
   1036 
   1037 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
   1038 		unsigned int count = UniformComponentCount(targetUniform->type);
   1039 
   1040 		// Sized query - ensure the provided buffer is large enough
   1041 		if(bufSize && static_cast<unsigned int>(*bufSize) < count * sizeof(GLuint))
   1042 		{
   1043 			return false;
   1044 		}
   1045 
   1046 		switch(UniformComponentType(targetUniform->type))
   1047 		{
   1048 		case GL_BOOL:
   1049 		{
   1050 			GLboolean *boolParams = targetUniform->data + uniformIndex[location].element * count;
   1051 
   1052 			for(unsigned int i = 0; i < count; i++)
   1053 			{
   1054 				params[i] = (GLuint)boolParams[i];
   1055 			}
   1056 		}
   1057 			break;
   1058 		case GL_FLOAT:
   1059 		{
   1060 			GLfloat *floatParams = (GLfloat*)targetUniform->data + uniformIndex[location].element * count;
   1061 
   1062 			for(unsigned int i = 0; i < count; i++)
   1063 			{
   1064 				params[i] = (GLuint)floatParams[i];
   1065 			}
   1066 		}
   1067 			break;
   1068 		case GL_INT:
   1069 		case GL_UNSIGNED_INT:
   1070 			memcpy(params, targetUniform->data + uniformIndex[location].element * count * sizeof(GLuint),
   1071 				   count * sizeof(GLuint));
   1072 			break;
   1073 		default: UNREACHABLE(targetUniform->type);
   1074 		}
   1075 
   1076 		return true;
   1077 	}
   1078 
   1079 	void Program::dirtyAllUniforms()
   1080 	{
   1081 		size_t numUniforms = uniforms.size();
   1082 		for(size_t index = 0; index < numUniforms; index++)
   1083 		{
   1084 			uniforms[index]->dirty = true;
   1085 		}
   1086 	}
   1087 
   1088 	// Applies all the uniforms set for this program object to the device
   1089 	void Program::applyUniforms(Device *device)
   1090 	{
   1091 		GLint numUniforms = static_cast<GLint>(uniformIndex.size());
   1092 		for(GLint location = 0; location < numUniforms; location++)
   1093 		{
   1094 			if((uniformIndex[location].element != 0) || (uniformIndex[location].index == GL_INVALID_INDEX))
   1095 			{
   1096 				continue;
   1097 			}
   1098 
   1099 			Uniform *targetUniform = uniforms[uniformIndex[location].index];
   1100 
   1101 			if(targetUniform->dirty && (targetUniform->blockInfo.index == -1))
   1102 			{
   1103 				GLsizei size = targetUniform->size();
   1104 				GLfloat *f = (GLfloat*)targetUniform->data;
   1105 				GLint *i = (GLint*)targetUniform->data;
   1106 				GLuint *ui = (GLuint*)targetUniform->data;
   1107 				GLboolean *b = (GLboolean*)targetUniform->data;
   1108 
   1109 				switch(targetUniform->type)
   1110 				{
   1111 				case GL_BOOL:       applyUniform1bv(device, location, size, b);       break;
   1112 				case GL_BOOL_VEC2:  applyUniform2bv(device, location, size, b);       break;
   1113 				case GL_BOOL_VEC3:  applyUniform3bv(device, location, size, b);       break;
   1114 				case GL_BOOL_VEC4:  applyUniform4bv(device, location, size, b);       break;
   1115 				case GL_FLOAT:      applyUniform1fv(device, location, size, f);       break;
   1116 				case GL_FLOAT_VEC2: applyUniform2fv(device, location, size, f);       break;
   1117 				case GL_FLOAT_VEC3: applyUniform3fv(device, location, size, f);       break;
   1118 				case GL_FLOAT_VEC4: applyUniform4fv(device, location, size, f);       break;
   1119 				case GL_FLOAT_MAT2:   applyUniformMatrix2fv(device, location, size, f);   break;
   1120 				case GL_FLOAT_MAT2x3: applyUniformMatrix2x3fv(device, location, size, f); break;
   1121 				case GL_FLOAT_MAT2x4: applyUniformMatrix2x4fv(device, location, size, f); break;
   1122 				case GL_FLOAT_MAT3x2: applyUniformMatrix3x2fv(device, location, size, f); break;
   1123 				case GL_FLOAT_MAT3:   applyUniformMatrix3fv(device, location, size, f);   break;
   1124 				case GL_FLOAT_MAT3x4: applyUniformMatrix3x4fv(device, location, size, f); break;
   1125 				case GL_FLOAT_MAT4x2: applyUniformMatrix4x2fv(device, location, size, f); break;
   1126 				case GL_FLOAT_MAT4x3: applyUniformMatrix4x3fv(device, location, size, f); break;
   1127 				case GL_FLOAT_MAT4:   applyUniformMatrix4fv(device, location, size, f);   break;
   1128 				case GL_SAMPLER_2D:
   1129 				case GL_SAMPLER_CUBE:
   1130 				case GL_SAMPLER_2D_RECT_ARB:
   1131 				case GL_SAMPLER_EXTERNAL_OES:
   1132 				case GL_SAMPLER_3D_OES:
   1133 				case GL_SAMPLER_2D_ARRAY:
   1134 				case GL_SAMPLER_2D_SHADOW:
   1135 				case GL_SAMPLER_CUBE_SHADOW:
   1136 				case GL_SAMPLER_2D_ARRAY_SHADOW:
   1137 				case GL_INT_SAMPLER_2D:
   1138 				case GL_UNSIGNED_INT_SAMPLER_2D:
   1139 				case GL_INT_SAMPLER_CUBE:
   1140 				case GL_UNSIGNED_INT_SAMPLER_CUBE:
   1141 				case GL_INT_SAMPLER_3D:
   1142 				case GL_UNSIGNED_INT_SAMPLER_3D:
   1143 				case GL_INT_SAMPLER_2D_ARRAY:
   1144 				case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
   1145 				case GL_INT:        applyUniform1iv(device, location, size, i);       break;
   1146 				case GL_INT_VEC2:   applyUniform2iv(device, location, size, i);       break;
   1147 				case GL_INT_VEC3:   applyUniform3iv(device, location, size, i);       break;
   1148 				case GL_INT_VEC4:   applyUniform4iv(device, location, size, i);       break;
   1149 				case GL_UNSIGNED_INT:      applyUniform1uiv(device, location, size, ui); break;
   1150 				case GL_UNSIGNED_INT_VEC2: applyUniform2uiv(device, location, size, ui); break;
   1151 				case GL_UNSIGNED_INT_VEC3: applyUniform3uiv(device, location, size, ui); break;
   1152 				case GL_UNSIGNED_INT_VEC4: applyUniform4uiv(device, location, size, ui); break;
   1153 				default:
   1154 					UNREACHABLE(targetUniform->type);
   1155 				}
   1156 
   1157 				targetUniform->dirty = false;
   1158 			}
   1159 		}
   1160 	}
   1161 
   1162 	void Program::applyUniformBuffers(Device *device, BufferBinding* uniformBuffers)
   1163 	{
   1164 		GLint vertexUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
   1165 		GLint fragmentUniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS];
   1166 
   1167 		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
   1168 		{
   1169 			vertexUniformBuffers[bufferBindingIndex] = -1;
   1170 		}
   1171 
   1172 		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
   1173 		{
   1174 			fragmentUniformBuffers[bufferBindingIndex] = -1;
   1175 		}
   1176 
   1177 		int vertexUniformBufferIndex = 0;
   1178 		int fragmentUniformBufferIndex = 0;
   1179 		for(unsigned int uniformBlockIndex = 0; uniformBlockIndex < uniformBlocks.size(); uniformBlockIndex++)
   1180 		{
   1181 			UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
   1182 
   1183 			// Unnecessary to apply an unreferenced standard or shared UBO
   1184 			if(!uniformBlock.isReferencedByVertexShader() && !uniformBlock.isReferencedByFragmentShader())
   1185 			{
   1186 				continue;
   1187 			}
   1188 
   1189 			GLuint blockBinding = uniformBlockBindings[uniformBlockIndex];
   1190 
   1191 			if(uniformBlock.isReferencedByVertexShader())
   1192 			{
   1193 				vertexUniformBuffers[vertexUniformBufferIndex++] = blockBinding;
   1194 			}
   1195 
   1196 			if(uniformBlock.isReferencedByFragmentShader())
   1197 			{
   1198 				fragmentUniformBuffers[fragmentUniformBufferIndex++] = blockBinding;
   1199 			}
   1200 		}
   1201 
   1202 		for(unsigned int bufferBindingIndex = 0; bufferBindingIndex < MAX_UNIFORM_BUFFER_BINDINGS; bufferBindingIndex++)
   1203 		{
   1204 			int index = vertexUniformBuffers[bufferBindingIndex];
   1205 			Buffer* vsBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr;
   1206 			device->VertexProcessor::setUniformBuffer(bufferBindingIndex,
   1207 				vsBuffer ? vsBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
   1208 			index = fragmentUniformBuffers[bufferBindingIndex];
   1209 			Buffer* psBuffer = (index != -1) ? (Buffer*)uniformBuffers[index].get() : nullptr;
   1210 			device->PixelProcessor::setUniformBuffer(bufferBindingIndex,
   1211 				psBuffer ? psBuffer->getResource() : nullptr, (index != -1) ? uniformBuffers[index].getOffset() : 0);
   1212 		}
   1213 	}
   1214 
   1215 	void Program::applyTransformFeedback(Device *device, TransformFeedback* transformFeedback)
   1216 	{
   1217 		// Make sure the flags will fit in a 64 bit unsigned int variable
   1218 		ASSERT(sw::max<int>(MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS) <= 64);
   1219 
   1220 		BufferBinding* transformFeedbackBuffers = (transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused()) ? transformFeedback->getBuffers() : nullptr;
   1221 
   1222 		uint64_t enableTransformFeedback = 0;
   1223 		if(!transformFeedbackBuffers)
   1224 		{
   1225 			for(unsigned int index = 0; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
   1226 			{
   1227 				device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
   1228 			}
   1229 			device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
   1230 			return;
   1231 		}
   1232 
   1233 		unsigned int maxVaryings = static_cast<unsigned int>(transformFeedbackLinkedVaryings.size());
   1234 		switch(transformFeedbackBufferMode)
   1235 		{
   1236 		case GL_SEPARATE_ATTRIBS:
   1237 		{
   1238 			maxVaryings = sw::min(maxVaryings, (unsigned int)MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
   1239 			// Attribs go to separate buffers
   1240 			for(unsigned int index = 0; index < maxVaryings; ++index)
   1241 			{
   1242 				int size = transformFeedbackLinkedVaryings[index].size;
   1243 				int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
   1244 				int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
   1245 				int nbRegs = rowCount > 1 ? colCount * size : size;
   1246 				int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
   1247 				int componentStride = rowCount * colCount * size;
   1248 				int baseOffset = transformFeedback->vertexOffset() * componentStride * sizeof(float);
   1249 				device->VertexProcessor::setTransformFeedbackBuffer(index,
   1250 					transformFeedbackBuffers[index].get()->getResource(),
   1251 					transformFeedbackBuffers[index].getOffset() + baseOffset,
   1252 					transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
   1253 					nbRegs, nbComponentsPerReg, componentStride);
   1254 				enableTransformFeedback |= 1ULL << index;
   1255 			}
   1256 		}
   1257 			break;
   1258 		case GL_INTERLEAVED_ATTRIBS:
   1259 		{
   1260 			// OpenGL ES 3.0.4 spec, section 2.15.2:
   1261 			// In INTERLEAVED_ATTRIBS mode, the values of one or more output variables
   1262 			// written by a vertex shader are written, interleaved, into the buffer object
   1263 			// bound to the first transform feedback binding point (index = 0).
   1264 			sw::Resource* resource = transformFeedbackBuffers[0].get() ?
   1265 			                         transformFeedbackBuffers[0].get()->getResource() :
   1266 			                         nullptr;
   1267 			int componentStride = static_cast<int>(totalLinkedVaryingsComponents);
   1268 			int baseOffset = transformFeedbackBuffers[0].getOffset() + (transformFeedback->vertexOffset() * componentStride * sizeof(float));
   1269 			maxVaryings = sw::min(maxVaryings, (unsigned int)sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
   1270 			ASSERT(resource || (maxVaryings == 0));
   1271 
   1272 			int totalComponents = 0;
   1273 			for(unsigned int index = 0; index < maxVaryings; ++index)
   1274 			{
   1275 				int size = transformFeedbackLinkedVaryings[index].size;
   1276 				int rowCount = VariableRowCount(transformFeedbackLinkedVaryings[index].type);
   1277 				int colCount = VariableColumnCount(transformFeedbackLinkedVaryings[index].type);
   1278 				int nbRegs = rowCount > 1 ? colCount * size : size;
   1279 				int nbComponentsPerReg = rowCount > 1 ? rowCount : colCount;
   1280 				device->VertexProcessor::setTransformFeedbackBuffer(index, resource,
   1281 					baseOffset + (totalComponents * sizeof(float)),
   1282 					transformFeedbackLinkedVaryings[index].reg * 4 + transformFeedbackLinkedVaryings[index].col,
   1283 					nbRegs, nbComponentsPerReg, componentStride);
   1284 				totalComponents += rowCount * colCount * size;
   1285 				enableTransformFeedback |= 1ULL << index;
   1286 			}
   1287 		}
   1288 			break;
   1289 		default:
   1290 			UNREACHABLE(transformFeedbackBufferMode);
   1291 			break;
   1292 		}
   1293 
   1294 		// Unset all other transform feedback buffers
   1295 		for(unsigned int index = maxVaryings; index < sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++index)
   1296 		{
   1297 			device->VertexProcessor::setTransformFeedbackBuffer(index, nullptr, 0, 0, 0, 0, 0);
   1298 		}
   1299 
   1300 		device->VertexProcessor::enableTransformFeedback(enableTransformFeedback);
   1301 	}
   1302 
   1303 	bool Program::linkVaryings()
   1304 	{
   1305 		glsl::VaryingList &psVaryings = fragmentShader->varyings;
   1306 		glsl::VaryingList &vsVaryings = vertexShader->varyings;
   1307 
   1308 		for(auto const &input : psVaryings)
   1309 		{
   1310 			bool matched = false;
   1311 
   1312 			for(auto const &output : vsVaryings)
   1313 			{
   1314 				if(output.name == input.name)
   1315 				{
   1316 					if(output.type != input.type || output.size() != input.size())
   1317 					{
   1318 						appendToInfoLog("Type of vertex varying %s does not match that of the fragment varying", output.name.c_str());
   1319 
   1320 						return false;
   1321 					}
   1322 
   1323 					if((output.qualifier == EvqFlatOut) ^ (input.qualifier == EvqFlatIn))
   1324 					{
   1325 						appendToInfoLog("Interpolation qualifiers for %s differ between vertex and fragment shaders", output.name.c_str());
   1326 
   1327 						return false;
   1328 					}
   1329 
   1330 					if(!areMatchingFields(input.fields, output.fields, input.name))
   1331 					{
   1332 						return false;
   1333 					}
   1334 
   1335 					matched = true;
   1336 					break;
   1337 				}
   1338 			}
   1339 
   1340 			if(!matched)
   1341 			{
   1342 				// If a fragment varying is declared but not statically used, it's not an error to not have a matching vertex varying.
   1343 				if(input.registerIndex >= 0)
   1344 				{
   1345 					appendToInfoLog("Fragment varying %s does not match any vertex varying", input.name.c_str());
   1346 
   1347 					return false;
   1348 				}
   1349 			}
   1350 		}
   1351 
   1352 		for(auto const &output : vsVaryings)
   1353 		{
   1354 			bool matched = false;
   1355 
   1356 			for(auto const &input : psVaryings)
   1357 			{
   1358 				if(output.name == input.name)
   1359 				{
   1360 					int in = input.registerIndex;
   1361 					int out = output.registerIndex;
   1362 					int components = VariableRegisterSize(output.type);
   1363 					int registers = VariableRegisterCount(output.type) * output.size();
   1364 
   1365 					if(in < 0)  // Fragment varying declared but not used
   1366 					{
   1367 						continue;
   1368 					}
   1369 
   1370 					if(in + registers >= MAX_VARYING_VECTORS)
   1371 					{
   1372 						appendToInfoLog("Too many varyings");
   1373 						return false;
   1374 					}
   1375 
   1376 					if(out >= 0)
   1377 					{
   1378 						if(out + registers >= MAX_VARYING_VECTORS)
   1379 						{
   1380 							appendToInfoLog("Too many varyings");
   1381 							return false;
   1382 						}
   1383 
   1384 						for(int i = 0; i < registers; i++)
   1385 						{
   1386 							vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR, in + i, pixelBinary->getInput(in + i, 0).flat));
   1387 						}
   1388 					}
   1389 					else   // Vertex varying is declared but not written to
   1390 					{
   1391 						for(int i = 0; i < registers; i++)
   1392 						{
   1393 							pixelBinary->setInput(in + i, components, sw::Shader::Semantic());
   1394 						}
   1395 					}
   1396 
   1397 					matched = true;
   1398 					break;
   1399 				}
   1400 			}
   1401 
   1402 			if(!matched)
   1403 			{
   1404 				// For openGL ES 3.0, we need to still add the vertex shader outputs for unmatched varyings, for transform feedback.
   1405 				for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
   1406 				{
   1407 					std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, nullptr);
   1408 
   1409 					if(tfVaryingName == output.name)
   1410 					{
   1411 						int out = output.registerIndex;
   1412 						int components = VariableRegisterSize(output.type);
   1413 						int registers = VariableRegisterCount(output.type) * output.size();
   1414 
   1415 						if(out >= 0)
   1416 						{
   1417 							if(out + registers >= MAX_VARYING_VECTORS)
   1418 							{
   1419 								appendToInfoLog("Too many varyings");
   1420 								return false;
   1421 							}
   1422 
   1423 							for(int i = 0; i < registers; i++)
   1424 							{
   1425 								vertexBinary->setOutput(out + i, components, sw::Shader::Semantic(sw::Shader::USAGE_COLOR));
   1426 							}
   1427 						}
   1428 						break;
   1429 					}
   1430 				}
   1431 			}
   1432 		}
   1433 
   1434 		return true;
   1435 	}
   1436 
   1437 	bool Program::linkTransformFeedback()
   1438 	{
   1439 		size_t totalComponents = 0;
   1440 		totalLinkedVaryingsComponents = 0;
   1441 
   1442 		std::set<std::string> uniqueNames;
   1443 
   1444 		for(const std::string &indexedTfVaryingName : transformFeedbackVaryings)
   1445 		{
   1446 			unsigned int subscript = GL_INVALID_INDEX;
   1447 			std::string tfVaryingName = es2::ParseUniformName(indexedTfVaryingName, &subscript);
   1448 			bool hasSubscript = (subscript != GL_INVALID_INDEX);
   1449 
   1450 			if(tfVaryingName.find('[') != std::string::npos)
   1451 			{
   1452 				appendToInfoLog("Capture of array sub-elements is undefined and not supported.");
   1453 				return false;
   1454 			}
   1455 
   1456 			bool found = false;
   1457 			for(const glsl::Varying varying : vertexShader->varyings)
   1458 			{
   1459 				if(tfVaryingName == varying.name)
   1460 				{
   1461 					if(uniqueNames.count(indexedTfVaryingName) > 0)
   1462 					{
   1463 						appendToInfoLog("Two transform feedback varyings specify the same output variable (%s)", indexedTfVaryingName.c_str());
   1464 						return false;
   1465 					}
   1466 					uniqueNames.insert(indexedTfVaryingName);
   1467 
   1468 					if(hasSubscript && ((static_cast<int>(subscript)) >= varying.size()))
   1469 					{
   1470 						appendToInfoLog("Specified transform feedback varying index out of bounds (%s)", indexedTfVaryingName.c_str());
   1471 						return false;
   1472 					}
   1473 
   1474 					int size = hasSubscript ? 1 : varying.size();
   1475 
   1476 					int rowCount = VariableRowCount(varying.type);
   1477 					int colCount = VariableColumnCount(varying.type);
   1478 					int componentCount = rowCount * colCount * size;
   1479 					if(transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
   1480 					   componentCount > sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS)
   1481 					{
   1482 						appendToInfoLog("Transform feedback varying's %s components (%d) exceed the maximum separate components (%d).",
   1483 						                varying.name.c_str(), componentCount, sw::MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
   1484 						return false;
   1485 					}
   1486 
   1487 					totalComponents += componentCount;
   1488 
   1489 					int reg = varying.registerIndex;
   1490 					if(hasSubscript)
   1491 					{
   1492 						reg += rowCount > 1 ? colCount * subscript : subscript;
   1493 					}
   1494 					int col = varying.column;
   1495 					if(tfVaryingName == "gl_PointSize")
   1496 					{
   1497 						// Point size is stored in the y element of the vector, not the x element
   1498 						col = 1; // FIXME: varying.col could already contain this information
   1499 					}
   1500 					transformFeedbackLinkedVaryings.push_back(LinkedVarying(varying.name, varying.type, size, reg, col));
   1501 
   1502 					found = true;
   1503 					break;
   1504 				}
   1505 			}
   1506 
   1507 			if(!found)
   1508 			{
   1509 				appendToInfoLog("Transform feedback varying %s does not exist in the vertex shader.", tfVaryingName.c_str());
   1510 				return false;
   1511 			}
   1512 		}
   1513 
   1514 		if(transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
   1515 		   totalComponents > sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS)
   1516 		{
   1517 			appendToInfoLog("Transform feedback varying total components (%d) exceed the maximum separate components (%d).",
   1518 			                totalComponents, sw::MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
   1519 			return false;
   1520 		}
   1521 
   1522 		totalLinkedVaryingsComponents = totalComponents;
   1523 
   1524 		return true;
   1525 	}
   1526 
   1527 	// Links the code of the vertex and pixel shader by matching up their varyings,
   1528 	// compiling them into binaries, determining the attribute mappings, and collecting
   1529 	// a list of uniforms
   1530 	void Program::link()
   1531 	{
   1532 		unlink();
   1533 
   1534 		resetUniformBlockBindings();
   1535 
   1536 		if(!fragmentShader || !fragmentShader->isCompiled())
   1537 		{
   1538 			return;
   1539 		}
   1540 
   1541 		if(!vertexShader || !vertexShader->isCompiled())
   1542 		{
   1543 			return;
   1544 		}
   1545 
   1546 		vertexBinary = new sw::VertexShader(vertexShader->getVertexShader());
   1547 		pixelBinary = new sw::PixelShader(fragmentShader->getPixelShader());
   1548 
   1549 		if(!linkVaryings())
   1550 		{
   1551 			return;
   1552 		}
   1553 
   1554 		if(!linkAttributes())
   1555 		{
   1556 			return;
   1557 		}
   1558 
   1559 		// Link uniform blocks before uniforms to make it easy to assign block indices to fields
   1560 		if(!linkUniformBlocks(vertexShader, fragmentShader))
   1561 		{
   1562 			return;
   1563 		}
   1564 
   1565 		if(!linkUniforms(fragmentShader))
   1566 		{
   1567 			return;
   1568 		}
   1569 
   1570 		if(!linkUniforms(vertexShader))
   1571 		{
   1572 			return;
   1573 		}
   1574 
   1575 		if(!linkTransformFeedback())
   1576 		{
   1577 			return;
   1578 		}
   1579 
   1580 		linked = true;   // Success
   1581 	}
   1582 
   1583 	// Determines the mapping between GL attributes and vertex stream usage indices
   1584 	bool Program::linkAttributes()
   1585 	{
   1586 		static_assert(MAX_VERTEX_ATTRIBS <= 32, "attribute count exceeds bitfield count");
   1587 		unsigned int usedLocations = 0;
   1588 
   1589 		// Link attributes that have a GLSL layout location qualifier
   1590 		for(auto const &attribute : vertexShader->activeAttributes)
   1591 		{
   1592 			if(attribute.layoutLocation != -1)
   1593 			{
   1594 				if(!linkAttribute(attribute, attribute.layoutLocation, usedLocations))
   1595 				{
   1596 					return false;
   1597 				}
   1598 			}
   1599 		}
   1600 
   1601 		// Link attributes that have an API provided binding location but no GLSL layout location
   1602 		for(auto const &attribute : vertexShader->activeAttributes)
   1603 		{
   1604 			int bindingLocation = (attributeBinding.find(attribute.name) != attributeBinding.end()) ? attributeBinding[attribute.name] : -1;
   1605 
   1606 			if(attribute.layoutLocation == -1 && bindingLocation != -1)
   1607 			{
   1608 				if(!linkAttribute(attribute, bindingLocation, usedLocations))
   1609 				{
   1610 					return false;
   1611 				}
   1612 			}
   1613 		}
   1614 
   1615 		// Link attributes that don't have a binding location nor a layout location
   1616 		for(auto const &attribute : vertexShader->activeAttributes)
   1617 		{
   1618 			if(attribute.layoutLocation == -1 && attributeBinding.find(attribute.name) == attributeBinding.end())
   1619 			{
   1620 				if(!linkAttribute(attribute, -1, usedLocations))
   1621 				{
   1622 					return false;
   1623 				}
   1624 			}
   1625 		}
   1626 
   1627 		ASSERT(linkedAttribute.size() == vertexShader->activeAttributes.size());
   1628 
   1629 		for(auto const &attribute : linkedAttribute)
   1630 		{
   1631 			int location = getAttributeLocation(attribute.name);
   1632 			ASSERT(location >= 0);
   1633 			int index = vertexShader->getSemanticIndex(attribute.name);
   1634 			int rows = VariableRegisterCount(attribute.type);
   1635 
   1636 			for(int r = 0; r < rows; r++)
   1637 			{
   1638 				attributeStream[r + location] = index++;
   1639 			}
   1640 		}
   1641 
   1642 		return true;
   1643 	}
   1644 
   1645 	bool Program::linkAttribute(const glsl::Attribute &attribute, int location, unsigned int &usedLocations)
   1646 	{
   1647 		int rows = VariableRegisterCount(attribute.type);
   1648 
   1649 		if(location == -1)
   1650 		{
   1651 			location = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
   1652 
   1653 			if(location == -1 || location + rows > MAX_VERTEX_ATTRIBS)
   1654 			{
   1655 				appendToInfoLog("Too many active attributes (%s)", attribute.name.c_str());
   1656 				return false;   // Fail to link
   1657 			}
   1658 		}
   1659 		else
   1660 		{
   1661 			if(rows + location > MAX_VERTEX_ATTRIBS)
   1662 			{
   1663 				appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute.name.c_str(), location);
   1664 				return false;
   1665 			}
   1666 
   1667 			// In GLSL 3.00, attribute aliasing produces a link error
   1668 			// In GLSL 1.00, attribute aliasing is allowed
   1669 			if(vertexShader->getShaderVersion() >= 300)
   1670 			{
   1671 				for(auto const &previousAttrib : linkedAttribute)
   1672 				{
   1673 					int previousLocation = getAttributeLocation(previousAttrib.name);
   1674 					int previousRows = VariableRegisterCount(previousAttrib.type);
   1675 
   1676 					if(location >= previousLocation && location < previousLocation + previousRows)
   1677 					{
   1678 						appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), previousAttrib.name.c_str(), location);
   1679 						return false;
   1680 					}
   1681 
   1682 					if(location <= previousLocation && location + rows > previousLocation)
   1683 					{
   1684 						appendToInfoLog("Attribute '%s' aliases attribute '%s' at location %d", attribute.name.c_str(), previousAttrib.name.c_str(), previousLocation);
   1685 						return false;
   1686 					}
   1687 				}
   1688 			}
   1689 
   1690 			for(int i = 0; i < rows; i++)
   1691 			{
   1692 				usedLocations |= 1 << (location + i);
   1693 			}
   1694 		}
   1695 
   1696 		linkedAttributeLocation[attribute.name] = location;
   1697 		linkedAttribute.push_back(attribute);
   1698 
   1699 		return true;
   1700 	}
   1701 
   1702 	int Program::getAttributeLocation(const std::string &name)
   1703 	{
   1704 		std::map<std::string, GLuint>::const_iterator attribute = linkedAttributeLocation.find(name);
   1705 		if(attribute != linkedAttributeLocation.end())
   1706 		{
   1707 			return attribute->second;
   1708 		}
   1709 
   1710 		return -1;
   1711 	}
   1712 
   1713 	bool Program::linkUniforms(const Shader *shader)
   1714 	{
   1715 		for(const auto &uniform : shader->activeUniforms)
   1716 		{
   1717 			unsigned int blockIndex = GL_INVALID_INDEX;
   1718 			if(uniform.blockId >= 0)
   1719 			{
   1720 				const glsl::ActiveUniformBlocks &activeUniformBlocks = shader->activeUniformBlocks;
   1721 				ASSERT(static_cast<size_t>(uniform.blockId) < activeUniformBlocks.size());
   1722 				const std::string &uniformBlockName = activeUniformBlocks[uniform.blockId].name;
   1723 				blockIndex = getUniformBlockIndex(uniformBlockName);
   1724 				ASSERT(blockIndex != GL_INVALID_INDEX);
   1725 
   1726 				if(activeUniformBlocks[uniform.blockId].dataSize > MAX_UNIFORM_BLOCK_SIZE)
   1727 				{
   1728 					if(shader->getType() == GL_VERTEX_SHADER)
   1729 					{
   1730 						appendToInfoLog("Vertex shader active uniform block (%s) exceeds GL_MAX_UNIFORM_BLOCK_SIZE (%d)", uniformBlockName.c_str(), MAX_UNIFORM_BLOCK_SIZE);
   1731 						return false;
   1732 					}
   1733 					else if(shader->getType() == GL_FRAGMENT_SHADER)
   1734 					{
   1735 						appendToInfoLog("Fragment shader active uniform block (%s) exceeds GL_MAX_UNIFORM_BLOCK_SIZE (%d)", uniformBlockName.c_str(), MAX_UNIFORM_BLOCK_SIZE);
   1736 						return false;
   1737 					}
   1738 					else UNREACHABLE(shader->getType());
   1739 				}
   1740 			}
   1741 
   1742 			if(!defineUniform(shader->getType(), uniform, Uniform::BlockInfo(uniform, blockIndex)))
   1743 			{
   1744 				return false;
   1745 			}
   1746 		}
   1747 
   1748 		for(const auto &uniformStruct : shader->activeUniformStructs)
   1749 		{
   1750 			if(!validateUniformStruct(shader->getType(), uniformStruct))
   1751 			{
   1752 				return false;
   1753 			}
   1754 		}
   1755 
   1756 		return true;
   1757 	}
   1758 
   1759 	bool Program::defineUniform(GLenum shader, const glsl::Uniform &glslUniform, const Uniform::BlockInfo& blockInfo)
   1760 	{
   1761 		if(IsSamplerUniform(glslUniform.type))
   1762 		{
   1763 			int index = glslUniform.registerIndex;
   1764 
   1765 			do
   1766 			{
   1767 				if(shader == GL_VERTEX_SHADER)
   1768 				{
   1769 					if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
   1770 					{
   1771 						samplersVS[index].active = true;
   1772 
   1773 						switch(glslUniform.type)
   1774 						{
   1775 						default:                      UNREACHABLE(glslUniform.type);
   1776 						case GL_INT_SAMPLER_2D:
   1777 						case GL_UNSIGNED_INT_SAMPLER_2D:
   1778 						case GL_SAMPLER_2D_SHADOW:
   1779 						case GL_SAMPLER_2D:           samplersVS[index].textureType = TEXTURE_2D;       break;
   1780 						case GL_INT_SAMPLER_CUBE:
   1781 						case GL_UNSIGNED_INT_SAMPLER_CUBE:
   1782 						case GL_SAMPLER_CUBE_SHADOW:
   1783 						case GL_SAMPLER_CUBE:         samplersVS[index].textureType = TEXTURE_CUBE;     break;
   1784 						case GL_INT_SAMPLER_3D:
   1785 						case GL_UNSIGNED_INT_SAMPLER_3D:
   1786 						case GL_SAMPLER_3D_OES:       samplersVS[index].textureType = TEXTURE_3D;       break;
   1787 						case GL_SAMPLER_2D_RECT_ARB:  samplersVS[index].textureType = TEXTURE_2D_RECT;  break;
   1788 						case GL_SAMPLER_EXTERNAL_OES: samplersVS[index].textureType = TEXTURE_EXTERNAL; break;
   1789 						case GL_INT_SAMPLER_2D_ARRAY:
   1790 						case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
   1791 						case GL_SAMPLER_2D_ARRAY_SHADOW:
   1792 						case GL_SAMPLER_2D_ARRAY:     samplersVS[index].textureType = TEXTURE_2D_ARRAY; break;
   1793 						}
   1794 
   1795 						samplersVS[index].logicalTextureUnit = 0;
   1796 					}
   1797 					else
   1798 					{
   1799 					   appendToInfoLog("Vertex shader sampler count exceeds MAX_VERTEX_TEXTURE_IMAGE_UNITS (%d).", MAX_VERTEX_TEXTURE_IMAGE_UNITS);
   1800 					   return false;
   1801 					}
   1802 				}
   1803 				else if(shader == GL_FRAGMENT_SHADER)
   1804 				{
   1805 					if(index < MAX_TEXTURE_IMAGE_UNITS)
   1806 					{
   1807 						samplersPS[index].active = true;
   1808 
   1809 						switch(glslUniform.type)
   1810 						{
   1811 						default:                      UNREACHABLE(glslUniform.type);
   1812 						case GL_INT_SAMPLER_2D:
   1813 						case GL_UNSIGNED_INT_SAMPLER_2D:
   1814 						case GL_SAMPLER_2D_SHADOW:
   1815 						case GL_SAMPLER_2D:           samplersPS[index].textureType = TEXTURE_2D;       break;
   1816 						case GL_INT_SAMPLER_CUBE:
   1817 						case GL_UNSIGNED_INT_SAMPLER_CUBE:
   1818 						case GL_SAMPLER_CUBE_SHADOW:
   1819 						case GL_SAMPLER_CUBE:         samplersPS[index].textureType = TEXTURE_CUBE;     break;
   1820 						case GL_INT_SAMPLER_3D:
   1821 						case GL_UNSIGNED_INT_SAMPLER_3D:
   1822 						case GL_SAMPLER_3D_OES:       samplersPS[index].textureType = TEXTURE_3D;       break;
   1823 						case GL_SAMPLER_2D_RECT_ARB:  samplersPS[index].textureType = TEXTURE_2D_RECT;  break;
   1824 						case GL_SAMPLER_EXTERNAL_OES: samplersPS[index].textureType = TEXTURE_EXTERNAL; break;
   1825 						case GL_INT_SAMPLER_2D_ARRAY:
   1826 						case GL_UNSIGNED_INT_SAMPLER_2D_ARRAY:
   1827 						case GL_SAMPLER_2D_ARRAY_SHADOW:
   1828 						case GL_SAMPLER_2D_ARRAY:     samplersPS[index].textureType = TEXTURE_2D_ARRAY; break;
   1829 						}
   1830 
   1831 						samplersPS[index].logicalTextureUnit = 0;
   1832 					}
   1833 					else
   1834 					{
   1835 						appendToInfoLog("Pixel shader sampler count exceeds MAX_TEXTURE_IMAGE_UNITS (%d).", MAX_TEXTURE_IMAGE_UNITS);
   1836 						return false;
   1837 					}
   1838 				}
   1839 				else UNREACHABLE(shader);
   1840 
   1841 				index++;
   1842 			}
   1843 			while(index < glslUniform.registerIndex + static_cast<int>(glslUniform.arraySize));
   1844 		}
   1845 
   1846 		Uniform *uniform = getUniform(glslUniform.name);
   1847 
   1848 		if(!uniform)
   1849 		{
   1850 			uniform = new Uniform(glslUniform, blockInfo);
   1851 			uniforms.push_back(uniform);
   1852 
   1853 			unsigned int index = (blockInfo.index == -1) ? static_cast<unsigned int>(uniforms.size() - 1) : GL_INVALID_INDEX;
   1854 
   1855 			for(int i = 0; i < uniform->size(); i++)
   1856 			{
   1857 				uniformIndex.push_back(UniformLocation(glslUniform.name, i, index));
   1858 			}
   1859 		}
   1860 		else   // Previously defined, types must match
   1861 		{
   1862 			if(uniform->type != glslUniform.type)
   1863 			{
   1864 				appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
   1865 				return false;
   1866 			}
   1867 
   1868 			if(uniform->precision != glslUniform.precision)
   1869 			{
   1870 				appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str());
   1871 				return false;
   1872 			}
   1873 
   1874 			if(!areMatchingFields(uniform->fields, glslUniform.fields, uniform->name))
   1875 			{
   1876 				return false;
   1877 			}
   1878 		}
   1879 
   1880 		if(shader == GL_VERTEX_SHADER)
   1881 		{
   1882 			uniform->vsRegisterIndex = glslUniform.registerIndex;
   1883 		}
   1884 		else if(shader == GL_FRAGMENT_SHADER)
   1885 		{
   1886 			uniform->psRegisterIndex = glslUniform.registerIndex;
   1887 		}
   1888 		else UNREACHABLE(shader);
   1889 
   1890 		if(uniform->blockInfo.index < 0)
   1891 		{
   1892 			if(shader == GL_VERTEX_SHADER)
   1893 			{
   1894 				if(glslUniform.registerIndex + uniform->registerCount() > MAX_VERTEX_UNIFORM_VECTORS)
   1895 				{
   1896 					appendToInfoLog("Vertex shader active uniforms exceed GL_MAX_VERTEX_UNIFORM_VECTORS (%d)", MAX_VERTEX_UNIFORM_VECTORS);
   1897 					return false;
   1898 				}
   1899 			}
   1900 			else if(shader == GL_FRAGMENT_SHADER)
   1901 			{
   1902 				if(glslUniform.registerIndex + uniform->registerCount() > MAX_FRAGMENT_UNIFORM_VECTORS)
   1903 				{
   1904 					appendToInfoLog("Fragment shader active uniforms exceed GL_MAX_FRAGMENT_UNIFORM_VECTORS (%d)", MAX_FRAGMENT_UNIFORM_VECTORS);
   1905 					return false;
   1906 				}
   1907 			}
   1908 			else UNREACHABLE(shader);
   1909 		}
   1910 
   1911 		return true;
   1912 	}
   1913 
   1914 	bool Program::validateUniformStruct(GLenum shader, const glsl::Uniform &newUniformStruct)
   1915 	{
   1916 		for(const auto &uniformStruct : uniformStructs)
   1917 		{
   1918 			if(uniformStruct.name == newUniformStruct.name)
   1919 			{
   1920 				return areMatchingFields(uniformStruct.fields, newUniformStruct.fields, newUniformStruct.name);
   1921 			}
   1922 		}
   1923 
   1924 		uniformStructs.push_back(Uniform(newUniformStruct, Uniform::BlockInfo(newUniformStruct, -1)));
   1925 
   1926 		return true;
   1927 	}
   1928 
   1929 	bool Program::areMatchingUniformBlocks(const glsl::UniformBlock &block1, const glsl::UniformBlock &block2, const Shader *shader1, const Shader *shader2)
   1930 	{
   1931 		// validate blocks for the same member types
   1932 		if(block1.fields.size() != block2.fields.size())
   1933 		{
   1934 			appendToInfoLog("Types for interface block '%s' differ between vertex and fragment shaders", block1.name.c_str());
   1935 			return false;
   1936 		}
   1937 		if(block1.arraySize != block2.arraySize)
   1938 		{
   1939 			appendToInfoLog("Array sizes differ for interface block '%s' between vertex and fragment shaders", block1.name.c_str());
   1940 			return false;
   1941 		}
   1942 		if(block1.layout != block2.layout || block1.isRowMajorLayout != block2.isRowMajorLayout)
   1943 		{
   1944 			appendToInfoLog("Layout qualifiers differ for interface block '%s' between vertex and fragment shaders", block1.name.c_str());
   1945 			return false;
   1946 		}
   1947 		const size_t numBlockMembers = block1.fields.size();
   1948 		for(size_t blockMemberIndex = 0; blockMemberIndex < numBlockMembers; blockMemberIndex++)
   1949 		{
   1950 			const glsl::Uniform& member1 = shader1->activeUniforms[block1.fields[blockMemberIndex]];
   1951 			const glsl::Uniform& member2 = shader2->activeUniforms[block2.fields[blockMemberIndex]];
   1952 			if(member1.name != member2.name)
   1953 			{
   1954 				appendToInfoLog("Name mismatch for field %d of interface block '%s': (in vertex: '%s', in fragment: '%s')",
   1955 				                blockMemberIndex, block1.name.c_str(), member1.name.c_str(), member2.name.c_str());
   1956 				return false;
   1957 			}
   1958 			if(member1.arraySize != member2.arraySize)
   1959 			{
   1960 				appendToInfoLog("Array sizes for %s differ between vertex and fragment shaders", member1.name.c_str());
   1961 				return false;
   1962 			}
   1963 			if(member1.precision != member2.precision)
   1964 			{
   1965 				appendToInfoLog("Precisions for %s differ between vertex and fragment shaders", member1.name.c_str());
   1966 				return false;
   1967 			}
   1968 			if(member1.type != member2.type)
   1969 			{
   1970 				appendToInfoLog("Types for %s differ between vertex and fragment shaders", member1.name.c_str());
   1971 				return false;
   1972 			}
   1973 			if(member1.blockInfo.isRowMajorMatrix != member2.blockInfo.isRowMajorMatrix)
   1974 			{
   1975 				appendToInfoLog("Matrix packings for %s differ between vertex and fragment shaders", member1.name.c_str());
   1976 				return false;
   1977 			}
   1978 		}
   1979 		return true;
   1980 	}
   1981 
   1982 	bool Program::areMatchingFields(const std::vector<glsl::ShaderVariable>& fields1, const std::vector<glsl::ShaderVariable>& fields2, const std::string& name)
   1983 	{
   1984 		if(fields1.size() != fields2.size())
   1985 		{
   1986 			appendToInfoLog("Structure lengths for %s differ between vertex and fragment shaders", name.c_str());
   1987 			return false;
   1988 		}
   1989 
   1990 		for(size_t i = 0; i < fields1.size(); ++i)
   1991 		{
   1992 			if(fields1[i].name != fields2[i].name)
   1993 			{
   1994 				appendToInfoLog("Name mismatch for field '%d' of %s: ('%s', '%s')",
   1995 				                i, name.c_str(), fields1[i].name.c_str(), fields2[i].name.c_str());
   1996 				return false;
   1997 			}
   1998 			if(fields1[i].type != fields2[i].type)
   1999 			{
   2000 				appendToInfoLog("Type for %s.%s differ between vertex and fragment shaders", name.c_str(), fields1[i].name.c_str());
   2001 				return false;
   2002 			}
   2003 			if(fields1[i].arraySize != fields2[i].arraySize)
   2004 			{
   2005 				appendToInfoLog("Array size for %s.%s differ between vertex and fragment shaders", name.c_str(), fields1[i].name.c_str());
   2006 				return false;
   2007 			}
   2008 			if(!areMatchingFields(fields1[i].fields, fields2[i].fields, fields1[i].name))
   2009 			{
   2010 				return false;
   2011 			}
   2012 		}
   2013 
   2014 		return true;
   2015 	}
   2016 
   2017 	bool Program::linkUniformBlocks(const Shader *vertexShader, const Shader *fragmentShader)
   2018 	{
   2019 		const glsl::ActiveUniformBlocks &vertexUniformBlocks = vertexShader->activeUniformBlocks;
   2020 		const glsl::ActiveUniformBlocks &fragmentUniformBlocks = fragmentShader->activeUniformBlocks;
   2021 		// Check that interface blocks defined in the vertex and fragment shaders are identical
   2022 		typedef std::map<std::string, const glsl::UniformBlock*> UniformBlockMap;
   2023 		UniformBlockMap linkedUniformBlocks;
   2024 		for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
   2025 		{
   2026 			const glsl::UniformBlock &vertexUniformBlock = vertexUniformBlocks[blockIndex];
   2027 			linkedUniformBlocks[vertexUniformBlock.name] = &vertexUniformBlock;
   2028 		}
   2029 		for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
   2030 		{
   2031 			const glsl::UniformBlock &fragmentUniformBlock = fragmentUniformBlocks[blockIndex];
   2032 			UniformBlockMap::const_iterator entry = linkedUniformBlocks.find(fragmentUniformBlock.name);
   2033 			if(entry != linkedUniformBlocks.end())
   2034 			{
   2035 				const glsl::UniformBlock &vertexUniformBlock = *entry->second;
   2036 				if(!areMatchingUniformBlocks(vertexUniformBlock, fragmentUniformBlock, vertexShader, fragmentShader))
   2037 				{
   2038 					return false;
   2039 				}
   2040 			}
   2041 		}
   2042 		for(unsigned int blockIndex = 0; blockIndex < vertexUniformBlocks.size(); blockIndex++)
   2043 		{
   2044 			const glsl::UniformBlock &uniformBlock = vertexUniformBlocks[blockIndex];
   2045 			if(!defineUniformBlock(vertexShader, uniformBlock))
   2046 			{
   2047 				return false;
   2048 			}
   2049 		}
   2050 		for(unsigned int blockIndex = 0; blockIndex < fragmentUniformBlocks.size(); blockIndex++)
   2051 		{
   2052 			const glsl::UniformBlock &uniformBlock = fragmentUniformBlocks[blockIndex];
   2053 			if(!defineUniformBlock(fragmentShader, uniformBlock))
   2054 			{
   2055 				return false;
   2056 			}
   2057 		}
   2058 		return true;
   2059 	}
   2060 
   2061 	bool Program::defineUniformBlock(const Shader *shader, const glsl::UniformBlock &block)
   2062 	{
   2063 		GLuint blockIndex = getUniformBlockIndex(block.name);
   2064 
   2065 		if(blockIndex == GL_INVALID_INDEX)
   2066 		{
   2067 			const std::vector<int>& fields = block.fields;
   2068 			std::vector<unsigned int> memberUniformIndexes;
   2069 			for(size_t i = 0; i < fields.size(); ++i)
   2070 			{
   2071 				memberUniformIndexes.push_back(fields[i]);
   2072 			}
   2073 
   2074 			if(block.arraySize > 0)
   2075 			{
   2076 				int regIndex = block.registerIndex;
   2077 				int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
   2078 				for(unsigned int i = 0; i < block.arraySize; ++i, regIndex += regInc)
   2079 				{
   2080 					uniformBlocks.push_back(new UniformBlock(block.name, i, block.dataSize, memberUniformIndexes));
   2081 					uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), regIndex);
   2082 				}
   2083 			}
   2084 			else
   2085 			{
   2086 				uniformBlocks.push_back(new UniformBlock(block.name, GL_INVALID_INDEX, block.dataSize, memberUniformIndexes));
   2087 				uniformBlocks[uniformBlocks.size() - 1]->setRegisterIndex(shader->getType(), block.registerIndex);
   2088 			}
   2089 		}
   2090 		else
   2091 		{
   2092 			int regIndex = block.registerIndex;
   2093 			int regInc = block.dataSize / (glsl::BlockLayoutEncoder::BytesPerComponent * glsl::BlockLayoutEncoder::ComponentsPerRegister);
   2094 			int nbBlocks = (block.arraySize > 0) ? block.arraySize : 1;
   2095 			for(int i = 0; i < nbBlocks; ++i, regIndex += regInc)
   2096 			{
   2097 				uniformBlocks[blockIndex + i]->setRegisterIndex(shader->getType(), regIndex);
   2098 			}
   2099 		}
   2100 
   2101 		return true;
   2102 	}
   2103 
   2104 	bool Program::applyUniform(Device *device, GLint location, float* data)
   2105 	{
   2106 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
   2107 
   2108 		if(targetUniform->psRegisterIndex != -1)
   2109 		{
   2110 			device->setPixelShaderConstantF(targetUniform->psRegisterIndex, data, targetUniform->registerCount());
   2111 		}
   2112 
   2113 		if(targetUniform->vsRegisterIndex != -1)
   2114 		{
   2115 			device->setVertexShaderConstantF(targetUniform->vsRegisterIndex, data, targetUniform->registerCount());
   2116 		}
   2117 
   2118 		return true;
   2119 	}
   2120 
   2121 	bool Program::applyUniform1bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
   2122 	{
   2123 		int vector[MAX_UNIFORM_VECTORS][4];
   2124 
   2125 		for(int i = 0; i < count; i++)
   2126 		{
   2127 			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2128 			vector[i][1] = 0;
   2129 			vector[i][2] = 0;
   2130 			vector[i][3] = 0;
   2131 
   2132 			v += 1;
   2133 		}
   2134 
   2135 		return applyUniform(device, location, (float*)vector);
   2136 	}
   2137 
   2138 	bool Program::applyUniform2bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
   2139 	{
   2140 		int vector[MAX_UNIFORM_VECTORS][4];
   2141 
   2142 		for(int i = 0; i < count; i++)
   2143 		{
   2144 			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2145 			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2146 			vector[i][2] = 0;
   2147 			vector[i][3] = 0;
   2148 
   2149 			v += 2;
   2150 		}
   2151 
   2152 		return applyUniform(device, location, (float*)vector);
   2153 	}
   2154 
   2155 	bool Program::applyUniform3bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
   2156 	{
   2157 		int vector[MAX_UNIFORM_VECTORS][4];
   2158 
   2159 		for(int i = 0; i < count; i++)
   2160 		{
   2161 			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2162 			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2163 			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2164 			vector[i][3] = 0;
   2165 
   2166 			v += 3;
   2167 		}
   2168 
   2169 		return applyUniform(device, location, (float*)vector);
   2170 	}
   2171 
   2172 	bool Program::applyUniform4bv(Device *device, GLint location, GLsizei count, const GLboolean *v)
   2173 	{
   2174 		int vector[MAX_UNIFORM_VECTORS][4];
   2175 
   2176 		for(int i = 0; i < count; i++)
   2177 		{
   2178 			vector[i][0] = (v[0] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2179 			vector[i][1] = (v[1] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2180 			vector[i][2] = (v[2] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2181 			vector[i][3] = (v[3] == GL_FALSE ? 0x00000000 : 0xFFFFFFFF);
   2182 
   2183 			v += 4;
   2184 		}
   2185 
   2186 		return applyUniform(device, location, (float*)vector);
   2187 	}
   2188 
   2189 	bool Program::applyUniform1fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
   2190 	{
   2191 		float vector[MAX_UNIFORM_VECTORS][4];
   2192 
   2193 		for(int i = 0; i < count; i++)
   2194 		{
   2195 			vector[i][0] = v[0];
   2196 			vector[i][1] = 0;
   2197 			vector[i][2] = 0;
   2198 			vector[i][3] = 0;
   2199 
   2200 			v += 1;
   2201 		}
   2202 
   2203 		return applyUniform(device, location, (float*)vector);
   2204 	}
   2205 
   2206 	bool Program::applyUniform2fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
   2207 	{
   2208 		float vector[MAX_UNIFORM_VECTORS][4];
   2209 
   2210 		for(int i = 0; i < count; i++)
   2211 		{
   2212 			vector[i][0] = v[0];
   2213 			vector[i][1] = v[1];
   2214 			vector[i][2] = 0;
   2215 			vector[i][3] = 0;
   2216 
   2217 			v += 2;
   2218 		}
   2219 
   2220 		return applyUniform(device, location, (float*)vector);
   2221 	}
   2222 
   2223 	bool Program::applyUniform3fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
   2224 	{
   2225 		float vector[MAX_UNIFORM_VECTORS][4];
   2226 
   2227 		for(int i = 0; i < count; i++)
   2228 		{
   2229 			vector[i][0] = v[0];
   2230 			vector[i][1] = v[1];
   2231 			vector[i][2] = v[2];
   2232 			vector[i][3] = 0;
   2233 
   2234 			v += 3;
   2235 		}
   2236 
   2237 		return applyUniform(device, location, (float*)vector);
   2238 	}
   2239 
   2240 	bool Program::applyUniform4fv(Device *device, GLint location, GLsizei count, const GLfloat *v)
   2241 	{
   2242 		return applyUniform(device, location, (float*)v);
   2243 	}
   2244 
   2245 	bool Program::applyUniformMatrix2fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2246 	{
   2247 		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
   2248 
   2249 		for(int i = 0; i < count; i++)
   2250 		{
   2251 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
   2252 			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
   2253 
   2254 			value += 4;
   2255 		}
   2256 
   2257 		return applyUniform(device, location, (float*)matrix);
   2258 	}
   2259 
   2260 	bool Program::applyUniformMatrix2x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2261 	{
   2262 		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
   2263 
   2264 		for(int i = 0; i < count; i++)
   2265 		{
   2266 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; matrix[i][0][3] = 0;
   2267 			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5]; matrix[i][1][3] = 0;
   2268 
   2269 			value += 6;
   2270 		}
   2271 
   2272 		return applyUniform(device, location, (float*)matrix);
   2273 	}
   2274 
   2275 	bool Program::applyUniformMatrix2x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2276 	{
   2277 		float matrix[(MAX_UNIFORM_VECTORS + 1) / 2][2][4];
   2278 
   2279 		for(int i = 0; i < count; i++)
   2280 		{
   2281 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; matrix[i][0][3] = value[3];
   2282 			matrix[i][1][0] = value[4];	matrix[i][1][1] = value[5];	matrix[i][1][2] = value[6]; matrix[i][1][3] = value[7];
   2283 
   2284 			value += 8;
   2285 		}
   2286 
   2287 		return applyUniform(device, location, (float*)matrix);
   2288 	}
   2289 
   2290 	bool Program::applyUniformMatrix3fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2291 	{
   2292 		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
   2293 
   2294 		for(int i = 0; i < count; i++)
   2295 		{
   2296 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2];	matrix[i][0][3] = 0;
   2297 			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];	matrix[i][1][2] = value[5];	matrix[i][1][3] = 0;
   2298 			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];	matrix[i][2][2] = value[8];	matrix[i][2][3] = 0;
   2299 
   2300 			value += 9;
   2301 		}
   2302 
   2303 		return applyUniform(device, location, (float*)matrix);
   2304 	}
   2305 
   2306 	bool Program::applyUniformMatrix3x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2307 	{
   2308 		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
   2309 
   2310 		for(int i = 0; i < count; i++)
   2311 		{
   2312 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
   2313 			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
   2314 			matrix[i][2][0] = value[4];	matrix[i][2][1] = value[5];	matrix[i][2][2] = 0; matrix[i][2][3] = 0;
   2315 
   2316 			value += 6;
   2317 		}
   2318 
   2319 		return applyUniform(device, location, (float*)matrix);
   2320 	}
   2321 
   2322 	bool Program::applyUniformMatrix3x4fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2323 	{
   2324 		float matrix[(MAX_UNIFORM_VECTORS + 2) / 3][3][4];
   2325 
   2326 		for(int i = 0; i < count; i++)
   2327 		{
   2328 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = value[2]; 	matrix[i][0][3] = value[3];
   2329 			matrix[i][1][0] = value[4];	matrix[i][1][1] = value[5];	matrix[i][1][2] = value[6]; 	matrix[i][1][3] = value[7];
   2330 			matrix[i][2][0] = value[8];	matrix[i][2][1] = value[9];	matrix[i][2][2] = value[10];	matrix[i][2][3] = value[11];
   2331 
   2332 			value += 12;
   2333 		}
   2334 
   2335 		return applyUniform(device, location, (float*)matrix);
   2336 	}
   2337 
   2338 	bool Program::applyUniformMatrix4fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2339 	{
   2340 		return applyUniform(device, location, (float*)value);
   2341 	}
   2342 
   2343 	bool Program::applyUniformMatrix4x2fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2344 	{
   2345 		float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
   2346 
   2347 		for(int i = 0; i < count; i++)
   2348 		{
   2349 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];	matrix[i][0][2] = 0; matrix[i][0][3] = 0;
   2350 			matrix[i][1][0] = value[2];	matrix[i][1][1] = value[3];	matrix[i][1][2] = 0; matrix[i][1][3] = 0;
   2351 			matrix[i][2][0] = value[4];	matrix[i][2][1] = value[5];	matrix[i][2][2] = 0; matrix[i][2][3] = 0;
   2352 			matrix[i][3][0] = value[6];	matrix[i][3][1] = value[7];	matrix[i][3][2] = 0; matrix[i][3][3] = 0;
   2353 
   2354 			value += 8;
   2355 		}
   2356 
   2357 		return applyUniform(device, location, (float*)matrix);
   2358 	}
   2359 
   2360 	bool Program::applyUniformMatrix4x3fv(Device *device, GLint location, GLsizei count, const GLfloat *value)
   2361 	{
   2362 		float matrix[(MAX_UNIFORM_VECTORS + 3) / 4][4][4];
   2363 
   2364 		for(int i = 0; i < count; i++)
   2365 		{
   2366 			matrix[i][0][0] = value[0];	matrix[i][0][1] = value[1];  matrix[i][0][2] = value[2];  matrix[i][0][3] = 0;
   2367 			matrix[i][1][0] = value[3];	matrix[i][1][1] = value[4];  matrix[i][1][2] = value[5];  matrix[i][1][3] = 0;
   2368 			matrix[i][2][0] = value[6];	matrix[i][2][1] = value[7];  matrix[i][2][2] = value[8];  matrix[i][2][3] = 0;
   2369 			matrix[i][3][0] = value[9];	matrix[i][3][1] = value[10]; matrix[i][3][2] = value[11]; matrix[i][3][3] = 0;
   2370 
   2371 			value += 12;
   2372 		}
   2373 
   2374 		return applyUniform(device, location, (float*)matrix);
   2375 	}
   2376 
   2377 	bool Program::applyUniform1iv(Device *device, GLint location, GLsizei count, const GLint *v)
   2378 	{
   2379 		GLint vector[MAX_UNIFORM_VECTORS][4];
   2380 
   2381 		for(int i = 0; i < count; i++)
   2382 		{
   2383 			vector[i][0] = v[i];
   2384 			vector[i][1] = 0;
   2385 			vector[i][2] = 0;
   2386 			vector[i][3] = 0;
   2387 		}
   2388 
   2389 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
   2390 		if(IsSamplerUniform(targetUniform->type))
   2391 		{
   2392 			if(targetUniform->psRegisterIndex != -1)
   2393 			{
   2394 				for(int i = 0; i < count; i++)
   2395 				{
   2396 					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
   2397 
   2398 					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
   2399 					{
   2400 						ASSERT(samplersPS[samplerIndex].active);
   2401 						samplersPS[samplerIndex].logicalTextureUnit = v[i];
   2402 					}
   2403 				}
   2404 			}
   2405 
   2406 			if(targetUniform->vsRegisterIndex != -1)
   2407 			{
   2408 				for(int i = 0; i < count; i++)
   2409 				{
   2410 					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
   2411 
   2412 					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
   2413 					{
   2414 						ASSERT(samplersVS[samplerIndex].active);
   2415 						samplersVS[samplerIndex].logicalTextureUnit = v[i];
   2416 					}
   2417 				}
   2418 			}
   2419 		}
   2420 		else
   2421 		{
   2422 			return applyUniform(device, location, (float*)vector);
   2423 		}
   2424 
   2425 		return true;
   2426 	}
   2427 
   2428 	bool Program::applyUniform2iv(Device *device, GLint location, GLsizei count, const GLint *v)
   2429 	{
   2430 		GLint vector[MAX_UNIFORM_VECTORS][4];
   2431 
   2432 		for(int i = 0; i < count; i++)
   2433 		{
   2434 			vector[i][0] = v[0];
   2435 			vector[i][1] = v[1];
   2436 			vector[i][2] = 0;
   2437 			vector[i][3] = 0;
   2438 
   2439 			v += 2;
   2440 		}
   2441 
   2442 		return applyUniform(device, location, (float*)vector);
   2443 	}
   2444 
   2445 	bool Program::applyUniform3iv(Device *device, GLint location, GLsizei count, const GLint *v)
   2446 	{
   2447 		GLint vector[MAX_UNIFORM_VECTORS][4];
   2448 
   2449 		for(int i = 0; i < count; i++)
   2450 		{
   2451 			vector[i][0] = v[0];
   2452 			vector[i][1] = v[1];
   2453 			vector[i][2] = v[2];
   2454 			vector[i][3] = 0;
   2455 
   2456 			v += 3;
   2457 		}
   2458 
   2459 		return applyUniform(device, location, (float*)vector);
   2460 	}
   2461 
   2462 	bool Program::applyUniform4iv(Device *device, GLint location, GLsizei count, const GLint *v)
   2463 	{
   2464 		GLint vector[MAX_UNIFORM_VECTORS][4];
   2465 
   2466 		for(int i = 0; i < count; i++)
   2467 		{
   2468 			vector[i][0] = v[0];
   2469 			vector[i][1] = v[1];
   2470 			vector[i][2] = v[2];
   2471 			vector[i][3] = v[3];
   2472 
   2473 			v += 4;
   2474 		}
   2475 
   2476 		return applyUniform(device, location, (float*)vector);
   2477 	}
   2478 
   2479 	bool Program::applyUniform1uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
   2480 	{
   2481 		GLuint vector[MAX_UNIFORM_VECTORS][4];
   2482 
   2483 		for(int i = 0; i < count; i++)
   2484 		{
   2485 			vector[i][0] = v[i];
   2486 			vector[i][1] = 0;
   2487 			vector[i][2] = 0;
   2488 			vector[i][3] = 0;
   2489 		}
   2490 
   2491 		Uniform *targetUniform = uniforms[uniformIndex[location].index];
   2492 		if(IsSamplerUniform(targetUniform->type))
   2493 		{
   2494 			if(targetUniform->psRegisterIndex != -1)
   2495 			{
   2496 				for(int i = 0; i < count; i++)
   2497 				{
   2498 					unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
   2499 
   2500 					if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
   2501 					{
   2502 						ASSERT(samplersPS[samplerIndex].active);
   2503 						samplersPS[samplerIndex].logicalTextureUnit = v[i];
   2504 					}
   2505 				}
   2506 			}
   2507 
   2508 			if(targetUniform->vsRegisterIndex != -1)
   2509 			{
   2510 				for(int i = 0; i < count; i++)
   2511 				{
   2512 					unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
   2513 
   2514 					if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
   2515 					{
   2516 						ASSERT(samplersVS[samplerIndex].active);
   2517 						samplersVS[samplerIndex].logicalTextureUnit = v[i];
   2518 					}
   2519 				}
   2520 			}
   2521 		}
   2522 		else
   2523 		{
   2524 			return applyUniform(device, location, (float*)vector);
   2525 		}
   2526 
   2527 		return true;
   2528 	}
   2529 
   2530 	bool Program::applyUniform2uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
   2531 	{
   2532 		GLuint vector[MAX_UNIFORM_VECTORS][4];
   2533 
   2534 		for(int i = 0; i < count; i++)
   2535 		{
   2536 			vector[i][0] = v[0];
   2537 			vector[i][1] = v[1];
   2538 			vector[i][2] = 0;
   2539 			vector[i][3] = 0;
   2540 
   2541 			v += 2;
   2542 		}
   2543 
   2544 		return applyUniform(device, location, (float*)vector);
   2545 	}
   2546 
   2547 	bool Program::applyUniform3uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
   2548 	{
   2549 		GLuint vector[MAX_UNIFORM_VECTORS][4];
   2550 
   2551 		for(int i = 0; i < count; i++)
   2552 		{
   2553 			vector[i][0] = v[0];
   2554 			vector[i][1] = v[1];
   2555 			vector[i][2] = v[2];
   2556 			vector[i][3] = 0;
   2557 
   2558 			v += 3;
   2559 		}
   2560 
   2561 		return applyUniform(device, location, (float*)vector);
   2562 	}
   2563 
   2564 	bool Program::applyUniform4uiv(Device *device, GLint location, GLsizei count, const GLuint *v)
   2565 	{
   2566 		GLuint vector[MAX_UNIFORM_VECTORS][4];
   2567 
   2568 		for(int i = 0; i < count; i++)
   2569 		{
   2570 			vector[i][0] = v[0];
   2571 			vector[i][1] = v[1];
   2572 			vector[i][2] = v[2];
   2573 			vector[i][3] = v[3];
   2574 
   2575 			v += 4;
   2576 		}
   2577 
   2578 		return applyUniform(device, location, (float*)vector);
   2579 	}
   2580 
   2581 	void Program::appendToInfoLog(const char *format, ...)
   2582 	{
   2583 		if(!format)
   2584 		{
   2585 			return;
   2586 		}
   2587 
   2588 		char info[1024];
   2589 
   2590 		va_list vararg;
   2591 		va_start(vararg, format);
   2592 		vsnprintf(info, sizeof(info), format, vararg);
   2593 		va_end(vararg);
   2594 
   2595 		size_t infoLength = strlen(info);
   2596 
   2597 		if(!infoLog)
   2598 		{
   2599 			infoLog = new char[infoLength + 2];
   2600 			strcpy(infoLog, info);
   2601 			strcpy(infoLog + infoLength, "\n");
   2602 		}
   2603 		else
   2604 		{
   2605 			size_t logLength = strlen(infoLog);
   2606 			char *newLog = new char[logLength + infoLength + 2];
   2607 			strcpy(newLog, infoLog);
   2608 			strcpy(newLog + logLength, info);
   2609 			strcpy(newLog + logLength + infoLength, "\n");
   2610 
   2611 			delete[] infoLog;
   2612 			infoLog = newLog;
   2613 		}
   2614 	}
   2615 
   2616 	void Program::resetInfoLog()
   2617 	{
   2618 		if(infoLog)
   2619 		{
   2620 			delete[] infoLog;
   2621 			infoLog = 0;
   2622 		}
   2623 	}
   2624 
   2625 	// Returns the program object to an unlinked state, before re-linking, or at destruction
   2626 	void Program::unlink()
   2627 	{
   2628 		delete vertexBinary;
   2629 		vertexBinary = 0;
   2630 		delete pixelBinary;
   2631 		pixelBinary = 0;
   2632 
   2633 		linkedAttribute.clear();
   2634 		linkedAttributeLocation.clear();
   2635 
   2636 		for(int index = 0; index < MAX_VERTEX_ATTRIBS; index++)
   2637 		{
   2638 			attributeStream[index] = -1;
   2639 		}
   2640 
   2641 		for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
   2642 		{
   2643 			samplersPS[index].active = false;
   2644 		}
   2645 
   2646 		for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
   2647 		{
   2648 			samplersVS[index].active = false;
   2649 		}
   2650 
   2651 		while(!uniforms.empty())
   2652 		{
   2653 			delete uniforms.back();
   2654 			uniforms.pop_back();
   2655 		}
   2656 
   2657 		while(!uniformBlocks.empty())
   2658 		{
   2659 			delete uniformBlocks.back();
   2660 			uniformBlocks.pop_back();
   2661 		}
   2662 
   2663 		uniformIndex.clear();
   2664 		transformFeedbackLinkedVaryings.clear();
   2665 
   2666 		delete[] infoLog;
   2667 		infoLog = 0;
   2668 
   2669 		linked = false;
   2670 	}
   2671 
   2672 	bool Program::isLinked() const
   2673 	{
   2674 		return linked;
   2675 	}
   2676 
   2677 	bool Program::isValidated() const
   2678 	{
   2679 		return validated;
   2680 	}
   2681 
   2682 	GLint Program::getBinaryLength() const
   2683 	{
   2684 		UNIMPLEMENTED();
   2685 		return 0;
   2686 	}
   2687 
   2688 	void Program::release()
   2689 	{
   2690 		referenceCount--;
   2691 
   2692 		if(referenceCount == 0 && orphaned)
   2693 		{
   2694 			resourceManager->deleteProgram(handle);
   2695 		}
   2696 	}
   2697 
   2698 	void Program::addRef()
   2699 	{
   2700 		referenceCount++;
   2701 	}
   2702 
   2703 	unsigned int Program::getRefCount() const
   2704 	{
   2705 		return referenceCount;
   2706 	}
   2707 
   2708 	unsigned int Program::getSerial() const
   2709 	{
   2710 		return serial;
   2711 	}
   2712 
   2713 	unsigned int Program::issueSerial()
   2714 	{
   2715 		return currentSerial++;
   2716 	}
   2717 
   2718 	size_t Program::getInfoLogLength() const
   2719 	{
   2720 		if(!infoLog)
   2721 		{
   2722 			return 0;
   2723 		}
   2724 		else
   2725 		{
   2726 		   return strlen(infoLog) + 1;
   2727 		}
   2728 	}
   2729 
   2730 	void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *buffer)
   2731 	{
   2732 		int index = 0;
   2733 
   2734 		if(bufSize > 0)
   2735 		{
   2736 			if(infoLog)
   2737 			{
   2738 				index = std::min(bufSize - 1, (int)strlen(infoLog));
   2739 				memcpy(buffer, infoLog, index);
   2740 			}
   2741 
   2742 			buffer[index] = '\0';
   2743 		}
   2744 
   2745 		if(length)
   2746 		{
   2747 			*length = index;
   2748 		}
   2749 	}
   2750 
   2751 	void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
   2752 	{
   2753 		int total = 0;
   2754 
   2755 		if(vertexShader && (total < maxCount))
   2756 		{
   2757 			shaders[total++] = vertexShader->getName();
   2758 		}
   2759 
   2760 		if(fragmentShader && (total < maxCount))
   2761 		{
   2762 			shaders[total++] = fragmentShader->getName();
   2763 		}
   2764 
   2765 		if(count)
   2766 		{
   2767 			*count = total;
   2768 		}
   2769 	}
   2770 
   2771 	void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
   2772 	{
   2773 		ASSERT(index < linkedAttribute.size());
   2774 
   2775 		std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin() + index;
   2776 
   2777 		if(bufsize > 0)
   2778 		{
   2779 			const char *string = it->name.c_str();
   2780 
   2781 			strncpy(name, string, bufsize);
   2782 			name[bufsize - 1] = '\0';
   2783 
   2784 			if(length)
   2785 			{
   2786 				*length = static_cast<GLsizei>(strlen(name));
   2787 			}
   2788 		}
   2789 
   2790 		*size = 1;   // Always a single 'type' instance
   2791 
   2792 		*type = it->type;
   2793 	}
   2794 
   2795 	size_t Program::getActiveAttributeCount() const
   2796 	{
   2797 		return linkedAttribute.size();
   2798 	}
   2799 
   2800 	GLint Program::getActiveAttributeMaxLength() const
   2801 	{
   2802 		int maxLength = 0;
   2803 
   2804 		std::vector<glsl::Attribute>::const_iterator it = linkedAttribute.begin();
   2805 		std::vector<glsl::Attribute>::const_iterator itEnd = linkedAttribute.end();
   2806 		for(; it != itEnd; ++it)
   2807 		{
   2808 			maxLength = std::max((int)(it->name.length() + 1), maxLength);
   2809 		}
   2810 
   2811 		return maxLength;
   2812 	}
   2813 
   2814 	void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const
   2815 	{
   2816 		if(bufsize > 0)
   2817 		{
   2818 			std::string string = uniforms[index]->name;
   2819 
   2820 			if(uniforms[index]->isArray())
   2821 			{
   2822 				string += "[0]";
   2823 			}
   2824 
   2825 			strncpy(name, string.c_str(), bufsize);
   2826 			name[bufsize - 1] = '\0';
   2827 
   2828 			if(length)
   2829 			{
   2830 				*length = static_cast<GLsizei>(strlen(name));
   2831 			}
   2832 		}
   2833 
   2834 		*size = uniforms[index]->size();
   2835 
   2836 		*type = uniforms[index]->type;
   2837 	}
   2838 
   2839 	size_t Program::getActiveUniformCount() const
   2840 	{
   2841 		return uniforms.size();
   2842 	}
   2843 
   2844 	GLint Program::getActiveUniformMaxLength() const
   2845 	{
   2846 		int maxLength = 0;
   2847 
   2848 		size_t numUniforms = uniforms.size();
   2849 		for(size_t uniformIndex = 0; uniformIndex < numUniforms; uniformIndex++)
   2850 		{
   2851 			if(!uniforms[uniformIndex]->name.empty())
   2852 			{
   2853 				int length = (int)(uniforms[uniformIndex]->name.length() + 1);
   2854 				if(uniforms[uniformIndex]->isArray())
   2855 				{
   2856 					length += 3;  // Counting in "[0]".
   2857 				}
   2858 				maxLength = std::max(length, maxLength);
   2859 			}
   2860 		}
   2861 
   2862 		return maxLength;
   2863 	}
   2864 
   2865 	GLint Program::getActiveUniformi(GLuint index, GLenum pname) const
   2866 	{
   2867 		const Uniform& uniform = *uniforms[index];
   2868 		switch(pname)
   2869 		{
   2870 		case GL_UNIFORM_TYPE:         return static_cast<GLint>(uniform.type);
   2871 		case GL_UNIFORM_SIZE:         return static_cast<GLint>(uniform.size());
   2872 		case GL_UNIFORM_NAME_LENGTH:  return static_cast<GLint>(uniform.name.size() + 1 + (uniform.isArray() ? 3 : 0));
   2873 		case GL_UNIFORM_BLOCK_INDEX:  return uniform.blockInfo.index;
   2874 		case GL_UNIFORM_OFFSET:       return uniform.blockInfo.offset;
   2875 		case GL_UNIFORM_ARRAY_STRIDE: return uniform.blockInfo.arrayStride;
   2876 		case GL_UNIFORM_MATRIX_STRIDE: return uniform.blockInfo.matrixStride;
   2877 		case GL_UNIFORM_IS_ROW_MAJOR: return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
   2878 		default:
   2879 			UNREACHABLE(pname);
   2880 			break;
   2881 		}
   2882 		return 0;
   2883 	}
   2884 
   2885 	void Program::getActiveUniformBlockName(GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name) const
   2886 	{
   2887 		ASSERT(index < getActiveUniformBlockCount());
   2888 
   2889 		const UniformBlock &uniformBlock = *uniformBlocks[index];
   2890 
   2891 		if(bufSize > 0)
   2892 		{
   2893 			std::string string = uniformBlock.name;
   2894 
   2895 			if(uniformBlock.isArrayElement())
   2896 			{
   2897 				std::ostringstream elementIndex;
   2898 				elementIndex << uniformBlock.elementIndex;
   2899 				string += "[" + elementIndex.str()  + "]";
   2900 			}
   2901 
   2902 			strncpy(name, string.c_str(), bufSize);
   2903 			name[bufSize - 1] = '\0';
   2904 
   2905 			if(length)
   2906 			{
   2907 				*length = static_cast<GLsizei>(strlen(name));
   2908 			}
   2909 		}
   2910 	}
   2911 
   2912 	size_t Program::getActiveUniformBlockCount() const
   2913 	{
   2914 		return uniformBlocks.size();
   2915 	}
   2916 
   2917 	GLint Program::getActiveUniformBlockMaxLength() const
   2918 	{
   2919 		GLint maxLength = 0;
   2920 
   2921 		if(isLinked())
   2922 		{
   2923 			size_t numUniformBlocks = getActiveUniformBlockCount();
   2924 			for(size_t uniformBlockIndex = 0; uniformBlockIndex < numUniformBlocks; uniformBlockIndex++)
   2925 			{
   2926 				const UniformBlock &uniformBlock = *uniformBlocks[uniformBlockIndex];
   2927 				if(!uniformBlock.name.empty())
   2928 				{
   2929 					GLint length = static_cast<GLint>(uniformBlock.name.length() + 1);
   2930 
   2931 					// Counting in "[0]".
   2932 					const GLint arrayLength = (uniformBlock.isArrayElement() ? 3 : 0);
   2933 
   2934 					maxLength = std::max(length + arrayLength, maxLength);
   2935 				}
   2936 			}
   2937 		}
   2938 
   2939 		return maxLength;
   2940 	}
   2941 
   2942 	void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
   2943 	{
   2944 		transformFeedbackVaryings.resize(count);
   2945 		for(GLsizei i = 0; i < count; i++)
   2946 		{
   2947 			transformFeedbackVaryings[i] = varyings[i];
   2948 		}
   2949 
   2950 		transformFeedbackBufferMode = bufferMode;
   2951 	}
   2952 
   2953 	void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
   2954 	{
   2955 		if(linked)
   2956 		{
   2957 			ASSERT(index < transformFeedbackLinkedVaryings.size());
   2958 			const LinkedVarying &varying = transformFeedbackLinkedVaryings[index];
   2959 			GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
   2960 			if(length)
   2961 			{
   2962 				*length = lastNameIdx;
   2963 			}
   2964 			if(size)
   2965 			{
   2966 				*size = varying.size;
   2967 			}
   2968 			if(type)
   2969 			{
   2970 				*type = varying.type;
   2971 			}
   2972 			if(name)
   2973 			{
   2974 				memcpy(name, varying.name.c_str(), lastNameIdx);
   2975 				name[lastNameIdx] = '\0';
   2976 			}
   2977 		}
   2978 	}
   2979 
   2980 	GLsizei Program::getTransformFeedbackVaryingCount() const
   2981 	{
   2982 		if(linked)
   2983 		{
   2984 			return static_cast<GLsizei>(transformFeedbackLinkedVaryings.size());
   2985 		}
   2986 		else
   2987 		{
   2988 			return 0;
   2989 		}
   2990 	}
   2991 
   2992 	GLsizei Program::getTransformFeedbackVaryingMaxLength() const
   2993 	{
   2994 		if(linked)
   2995 		{
   2996 			GLsizei maxSize = 0;
   2997 			for(size_t i = 0; i < transformFeedbackLinkedVaryings.size(); i++)
   2998 			{
   2999 				const LinkedVarying &varying = transformFeedbackLinkedVaryings[i];
   3000 				maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
   3001 			}
   3002 
   3003 			return maxSize;
   3004 		}
   3005 		else
   3006 		{
   3007 			return 0;
   3008 		}
   3009 	}
   3010 
   3011 	GLenum Program::getTransformFeedbackBufferMode() const
   3012 	{
   3013 		return transformFeedbackBufferMode;
   3014 	}
   3015 
   3016 	void Program::flagForDeletion()
   3017 	{
   3018 		orphaned = true;
   3019 	}
   3020 
   3021 	bool Program::isFlaggedForDeletion() const
   3022 	{
   3023 		return orphaned;
   3024 	}
   3025 
   3026 	void Program::validate(Device* device)
   3027 	{
   3028 		resetInfoLog();
   3029 
   3030 		if(!isLinked())
   3031 		{
   3032 			appendToInfoLog("Program has not been successfully linked.");
   3033 			validated = false;
   3034 		}
   3035 		else
   3036 		{
   3037 			applyUniforms(device);
   3038 			if(!validateSamplers(true))
   3039 			{
   3040 				validated = false;
   3041 			}
   3042 			else
   3043 			{
   3044 				validated = true;
   3045 			}
   3046 		}
   3047 	}
   3048 
   3049 	bool Program::validateSamplers(bool logErrors)
   3050 	{
   3051 		// if any two active samplers in a program are of different types, but refer to the same
   3052 		// texture image unit, and this is the current program, then ValidateProgram will fail, and
   3053 		// DrawArrays and DrawElements will issue the INVALID_OPERATION error.
   3054 
   3055 		TextureType textureUnitType[MAX_COMBINED_TEXTURE_IMAGE_UNITS];
   3056 
   3057 		for(unsigned int i = 0; i < MAX_COMBINED_TEXTURE_IMAGE_UNITS; i++)
   3058 		{
   3059 			textureUnitType[i] = TEXTURE_UNKNOWN;
   3060 		}
   3061 
   3062 		for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
   3063 		{
   3064 			if(samplersPS[i].active)
   3065 			{
   3066 				unsigned int unit = samplersPS[i].logicalTextureUnit;
   3067 
   3068 				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
   3069 				{
   3070 					if(logErrors)
   3071 					{
   3072 						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
   3073 					}
   3074 
   3075 					return false;
   3076 				}
   3077 
   3078 				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
   3079 				{
   3080 					if(samplersPS[i].textureType != textureUnitType[unit])
   3081 					{
   3082 						if(logErrors)
   3083 						{
   3084 							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
   3085 						}
   3086 
   3087 						return false;
   3088 					}
   3089 				}
   3090 				else
   3091 				{
   3092 					textureUnitType[unit] = samplersPS[i].textureType;
   3093 				}
   3094 			}
   3095 		}
   3096 
   3097 		for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++)
   3098 		{
   3099 			if(samplersVS[i].active)
   3100 			{
   3101 				unsigned int unit = samplersVS[i].logicalTextureUnit;
   3102 
   3103 				if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
   3104 				{
   3105 					if(logErrors)
   3106 					{
   3107 						appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
   3108 					}
   3109 
   3110 					return false;
   3111 				}
   3112 
   3113 				if(textureUnitType[unit] != TEXTURE_UNKNOWN)
   3114 				{
   3115 					if(samplersVS[i].textureType != textureUnitType[unit])
   3116 					{
   3117 						if(logErrors)
   3118 						{
   3119 							appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
   3120 						}
   3121 
   3122 						return false;
   3123 					}
   3124 				}
   3125 				else
   3126 				{
   3127 					textureUnitType[unit] = samplersVS[i].textureType;
   3128 				}
   3129 			}
   3130 		}
   3131 
   3132 		return true;
   3133 	}
   3134 }
   3135