• 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/Debug.hpp"
24 
25 #include <string.h>
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 	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 
State()52 	VertexProcessor::State::State()
53 	{
54 		memset(this, 0, sizeof(State));
55 	}
56 
operator ==(const State & state) const57 	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 
TransformFeedbackInfo()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 
UniformBufferInfo()77 	VertexProcessor::UniformBufferInfo::UniformBufferInfo()
78 	{
79 		buffer = nullptr;
80 		offset = 0;
81 	}
82 
VertexProcessor(Context * context)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 
~VertexProcessor()125 	VertexProcessor::~VertexProcessor()
126 	{
127 		delete routineCache;
128 		routineCache = 0;
129 	}
130 
setInputStream(int index,const Stream & stream)131 	void VertexProcessor::setInputStream(int index, const Stream &stream)
132 	{
133 		context->input[index] = stream;
134 	}
135 
resetInputStreams(bool preTransformed)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 
setFloatConstant(unsigned int index,const float value[4])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 
setIntegerConstant(unsigned int index,const int integer[4])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 
setBooleanConstant(unsigned int index,int boolean)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 
setUniformBuffer(int index,sw::Resource * buffer,int offset)179 	void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
180 	{
181 		uniformBufferInfo[index].buffer = buffer;
182 		uniformBufferInfo[index].offset = offset;
183 	}
184 
lockUniformBuffers(byte ** u,sw::Resource * uniformBuffers[])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 
setTransformFeedbackBuffer(int index,sw::Resource * buffer,int offset,unsigned int reg,unsigned int row,unsigned int col,unsigned int stride)194 	void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, unsigned int stride)
195 	{
196 		transformFeedbackInfo[index].buffer = buffer;
197 		transformFeedbackInfo[index].offset = offset;
198 		transformFeedbackInfo[index].reg = reg;
199 		transformFeedbackInfo[index].row = row;
200 		transformFeedbackInfo[index].col = col;
201 		transformFeedbackInfo[index].stride = stride;
202 	}
203 
lockTransformFeedbackBuffers(byte ** t,unsigned int * v,unsigned int * r,unsigned int * c,unsigned int * s,sw::Resource * transformFeedbackBuffers[])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 
setModelMatrix(const Matrix & M,int i)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 
setViewMatrix(const Matrix & V)230 	void VertexProcessor::setViewMatrix(const Matrix &V)
231 	{
232 		this->V = V;
233 
234 		updateMatrix = true;
235 		updateViewMatrix = true;
236 	}
237 
setBaseMatrix(const Matrix & B)238 	void VertexProcessor::setBaseMatrix(const Matrix &B)
239 	{
240 		this->B = B;
241 
242 		updateMatrix = true;
243 		updateBaseMatrix = true;
244 	}
245 
setProjectionMatrix(const Matrix & P)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 
setLightingEnable(bool lightingEnable)255 	void VertexProcessor::setLightingEnable(bool lightingEnable)
256 	{
257 		context->setLightingEnable(lightingEnable);
258 
259 		updateLighting = true;
260 	}
261 
setLightEnable(unsigned int light,bool lightEnable)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 
setSpecularEnable(bool specularEnable)273 	void VertexProcessor::setSpecularEnable(bool specularEnable)
274 	{
275 		context->setSpecularEnable(specularEnable);
276 
277 		updateLighting = true;
278 	}
279 
setLightPosition(unsigned int light,const Point & lightPosition)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 
setLightDiffuse(unsigned int light,const Color<float> & lightDiffuse)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 
setLightSpecular(unsigned int light,const Color<float> & lightSpecular)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 
setLightAmbient(unsigned int light,const Color<float> & lightAmbient)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 
setLightAttenuation(unsigned int light,float constant,float linear,float quadratic)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 
setLightRange(unsigned int light,float lightRange)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 
setFogEnable(bool fogEnable)347 	void VertexProcessor::setFogEnable(bool fogEnable)
348 	{
349 		context->fogEnable = fogEnable;
350 	}
351 
setVertexFogMode(FogMode fogMode)352 	void VertexProcessor::setVertexFogMode(FogMode fogMode)
353 	{
354 		context->vertexFogMode = fogMode;
355 	}
356 
setInstanceID(int instanceID)357 	void VertexProcessor::setInstanceID(int instanceID)
358 	{
359 		context->instanceID = instanceID;
360 	}
361 
setColorVertexEnable(bool colorVertexEnable)362 	void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
363 	{
364 		context->setColorVertexEnable(colorVertexEnable);
365 	}
366 
setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)367 	void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
368 	{
369 		context->setDiffuseMaterialSource(diffuseMaterialSource);
370 	}
371 
setSpecularMaterialSource(MaterialSource specularMaterialSource)372 	void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
373 	{
374 		context->setSpecularMaterialSource(specularMaterialSource);
375 	}
376 
setAmbientMaterialSource(MaterialSource ambientMaterialSource)377 	void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
378 	{
379 		context->setAmbientMaterialSource(ambientMaterialSource);
380 	}
381 
setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)382 	void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
383 	{
384 		context->setEmissiveMaterialSource(emissiveMaterialSource);
385 	}
386 
setGlobalAmbient(const Color<float> & globalAmbient)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 
setMaterialEmission(const Color<float> & emission)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 
setMaterialAmbient(const Color<float> & materialAmbient)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 
setMaterialDiffuse(const Color<float> & diffuseColor)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 
setMaterialSpecular(const Color<float> & specularColor)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 
setMaterialShininess(float specularPower)427 	void VertexProcessor::setMaterialShininess(float specularPower)
428 	{
429 		ff.materialShininess = specularPower;
430 	}
431 
setLightViewPosition(unsigned int light,const Point & P)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 
setRangeFogEnable(bool enable)444 	void VertexProcessor::setRangeFogEnable(bool enable)
445 	{
446 		context->rangeFogEnable = enable;
447 	}
448 
setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)449 	void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
450 	{
451 		context->indexedVertexBlendEnable = indexedVertexBlendEnable;
452 	}
453 
setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)454 	void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
455 	{
456 		if(vertexBlendMatrixCount <= 4)
457 		{
458 			context->vertexBlendMatrixCount = vertexBlendMatrixCount;
459 		}
460 		else ASSERT(false);
461 	}
462 
setTextureWrap(unsigned int stage,int mask)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 
setTexGen(unsigned int stage,TexGen texGen)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 
setLocalViewer(bool localViewer)488 	void VertexProcessor::setLocalViewer(bool localViewer)
489 	{
490 		context->localViewer = localViewer;
491 	}
492 
setNormalizeNormals(bool normalizeNormals)493 	void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
494 	{
495 		context->normalizeNormals = normalizeNormals;
496 	}
497 
setTextureMatrix(int stage,const Matrix & T)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 
setTextureTransform(int stage,int count,bool project)509 	void VertexProcessor::setTextureTransform(int stage, int count, bool project)
510 	{
511 		context->textureTransformCount[stage] = count;
512 		context->textureTransformProject[stage] = project;
513 	}
514 
setTextureFilter(unsigned int sampler,FilterType textureFilter)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 
setMipmapFilter(unsigned int sampler,MipmapType mipmapFilter)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 
setGatherEnable(unsigned int sampler,bool enable)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 
setAddressingModeU(unsigned int sampler,AddressingMode addressMode)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 
setAddressingModeV(unsigned int sampler,AddressingMode addressMode)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 
setAddressingModeW(unsigned int sampler,AddressingMode addressMode)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 
setReadSRGB(unsigned int sampler,bool sRGB)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 
setMipmapLOD(unsigned int sampler,float bias)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 
setBorderColor(unsigned int sampler,const Color<float> & borderColor)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 
setMaxAnisotropy(unsigned int sampler,float maxAnisotropy)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 
setHighPrecisionFiltering(unsigned int sampler,bool highPrecisionFiltering)605 	void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
606 	{
607 		if(sampler < TEXTURE_IMAGE_UNITS)
608 		{
609 			context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
610 		}
611 		else ASSERT(false);
612 	}
613 
setSwizzleR(unsigned int sampler,SwizzleType swizzleR)614 	void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
615 	{
616 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
617 		{
618 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
619 		}
620 		else ASSERT(false);
621 	}
622 
setSwizzleG(unsigned int sampler,SwizzleType swizzleG)623 	void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
624 	{
625 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
626 		{
627 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
628 		}
629 		else ASSERT(false);
630 	}
631 
setSwizzleB(unsigned int sampler,SwizzleType swizzleB)632 	void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
633 	{
634 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
635 		{
636 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
637 		}
638 		else ASSERT(false);
639 	}
640 
setSwizzleA(unsigned int sampler,SwizzleType swizzleA)641 	void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
642 	{
643 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
644 		{
645 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
646 		}
647 		else ASSERT(false);
648 	}
649 
setCompareFunc(unsigned int sampler,CompareFunc compFunc)650 	void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
651 	{
652 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
653 		{
654 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
655 		}
656 		else ASSERT(false);
657 	}
658 
setBaseLevel(unsigned int sampler,int baseLevel)659 	void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
660 	{
661 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
662 		{
663 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
664 		}
665 		else ASSERT(false);
666 	}
667 
setMaxLevel(unsigned int sampler,int maxLevel)668 	void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
669 	{
670 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
671 		{
672 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
673 		}
674 		else ASSERT(false);
675 	}
676 
setMinLod(unsigned int sampler,float minLod)677 	void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
678 	{
679 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
680 		{
681 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
682 		}
683 		else ASSERT(false);
684 	}
685 
setMaxLod(unsigned int sampler,float maxLod)686 	void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
687 	{
688 		if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
689 		{
690 			context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
691 		}
692 		else ASSERT(false);
693 	}
694 
setSyncRequired(unsigned int sampler,bool isSincRequired)695 	void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
696 	{
697 		if(sampler < TEXTURE_IMAGE_UNITS)
698 		{
699 			context->sampler[sampler].setSyncRequired(isSincRequired);
700 		}
701 		else ASSERT(false);
702 	}
703 
setPointSize(float pointSize)704 	void VertexProcessor::setPointSize(float pointSize)
705 	{
706 		point.pointSize = replicate(pointSize);
707 	}
708 
setPointSizeMin(float pointSizeMin)709 	void VertexProcessor::setPointSizeMin(float pointSizeMin)
710 	{
711 		point.pointSizeMin = pointSizeMin;
712 	}
713 
setPointSizeMax(float pointSizeMax)714 	void VertexProcessor::setPointSizeMax(float pointSizeMax)
715 	{
716 		point.pointSizeMax = pointSizeMax;
717 	}
718 
setPointScaleA(float pointScaleA)719 	void VertexProcessor::setPointScaleA(float pointScaleA)
720 	{
721 		point.pointScaleA = pointScaleA;
722 	}
723 
setPointScaleB(float pointScaleB)724 	void VertexProcessor::setPointScaleB(float pointScaleB)
725 	{
726 		point.pointScaleB = pointScaleB;
727 	}
728 
setPointScaleC(float pointScaleC)729 	void VertexProcessor::setPointScaleC(float pointScaleC)
730 	{
731 		point.pointScaleC = pointScaleC;
732 	}
733 
setTransformFeedbackQueryEnabled(bool enable)734 	void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
735 	{
736 		context->transformFeedbackQueryEnabled = enable;
737 	}
738 
enableTransformFeedback(uint64_t enable)739 	void VertexProcessor::enableTransformFeedback(uint64_t enable)
740 	{
741 		context->transformFeedbackEnabled = enable;
742 	}
743 
getModelTransform(int i)744 	const Matrix &VertexProcessor::getModelTransform(int i)
745 	{
746 		updateTransform();
747 		return PBVM[i];
748 	}
749 
getViewTransform()750 	const Matrix &VertexProcessor::getViewTransform()
751 	{
752 		updateTransform();
753 		return PBV;
754 	}
755 
isFixedFunction()756 	bool VertexProcessor::isFixedFunction()
757 	{
758 		return !context->vertexShader;
759 	}
760 
setTransform(const Matrix & M,int i)761 	void VertexProcessor::setTransform(const Matrix &M, int i)
762 	{
763 		ff.transformT[i][0][0] = M[0][0];
764 		ff.transformT[i][0][1] = M[1][0];
765 		ff.transformT[i][0][2] = M[2][0];
766 		ff.transformT[i][0][3] = M[3][0];
767 
768 		ff.transformT[i][1][0] = M[0][1];
769 		ff.transformT[i][1][1] = M[1][1];
770 		ff.transformT[i][1][2] = M[2][1];
771 		ff.transformT[i][1][3] = M[3][1];
772 
773 		ff.transformT[i][2][0] = M[0][2];
774 		ff.transformT[i][2][1] = M[1][2];
775 		ff.transformT[i][2][2] = M[2][2];
776 		ff.transformT[i][2][3] = M[3][2];
777 
778 		ff.transformT[i][3][0] = M[0][3];
779 		ff.transformT[i][3][1] = M[1][3];
780 		ff.transformT[i][3][2] = M[2][3];
781 		ff.transformT[i][3][3] = M[3][3];
782 	}
783 
setCameraTransform(const Matrix & M,int i)784 	void VertexProcessor::setCameraTransform(const Matrix &M, int i)
785 	{
786 		ff.cameraTransformT[i][0][0] = M[0][0];
787 		ff.cameraTransformT[i][0][1] = M[1][0];
788 		ff.cameraTransformT[i][0][2] = M[2][0];
789 		ff.cameraTransformT[i][0][3] = M[3][0];
790 
791 		ff.cameraTransformT[i][1][0] = M[0][1];
792 		ff.cameraTransformT[i][1][1] = M[1][1];
793 		ff.cameraTransformT[i][1][2] = M[2][1];
794 		ff.cameraTransformT[i][1][3] = M[3][1];
795 
796 		ff.cameraTransformT[i][2][0] = M[0][2];
797 		ff.cameraTransformT[i][2][1] = M[1][2];
798 		ff.cameraTransformT[i][2][2] = M[2][2];
799 		ff.cameraTransformT[i][2][3] = M[3][2];
800 
801 		ff.cameraTransformT[i][3][0] = M[0][3];
802 		ff.cameraTransformT[i][3][1] = M[1][3];
803 		ff.cameraTransformT[i][3][2] = M[2][3];
804 		ff.cameraTransformT[i][3][3] = M[3][3];
805 	}
806 
setNormalTransform(const Matrix & M,int i)807 	void VertexProcessor::setNormalTransform(const Matrix &M, int i)
808 	{
809 		ff.normalTransformT[i][0][0] = M[0][0];
810 		ff.normalTransformT[i][0][1] = M[1][0];
811 		ff.normalTransformT[i][0][2] = M[2][0];
812 		ff.normalTransformT[i][0][3] = M[3][0];
813 
814 		ff.normalTransformT[i][1][0] = M[0][1];
815 		ff.normalTransformT[i][1][1] = M[1][1];
816 		ff.normalTransformT[i][1][2] = M[2][1];
817 		ff.normalTransformT[i][1][3] = M[3][1];
818 
819 		ff.normalTransformT[i][2][0] = M[0][2];
820 		ff.normalTransformT[i][2][1] = M[1][2];
821 		ff.normalTransformT[i][2][2] = M[2][2];
822 		ff.normalTransformT[i][2][3] = M[3][2];
823 
824 		ff.normalTransformT[i][3][0] = M[0][3];
825 		ff.normalTransformT[i][3][1] = M[1][3];
826 		ff.normalTransformT[i][3][2] = M[2][3];
827 		ff.normalTransformT[i][3][3] = M[3][3];
828 	}
829 
updateTransform()830 	void VertexProcessor::updateTransform()
831 	{
832 		if(!updateMatrix) return;
833 
834 		int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
835 
836 		if(updateProjectionMatrix)
837 		{
838 			PB = P * B;
839 			PBV = PB * V;
840 
841 			for(int i = 0; i < activeMatrices; i++)
842 			{
843 				PBVM[i] = PBV * M[i];
844 				updateModelMatrix[i] = false;
845 			}
846 
847 			updateProjectionMatrix = false;
848 			updateBaseMatrix = false;
849 			updateViewMatrix = false;
850 		}
851 
852 		if(updateBaseMatrix)
853 		{
854 			PB = P * B;
855 			PBV = PB * V;
856 
857 			for(int i = 0; i < activeMatrices; i++)
858 			{
859 				PBVM[i] = PBV * M[i];
860 				updateModelMatrix[i] = false;
861 			}
862 
863 			updateBaseMatrix = false;
864 			updateViewMatrix = false;
865 		}
866 
867 		if(updateViewMatrix)
868 		{
869 			PBV = PB * V;
870 
871 			for(int i = 0; i < activeMatrices; i++)
872 			{
873 				PBVM[i] = PBV * M[i];
874 				updateModelMatrix[i] = false;
875 			}
876 
877 			updateViewMatrix = false;
878 		}
879 
880 		for(int i = 0; i < activeMatrices; i++)
881 		{
882 			if(updateModelMatrix[i])
883 			{
884 				PBVM[i] = PBV * M[i];
885 				updateModelMatrix[i] = false;
886 			}
887 		}
888 
889 		for(int i = 0; i < activeMatrices; i++)
890 		{
891 			setTransform(PBVM[i], i);
892 			setCameraTransform(B * V * M[i], i);
893 			setNormalTransform(~!(B * V * M[i]), i);
894 		}
895 
896 		updateMatrix = false;
897 	}
898 
setRoutineCacheSize(int cacheSize)899 	void VertexProcessor::setRoutineCacheSize(int cacheSize)
900 	{
901 		delete routineCache;
902 		routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
903 	}
904 
update(DrawType drawType)905 	const VertexProcessor::State VertexProcessor::update(DrawType drawType)
906 	{
907 		if(isFixedFunction())
908 		{
909 			updateTransform();
910 
911 			if(updateLighting)
912 			{
913 				for(int i = 0; i < 8; i++)
914 				{
915 					if(context->vertexLightActive(i))
916 					{
917 						// Light position in camera coordinates
918 						setLightViewPosition(i, B * V * context->getLightPosition(i));
919 					}
920 				}
921 
922 				updateLighting = false;
923 			}
924 		}
925 
926 		State state;
927 
928 		if(context->vertexShader)
929 		{
930 			state.shaderID = context->vertexShader->getSerialID();
931 		}
932 		else
933 		{
934 			state.shaderID = 0;
935 		}
936 
937 		state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
938 		state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
939 		state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
940 		state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
941 
942 		state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
943 		state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
944 		state.vertexNormalActive = context->vertexNormalActive();
945 		state.normalizeNormals = context->normalizeNormalsActive();
946 		state.vertexLightingActive = context->vertexLightingActive();
947 		state.diffuseActive = context->diffuseActive();
948 		state.specularActive = context->specularActive();
949 		state.vertexSpecularActive = context->vertexSpecularActive();
950 
951 		state.vertexLightActive = context->vertexLightActive(0) << 0 |
952 		                          context->vertexLightActive(1) << 1 |
953 		                          context->vertexLightActive(2) << 2 |
954 		                          context->vertexLightActive(3) << 3 |
955 		                          context->vertexLightActive(4) << 4 |
956 		                          context->vertexLightActive(5) << 5 |
957 		                          context->vertexLightActive(6) << 6 |
958 		                          context->vertexLightActive(7) << 7;
959 
960 		state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
961 		state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
962 		state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
963 		state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
964 		state.fogActive = context->fogActive();
965 		state.vertexFogMode = context->vertexFogModeActive();
966 		state.rangeFogActive = context->rangeFogActive();
967 		state.localViewerActive = context->localViewerActive();
968 		state.pointSizeActive = context->pointSizeActive();
969 		state.pointScaleActive = context->pointScaleActive();
970 
971 		state.preTransformed = context->preTransformed;
972 		state.superSampling = context->getSuperSampleCount() > 1;
973 		state.multiSampling = context->getMultiSampleCount() > 1;
974 
975 		state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
976 		state.transformFeedbackEnabled = context->transformFeedbackEnabled;
977 
978 		// Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
979 		//       which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
980 		DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
981 		state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
982 
983 		for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
984 		{
985 			state.input[i].type = context->input[i].type;
986 			state.input[i].count = context->input[i].count;
987 			state.input[i].normalized = context->input[i].normalized;
988 			state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
989 		}
990 
991 		if(!context->vertexShader)
992 		{
993 			for(int i = 0; i < 8; i++)
994 			{
995 			//	state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
996 				state.textureState[i].texGenActive = context->texGenActive(i);
997 				state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
998 				state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
999 			}
1000 		}
1001 		else
1002 		{
1003 			for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
1004 			{
1005 				if(context->vertexShader->usesSampler(i))
1006 				{
1007 					state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
1008 				}
1009 			}
1010 		}
1011 
1012 		if(context->vertexShader)   // FIXME: Also when pre-transformed?
1013 		{
1014 			for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
1015 			{
1016 				state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
1017 				state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
1018 				state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
1019 				state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
1020 			}
1021 		}
1022 		else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
1023 		{
1024 			state.output[Pos].write = 0xF;
1025 
1026 			if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
1027 			{
1028 				state.output[C0].write = 0xF;
1029 			}
1030 
1031 			if(context->specularActive())
1032 			{
1033 				state.output[C1].write = 0xF;
1034 			}
1035 
1036 			for(int stage = 0; stage < 8; stage++)
1037 			{
1038 				if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
1039 				if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
1040 				if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
1041 				if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
1042 			}
1043 
1044 			if(context->fogActive())
1045 			{
1046 				state.output[Fog].xWrite = true;
1047 			}
1048 
1049 			if(context->pointSizeActive())
1050 			{
1051 				state.output[Pts].yWrite = true;
1052 			}
1053 		}
1054 		else
1055 		{
1056 			state.output[Pos].write = 0xF;
1057 
1058 			for(int i = 0; i < 2; i++)
1059 			{
1060 				if(context->input[Color0 + i])
1061 				{
1062 					state.output[C0 + i].write = 0xF;
1063 				}
1064 			}
1065 
1066 			for(int i = 0; i < 8; i++)
1067 			{
1068 				if(context->input[TexCoord0 + i])
1069 				{
1070 					state.output[T0 + i].write = 0xF;
1071 				}
1072 			}
1073 
1074 			if(context->input[PointSize])
1075 			{
1076 				state.output[Pts].yWrite = true;
1077 			}
1078 		}
1079 
1080 		if(context->vertexShaderModel() < 0x0300)
1081 		{
1082 			state.output[C0].clamp = 0xF;
1083 			state.output[C1].clamp = 0xF;
1084 			state.output[Fog].xClamp = true;
1085 		}
1086 
1087 		state.hash = state.computeHash();
1088 
1089 		return state;
1090 	}
1091 
routine(const State & state)1092 	Routine *VertexProcessor::routine(const State &state)
1093 	{
1094 		Routine *routine = routineCache->query(state);
1095 
1096 		if(!routine)   // Create one
1097 		{
1098 			VertexRoutine *generator = nullptr;
1099 
1100 			if(state.fixedFunction)
1101 			{
1102 				generator = new VertexPipeline(state);
1103 			}
1104 			else
1105 			{
1106 				generator = new VertexProgram(state, context->vertexShader);
1107 			}
1108 
1109 			generator->generate();
1110 			routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
1111 			delete generator;
1112 
1113 			routineCache->add(state, routine);
1114 		}
1115 
1116 		return routine;
1117 	}
1118 }
1119