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