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