blob: d5a394c5165b596db90d1f68d16eca4129c78a2d [file] [log] [blame]
John Bauman89401822014-05-06 15:04:28 -04001// SwiftShader Software Renderer
2//
John Bauman19bac1e2014-05-06 15:23:49 -04003// Copyright(c) 2005-2012 TransGaming Inc.
John Bauman89401822014-05-06 15:04:28 -04004//
5// All rights reserved. No part of this software may be copied, distributed, transmitted,
6// transcribed, stored in a retrieval system, translated into any human or computer
7// language by any means, or disclosed to third parties without the explicit written
8// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
9// or implied, including but not limited to any patent rights, are granted to you.
10//
11
12#include "VertexProcessor.hpp"
13
John Bauman89401822014-05-06 15:04:28 -040014#include "Math.hpp"
15#include "VertexPipeline.hpp"
16#include "VertexProgram.hpp"
17#include "VertexShader.hpp"
18#include "PixelShader.hpp"
19#include "Constants.hpp"
20#include "Debug.hpp"
21
John Bauman66b8ab22014-05-06 15:57:45 -040022#include <string.h>
John Bauman89401822014-05-06 15:04:28 -040023
24namespace sw
25{
John Bauman66b8ab22014-05-06 15:57:45 -040026 bool precacheVertex = false;
27
John Bauman89401822014-05-06 15:04:28 -040028 void VertexCache::clear()
29 {
30 for(int i = 0; i < 16; i++)
31 {
32 tag[i] = 0x80000000;
33 }
34 }
35
36 unsigned int VertexProcessor::States::computeHash()
37 {
38 unsigned int *state = (unsigned int*)this;
39 unsigned int hash = 0;
40
41 for(int i = 0; i < sizeof(States) / 4; i++)
42 {
43 hash ^= state[i];
44 }
45
46 return hash;
47 }
48
49 VertexProcessor::State::State()
50 {
51 memset(this, 0, sizeof(State));
52 }
53
54 bool VertexProcessor::State::operator==(const State &state) const
55 {
56 if(hash != state.hash)
57 {
58 return false;
59 }
60
61 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
62 }
63
64 VertexProcessor::VertexProcessor(Context *context) : context(context)
65 {
66 for(int i = 0; i < 12; i++)
67 {
68 M[i] = 1;
69 }
70
71 V = 1;
72 B = 1;
73 P = 0;
74 PB = 0;
75 PBV = 0;
76
77 for(int i = 0; i < 12; i++)
78 {
79 PBVM[i] = 0;
80 }
81
82 setLightingEnable(true);
83 setSpecularEnable(false);
84
85 for(int i = 0; i < 8; i++)
86 {
87 setLightEnable(i, false);
88 setLightPosition(i, 0);
89 }
90
91 updateMatrix = true;
92 updateViewMatrix = true;
93 updateBaseMatrix = true;
94 updateProjectionMatrix = true;
95 updateLighting = true;
96
97 for(int i = 0; i < 12; i++)
98 {
99 updateModelMatrix[i] = true;
100 }
101
102 routineCache = 0;
103 setRoutineCacheSize(1024);
104 }
105
106 VertexProcessor::~VertexProcessor()
107 {
108 delete routineCache;
109 routineCache = 0;
110 }
111
112 void VertexProcessor::setInputStream(int index, const Stream &stream)
113 {
114 context->input[index] = stream;
115 }
116
John Bauman89401822014-05-06 15:04:28 -0400117 void VertexProcessor::resetInputStreams(bool preTransformed)
118 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400119 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400120 {
121 context->input[i].defaults();
122 }
123
124 context->preTransformed = preTransformed;
125 }
126
127 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
128 {
129 if(index < 256)
130 {
131 c[index][0] = value[0];
132 c[index][1] = value[1];
133 c[index][2] = value[2];
134 c[index][3] = value[3];
135 }
136 else ASSERT(false);
137 }
138
139 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
140 {
141 if(index < 16)
142 {
143 i[index][0] = integer[0];
144 i[index][1] = integer[1];
145 i[index][2] = integer[2];
146 i[index][3] = integer[3];
147 }
148 else ASSERT(false);
149 }
150
151 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
152 {
153 if(index < 16)
154 {
155 b[index] = boolean != 0;
156 }
157 else ASSERT(false);
158 }
159
160 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
161 {
162 if(i < 12)
163 {
164 this->M[i] = M;
165
166 updateMatrix = true;
167 updateModelMatrix[i] = true;
168 updateLighting = true;
169 }
170 else ASSERT(false);
171 }
172
173 void VertexProcessor::setViewMatrix(const Matrix &V)
174 {
175 this->V = V;
176
177 updateMatrix = true;
178 updateViewMatrix = true;
179 }
180
181 void VertexProcessor::setBaseMatrix(const Matrix &B)
182 {
183 this->B = B;
184
185 updateMatrix = true;
186 updateBaseMatrix = true;
187 }
188
189 void VertexProcessor::setProjectionMatrix(const Matrix &P)
190 {
191 this->P = P;
192 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
193
194 updateMatrix = true;
195 updateProjectionMatrix = true;
196 }
197
198 void VertexProcessor::setLightingEnable(bool lightingEnable)
199 {
200 context->setLightingEnable(lightingEnable);
201
202 updateLighting = true;
203 }
204
205 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
206 {
207 if(light < 8)
208 {
209 context->setLightEnable(light, lightEnable);
210 }
211 else ASSERT(false);
212
213 updateLighting = true;
214 }
215
216 void VertexProcessor::setSpecularEnable(bool specularEnable)
217 {
218 context->setSpecularEnable(specularEnable);
219
220 updateLighting = true;
221 }
222
223 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
224 {
225 if(light < 8)
226 {
227 context->setLightPosition(light, lightPosition);
228 }
229 else ASSERT(false);
230
231 updateLighting = true;
232 }
233
234 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
235 {
236 if(light < 8)
237 {
238 ff.lightDiffuse[light][0] = lightDiffuse.r;
239 ff.lightDiffuse[light][1] = lightDiffuse.g;
240 ff.lightDiffuse[light][2] = lightDiffuse.b;
241 ff.lightDiffuse[light][3] = lightDiffuse.a;
242 }
243 else ASSERT(false);
244 }
245
246 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
247 {
248 if(light < 8)
249 {
250 ff.lightSpecular[light][0] = lightSpecular.r;
251 ff.lightSpecular[light][1] = lightSpecular.g;
252 ff.lightSpecular[light][2] = lightSpecular.b;
253 ff.lightSpecular[light][3] = lightSpecular.a;
254 }
255 else ASSERT(false);
256 }
257
258 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
259 {
260 if(light < 8)
261 {
262 ff.lightAmbient[light][0] = lightAmbient.r;
263 ff.lightAmbient[light][1] = lightAmbient.g;
264 ff.lightAmbient[light][2] = lightAmbient.b;
265 ff.lightAmbient[light][3] = lightAmbient.a;
266 }
267 else ASSERT(false);
268 }
269
270 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
271 {
272 if(light < 8)
273 {
274 ff.attenuationConstant[light] = replicate(constant);
275 ff.attenuationLinear[light] = replicate(linear);
276 ff.attenuationQuadratic[light] = replicate(quadratic);
277 }
278 else ASSERT(false);
279 }
280
281 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
282 {
283 if(light < 8)
284 {
285 ff.lightRange[light] = lightRange;
286 }
287 else ASSERT(false);
288 }
289
290 void VertexProcessor::setFogEnable(bool fogEnable)
291 {
292 context->fogEnable = fogEnable;
293 }
294
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400295 void VertexProcessor::setVertexFogMode(FogMode fogMode)
John Bauman89401822014-05-06 15:04:28 -0400296 {
297 context->vertexFogMode = fogMode;
298 }
299
Alexis Hetu6743bbf2015-04-21 17:06:14 -0400300 void VertexProcessor::setInstanceID(int instanceID)
301 {
302 context->instanceID = instanceID;
303 }
304
John Bauman89401822014-05-06 15:04:28 -0400305 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
306 {
307 context->setColorVertexEnable(colorVertexEnable);
308 }
309
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400310 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400311 {
312 context->setDiffuseMaterialSource(diffuseMaterialSource);
313 }
314
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400315 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400316 {
317 context->setSpecularMaterialSource(specularMaterialSource);
318 }
319
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400320 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400321 {
322 context->setAmbientMaterialSource(ambientMaterialSource);
323 }
324
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400325 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400326 {
327 context->setEmissiveMaterialSource(emissiveMaterialSource);
328 }
329
330 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
331 {
332 ff.globalAmbient[0] = globalAmbient.r;
333 ff.globalAmbient[1] = globalAmbient.g;
334 ff.globalAmbient[2] = globalAmbient.b;
335 ff.globalAmbient[3] = globalAmbient.a;
336 }
337
338 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
339 {
340 ff.materialEmission[0] = emission.r;
341 ff.materialEmission[1] = emission.g;
342 ff.materialEmission[2] = emission.b;
343 ff.materialEmission[3] = emission.a;
344 }
345
346 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
347 {
348 ff.materialAmbient[0] = materialAmbient.r;
349 ff.materialAmbient[1] = materialAmbient.g;
350 ff.materialAmbient[2] = materialAmbient.b;
351 ff.materialAmbient[3] = materialAmbient.a;
352 }
353
354 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
355 {
356 ff.materialDiffuse[0] = diffuseColor.r;
357 ff.materialDiffuse[1] = diffuseColor.g;
358 ff.materialDiffuse[2] = diffuseColor.b;
359 ff.materialDiffuse[3] = diffuseColor.a;
360 }
361
362 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
363 {
364 ff.materialSpecular[0] = specularColor.r;
365 ff.materialSpecular[1] = specularColor.g;
366 ff.materialSpecular[2] = specularColor.b;
367 ff.materialSpecular[3] = specularColor.a;
368 }
369
370 void VertexProcessor::setMaterialShininess(float specularPower)
371 {
372 ff.materialShininess = specularPower;
373 }
374
375 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
376 {
377 if(light < 8)
378 {
379 ff.lightPosition[light][0] = P.x;
380 ff.lightPosition[light][1] = P.y;
381 ff.lightPosition[light][2] = P.z;
382 ff.lightPosition[light][3] = 1;
383 }
384 else ASSERT(false);
385 }
386
387 void VertexProcessor::setRangeFogEnable(bool enable)
388 {
389 context->rangeFogEnable = enable;
390 }
391
392 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
393 {
394 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
395 }
396
397 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
398 {
399 if(vertexBlendMatrixCount <= 4)
400 {
401 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
402 }
403 else ASSERT(false);
404 }
405
406 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
407 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400408 if(stage < TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400409 {
410 context->textureWrap[stage] = mask;
411 }
412 else ASSERT(false);
413
414 context->textureWrapActive = false;
415
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400416 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400417 {
418 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
419 }
420 }
421
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400422 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400423 {
424 if(stage < 8)
425 {
426 context->texGen[stage] = texGen;
427 }
428 else ASSERT(false);
429 }
430
431 void VertexProcessor::setLocalViewer(bool localViewer)
432 {
433 context->localViewer = localViewer;
434 }
435
436 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
437 {
438 context->normalizeNormals = normalizeNormals;
439 }
440
441 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
442 {
443 for(int i = 0; i < 4; i++)
444 {
445 for(int j = 0; j < 4; j++)
446 {
447 ff.textureTransform[stage][i][j] = T[i][j];
448 }
449 }
450 }
451
452 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
453 {
454 context->textureTransformCount[stage] = count;
455 context->textureTransformProject[stage] = project;
456 }
457
458 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
459 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400460 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400461 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400462 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
John Bauman89401822014-05-06 15:04:28 -0400463 }
464 else ASSERT(false);
465 }
466
467 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
468 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400469 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400470 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400471 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
John Bauman89401822014-05-06 15:04:28 -0400472 }
473 else ASSERT(false);
474 }
475
476 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
477 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400478 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400479 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400480 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
John Bauman89401822014-05-06 15:04:28 -0400481 }
482 else ASSERT(false);
483 }
484
485 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
486 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400487 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400488 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400489 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400490 }
491 else ASSERT(false);
492 }
493
494 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
495 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400496 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400497 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400498 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400499 }
500 else ASSERT(false);
501 }
502
503 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
504 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400505 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400506 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400507 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
John Bauman89401822014-05-06 15:04:28 -0400508 }
509 else ASSERT(false);
510 }
511
512 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
513 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400514 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400515 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400516 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
John Bauman89401822014-05-06 15:04:28 -0400517 }
518 else ASSERT(false);
519 }
520
521 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
522 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400523 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400524 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400525 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
John Bauman89401822014-05-06 15:04:28 -0400526 }
527 else ASSERT(false);
528 }
529
530 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
531 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400532 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400533 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400534 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
John Bauman89401822014-05-06 15:04:28 -0400535 }
536 else ASSERT(false);
537 }
538
Alexis Hetu617a5d52014-11-13 10:56:20 -0500539 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
John Bauman89401822014-05-06 15:04:28 -0400540 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400541 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
John Bauman89401822014-05-06 15:04:28 -0400542 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400543 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
John Bauman89401822014-05-06 15:04:28 -0400544 }
545 else ASSERT(false);
546 }
547
548 void VertexProcessor::setPointSize(float pointSize)
549 {
550 point.pointSize = replicate(pointSize);
551 }
552
553 void VertexProcessor::setPointSizeMin(float pointSizeMin)
554 {
555 point.pointSizeMin = pointSizeMin;
556 }
557
558 void VertexProcessor::setPointSizeMax(float pointSizeMax)
559 {
560 point.pointSizeMax = pointSizeMax;
561 }
562
563 void VertexProcessor::setPointScaleA(float pointScaleA)
564 {
565 point.pointScaleA = pointScaleA;
566 }
567
568 void VertexProcessor::setPointScaleB(float pointScaleB)
569 {
570 point.pointScaleB = pointScaleB;
571 }
572
573 void VertexProcessor::setPointScaleC(float pointScaleC)
574 {
575 point.pointScaleC = pointScaleC;
576 }
577
578 const Matrix &VertexProcessor::getModelTransform(int i)
579 {
580 updateTransform();
581 return PBVM[i];
582 }
583
584 const Matrix &VertexProcessor::getViewTransform()
585 {
586 updateTransform();
587 return PBV;
588 }
589
590 bool VertexProcessor::isFixedFunction()
591 {
592 return !context->vertexShader;
593 }
594
595 void VertexProcessor::setTransform(const Matrix &M, int i)
596 {
597 ff.transformT[i][0][0] = M[0][0];
598 ff.transformT[i][0][1] = M[1][0];
599 ff.transformT[i][0][2] = M[2][0];
600 ff.transformT[i][0][3] = M[3][0];
601
602 ff.transformT[i][1][0] = M[0][1];
603 ff.transformT[i][1][1] = M[1][1];
604 ff.transformT[i][1][2] = M[2][1];
605 ff.transformT[i][1][3] = M[3][1];
606
607 ff.transformT[i][2][0] = M[0][2];
608 ff.transformT[i][2][1] = M[1][2];
609 ff.transformT[i][2][2] = M[2][2];
610 ff.transformT[i][2][3] = M[3][2];
611
612 ff.transformT[i][3][0] = M[0][3];
613 ff.transformT[i][3][1] = M[1][3];
614 ff.transformT[i][3][2] = M[2][3];
615 ff.transformT[i][3][3] = M[3][3];
616 }
617
618 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
619 {
620 ff.cameraTransformT[i][0][0] = M[0][0];
621 ff.cameraTransformT[i][0][1] = M[1][0];
622 ff.cameraTransformT[i][0][2] = M[2][0];
623 ff.cameraTransformT[i][0][3] = M[3][0];
624
625 ff.cameraTransformT[i][1][0] = M[0][1];
626 ff.cameraTransformT[i][1][1] = M[1][1];
627 ff.cameraTransformT[i][1][2] = M[2][1];
628 ff.cameraTransformT[i][1][3] = M[3][1];
629
630 ff.cameraTransformT[i][2][0] = M[0][2];
631 ff.cameraTransformT[i][2][1] = M[1][2];
632 ff.cameraTransformT[i][2][2] = M[2][2];
633 ff.cameraTransformT[i][2][3] = M[3][2];
634
635 ff.cameraTransformT[i][3][0] = M[0][3];
636 ff.cameraTransformT[i][3][1] = M[1][3];
637 ff.cameraTransformT[i][3][2] = M[2][3];
638 ff.cameraTransformT[i][3][3] = M[3][3];
639 }
640
641 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
642 {
643 ff.normalTransformT[i][0][0] = M[0][0];
644 ff.normalTransformT[i][0][1] = M[1][0];
645 ff.normalTransformT[i][0][2] = M[2][0];
646 ff.normalTransformT[i][0][3] = M[3][0];
647
648 ff.normalTransformT[i][1][0] = M[0][1];
649 ff.normalTransformT[i][1][1] = M[1][1];
650 ff.normalTransformT[i][1][2] = M[2][1];
651 ff.normalTransformT[i][1][3] = M[3][1];
652
653 ff.normalTransformT[i][2][0] = M[0][2];
654 ff.normalTransformT[i][2][1] = M[1][2];
655 ff.normalTransformT[i][2][2] = M[2][2];
656 ff.normalTransformT[i][2][3] = M[3][2];
657
658 ff.normalTransformT[i][3][0] = M[0][3];
659 ff.normalTransformT[i][3][1] = M[1][3];
660 ff.normalTransformT[i][3][2] = M[2][3];
661 ff.normalTransformT[i][3][3] = M[3][3];
662 }
663
664 void VertexProcessor::updateTransform()
665 {
666 if(!updateMatrix) return;
667
668 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
669
670 if(updateProjectionMatrix)
671 {
672 PB = P * B;
673 PBV = PB * V;
674
675 for(int i = 0; i < activeMatrices; i++)
676 {
677 PBVM[i] = PBV * M[i];
678 updateModelMatrix[i] = false;
679 }
680
681 updateProjectionMatrix = false;
682 updateBaseMatrix = false;
683 updateViewMatrix = false;
684 }
685
686 if(updateBaseMatrix)
687 {
688 PB = P * B;
689 PBV = PB * V;
690
691 for(int i = 0; i < activeMatrices; i++)
692 {
693 PBVM[i] = PBV * M[i];
694 updateModelMatrix[i] = false;
695 }
696
697 updateBaseMatrix = false;
698 updateViewMatrix = false;
699 }
700
701 if(updateViewMatrix)
702 {
703 PBV = PB * V;
704
705 for(int i = 0; i < activeMatrices; i++)
706 {
707 PBVM[i] = PBV * M[i];
708 updateModelMatrix[i] = false;
709 }
710
711 updateViewMatrix = false;
712 }
713
714 for(int i = 0; i < activeMatrices; i++)
715 {
716 if(updateModelMatrix[i])
717 {
718 PBVM[i] = PBV * M[i];
719 updateModelMatrix[i] = false;
720 }
721 }
722
723 for(int i = 0; i < activeMatrices; i++)
724 {
725 setTransform(PBVM[i], i);
726 setCameraTransform(B * V * M[i], i);
727 setNormalTransform(~!(B * V * M[i]), i);
728 }
729
730 updateMatrix = false;
731 }
732
733 void VertexProcessor::setRoutineCacheSize(int cacheSize)
734 {
735 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400736 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400737 }
738
739 const VertexProcessor::State VertexProcessor::update()
740 {
741 if(isFixedFunction())
742 {
743 updateTransform();
744
745 if(updateLighting)
746 {
747 for(int i = 0; i < 8; i++)
748 {
749 if(context->vertexLightActive(i))
750 {
751 // Light position in camera coordinates
752 setLightViewPosition(i, B * V * context->getLightPosition(i));
753 }
754 }
755
756 updateLighting = false;
757 }
758 }
759
760 State state;
761
762 if(context->vertexShader)
763 {
John Bauman19bac1e2014-05-06 15:23:49 -0400764 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400765 }
766 else
767 {
John Bauman19bac1e2014-05-06 15:23:49 -0400768 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400769 }
770
771 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
772 state.shaderContainsTexldl = context->vertexShader ? context->vertexShader->containsTexldl() : false;
773 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
774 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
775
776 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
777 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
778 state.vertexNormalActive = context->vertexNormalActive();
779 state.normalizeNormals = context->normalizeNormalsActive();
780 state.vertexLightingActive = context->vertexLightingActive();
781 state.diffuseActive = context->diffuseActive();
782 state.specularActive = context->specularActive();
783 state.vertexSpecularActive = context->vertexSpecularActive();
784
785 state.vertexLightActive = context->vertexLightActive(0) << 0 |
786 context->vertexLightActive(1) << 1 |
787 context->vertexLightActive(2) << 2 |
788 context->vertexLightActive(3) << 3 |
789 context->vertexLightActive(4) << 4 |
790 context->vertexLightActive(5) << 5 |
791 context->vertexLightActive(6) << 6 |
792 context->vertexLightActive(7) << 7;
793
794 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
795 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
796 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
797 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
798 state.fogActive = context->fogActive();
799 state.vertexFogMode = context->vertexFogModeActive();
800 state.rangeFogActive = context->rangeFogActive();
801 state.localViewerActive = context->localViewerActive();
802 state.pointSizeActive = context->pointSizeActive();
803 state.pointScaleActive = context->pointScaleActive();
804
805 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400806 state.superSampling = context->getSuperSampleCount() > 1;
807 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400808
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400809 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400810 {
811 state.input[i].type = context->input[i].type;
812 state.input[i].count = context->input[i].count;
813 state.input[i].normalized = context->input[i].normalized;
814 }
815
816 if(!context->vertexShader)
817 {
818 for(int i = 0; i < 8; i++)
819 {
820 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
821 state.textureState[i].texGenActive = context->texGenActive(i);
822 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
823 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
824 }
825 }
826 else
827 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400828 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400829 {
830 if(context->vertexShader->usesSampler(i))
831 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400832 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400833 }
834 }
835 }
836
837 if(context->vertexShader) // FIXME: Also when pre-transformed?
838 {
839 for(int i = 0; i < 12; i++)
840 {
841 state.output[i].xWrite = context->vertexShader->output[i][0].active();
842 state.output[i].yWrite = context->vertexShader->output[i][1].active();
843 state.output[i].zWrite = context->vertexShader->output[i][2].active();
844 state.output[i].wWrite = context->vertexShader->output[i][3].active();
845 }
846 }
847 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
848 {
849 state.output[Pos].write = 0xF;
850
851 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
852 {
853 state.output[D0].write = 0xF;
854 }
855
856 if(context->specularActive())
857 {
858 state.output[D1].write = 0xF;
859 }
860
861 for(int stage = 0; stage < 8; stage++)
862 {
John Bauman19bac1e2014-05-06 15:23:49 -0400863 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
864 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
865 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
866 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400867 }
868
869 if(context->fogActive())
870 {
871 state.output[Fog].xWrite = true;
872 }
873
874 if(context->pointSizeActive())
875 {
876 state.output[Pts].yWrite = true;
877 }
878 }
879 else
880 {
881 state.output[Pos].write = 0xF;
882
883 for(int i = 0; i < 2; i++)
884 {
885 if(context->input[Color0 + i])
886 {
887 state.output[D0 + i].write = 0xF;
888 }
889 }
890
891 for(int i = 0; i < 8; i++)
892 {
893 if(context->input[TexCoord0 + i])
894 {
895 state.output[T0 + i].write = 0xF;
896 }
897 }
898
John Bauman66b8ab22014-05-06 15:57:45 -0400899 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400900 {
901 state.output[Pts].yWrite = true;
902 }
903 }
904
905 if(context->vertexShaderVersion() < 0x0300)
906 {
907 state.output[D0].clamp = 0xF;
908 state.output[D1].clamp = 0xF;
909 state.output[Fog].xClamp = true;
910 }
911
912 state.hash = state.computeHash();
913
914 return state;
915 }
916
917 Routine *VertexProcessor::routine(const State &state)
918 {
919 Routine *routine = routineCache->query(state);
920
921 if(!routine) // Create one
922 {
923 VertexRoutine *generator = 0;
924
925 if(state.fixedFunction)
926 {
927 generator = new VertexPipeline(state);
928 }
929 else
930 {
931 generator = new VertexProgram(state, context->vertexShader);
932 }
933
934 generator->generate();
935 routine = generator->getRoutine();
936 delete generator;
937
938 routineCache->add(state, routine);
939 }
940
941 return routine;
942 }
943}