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