Home | History | Annotate | Download | only in Renderer
      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 #include "VertexProcessor.hpp"
     16 
     17 #include "Shader/VertexPipeline.hpp"
     18 #include "Shader/VertexProgram.hpp"
     19 #include "Shader/VertexShader.hpp"
     20 #include "Shader/PixelShader.hpp"
     21 #include "Shader/Constants.hpp"
     22 #include "Common/Math.hpp"
     23 #include "Common/Debug.hpp"
     24 
     25 #include <string.h>
     26 
     27 namespace sw
     28 {
     29 	bool precacheVertex = false;
     30 
     31 	void VertexCache::clear()
     32 	{
     33 		for(int i = 0; i < 16; i++)
     34 		{
     35 			tag[i] = 0x80000000;
     36 		}
     37 	}
     38 
     39 	unsigned int VertexProcessor::States::computeHash()
     40 	{
     41 		unsigned int *state = (unsigned int*)this;
     42 		unsigned int hash = 0;
     43 
     44 		for(unsigned int i = 0; i < sizeof(States) / 4; i++)
     45 		{
     46 			hash ^= state[i];
     47 		}
     48 
     49 		return hash;
     50 	}
     51 
     52 	VertexProcessor::State::State()
     53 	{
     54 		memset(this, 0, sizeof(State));
     55 	}
     56 
     57 	bool VertexProcessor::State::operator==(const State &state) const
     58 	{
     59 		if(hash != state.hash)
     60 		{
     61 			return false;
     62 		}
     63 
     64 		return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
     65 	}
     66 
     67 	VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo()
     68 	{
     69 		buffer = nullptr;
     70 		offset = 0;
     71 		reg = 0;
     72 		row = 0;
     73 		col = 0;
     74 		stride = 0;
     75 	}
     76 
     77 	VertexProcessor::UniformBufferInfo::UniformBufferInfo()
     78 	{
     79 		buffer = nullptr;
     80 		offset = 0;
     81 	}
     82 
     83 	VertexProcessor::VertexProcessor(Context *context) : context(context)
     84 	{
     85 		for(int i = 0; i < 12; i++)
     86 		{
     87 			M[i] = 1;
     88 		}
     89 
     90 		V = 1;
     91 		B = 1;
     92 		P = 0;
     93 		PB = 0;
     94 		PBV = 0;
     95 
     96 		for(int i = 0; i < 12; i++)
     97 		{
     98 			PBVM[i] = 0;
     99 		}
    100 
    101 		setLightingEnable(true);
    102 		setSpecularEnable(false);
    103 
    104 		for(int i = 0; i < 8; i++)
    105 		{
    106 			setLightEnable(i, false);
    107 			setLightPosition(i, 0);
    108 		}
    109 
    110 		updateMatrix = true;
    111 		updateViewMatrix = true;
    112 		updateBaseMatrix = true;
    113 		updateProjectionMatrix = true;
    114 		updateLighting = true;
    115 
    116 		for(int i = 0; i < 12; i++)
    117 		{
    118 			updateModelMatrix[i] = true;
    119 		}
    120 
    121 		routineCache = 0;
    122 		setRoutineCacheSize(1024);
    123 	}
    124 
    125 	VertexProcessor::~VertexProcessor()
    126 	{
    127 		delete routineCache;
    128 		routineCache = 0;
    129 	}
    130 
    131 	void VertexProcessor::setInputStream(int index, const Stream &stream)
    132 	{
    133 		context->input[index] = stream;
    134 	}
    135 
    136 	void VertexProcessor::resetInputStreams(bool preTransformed)
    137 	{
    138 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
    139 		{
    140 			context->input[i].defaults();
    141 		}
    142 
    143 		context->preTransformed = preTransformed;
    144 	}
    145 
    146 	void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
    147 	{
    148 		if(index < VERTEX_UNIFORM_VECTORS)
    149 		{
    150 			c[index][0] = value[0];
    151 			c[index][1] = value[1];
    152 			c[index][2] = value[2];
    153 			c[index][3] = value[3];
    154 		}
    155 		else ASSERT(false);
    156 	}
    157 
    158 	void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
    159 	{
    160 		if(index < 16)
    161 		{
    162 			i[index][0] = integer[0];
    163 			i[index][1] = integer[1];
    164 			i[index][2] = integer[2];
    165 			i[index][3] = integer[3];
    166 		}
    167 		else ASSERT(false);
    168 	}
    169 
    170 	void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
    171 	{
    172 		if(index < 16)
    173 		{
    174 			b[index] = boolean != 0;
    175 		}
    176 		else ASSERT(false);
    177 	}
    178 
    179 	void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
    180 	{
    181 		uniformBufferInfo[index].buffer = buffer;
    182 		uniformBufferInfo[index].offset = offset;
    183 	}
    184 
    185 	void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
    186 	{
    187 		for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
    188 		{
    189 			u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
    190 			uniformBuffers[i] = uniformBufferInfo[i].buffer;
    191 		}
    192 	}
    193 
    194 	void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, unsigned int stride)
    195 	{
    196 		transformFeedbackInfo[index].buffer = buffer;
    197 		transformFeedbackInfo[index].offset = offset;
    198 		transformFeedbackInfo[index].reg = reg;
    199 		transformFeedbackInfo[index].row = row;
    200 		transformFeedbackInfo[index].col = col;
    201 		transformFeedbackInfo[index].stride = stride;
    202 	}
    203 
    204 	void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[])
    205 	{
    206 		for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
    207 		{
    208 			t[i] = transformFeedbackInfo[i].buffer ? static_cast<byte*>(transformFeedbackInfo[i].buffer->lock(PUBLIC, PRIVATE)) + transformFeedbackInfo[i].offset : nullptr;
    209 			transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer;
    210 			v[i] = transformFeedbackInfo[i].reg;
    211 			r[i] = transformFeedbackInfo[i].row;
    212 			c[i] = transformFeedbackInfo[i].col;
    213 			s[i] = transformFeedbackInfo[i].stride;
    214 		}
    215 	}
    216 
    217 	void VertexProcessor::setModelMatrix(const Matrix &M, int i)
    218 	{
    219 		if(i < 12)
    220 		{
    221 			this->M[i] = M;
    222 
    223 			updateMatrix = true;
    224 			updateModelMatrix[i] = true;
    225 			updateLighting = true;
    226 		}
    227 		else ASSERT(false);
    228 	}
    229 
    230 	void VertexProcessor::setViewMatrix(const Matrix &V)
    231 	{
    232 		this->V = V;
    233 
    234 		updateMatrix = true;
    235 		updateViewMatrix = true;
    236 	}
    237 
    238 	void VertexProcessor::setBaseMatrix(const Matrix &B)
    239 	{
    240 		this->B = B;
    241 
    242 		updateMatrix = true;
    243 		updateBaseMatrix = true;
    244 	}
    245 
    246 	void VertexProcessor::setProjectionMatrix(const Matrix &P)
    247 	{
    248 		this->P = P;
    249 		context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
    250 
    251 		updateMatrix = true;
    252 		updateProjectionMatrix = true;
    253 	}
    254 
    255 	void VertexProcessor::setLightingEnable(bool lightingEnable)
    256 	{
    257 		context->setLightingEnable(lightingEnable);
    258 
    259 		updateLighting = true;
    260 	}
    261 
    262 	void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
    263 	{
    264 		if(light < 8)
    265 		{
    266 			context->setLightEnable(light, lightEnable);
    267 		}
    268 		else ASSERT(false);
    269 
    270 		updateLighting = true;
    271 	}
    272 
    273 	void VertexProcessor::setSpecularEnable(bool specularEnable)
    274 	{
    275 		context->setSpecularEnable(specularEnable);
    276 
    277 		updateLighting = true;
    278 	}
    279 
    280 	void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
    281 	{
    282 		if(light < 8)
    283 		{
    284 			context->setLightPosition(light, lightPosition);
    285 		}
    286 		else ASSERT(false);
    287 
    288 		updateLighting = true;
    289 	}
    290 
    291 	void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
    292 	{
    293 		if(light < 8)
    294 		{
    295 			ff.lightDiffuse[light][0] = lightDiffuse.r;
    296 			ff.lightDiffuse[light][1] = lightDiffuse.g;
    297 			ff.lightDiffuse[light][2] = lightDiffuse.b;
    298 			ff.lightDiffuse[light][3] = lightDiffuse.a;
    299 		}
    300 		else ASSERT(false);
    301 	}
    302 
    303 	void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
    304 	{
    305 		if(light < 8)
    306 		{
    307 			ff.lightSpecular[light][0] = lightSpecular.r;
    308 			ff.lightSpecular[light][1] = lightSpecular.g;
    309 			ff.lightSpecular[light][2] = lightSpecular.b;
    310 			ff.lightSpecular[light][3] = lightSpecular.a;
    311 		}
    312 		else ASSERT(false);
    313 	}
    314 
    315 	void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
    316 	{
    317 		if(light < 8)
    318 		{
    319 			ff.lightAmbient[light][0] = lightAmbient.r;
    320 			ff.lightAmbient[light][1] = lightAmbient.g;
    321 			ff.lightAmbient[light][2] = lightAmbient.b;
    322 			ff.lightAmbient[light][3] = lightAmbient.a;
    323 		}
    324 		else ASSERT(false);
    325 	}
    326 
    327 	void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
    328 	{
    329 		if(light < 8)
    330 		{
    331 			ff.attenuationConstant[light] = replicate(constant);
    332 			ff.attenuationLinear[light] = replicate(linear);
    333 			ff.attenuationQuadratic[light] = replicate(quadratic);
    334 		}
    335 		else ASSERT(false);
    336 	}
    337 
    338 	void VertexProcessor::setLightRange(unsigned int light, float lightRange)
    339 	{
    340 		if(light < 8)
    341 		{
    342 			ff.lightRange[light] = lightRange;
    343 		}
    344 		else ASSERT(false);
    345 	}
    346 
    347 	void VertexProcessor::setFogEnable(bool fogEnable)
    348 	{
    349 		context->fogEnable = fogEnable;
    350 	}
    351 
    352 	void VertexProcessor::setVertexFogMode(FogMode fogMode)
    353 	{
    354 		context->vertexFogMode = fogMode;
    355 	}
    356 
    357 	void VertexProcessor::setInstanceID(int instanceID)
    358 	{
    359 		context->instanceID = instanceID;
    360 	}
    361 
    362 	void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
    363 	{
    364 		context->setColorVertexEnable(colorVertexEnable);
    365 	}
    366 
    367 	void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
    368 	{
    369 		context->setDiffuseMaterialSource(diffuseMaterialSource);
    370 	}
    371 
    372 	void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
    373 	{
    374 		context->setSpecularMaterialSource(specularMaterialSource);
    375 	}
    376 
    377 	void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
    378 	{
    379 		context->setAmbientMaterialSource(ambientMaterialSource);
    380 	}
    381 
    382 	void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
    383 	{
    384 		context->setEmissiveMaterialSource(emissiveMaterialSource);
    385 	}
    386 
    387 	void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
    388 	{
    389 		ff.globalAmbient[0] = globalAmbient.r;
    390 		ff.globalAmbient[1] = globalAmbient.g;
    391 		ff.globalAmbient[2] = globalAmbient.b;
    392 		ff.globalAmbient[3] = globalAmbient.a;
    393 	}
    394 
    395 	void VertexProcessor::setMaterialEmission(const Color<float> &emission)
    396 	{
    397 		ff.materialEmission[0] = emission.r;
    398 		ff.materialEmission[1] = emission.g;
    399 		ff.materialEmission[2] = emission.b;
    400 		ff.materialEmission[3] = emission.a;
    401 	}
    402 
    403 	void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
    404 	{
    405 		ff.materialAmbient[0] = materialAmbient.r;
    406 		ff.materialAmbient[1] = materialAmbient.g;
    407 		ff.materialAmbient[2] = materialAmbient.b;
    408 		ff.materialAmbient[3] = materialAmbient.a;
    409 	}
    410 
    411 	void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
    412 	{
    413 		ff.materialDiffuse[0] = diffuseColor.r;
    414 		ff.materialDiffuse[1] = diffuseColor.g;
    415 		ff.materialDiffuse[2] = diffuseColor.b;
    416 		ff.materialDiffuse[3] = diffuseColor.a;
    417 	}
    418 
    419 	void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
    420 	{
    421 		ff.materialSpecular[0] = specularColor.r;
    422 		ff.materialSpecular[1] = specularColor.g;
    423 		ff.materialSpecular[2] = specularColor.b;
    424 		ff.materialSpecular[3] = specularColor.a;
    425 	}
    426 
    427 	void VertexProcessor::setMaterialShininess(float specularPower)
    428 	{
    429 		ff.materialShininess = specularPower;
    430 	}
    431 
    432 	void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
    433 	{
    434 		if(light < 8)
    435 		{
    436 			ff.lightPosition[light][0] = P.x;
    437 			ff.lightPosition[light][1] = P.y;
    438 			ff.lightPosition[light][2] = P.z;
    439 			ff.lightPosition[light][3] = 1;
    440 		}
    441 		else ASSERT(false);
    442 	}
    443 
    444 	void VertexProcessor::setRangeFogEnable(bool enable)
    445 	{
    446 		context->rangeFogEnable = enable;
    447 	}
    448 
    449 	void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
    450 	{
    451 		context->indexedVertexBlendEnable = indexedVertexBlendEnable;
    452 	}
    453 
    454 	void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
    455 	{
    456 		if(vertexBlendMatrixCount <= 4)
    457 		{
    458 			context->vertexBlendMatrixCount = vertexBlendMatrixCount;
    459 		}
    460 		else ASSERT(false);
    461 	}
    462 
    463 	void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
    464 	{
    465 		if(stage < TEXTURE_IMAGE_UNITS)
    466 		{
    467 			context->textureWrap[stage] = mask;
    468 		}
    469 		else ASSERT(false);
    470 
    471 		context->textureWrapActive = false;
    472 
    473 		for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
    474 		{
    475 			context->textureWrapActive |= (context->textureWrap[i] != 0x00);
    476 		}
    477 	}
    478 
    479 	void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
    480 	{
    481 		if(stage < 8)
    482 		{
    483 			context->texGen[stage] = texGen;
    484 		}
    485 		else ASSERT(false);
    486 	}
    487 
    488 	void VertexProcessor::setLocalViewer(bool localViewer)
    489 	{
    490 		context->localViewer = localViewer;
    491 	}
    492 
    493 	void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
    494 	{
    495 		context->normalizeNormals = normalizeNormals;
    496 	}
    497 
    498 	void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
    499 	{
    500 		for(int i = 0; i < 4; i++)
    501 		{
    502 			for(int j = 0; j < 4; j++)
    503 			{
    504 				ff.textureTransform[stage][i][j] = T[i][j];
    505 			}
    506 		}
    507 	}
    508 
    509 	void VertexProcessor::setTextureTransform(int stage, int count, bool project)
    510 	{
    511 		context->textureTransformCount[stage] = count;
    512 		context->textureTransformProject[stage] = project;
    513 	}
    514 
    515 	void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
    516 	{
    517 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    518 		{
    519 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
    520 		}
    521 		else ASSERT(false);
    522 	}
    523 
    524 	void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
    525 	{
    526 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    527 		{
    528 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
    529 		}
    530 		else ASSERT(false);
    531 	}
    532 
    533 	void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
    534 	{
    535 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    536 		{
    537 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
    538 		}
    539 		else ASSERT(false);
    540 	}
    541 
    542 	void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
    543 	{
    544 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    545 		{
    546 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
    547 		}
    548 		else ASSERT(false);
    549 	}
    550 
    551 	void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
    552 	{
    553 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    554 		{
    555 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
    556 		}
    557 		else ASSERT(false);
    558 	}
    559 
    560 	void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
    561 	{
    562 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    563 		{
    564 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
    565 		}
    566 		else ASSERT(false);
    567 	}
    568 
    569 	void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
    570 	{
    571 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    572 		{
    573 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
    574 		}
    575 		else ASSERT(false);
    576 	}
    577 
    578 	void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
    579 	{
    580 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    581 		{
    582 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
    583 		}
    584 		else ASSERT(false);
    585 	}
    586 
    587 	void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
    588 	{
    589 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    590 		{
    591 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
    592 		}
    593 		else ASSERT(false);
    594 	}
    595 
    596 	void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
    597 	{
    598 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    599 		{
    600 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
    601 		}
    602 		else ASSERT(false);
    603 	}
    604 
    605 	void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
    606 	{
    607 		if(sampler < TEXTURE_IMAGE_UNITS)
    608 		{
    609 			context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
    610 		}
    611 		else ASSERT(false);
    612 	}
    613 
    614 	void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
    615 	{
    616 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    617 		{
    618 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
    619 		}
    620 		else ASSERT(false);
    621 	}
    622 
    623 	void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
    624 	{
    625 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    626 		{
    627 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
    628 		}
    629 		else ASSERT(false);
    630 	}
    631 
    632 	void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
    633 	{
    634 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    635 		{
    636 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
    637 		}
    638 		else ASSERT(false);
    639 	}
    640 
    641 	void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
    642 	{
    643 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    644 		{
    645 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
    646 		}
    647 		else ASSERT(false);
    648 	}
    649 
    650 	void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
    651 	{
    652 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    653 		{
    654 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
    655 		}
    656 		else ASSERT(false);
    657 	}
    658 
    659 	void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
    660 	{
    661 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    662 		{
    663 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
    664 		}
    665 		else ASSERT(false);
    666 	}
    667 
    668 	void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
    669 	{
    670 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    671 		{
    672 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
    673 		}
    674 		else ASSERT(false);
    675 	}
    676 
    677 	void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
    678 	{
    679 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    680 		{
    681 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
    682 		}
    683 		else ASSERT(false);
    684 	}
    685 
    686 	void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
    687 	{
    688 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
    689 		{
    690 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
    691 		}
    692 		else ASSERT(false);
    693 	}
    694 
    695 	void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
    696 	{
    697 		if(sampler < TEXTURE_IMAGE_UNITS)
    698 		{
    699 			context->sampler[sampler].setSyncRequired(isSincRequired);
    700 		}
    701 		else ASSERT(false);
    702 	}
    703 
    704 	void VertexProcessor::setPointSize(float pointSize)
    705 	{
    706 		point.pointSize = replicate(pointSize);
    707 	}
    708 
    709 	void VertexProcessor::setPointSizeMin(float pointSizeMin)
    710 	{
    711 		point.pointSizeMin = pointSizeMin;
    712 	}
    713 
    714 	void VertexProcessor::setPointSizeMax(float pointSizeMax)
    715 	{
    716 		point.pointSizeMax = pointSizeMax;
    717 	}
    718 
    719 	void VertexProcessor::setPointScaleA(float pointScaleA)
    720 	{
    721 		point.pointScaleA = pointScaleA;
    722 	}
    723 
    724 	void VertexProcessor::setPointScaleB(float pointScaleB)
    725 	{
    726 		point.pointScaleB = pointScaleB;
    727 	}
    728 
    729 	void VertexProcessor::setPointScaleC(float pointScaleC)
    730 	{
    731 		point.pointScaleC = pointScaleC;
    732 	}
    733 
    734 	void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
    735 	{
    736 		context->transformFeedbackQueryEnabled = enable;
    737 	}
    738 
    739 	void VertexProcessor::enableTransformFeedback(uint64_t enable)
    740 	{
    741 		context->transformFeedbackEnabled = enable;
    742 	}
    743 
    744 	const Matrix &VertexProcessor::getModelTransform(int i)
    745 	{
    746 		updateTransform();
    747 		return PBVM[i];
    748 	}
    749 
    750 	const Matrix &VertexProcessor::getViewTransform()
    751 	{
    752 		updateTransform();
    753 		return PBV;
    754 	}
    755 
    756 	bool VertexProcessor::isFixedFunction()
    757 	{
    758 		return !context->vertexShader;
    759 	}
    760 
    761 	void VertexProcessor::setTransform(const Matrix &M, int i)
    762 	{
    763 		ff.transformT[i][0][0] = M[0][0];
    764 		ff.transformT[i][0][1] = M[1][0];
    765 		ff.transformT[i][0][2] = M[2][0];
    766 		ff.transformT[i][0][3] = M[3][0];
    767 
    768 		ff.transformT[i][1][0] = M[0][1];
    769 		ff.transformT[i][1][1] = M[1][1];
    770 		ff.transformT[i][1][2] = M[2][1];
    771 		ff.transformT[i][1][3] = M[3][1];
    772 
    773 		ff.transformT[i][2][0] = M[0][2];
    774 		ff.transformT[i][2][1] = M[1][2];
    775 		ff.transformT[i][2][2] = M[2][2];
    776 		ff.transformT[i][2][3] = M[3][2];
    777 
    778 		ff.transformT[i][3][0] = M[0][3];
    779 		ff.transformT[i][3][1] = M[1][3];
    780 		ff.transformT[i][3][2] = M[2][3];
    781 		ff.transformT[i][3][3] = M[3][3];
    782 	}
    783 
    784 	void VertexProcessor::setCameraTransform(const Matrix &M, int i)
    785 	{
    786 		ff.cameraTransformT[i][0][0] = M[0][0];
    787 		ff.cameraTransformT[i][0][1] = M[1][0];
    788 		ff.cameraTransformT[i][0][2] = M[2][0];
    789 		ff.cameraTransformT[i][0][3] = M[3][0];
    790 
    791 		ff.cameraTransformT[i][1][0] = M[0][1];
    792 		ff.cameraTransformT[i][1][1] = M[1][1];
    793 		ff.cameraTransformT[i][1][2] = M[2][1];
    794 		ff.cameraTransformT[i][1][3] = M[3][1];
    795 
    796 		ff.cameraTransformT[i][2][0] = M[0][2];
    797 		ff.cameraTransformT[i][2][1] = M[1][2];
    798 		ff.cameraTransformT[i][2][2] = M[2][2];
    799 		ff.cameraTransformT[i][2][3] = M[3][2];
    800 
    801 		ff.cameraTransformT[i][3][0] = M[0][3];
    802 		ff.cameraTransformT[i][3][1] = M[1][3];
    803 		ff.cameraTransformT[i][3][2] = M[2][3];
    804 		ff.cameraTransformT[i][3][3] = M[3][3];
    805 	}
    806 
    807 	void VertexProcessor::setNormalTransform(const Matrix &M, int i)
    808 	{
    809 		ff.normalTransformT[i][0][0] = M[0][0];
    810 		ff.normalTransformT[i][0][1] = M[1][0];
    811 		ff.normalTransformT[i][0][2] = M[2][0];
    812 		ff.normalTransformT[i][0][3] = M[3][0];
    813 
    814 		ff.normalTransformT[i][1][0] = M[0][1];
    815 		ff.normalTransformT[i][1][1] = M[1][1];
    816 		ff.normalTransformT[i][1][2] = M[2][1];
    817 		ff.normalTransformT[i][1][3] = M[3][1];
    818 
    819 		ff.normalTransformT[i][2][0] = M[0][2];
    820 		ff.normalTransformT[i][2][1] = M[1][2];
    821 		ff.normalTransformT[i][2][2] = M[2][2];
    822 		ff.normalTransformT[i][2][3] = M[3][2];
    823 
    824 		ff.normalTransformT[i][3][0] = M[0][3];
    825 		ff.normalTransformT[i][3][1] = M[1][3];
    826 		ff.normalTransformT[i][3][2] = M[2][3];
    827 		ff.normalTransformT[i][3][3] = M[3][3];
    828 	}
    829 
    830 	void VertexProcessor::updateTransform()
    831 	{
    832 		if(!updateMatrix) return;
    833 
    834 		int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
    835 
    836 		if(updateProjectionMatrix)
    837 		{
    838 			PB = P * B;
    839 			PBV = PB * V;
    840 
    841 			for(int i = 0; i < activeMatrices; i++)
    842 			{
    843 				PBVM[i] = PBV * M[i];
    844 				updateModelMatrix[i] = false;
    845 			}
    846 
    847 			updateProjectionMatrix = false;
    848 			updateBaseMatrix = false;
    849 			updateViewMatrix = false;
    850 		}
    851 
    852 		if(updateBaseMatrix)
    853 		{
    854 			PB = P * B;
    855 			PBV = PB * V;
    856 
    857 			for(int i = 0; i < activeMatrices; i++)
    858 			{
    859 				PBVM[i] = PBV * M[i];
    860 				updateModelMatrix[i] = false;
    861 			}
    862 
    863 			updateBaseMatrix = false;
    864 			updateViewMatrix = false;
    865 		}
    866 
    867 		if(updateViewMatrix)
    868 		{
    869 			PBV = PB * V;
    870 
    871 			for(int i = 0; i < activeMatrices; i++)
    872 			{
    873 				PBVM[i] = PBV * M[i];
    874 				updateModelMatrix[i] = false;
    875 			}
    876 
    877 			updateViewMatrix = false;
    878 		}
    879 
    880 		for(int i = 0; i < activeMatrices; i++)
    881 		{
    882 			if(updateModelMatrix[i])
    883 			{
    884 				PBVM[i] = PBV * M[i];
    885 				updateModelMatrix[i] = false;
    886 			}
    887 		}
    888 
    889 		for(int i = 0; i < activeMatrices; i++)
    890 		{
    891 			setTransform(PBVM[i], i);
    892 			setCameraTransform(B * V * M[i], i);
    893 			setNormalTransform(~!(B * V * M[i]), i);
    894 		}
    895 
    896 		updateMatrix = false;
    897 	}
    898 
    899 	void VertexProcessor::setRoutineCacheSize(int cacheSize)
    900 	{
    901 		delete routineCache;
    902 		routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
    903 	}
    904 
    905 	const VertexProcessor::State VertexProcessor::update(DrawType drawType)
    906 	{
    907 		if(isFixedFunction())
    908 		{
    909 			updateTransform();
    910 
    911 			if(updateLighting)
    912 			{
    913 				for(int i = 0; i < 8; i++)
    914 				{
    915 					if(context->vertexLightActive(i))
    916 					{
    917 						// Light position in camera coordinates
    918 						setLightViewPosition(i, B * V * context->getLightPosition(i));
    919 					}
    920 				}
    921 
    922 				updateLighting = false;
    923 			}
    924 		}
    925 
    926 		State state;
    927 
    928 		if(context->vertexShader)
    929 		{
    930 			state.shaderID = context->vertexShader->getSerialID();
    931 		}
    932 		else
    933 		{
    934 			state.shaderID = 0;
    935 		}
    936 
    937 		state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
    938 		state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
    939 		state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
    940 		state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
    941 
    942 		state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
    943 		state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
    944 		state.vertexNormalActive = context->vertexNormalActive();
    945 		state.normalizeNormals = context->normalizeNormalsActive();
    946 		state.vertexLightingActive = context->vertexLightingActive();
    947 		state.diffuseActive = context->diffuseActive();
    948 		state.specularActive = context->specularActive();
    949 		state.vertexSpecularActive = context->vertexSpecularActive();
    950 
    951 		state.vertexLightActive = context->vertexLightActive(0) << 0 |
    952 		                          context->vertexLightActive(1) << 1 |
    953 		                          context->vertexLightActive(2) << 2 |
    954 		                          context->vertexLightActive(3) << 3 |
    955 		                          context->vertexLightActive(4) << 4 |
    956 		                          context->vertexLightActive(5) << 5 |
    957 		                          context->vertexLightActive(6) << 6 |
    958 		                          context->vertexLightActive(7) << 7;
    959 
    960 		state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
    961 		state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
    962 		state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
    963 		state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
    964 		state.fogActive = context->fogActive();
    965 		state.vertexFogMode = context->vertexFogModeActive();
    966 		state.rangeFogActive = context->rangeFogActive();
    967 		state.localViewerActive = context->localViewerActive();
    968 		state.pointSizeActive = context->pointSizeActive();
    969 		state.pointScaleActive = context->pointScaleActive();
    970 
    971 		state.preTransformed = context->preTransformed;
    972 		state.superSampling = context->getSuperSampleCount() > 1;
    973 		state.multiSampling = context->getMultiSampleCount() > 1;
    974 
    975 		state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
    976 		state.transformFeedbackEnabled = context->transformFeedbackEnabled;
    977 
    978 		// Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
    979 		//       which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
    980 		DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
    981 		state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
    982 
    983 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
    984 		{
    985 			state.input[i].type = context->input[i].type;
    986 			state.input[i].count = context->input[i].count;
    987 			state.input[i].normalized = context->input[i].normalized;
    988 			state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
    989 		}
    990 
    991 		if(!context->vertexShader)
    992 		{
    993 			for(int i = 0; i < 8; i++)
    994 			{
    995 			//	state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
    996 				state.textureState[i].texGenActive = context->texGenActive(i);
    997 				state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
    998 				state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
    999 			}
   1000 		}
   1001 		else
   1002 		{
   1003 			for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
   1004 			{
   1005 				if(context->vertexShader->usesSampler(i))
   1006 				{
   1007 					state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
   1008 				}
   1009 			}
   1010 		}
   1011 
   1012 		if(context->vertexShader)   // FIXME: Also when pre-transformed?
   1013 		{
   1014 			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
   1015 			{
   1016 				state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
   1017 				state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
   1018 				state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
   1019 				state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
   1020 			}
   1021 		}
   1022 		else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
   1023 		{
   1024 			state.output[Pos].write = 0xF;
   1025 
   1026 			if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
   1027 			{
   1028 				state.output[C0].write = 0xF;
   1029 			}
   1030 
   1031 			if(context->specularActive())
   1032 			{
   1033 				state.output[C1].write = 0xF;
   1034 			}
   1035 
   1036 			for(int stage = 0; stage < 8; stage++)
   1037 			{
   1038 				if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
   1039 				if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
   1040 				if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
   1041 				if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
   1042 			}
   1043 
   1044 			if(context->fogActive())
   1045 			{
   1046 				state.output[Fog].xWrite = true;
   1047 			}
   1048 
   1049 			if(context->pointSizeActive())
   1050 			{
   1051 				state.output[Pts].yWrite = true;
   1052 			}
   1053 		}
   1054 		else
   1055 		{
   1056 			state.output[Pos].write = 0xF;
   1057 
   1058 			for(int i = 0; i < 2; i++)
   1059 			{
   1060 				if(context->input[Color0 + i])
   1061 				{
   1062 					state.output[C0 + i].write = 0xF;
   1063 				}
   1064 			}
   1065 
   1066 			for(int i = 0; i < 8; i++)
   1067 			{
   1068 				if(context->input[TexCoord0 + i])
   1069 				{
   1070 					state.output[T0 + i].write = 0xF;
   1071 				}
   1072 			}
   1073 
   1074 			if(context->input[PointSize])
   1075 			{
   1076 				state.output[Pts].yWrite = true;
   1077 			}
   1078 		}
   1079 
   1080 		if(context->vertexShaderModel() < 0x0300)
   1081 		{
   1082 			state.output[C0].clamp = 0xF;
   1083 			state.output[C1].clamp = 0xF;
   1084 			state.output[Fog].xClamp = true;
   1085 		}
   1086 
   1087 		state.hash = state.computeHash();
   1088 
   1089 		return state;
   1090 	}
   1091 
   1092 	Routine *VertexProcessor::routine(const State &state)
   1093 	{
   1094 		Routine *routine = routineCache->query(state);
   1095 
   1096 		if(!routine)   // Create one
   1097 		{
   1098 			VertexRoutine *generator = nullptr;
   1099 
   1100 			if(state.fixedFunction)
   1101 			{
   1102 				generator = new VertexPipeline(state);
   1103 			}
   1104 			else
   1105 			{
   1106 				generator = new VertexProgram(state, context->vertexShader);
   1107 			}
   1108 
   1109 			generator->generate();
   1110 			routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
   1111 			delete generator;
   1112 
   1113 			routineCache->add(state, routine);
   1114 		}
   1115 
   1116 		return routine;
   1117 	}
   1118 }
   1119