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::setPointSize(float pointSize)
    696 	{
    697 		point.pointSize = replicate(pointSize);
    698 	}
    699 
    700 	void VertexProcessor::setPointSizeMin(float pointSizeMin)
    701 	{
    702 		point.pointSizeMin = pointSizeMin;
    703 	}
    704 
    705 	void VertexProcessor::setPointSizeMax(float pointSizeMax)
    706 	{
    707 		point.pointSizeMax = pointSizeMax;
    708 	}
    709 
    710 	void VertexProcessor::setPointScaleA(float pointScaleA)
    711 	{
    712 		point.pointScaleA = pointScaleA;
    713 	}
    714 
    715 	void VertexProcessor::setPointScaleB(float pointScaleB)
    716 	{
    717 		point.pointScaleB = pointScaleB;
    718 	}
    719 
    720 	void VertexProcessor::setPointScaleC(float pointScaleC)
    721 	{
    722 		point.pointScaleC = pointScaleC;
    723 	}
    724 
    725 	void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
    726 	{
    727 		context->transformFeedbackQueryEnabled = enable;
    728 	}
    729 
    730 	void VertexProcessor::enableTransformFeedback(uint64_t enable)
    731 	{
    732 		context->transformFeedbackEnabled = enable;
    733 	}
    734 
    735 	const Matrix &VertexProcessor::getModelTransform(int i)
    736 	{
    737 		updateTransform();
    738 		return PBVM[i];
    739 	}
    740 
    741 	const Matrix &VertexProcessor::getViewTransform()
    742 	{
    743 		updateTransform();
    744 		return PBV;
    745 	}
    746 
    747 	bool VertexProcessor::isFixedFunction()
    748 	{
    749 		return !context->vertexShader;
    750 	}
    751 
    752 	void VertexProcessor::setTransform(const Matrix &M, int i)
    753 	{
    754 		ff.transformT[i][0][0] = M[0][0];
    755 		ff.transformT[i][0][1] = M[1][0];
    756 		ff.transformT[i][0][2] = M[2][0];
    757 		ff.transformT[i][0][3] = M[3][0];
    758 
    759 		ff.transformT[i][1][0] = M[0][1];
    760 		ff.transformT[i][1][1] = M[1][1];
    761 		ff.transformT[i][1][2] = M[2][1];
    762 		ff.transformT[i][1][3] = M[3][1];
    763 
    764 		ff.transformT[i][2][0] = M[0][2];
    765 		ff.transformT[i][2][1] = M[1][2];
    766 		ff.transformT[i][2][2] = M[2][2];
    767 		ff.transformT[i][2][3] = M[3][2];
    768 
    769 		ff.transformT[i][3][0] = M[0][3];
    770 		ff.transformT[i][3][1] = M[1][3];
    771 		ff.transformT[i][3][2] = M[2][3];
    772 		ff.transformT[i][3][3] = M[3][3];
    773 	}
    774 
    775 	void VertexProcessor::setCameraTransform(const Matrix &M, int i)
    776 	{
    777 		ff.cameraTransformT[i][0][0] = M[0][0];
    778 		ff.cameraTransformT[i][0][1] = M[1][0];
    779 		ff.cameraTransformT[i][0][2] = M[2][0];
    780 		ff.cameraTransformT[i][0][3] = M[3][0];
    781 
    782 		ff.cameraTransformT[i][1][0] = M[0][1];
    783 		ff.cameraTransformT[i][1][1] = M[1][1];
    784 		ff.cameraTransformT[i][1][2] = M[2][1];
    785 		ff.cameraTransformT[i][1][3] = M[3][1];
    786 
    787 		ff.cameraTransformT[i][2][0] = M[0][2];
    788 		ff.cameraTransformT[i][2][1] = M[1][2];
    789 		ff.cameraTransformT[i][2][2] = M[2][2];
    790 		ff.cameraTransformT[i][2][3] = M[3][2];
    791 
    792 		ff.cameraTransformT[i][3][0] = M[0][3];
    793 		ff.cameraTransformT[i][3][1] = M[1][3];
    794 		ff.cameraTransformT[i][3][2] = M[2][3];
    795 		ff.cameraTransformT[i][3][3] = M[3][3];
    796 	}
    797 
    798 	void VertexProcessor::setNormalTransform(const Matrix &M, int i)
    799 	{
    800 		ff.normalTransformT[i][0][0] = M[0][0];
    801 		ff.normalTransformT[i][0][1] = M[1][0];
    802 		ff.normalTransformT[i][0][2] = M[2][0];
    803 		ff.normalTransformT[i][0][3] = M[3][0];
    804 
    805 		ff.normalTransformT[i][1][0] = M[0][1];
    806 		ff.normalTransformT[i][1][1] = M[1][1];
    807 		ff.normalTransformT[i][1][2] = M[2][1];
    808 		ff.normalTransformT[i][1][3] = M[3][1];
    809 
    810 		ff.normalTransformT[i][2][0] = M[0][2];
    811 		ff.normalTransformT[i][2][1] = M[1][2];
    812 		ff.normalTransformT[i][2][2] = M[2][2];
    813 		ff.normalTransformT[i][2][3] = M[3][2];
    814 
    815 		ff.normalTransformT[i][3][0] = M[0][3];
    816 		ff.normalTransformT[i][3][1] = M[1][3];
    817 		ff.normalTransformT[i][3][2] = M[2][3];
    818 		ff.normalTransformT[i][3][3] = M[3][3];
    819 	}
    820 
    821 	void VertexProcessor::updateTransform()
    822 	{
    823 		if(!updateMatrix) return;
    824 
    825 		int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
    826 
    827 		if(updateProjectionMatrix)
    828 		{
    829 			PB = P * B;
    830 			PBV = PB * V;
    831 
    832 			for(int i = 0; i < activeMatrices; i++)
    833 			{
    834 				PBVM[i] = PBV * M[i];
    835 				updateModelMatrix[i] = false;
    836 			}
    837 
    838 			updateProjectionMatrix = false;
    839 			updateBaseMatrix = false;
    840 			updateViewMatrix = false;
    841 		}
    842 
    843 		if(updateBaseMatrix)
    844 		{
    845 			PB = P * B;
    846 			PBV = PB * V;
    847 
    848 			for(int i = 0; i < activeMatrices; i++)
    849 			{
    850 				PBVM[i] = PBV * M[i];
    851 				updateModelMatrix[i] = false;
    852 			}
    853 
    854 			updateBaseMatrix = false;
    855 			updateViewMatrix = false;
    856 		}
    857 
    858 		if(updateViewMatrix)
    859 		{
    860 			PBV = PB * V;
    861 
    862 			for(int i = 0; i < activeMatrices; i++)
    863 			{
    864 				PBVM[i] = PBV * M[i];
    865 				updateModelMatrix[i] = false;
    866 			}
    867 
    868 			updateViewMatrix = false;
    869 		}
    870 
    871 		for(int i = 0; i < activeMatrices; i++)
    872 		{
    873 			if(updateModelMatrix[i])
    874 			{
    875 				PBVM[i] = PBV * M[i];
    876 				updateModelMatrix[i] = false;
    877 			}
    878 		}
    879 
    880 		for(int i = 0; i < activeMatrices; i++)
    881 		{
    882 			setTransform(PBVM[i], i);
    883 			setCameraTransform(B * V * M[i], i);
    884 			setNormalTransform(~!(B * V * M[i]), i);
    885 		}
    886 
    887 		updateMatrix = false;
    888 	}
    889 
    890 	void VertexProcessor::setRoutineCacheSize(int cacheSize)
    891 	{
    892 		delete routineCache;
    893 		routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
    894 	}
    895 
    896 	const VertexProcessor::State VertexProcessor::update(DrawType drawType)
    897 	{
    898 		if(isFixedFunction())
    899 		{
    900 			updateTransform();
    901 
    902 			if(updateLighting)
    903 			{
    904 				for(int i = 0; i < 8; i++)
    905 				{
    906 					if(context->vertexLightActive(i))
    907 					{
    908 						// Light position in camera coordinates
    909 						setLightViewPosition(i, B * V * context->getLightPosition(i));
    910 					}
    911 				}
    912 
    913 				updateLighting = false;
    914 			}
    915 		}
    916 
    917 		State state;
    918 
    919 		if(context->vertexShader)
    920 		{
    921 			state.shaderID = context->vertexShader->getSerialID();
    922 		}
    923 		else
    924 		{
    925 			state.shaderID = 0;
    926 		}
    927 
    928 		state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
    929 		state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
    930 		state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
    931 		state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
    932 
    933 		state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
    934 		state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
    935 		state.vertexNormalActive = context->vertexNormalActive();
    936 		state.normalizeNormals = context->normalizeNormalsActive();
    937 		state.vertexLightingActive = context->vertexLightingActive();
    938 		state.diffuseActive = context->diffuseActive();
    939 		state.specularActive = context->specularActive();
    940 		state.vertexSpecularActive = context->vertexSpecularActive();
    941 
    942 		state.vertexLightActive = context->vertexLightActive(0) << 0 |
    943 		                          context->vertexLightActive(1) << 1 |
    944 		                          context->vertexLightActive(2) << 2 |
    945 		                          context->vertexLightActive(3) << 3 |
    946 		                          context->vertexLightActive(4) << 4 |
    947 		                          context->vertexLightActive(5) << 5 |
    948 		                          context->vertexLightActive(6) << 6 |
    949 		                          context->vertexLightActive(7) << 7;
    950 
    951 		state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
    952 		state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
    953 		state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
    954 		state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
    955 		state.fogActive = context->fogActive();
    956 		state.vertexFogMode = context->vertexFogModeActive();
    957 		state.rangeFogActive = context->rangeFogActive();
    958 		state.localViewerActive = context->localViewerActive();
    959 		state.pointSizeActive = context->pointSizeActive();
    960 		state.pointScaleActive = context->pointScaleActive();
    961 
    962 		state.preTransformed = context->preTransformed;
    963 		state.superSampling = context->getSuperSampleCount() > 1;
    964 		state.multiSampling = context->getMultiSampleCount() > 1;
    965 
    966 		state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
    967 		state.transformFeedbackEnabled = context->transformFeedbackEnabled;
    968 
    969 		// Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
    970 		//       which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
    971 		DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
    972 		state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
    973 
    974 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
    975 		{
    976 			state.input[i].type = context->input[i].type;
    977 			state.input[i].count = context->input[i].count;
    978 			state.input[i].normalized = context->input[i].normalized;
    979 			state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
    980 		}
    981 
    982 		if(!context->vertexShader)
    983 		{
    984 			for(int i = 0; i < 8; i++)
    985 			{
    986 			//	state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
    987 				state.textureState[i].texGenActive = context->texGenActive(i);
    988 				state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
    989 				state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
    990 			}
    991 		}
    992 		else
    993 		{
    994 			for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
    995 			{
    996 				if(context->vertexShader->usesSampler(i))
    997 				{
    998 					state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
    999 				}
   1000 			}
   1001 		}
   1002 
   1003 		if(context->vertexShader)   // FIXME: Also when pre-transformed?
   1004 		{
   1005 			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
   1006 			{
   1007 				state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
   1008 				state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
   1009 				state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
   1010 				state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
   1011 			}
   1012 		}
   1013 		else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
   1014 		{
   1015 			state.output[Pos].write = 0xF;
   1016 
   1017 			if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
   1018 			{
   1019 				state.output[C0].write = 0xF;
   1020 			}
   1021 
   1022 			if(context->specularActive())
   1023 			{
   1024 				state.output[C1].write = 0xF;
   1025 			}
   1026 
   1027 			for(int stage = 0; stage < 8; stage++)
   1028 			{
   1029 				if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
   1030 				if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
   1031 				if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
   1032 				if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
   1033 			}
   1034 
   1035 			if(context->fogActive())
   1036 			{
   1037 				state.output[Fog].xWrite = true;
   1038 			}
   1039 
   1040 			if(context->pointSizeActive())
   1041 			{
   1042 				state.output[Pts].yWrite = true;
   1043 			}
   1044 		}
   1045 		else
   1046 		{
   1047 			state.output[Pos].write = 0xF;
   1048 
   1049 			for(int i = 0; i < 2; i++)
   1050 			{
   1051 				if(context->input[Color0 + i])
   1052 				{
   1053 					state.output[C0 + i].write = 0xF;
   1054 				}
   1055 			}
   1056 
   1057 			for(int i = 0; i < 8; i++)
   1058 			{
   1059 				if(context->input[TexCoord0 + i])
   1060 				{
   1061 					state.output[T0 + i].write = 0xF;
   1062 				}
   1063 			}
   1064 
   1065 			if(context->input[PointSize])
   1066 			{
   1067 				state.output[Pts].yWrite = true;
   1068 			}
   1069 		}
   1070 
   1071 		if(context->vertexShaderModel() < 0x0300)
   1072 		{
   1073 			state.output[C0].clamp = 0xF;
   1074 			state.output[C1].clamp = 0xF;
   1075 			state.output[Fog].xClamp = true;
   1076 		}
   1077 
   1078 		state.hash = state.computeHash();
   1079 
   1080 		return state;
   1081 	}
   1082 
   1083 	Routine *VertexProcessor::routine(const State &state)
   1084 	{
   1085 		Routine *routine = routineCache->query(state);
   1086 
   1087 		if(!routine)   // Create one
   1088 		{
   1089 			VertexRoutine *generator = nullptr;
   1090 
   1091 			if(state.fixedFunction)
   1092 			{
   1093 				generator = new VertexPipeline(state);
   1094 			}
   1095 			else
   1096 			{
   1097 				generator = new VertexProgram(state, context->vertexShader);
   1098 			}
   1099 
   1100 			generator->generate();
   1101 			routine = (*generator)(L"VertexRoutine_%0.8X", state.shaderID);
   1102 			delete generator;
   1103 
   1104 			routineCache->add(state, routine);
   1105 		}
   1106 
   1107 		return routine;
   1108 	}
   1109 }
   1110