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