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