blob: 6f23be7acd06fd3b71825a946497c375efd3bc53 [file] [log] [blame]
John Bauman89401822014-05-06 15:04:28 -04001// SwiftShader Software Renderer
2//
3// Copyright(c) 2005-2011 TransGaming Inc.
4//
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
14#include "Viewport.hpp"
15#include "Math.hpp"
16#include "VertexPipeline.hpp"
17#include "VertexProgram.hpp"
18#include "VertexShader.hpp"
19#include "PixelShader.hpp"
20#include "Constants.hpp"
21#include "Debug.hpp"
22
23#include <malloc.h>
24
25namespace sw
26{
27 void VertexCache::clear()
28 {
29 for(int i = 0; i < 16; i++)
30 {
31 tag[i] = 0x80000000;
32 }
33 }
34
35 unsigned int VertexProcessor::States::computeHash()
36 {
37 unsigned int *state = (unsigned int*)this;
38 unsigned int hash = 0;
39
40 for(int i = 0; i < sizeof(States) / 4; i++)
41 {
42 hash ^= state[i];
43 }
44
45 return hash;
46 }
47
48 VertexProcessor::State::State()
49 {
50 memset(this, 0, sizeof(State));
51 }
52
53 bool VertexProcessor::State::operator==(const State &state) const
54 {
55 if(hash != state.hash)
56 {
57 return false;
58 }
59
60 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
61 }
62
63 VertexProcessor::VertexProcessor(Context *context) : context(context)
64 {
65 for(int i = 0; i < 12; i++)
66 {
67 M[i] = 1;
68 }
69
70 V = 1;
71 B = 1;
72 P = 0;
73 PB = 0;
74 PBV = 0;
75
76 for(int i = 0; i < 12; i++)
77 {
78 PBVM[i] = 0;
79 }
80
81 setLightingEnable(true);
82 setSpecularEnable(false);
83
84 for(int i = 0; i < 8; i++)
85 {
86 setLightEnable(i, false);
87 setLightPosition(i, 0);
88 }
89
90 updateMatrix = true;
91 updateViewMatrix = true;
92 updateBaseMatrix = true;
93 updateProjectionMatrix = true;
94 updateLighting = true;
95
96 for(int i = 0; i < 12; i++)
97 {
98 updateModelMatrix[i] = true;
99 }
100
101 routineCache = 0;
102 setRoutineCacheSize(1024);
103 }
104
105 VertexProcessor::~VertexProcessor()
106 {
107 delete routineCache;
108 routineCache = 0;
109 }
110
111 void VertexProcessor::setInputStream(int index, const Stream &stream)
112 {
113 context->input[index] = stream;
114 }
115
116 void VertexProcessor::setInputPositionStream(const Stream &stream)
117 {
118 context->input[Position] = stream;
119 }
120
121 void VertexProcessor::setInputBlendWeightStream(const Stream &stream)
122 {
123 context->input[BlendWeight] = stream;
124 }
125
126 void VertexProcessor::setInputBlendIndicesStream(const Stream &stream)
127 {
128 context->input[BlendIndices] = stream;
129 }
130
131 void VertexProcessor::setInputNormalStream(const Stream &stream)
132 {
133 context->input[Normal] = stream;
134 }
135
136 void VertexProcessor::setInputPSizeStream(const Stream &stream)
137 {
138 context->input[PSize] = stream;
139 }
140
141 void VertexProcessor::setInputTexCoordStream(const Stream &stream, int index)
142 {
143 context->input[TexCoord0 + index] = stream;
144 }
145
146 void VertexProcessor::setInputPositiontStream(const Stream &stream)
147 {
148 context->input[PositionT] = stream;
149 }
150
151 void VertexProcessor::setInputColorStream(const Stream &stream, int index)
152 {
153 context->input[Color0 + index] = stream;
154 }
155
156 void VertexProcessor::resetInputStreams(bool preTransformed)
157 {
158 for(int i = 0; i < 16; i++)
159 {
160 context->input[i].defaults();
161 }
162
163 context->preTransformed = preTransformed;
164 }
165
166 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
167 {
168 if(index < 256)
169 {
170 c[index][0] = value[0];
171 c[index][1] = value[1];
172 c[index][2] = value[2];
173 c[index][3] = value[3];
174 }
175 else ASSERT(false);
176 }
177
178 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
179 {
180 if(index < 16)
181 {
182 i[index][0] = integer[0];
183 i[index][1] = integer[1];
184 i[index][2] = integer[2];
185 i[index][3] = integer[3];
186 }
187 else ASSERT(false);
188 }
189
190 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
191 {
192 if(index < 16)
193 {
194 b[index] = boolean != 0;
195 }
196 else ASSERT(false);
197 }
198
199 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
200 {
201 if(i < 12)
202 {
203 this->M[i] = M;
204
205 updateMatrix = true;
206 updateModelMatrix[i] = true;
207 updateLighting = true;
208 }
209 else ASSERT(false);
210 }
211
212 void VertexProcessor::setViewMatrix(const Matrix &V)
213 {
214 this->V = V;
215
216 updateMatrix = true;
217 updateViewMatrix = true;
218 }
219
220 void VertexProcessor::setBaseMatrix(const Matrix &B)
221 {
222 this->B = B;
223
224 updateMatrix = true;
225 updateBaseMatrix = true;
226 }
227
228 void VertexProcessor::setProjectionMatrix(const Matrix &P)
229 {
230 this->P = P;
231 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
232
233 updateMatrix = true;
234 updateProjectionMatrix = true;
235 }
236
237 void VertexProcessor::setLightingEnable(bool lightingEnable)
238 {
239 context->setLightingEnable(lightingEnable);
240
241 updateLighting = true;
242 }
243
244 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
245 {
246 if(light < 8)
247 {
248 context->setLightEnable(light, lightEnable);
249 }
250 else ASSERT(false);
251
252 updateLighting = true;
253 }
254
255 void VertexProcessor::setSpecularEnable(bool specularEnable)
256 {
257 context->setSpecularEnable(specularEnable);
258
259 updateLighting = true;
260 }
261
262 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
263 {
264 if(light < 8)
265 {
266 context->setLightPosition(light, lightPosition);
267 }
268 else ASSERT(false);
269
270 updateLighting = true;
271 }
272
273 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
274 {
275 if(light < 8)
276 {
277 ff.lightDiffuse[light][0] = lightDiffuse.r;
278 ff.lightDiffuse[light][1] = lightDiffuse.g;
279 ff.lightDiffuse[light][2] = lightDiffuse.b;
280 ff.lightDiffuse[light][3] = lightDiffuse.a;
281 }
282 else ASSERT(false);
283 }
284
285 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
286 {
287 if(light < 8)
288 {
289 ff.lightSpecular[light][0] = lightSpecular.r;
290 ff.lightSpecular[light][1] = lightSpecular.g;
291 ff.lightSpecular[light][2] = lightSpecular.b;
292 ff.lightSpecular[light][3] = lightSpecular.a;
293 }
294 else ASSERT(false);
295 }
296
297 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
298 {
299 if(light < 8)
300 {
301 ff.lightAmbient[light][0] = lightAmbient.r;
302 ff.lightAmbient[light][1] = lightAmbient.g;
303 ff.lightAmbient[light][2] = lightAmbient.b;
304 ff.lightAmbient[light][3] = lightAmbient.a;
305 }
306 else ASSERT(false);
307 }
308
309 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
310 {
311 if(light < 8)
312 {
313 ff.attenuationConstant[light] = replicate(constant);
314 ff.attenuationLinear[light] = replicate(linear);
315 ff.attenuationQuadratic[light] = replicate(quadratic);
316 }
317 else ASSERT(false);
318 }
319
320 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
321 {
322 if(light < 8)
323 {
324 ff.lightRange[light] = lightRange;
325 }
326 else ASSERT(false);
327 }
328
329 void VertexProcessor::setFogEnable(bool fogEnable)
330 {
331 context->fogEnable = fogEnable;
332 }
333
334 void VertexProcessor::setVertexFogMode(Context::FogMode fogMode)
335 {
336 context->vertexFogMode = fogMode;
337 }
338
339 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
340 {
341 context->setColorVertexEnable(colorVertexEnable);
342 }
343
344 void VertexProcessor::setDiffuseMaterialSource(Context::MaterialSource diffuseMaterialSource)
345 {
346 context->setDiffuseMaterialSource(diffuseMaterialSource);
347 }
348
349 void VertexProcessor::setSpecularMaterialSource(Context::MaterialSource specularMaterialSource)
350 {
351 context->setSpecularMaterialSource(specularMaterialSource);
352 }
353
354 void VertexProcessor::setAmbientMaterialSource(Context::MaterialSource ambientMaterialSource)
355 {
356 context->setAmbientMaterialSource(ambientMaterialSource);
357 }
358
359 void VertexProcessor::setEmissiveMaterialSource(Context::MaterialSource emissiveMaterialSource)
360 {
361 context->setEmissiveMaterialSource(emissiveMaterialSource);
362 }
363
364 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
365 {
366 ff.globalAmbient[0] = globalAmbient.r;
367 ff.globalAmbient[1] = globalAmbient.g;
368 ff.globalAmbient[2] = globalAmbient.b;
369 ff.globalAmbient[3] = globalAmbient.a;
370 }
371
372 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
373 {
374 ff.materialEmission[0] = emission.r;
375 ff.materialEmission[1] = emission.g;
376 ff.materialEmission[2] = emission.b;
377 ff.materialEmission[3] = emission.a;
378 }
379
380 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
381 {
382 ff.materialAmbient[0] = materialAmbient.r;
383 ff.materialAmbient[1] = materialAmbient.g;
384 ff.materialAmbient[2] = materialAmbient.b;
385 ff.materialAmbient[3] = materialAmbient.a;
386 }
387
388 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
389 {
390 ff.materialDiffuse[0] = diffuseColor.r;
391 ff.materialDiffuse[1] = diffuseColor.g;
392 ff.materialDiffuse[2] = diffuseColor.b;
393 ff.materialDiffuse[3] = diffuseColor.a;
394 }
395
396 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
397 {
398 ff.materialSpecular[0] = specularColor.r;
399 ff.materialSpecular[1] = specularColor.g;
400 ff.materialSpecular[2] = specularColor.b;
401 ff.materialSpecular[3] = specularColor.a;
402 }
403
404 void VertexProcessor::setMaterialShininess(float specularPower)
405 {
406 ff.materialShininess = specularPower;
407 }
408
409 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
410 {
411 if(light < 8)
412 {
413 ff.lightPosition[light][0] = P.x;
414 ff.lightPosition[light][1] = P.y;
415 ff.lightPosition[light][2] = P.z;
416 ff.lightPosition[light][3] = 1;
417 }
418 else ASSERT(false);
419 }
420
421 void VertexProcessor::setRangeFogEnable(bool enable)
422 {
423 context->rangeFogEnable = enable;
424 }
425
426 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
427 {
428 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
429 }
430
431 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
432 {
433 if(vertexBlendMatrixCount <= 4)
434 {
435 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
436 }
437 else ASSERT(false);
438 }
439
440 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
441 {
442 if(stage < 16)
443 {
444 context->textureWrap[stage] = mask;
445 }
446 else ASSERT(false);
447
448 context->textureWrapActive = false;
449
450 for(int i = 0; i < 16; i++)
451 {
452 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
453 }
454 }
455
456 void VertexProcessor::setTexGen(unsigned int stage, Context::TexGen texGen)
457 {
458 if(stage < 8)
459 {
460 context->texGen[stage] = texGen;
461 }
462 else ASSERT(false);
463 }
464
465 void VertexProcessor::setLocalViewer(bool localViewer)
466 {
467 context->localViewer = localViewer;
468 }
469
470 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
471 {
472 context->normalizeNormals = normalizeNormals;
473 }
474
475 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
476 {
477 for(int i = 0; i < 4; i++)
478 {
479 for(int j = 0; j < 4; j++)
480 {
481 ff.textureTransform[stage][i][j] = T[i][j];
482 }
483 }
484 }
485
486 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
487 {
488 context->textureTransformCount[stage] = count;
489 context->textureTransformProject[stage] = project;
490 }
491
492 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
493 {
494 if(sampler < 4)
495 {
496 context->sampler[16 + sampler].setTextureFilter(textureFilter);
497 }
498 else ASSERT(false);
499 }
500
501 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
502 {
503 if(sampler < 4)
504 {
505 context->sampler[16 + sampler].setMipmapFilter(mipmapFilter);
506 }
507 else ASSERT(false);
508 }
509
510 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
511 {
512 if(sampler < 4)
513 {
514 context->sampler[16 + sampler].setGatherEnable(enable);
515 }
516 else ASSERT(false);
517 }
518
519 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
520 {
521 if(sampler < 4)
522 {
523 context->sampler[16 + sampler].setAddressingModeU(addressMode);
524 }
525 else ASSERT(false);
526 }
527
528 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
529 {
530 if(sampler < 4)
531 {
532 context->sampler[16 + sampler].setAddressingModeV(addressMode);
533 }
534 else ASSERT(false);
535 }
536
537 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
538 {
539 if(sampler < 4)
540 {
541 context->sampler[16 + sampler].setAddressingModeW(addressMode);
542 }
543 else ASSERT(false);
544 }
545
546 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
547 {
548 if(sampler < 4)
549 {
550 context->sampler[16 + sampler].setReadSRGB(sRGB);
551 }
552 else ASSERT(false);
553 }
554
555 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
556 {
557 if(sampler < 4)
558 {
559 context->sampler[16 + sampler].setMipmapLOD(bias);
560 }
561 else ASSERT(false);
562 }
563
564 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
565 {
566 if(sampler < 4)
567 {
568 context->sampler[16 + sampler].setBorderColor(borderColor);
569 }
570 else ASSERT(false);
571 }
572
573 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, unsigned int maxAnisotropy)
574 {
575 if(sampler < 4)
576 {
577 context->sampler[16 + sampler].setMaxAnisotropy(maxAnisotropy);
578 }
579 else ASSERT(false);
580 }
581
582 void VertexProcessor::setPointSize(float pointSize)
583 {
584 point.pointSize = replicate(pointSize);
585 }
586
587 void VertexProcessor::setPointSizeMin(float pointSizeMin)
588 {
589 point.pointSizeMin = pointSizeMin;
590 }
591
592 void VertexProcessor::setPointSizeMax(float pointSizeMax)
593 {
594 point.pointSizeMax = pointSizeMax;
595 }
596
597 void VertexProcessor::setPointScaleA(float pointScaleA)
598 {
599 point.pointScaleA = pointScaleA;
600 }
601
602 void VertexProcessor::setPointScaleB(float pointScaleB)
603 {
604 point.pointScaleB = pointScaleB;
605 }
606
607 void VertexProcessor::setPointScaleC(float pointScaleC)
608 {
609 point.pointScaleC = pointScaleC;
610 }
611
612 const Matrix &VertexProcessor::getModelTransform(int i)
613 {
614 updateTransform();
615 return PBVM[i];
616 }
617
618 const Matrix &VertexProcessor::getViewTransform()
619 {
620 updateTransform();
621 return PBV;
622 }
623
624 bool VertexProcessor::isFixedFunction()
625 {
626 return !context->vertexShader;
627 }
628
629 void VertexProcessor::setTransform(const Matrix &M, int i)
630 {
631 ff.transformT[i][0][0] = M[0][0];
632 ff.transformT[i][0][1] = M[1][0];
633 ff.transformT[i][0][2] = M[2][0];
634 ff.transformT[i][0][3] = M[3][0];
635
636 ff.transformT[i][1][0] = M[0][1];
637 ff.transformT[i][1][1] = M[1][1];
638 ff.transformT[i][1][2] = M[2][1];
639 ff.transformT[i][1][3] = M[3][1];
640
641 ff.transformT[i][2][0] = M[0][2];
642 ff.transformT[i][2][1] = M[1][2];
643 ff.transformT[i][2][2] = M[2][2];
644 ff.transformT[i][2][3] = M[3][2];
645
646 ff.transformT[i][3][0] = M[0][3];
647 ff.transformT[i][3][1] = M[1][3];
648 ff.transformT[i][3][2] = M[2][3];
649 ff.transformT[i][3][3] = M[3][3];
650 }
651
652 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
653 {
654 ff.cameraTransformT[i][0][0] = M[0][0];
655 ff.cameraTransformT[i][0][1] = M[1][0];
656 ff.cameraTransformT[i][0][2] = M[2][0];
657 ff.cameraTransformT[i][0][3] = M[3][0];
658
659 ff.cameraTransformT[i][1][0] = M[0][1];
660 ff.cameraTransformT[i][1][1] = M[1][1];
661 ff.cameraTransformT[i][1][2] = M[2][1];
662 ff.cameraTransformT[i][1][3] = M[3][1];
663
664 ff.cameraTransformT[i][2][0] = M[0][2];
665 ff.cameraTransformT[i][2][1] = M[1][2];
666 ff.cameraTransformT[i][2][2] = M[2][2];
667 ff.cameraTransformT[i][2][3] = M[3][2];
668
669 ff.cameraTransformT[i][3][0] = M[0][3];
670 ff.cameraTransformT[i][3][1] = M[1][3];
671 ff.cameraTransformT[i][3][2] = M[2][3];
672 ff.cameraTransformT[i][3][3] = M[3][3];
673 }
674
675 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
676 {
677 ff.normalTransformT[i][0][0] = M[0][0];
678 ff.normalTransformT[i][0][1] = M[1][0];
679 ff.normalTransformT[i][0][2] = M[2][0];
680 ff.normalTransformT[i][0][3] = M[3][0];
681
682 ff.normalTransformT[i][1][0] = M[0][1];
683 ff.normalTransformT[i][1][1] = M[1][1];
684 ff.normalTransformT[i][1][2] = M[2][1];
685 ff.normalTransformT[i][1][3] = M[3][1];
686
687 ff.normalTransformT[i][2][0] = M[0][2];
688 ff.normalTransformT[i][2][1] = M[1][2];
689 ff.normalTransformT[i][2][2] = M[2][2];
690 ff.normalTransformT[i][2][3] = M[3][2];
691
692 ff.normalTransformT[i][3][0] = M[0][3];
693 ff.normalTransformT[i][3][1] = M[1][3];
694 ff.normalTransformT[i][3][2] = M[2][3];
695 ff.normalTransformT[i][3][3] = M[3][3];
696 }
697
698 void VertexProcessor::updateTransform()
699 {
700 if(!updateMatrix) return;
701
702 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
703
704 if(updateProjectionMatrix)
705 {
706 PB = P * B;
707 PBV = PB * V;
708
709 for(int i = 0; i < activeMatrices; i++)
710 {
711 PBVM[i] = PBV * M[i];
712 updateModelMatrix[i] = false;
713 }
714
715 updateProjectionMatrix = false;
716 updateBaseMatrix = false;
717 updateViewMatrix = false;
718 }
719
720 if(updateBaseMatrix)
721 {
722 PB = P * B;
723 PBV = PB * V;
724
725 for(int i = 0; i < activeMatrices; i++)
726 {
727 PBVM[i] = PBV * M[i];
728 updateModelMatrix[i] = false;
729 }
730
731 updateBaseMatrix = false;
732 updateViewMatrix = false;
733 }
734
735 if(updateViewMatrix)
736 {
737 PBV = PB * V;
738
739 for(int i = 0; i < activeMatrices; i++)
740 {
741 PBVM[i] = PBV * M[i];
742 updateModelMatrix[i] = false;
743 }
744
745 updateViewMatrix = false;
746 }
747
748 for(int i = 0; i < activeMatrices; i++)
749 {
750 if(updateModelMatrix[i])
751 {
752 PBVM[i] = PBV * M[i];
753 updateModelMatrix[i] = false;
754 }
755 }
756
757 for(int i = 0; i < activeMatrices; i++)
758 {
759 setTransform(PBVM[i], i);
760 setCameraTransform(B * V * M[i], i);
761 setNormalTransform(~!(B * V * M[i]), i);
762 }
763
764 updateMatrix = false;
765 }
766
767 void VertexProcessor::setRoutineCacheSize(int cacheSize)
768 {
769 delete routineCache;
770 routineCache = new LRUCache<State, Routine>(clamp(cacheSize, 1, 65536));
771 }
772
773 const VertexProcessor::State VertexProcessor::update()
774 {
775 if(isFixedFunction())
776 {
777 updateTransform();
778
779 if(updateLighting)
780 {
781 for(int i = 0; i < 8; i++)
782 {
783 if(context->vertexLightActive(i))
784 {
785 // Light position in camera coordinates
786 setLightViewPosition(i, B * V * context->getLightPosition(i));
787 }
788 }
789
790 updateLighting = false;
791 }
792 }
793
794 State state;
795
796 if(context->vertexShader)
797 {
798 state.shaderHash = context->vertexShader->getHash();
799 }
800 else
801 {
802 state.shaderHash = 0;
803 }
804
805 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
806 state.shaderContainsTexldl = context->vertexShader ? context->vertexShader->containsTexldl() : false;
807 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
808 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
809
810 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
811 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
812 state.vertexNormalActive = context->vertexNormalActive();
813 state.normalizeNormals = context->normalizeNormalsActive();
814 state.vertexLightingActive = context->vertexLightingActive();
815 state.diffuseActive = context->diffuseActive();
816 state.specularActive = context->specularActive();
817 state.vertexSpecularActive = context->vertexSpecularActive();
818
819 state.vertexLightActive = context->vertexLightActive(0) << 0 |
820 context->vertexLightActive(1) << 1 |
821 context->vertexLightActive(2) << 2 |
822 context->vertexLightActive(3) << 3 |
823 context->vertexLightActive(4) << 4 |
824 context->vertexLightActive(5) << 5 |
825 context->vertexLightActive(6) << 6 |
826 context->vertexLightActive(7) << 7;
827
828 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
829 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
830 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
831 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
832 state.fogActive = context->fogActive();
833 state.vertexFogMode = context->vertexFogModeActive();
834 state.rangeFogActive = context->rangeFogActive();
835 state.localViewerActive = context->localViewerActive();
836 state.pointSizeActive = context->pointSizeActive();
837 state.pointScaleActive = context->pointScaleActive();
838
839 state.preTransformed = context->preTransformed;
840 state.postTransform = context->postTransform;
841 state.superSampling = context->renderTarget[0]->getSuperSampleCount() > 1;
842 state.multiSampling = context->renderTarget[0]->getMultiSampleCount() > 1;
843
844 for(int i = 0; i < 16; i++)
845 {
846 state.input[i].type = context->input[i].type;
847 state.input[i].count = context->input[i].count;
848 state.input[i].normalized = context->input[i].normalized;
849 }
850
851 if(!context->vertexShader)
852 {
853 for(int i = 0; i < 8; i++)
854 {
855 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
856 state.textureState[i].texGenActive = context->texGenActive(i);
857 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
858 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
859 }
860 }
861 else
862 {
863 for(unsigned int i = 0; i < 4; i++)
864 {
865 if(context->vertexShader->usesSampler(i))
866 {
867 state.samplerState[i] = context->sampler[16 + i].samplerState();
868 }
869 }
870 }
871
872 if(context->vertexShader) // FIXME: Also when pre-transformed?
873 {
874 for(int i = 0; i < 12; i++)
875 {
876 state.output[i].xWrite = context->vertexShader->output[i][0].active();
877 state.output[i].yWrite = context->vertexShader->output[i][1].active();
878 state.output[i].zWrite = context->vertexShader->output[i][2].active();
879 state.output[i].wWrite = context->vertexShader->output[i][3].active();
880 }
881 }
882 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
883 {
884 state.output[Pos].write = 0xF;
885
886 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
887 {
888 state.output[D0].write = 0xF;
889 }
890
891 if(context->specularActive())
892 {
893 state.output[D1].write = 0xF;
894 }
895
896 for(int stage = 0; stage < 8; stage++)
897 {
898 if(context->vertexTextureActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
899 if(context->vertexTextureActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
900 if(context->vertexTextureActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
901 if(context->vertexTextureActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
902 }
903
904 if(context->fogActive())
905 {
906 state.output[Fog].xWrite = true;
907 }
908
909 if(context->pointSizeActive())
910 {
911 state.output[Pts].yWrite = true;
912 }
913 }
914 else
915 {
916 state.output[Pos].write = 0xF;
917
918 for(int i = 0; i < 2; i++)
919 {
920 if(context->input[Color0 + i])
921 {
922 state.output[D0 + i].write = 0xF;
923 }
924 }
925
926 for(int i = 0; i < 8; i++)
927 {
928 if(context->input[TexCoord0 + i])
929 {
930 state.output[T0 + i].write = 0xF;
931 }
932 }
933
934 if(context->input[PSize])
935 {
936 state.output[Pts].yWrite = true;
937 }
938 }
939
940 if(context->vertexShaderVersion() < 0x0300)
941 {
942 state.output[D0].clamp = 0xF;
943 state.output[D1].clamp = 0xF;
944 state.output[Fog].xClamp = true;
945 }
946
947 state.hash = state.computeHash();
948
949 return state;
950 }
951
952 Routine *VertexProcessor::routine(const State &state)
953 {
954 Routine *routine = routineCache->query(state);
955
956 if(!routine) // Create one
957 {
958 VertexRoutine *generator = 0;
959
960 if(state.fixedFunction)
961 {
962 generator = new VertexPipeline(state);
963 }
964 else
965 {
966 generator = new VertexProgram(state, context->vertexShader);
967 }
968
969 generator->generate();
970 routine = generator->getRoutine();
971 delete generator;
972
973 routineCache->add(state, routine);
974 }
975
976 return routine;
977 }
978}