blob: 516fdc5add081ca8777640340565ef4b87c7c0bf [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
Nicolas Capens5d961882016-01-01 23:18:14 -050041 for(unsigned int i = 0; i < sizeof(States) / 4; i++)
John Bauman89401822014-05-06 15:04:28 -040042 {
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 {
Nicolas Capens0f250902015-06-25 15:25:29 -0400119 for(int i = 0; i < VERTEX_ATTRIBUTES; 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
Alexis Hetu1d01aa32015-09-29 11:50:05 -0400548 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
549 {
550 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
551 {
552 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
553 }
554 else ASSERT(false);
555 }
556
557 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
558 {
559 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
560 {
561 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
562 }
563 else ASSERT(false);
564 }
565
566 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
567 {
568 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
569 {
570 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
571 }
572 else ASSERT(false);
573 }
574
575 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
576 {
577 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
578 {
579 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
580 }
581 else ASSERT(false);
582 }
583
John Bauman89401822014-05-06 15:04:28 -0400584 void VertexProcessor::setPointSize(float pointSize)
585 {
586 point.pointSize = replicate(pointSize);
587 }
588
589 void VertexProcessor::setPointSizeMin(float pointSizeMin)
590 {
591 point.pointSizeMin = pointSizeMin;
592 }
593
594 void VertexProcessor::setPointSizeMax(float pointSizeMax)
595 {
596 point.pointSizeMax = pointSizeMax;
597 }
598
599 void VertexProcessor::setPointScaleA(float pointScaleA)
600 {
601 point.pointScaleA = pointScaleA;
602 }
603
604 void VertexProcessor::setPointScaleB(float pointScaleB)
605 {
606 point.pointScaleB = pointScaleB;
607 }
608
609 void VertexProcessor::setPointScaleC(float pointScaleC)
610 {
611 point.pointScaleC = pointScaleC;
612 }
613
614 const Matrix &VertexProcessor::getModelTransform(int i)
615 {
616 updateTransform();
617 return PBVM[i];
618 }
619
620 const Matrix &VertexProcessor::getViewTransform()
621 {
622 updateTransform();
623 return PBV;
624 }
625
626 bool VertexProcessor::isFixedFunction()
627 {
628 return !context->vertexShader;
629 }
630
631 void VertexProcessor::setTransform(const Matrix &M, int i)
632 {
633 ff.transformT[i][0][0] = M[0][0];
634 ff.transformT[i][0][1] = M[1][0];
635 ff.transformT[i][0][2] = M[2][0];
636 ff.transformT[i][0][3] = M[3][0];
637
638 ff.transformT[i][1][0] = M[0][1];
639 ff.transformT[i][1][1] = M[1][1];
640 ff.transformT[i][1][2] = M[2][1];
641 ff.transformT[i][1][3] = M[3][1];
642
643 ff.transformT[i][2][0] = M[0][2];
644 ff.transformT[i][2][1] = M[1][2];
645 ff.transformT[i][2][2] = M[2][2];
646 ff.transformT[i][2][3] = M[3][2];
647
648 ff.transformT[i][3][0] = M[0][3];
649 ff.transformT[i][3][1] = M[1][3];
650 ff.transformT[i][3][2] = M[2][3];
651 ff.transformT[i][3][3] = M[3][3];
652 }
653
654 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
655 {
656 ff.cameraTransformT[i][0][0] = M[0][0];
657 ff.cameraTransformT[i][0][1] = M[1][0];
658 ff.cameraTransformT[i][0][2] = M[2][0];
659 ff.cameraTransformT[i][0][3] = M[3][0];
660
661 ff.cameraTransformT[i][1][0] = M[0][1];
662 ff.cameraTransformT[i][1][1] = M[1][1];
663 ff.cameraTransformT[i][1][2] = M[2][1];
664 ff.cameraTransformT[i][1][3] = M[3][1];
665
666 ff.cameraTransformT[i][2][0] = M[0][2];
667 ff.cameraTransformT[i][2][1] = M[1][2];
668 ff.cameraTransformT[i][2][2] = M[2][2];
669 ff.cameraTransformT[i][2][3] = M[3][2];
670
671 ff.cameraTransformT[i][3][0] = M[0][3];
672 ff.cameraTransformT[i][3][1] = M[1][3];
673 ff.cameraTransformT[i][3][2] = M[2][3];
674 ff.cameraTransformT[i][3][3] = M[3][3];
675 }
676
677 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
678 {
679 ff.normalTransformT[i][0][0] = M[0][0];
680 ff.normalTransformT[i][0][1] = M[1][0];
681 ff.normalTransformT[i][0][2] = M[2][0];
682 ff.normalTransformT[i][0][3] = M[3][0];
683
684 ff.normalTransformT[i][1][0] = M[0][1];
685 ff.normalTransformT[i][1][1] = M[1][1];
686 ff.normalTransformT[i][1][2] = M[2][1];
687 ff.normalTransformT[i][1][3] = M[3][1];
688
689 ff.normalTransformT[i][2][0] = M[0][2];
690 ff.normalTransformT[i][2][1] = M[1][2];
691 ff.normalTransformT[i][2][2] = M[2][2];
692 ff.normalTransformT[i][2][3] = M[3][2];
693
694 ff.normalTransformT[i][3][0] = M[0][3];
695 ff.normalTransformT[i][3][1] = M[1][3];
696 ff.normalTransformT[i][3][2] = M[2][3];
697 ff.normalTransformT[i][3][3] = M[3][3];
698 }
699
700 void VertexProcessor::updateTransform()
701 {
702 if(!updateMatrix) return;
703
704 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
705
706 if(updateProjectionMatrix)
707 {
708 PB = P * B;
709 PBV = PB * V;
710
711 for(int i = 0; i < activeMatrices; i++)
712 {
713 PBVM[i] = PBV * M[i];
714 updateModelMatrix[i] = false;
715 }
716
717 updateProjectionMatrix = false;
718 updateBaseMatrix = false;
719 updateViewMatrix = false;
720 }
721
722 if(updateBaseMatrix)
723 {
724 PB = P * B;
725 PBV = PB * V;
726
727 for(int i = 0; i < activeMatrices; i++)
728 {
729 PBVM[i] = PBV * M[i];
730 updateModelMatrix[i] = false;
731 }
732
733 updateBaseMatrix = false;
734 updateViewMatrix = false;
735 }
736
737 if(updateViewMatrix)
738 {
739 PBV = PB * V;
740
741 for(int i = 0; i < activeMatrices; i++)
742 {
743 PBVM[i] = PBV * M[i];
744 updateModelMatrix[i] = false;
745 }
746
747 updateViewMatrix = false;
748 }
749
750 for(int i = 0; i < activeMatrices; i++)
751 {
752 if(updateModelMatrix[i])
753 {
754 PBVM[i] = PBV * M[i];
755 updateModelMatrix[i] = false;
756 }
757 }
758
759 for(int i = 0; i < activeMatrices; i++)
760 {
761 setTransform(PBVM[i], i);
762 setCameraTransform(B * V * M[i], i);
763 setNormalTransform(~!(B * V * M[i]), i);
764 }
765
766 updateMatrix = false;
767 }
768
769 void VertexProcessor::setRoutineCacheSize(int cacheSize)
770 {
771 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400772 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400773 }
774
775 const VertexProcessor::State VertexProcessor::update()
776 {
777 if(isFixedFunction())
778 {
779 updateTransform();
780
781 if(updateLighting)
782 {
783 for(int i = 0; i < 8; i++)
784 {
785 if(context->vertexLightActive(i))
786 {
787 // Light position in camera coordinates
788 setLightViewPosition(i, B * V * context->getLightPosition(i));
789 }
790 }
791
792 updateLighting = false;
793 }
794 }
795
796 State state;
797
798 if(context->vertexShader)
799 {
John Bauman19bac1e2014-05-06 15:23:49 -0400800 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400801 }
802 else
803 {
John Bauman19bac1e2014-05-06 15:23:49 -0400804 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400805 }
806
807 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
808 state.shaderContainsTexldl = context->vertexShader ? context->vertexShader->containsTexldl() : false;
809 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
810 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
811
812 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
813 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
814 state.vertexNormalActive = context->vertexNormalActive();
815 state.normalizeNormals = context->normalizeNormalsActive();
816 state.vertexLightingActive = context->vertexLightingActive();
817 state.diffuseActive = context->diffuseActive();
818 state.specularActive = context->specularActive();
819 state.vertexSpecularActive = context->vertexSpecularActive();
820
821 state.vertexLightActive = context->vertexLightActive(0) << 0 |
822 context->vertexLightActive(1) << 1 |
823 context->vertexLightActive(2) << 2 |
824 context->vertexLightActive(3) << 3 |
825 context->vertexLightActive(4) << 4 |
826 context->vertexLightActive(5) << 5 |
827 context->vertexLightActive(6) << 6 |
828 context->vertexLightActive(7) << 7;
829
830 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
831 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
832 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
833 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
834 state.fogActive = context->fogActive();
835 state.vertexFogMode = context->vertexFogModeActive();
836 state.rangeFogActive = context->rangeFogActive();
837 state.localViewerActive = context->localViewerActive();
838 state.pointSizeActive = context->pointSizeActive();
839 state.pointScaleActive = context->pointScaleActive();
840
841 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400842 state.superSampling = context->getSuperSampleCount() > 1;
843 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400844
Nicolas Capens0f250902015-06-25 15:25:29 -0400845 for(int i = 0; i < VERTEX_ATTRIBUTES; i++)
John Bauman89401822014-05-06 15:04:28 -0400846 {
847 state.input[i].type = context->input[i].type;
848 state.input[i].count = context->input[i].count;
849 state.input[i].normalized = context->input[i].normalized;
850 }
851
852 if(!context->vertexShader)
853 {
854 for(int i = 0; i < 8; i++)
855 {
856 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
857 state.textureState[i].texGenActive = context->texGenActive(i);
858 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
859 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
860 }
861 }
862 else
863 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400864 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
John Bauman89401822014-05-06 15:04:28 -0400865 {
866 if(context->vertexShader->usesSampler(i))
867 {
Alexis Hetu0b65c5e2015-03-31 11:48:57 -0400868 state.samplerState[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
John Bauman89401822014-05-06 15:04:28 -0400869 }
870 }
871 }
872
873 if(context->vertexShader) // FIXME: Also when pre-transformed?
874 {
875 for(int i = 0; i < 12; i++)
876 {
877 state.output[i].xWrite = context->vertexShader->output[i][0].active();
878 state.output[i].yWrite = context->vertexShader->output[i][1].active();
879 state.output[i].zWrite = context->vertexShader->output[i][2].active();
880 state.output[i].wWrite = context->vertexShader->output[i][3].active();
881 }
882 }
883 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
884 {
885 state.output[Pos].write = 0xF;
886
887 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
888 {
889 state.output[D0].write = 0xF;
890 }
891
892 if(context->specularActive())
893 {
894 state.output[D1].write = 0xF;
895 }
896
897 for(int stage = 0; stage < 8; stage++)
898 {
John Bauman19bac1e2014-05-06 15:23:49 -0400899 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
900 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
901 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
902 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400903 }
904
905 if(context->fogActive())
906 {
907 state.output[Fog].xWrite = true;
908 }
909
910 if(context->pointSizeActive())
911 {
912 state.output[Pts].yWrite = true;
913 }
914 }
915 else
916 {
917 state.output[Pos].write = 0xF;
918
919 for(int i = 0; i < 2; i++)
920 {
921 if(context->input[Color0 + i])
922 {
923 state.output[D0 + i].write = 0xF;
924 }
925 }
926
927 for(int i = 0; i < 8; i++)
928 {
929 if(context->input[TexCoord0 + i])
930 {
931 state.output[T0 + i].write = 0xF;
932 }
933 }
934
John Bauman66b8ab22014-05-06 15:57:45 -0400935 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400936 {
937 state.output[Pts].yWrite = true;
938 }
939 }
940
941 if(context->vertexShaderVersion() < 0x0300)
942 {
943 state.output[D0].clamp = 0xF;
944 state.output[D1].clamp = 0xF;
945 state.output[Fog].xClamp = true;
946 }
947
948 state.hash = state.computeHash();
949
950 return state;
951 }
952
953 Routine *VertexProcessor::routine(const State &state)
954 {
955 Routine *routine = routineCache->query(state);
956
957 if(!routine) // Create one
958 {
959 VertexRoutine *generator = 0;
960
961 if(state.fixedFunction)
962 {
963 generator = new VertexPipeline(state);
964 }
965 else
966 {
967 generator = new VertexProgram(state, context->vertexShader);
968 }
969
970 generator->generate();
971 routine = generator->getRoutine();
972 delete generator;
973
974 routineCache->add(state, routine);
975 }
976
977 return routine;
978 }
979}