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