blob: dec0e9ce0bc0e0b233fd7110c1ce67b0d7859814 [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 {
119 for(int i = 0; i < 16; i++)
120 {
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
300 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
301 {
302 context->setColorVertexEnable(colorVertexEnable);
303 }
304
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400305 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400306 {
307 context->setDiffuseMaterialSource(diffuseMaterialSource);
308 }
309
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400310 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400311 {
312 context->setSpecularMaterialSource(specularMaterialSource);
313 }
314
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400315 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400316 {
317 context->setAmbientMaterialSource(ambientMaterialSource);
318 }
319
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400320 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
John Bauman89401822014-05-06 15:04:28 -0400321 {
322 context->setEmissiveMaterialSource(emissiveMaterialSource);
323 }
324
325 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
326 {
327 ff.globalAmbient[0] = globalAmbient.r;
328 ff.globalAmbient[1] = globalAmbient.g;
329 ff.globalAmbient[2] = globalAmbient.b;
330 ff.globalAmbient[3] = globalAmbient.a;
331 }
332
333 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
334 {
335 ff.materialEmission[0] = emission.r;
336 ff.materialEmission[1] = emission.g;
337 ff.materialEmission[2] = emission.b;
338 ff.materialEmission[3] = emission.a;
339 }
340
341 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
342 {
343 ff.materialAmbient[0] = materialAmbient.r;
344 ff.materialAmbient[1] = materialAmbient.g;
345 ff.materialAmbient[2] = materialAmbient.b;
346 ff.materialAmbient[3] = materialAmbient.a;
347 }
348
349 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
350 {
351 ff.materialDiffuse[0] = diffuseColor.r;
352 ff.materialDiffuse[1] = diffuseColor.g;
353 ff.materialDiffuse[2] = diffuseColor.b;
354 ff.materialDiffuse[3] = diffuseColor.a;
355 }
356
357 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
358 {
359 ff.materialSpecular[0] = specularColor.r;
360 ff.materialSpecular[1] = specularColor.g;
361 ff.materialSpecular[2] = specularColor.b;
362 ff.materialSpecular[3] = specularColor.a;
363 }
364
365 void VertexProcessor::setMaterialShininess(float specularPower)
366 {
367 ff.materialShininess = specularPower;
368 }
369
370 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
371 {
372 if(light < 8)
373 {
374 ff.lightPosition[light][0] = P.x;
375 ff.lightPosition[light][1] = P.y;
376 ff.lightPosition[light][2] = P.z;
377 ff.lightPosition[light][3] = 1;
378 }
379 else ASSERT(false);
380 }
381
382 void VertexProcessor::setRangeFogEnable(bool enable)
383 {
384 context->rangeFogEnable = enable;
385 }
386
387 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
388 {
389 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
390 }
391
392 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
393 {
394 if(vertexBlendMatrixCount <= 4)
395 {
396 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
397 }
398 else ASSERT(false);
399 }
400
401 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
402 {
403 if(stage < 16)
404 {
405 context->textureWrap[stage] = mask;
406 }
407 else ASSERT(false);
408
409 context->textureWrapActive = false;
410
411 for(int i = 0; i < 16; i++)
412 {
413 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
414 }
415 }
416
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400417 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
John Bauman89401822014-05-06 15:04:28 -0400418 {
419 if(stage < 8)
420 {
421 context->texGen[stage] = texGen;
422 }
423 else ASSERT(false);
424 }
425
426 void VertexProcessor::setLocalViewer(bool localViewer)
427 {
428 context->localViewer = localViewer;
429 }
430
431 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
432 {
433 context->normalizeNormals = normalizeNormals;
434 }
435
436 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
437 {
438 for(int i = 0; i < 4; i++)
439 {
440 for(int j = 0; j < 4; j++)
441 {
442 ff.textureTransform[stage][i][j] = T[i][j];
443 }
444 }
445 }
446
447 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
448 {
449 context->textureTransformCount[stage] = count;
450 context->textureTransformProject[stage] = project;
451 }
452
453 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
454 {
455 if(sampler < 4)
456 {
457 context->sampler[16 + sampler].setTextureFilter(textureFilter);
458 }
459 else ASSERT(false);
460 }
461
462 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
463 {
464 if(sampler < 4)
465 {
466 context->sampler[16 + sampler].setMipmapFilter(mipmapFilter);
467 }
468 else ASSERT(false);
469 }
470
471 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
472 {
473 if(sampler < 4)
474 {
475 context->sampler[16 + sampler].setGatherEnable(enable);
476 }
477 else ASSERT(false);
478 }
479
480 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
481 {
482 if(sampler < 4)
483 {
484 context->sampler[16 + sampler].setAddressingModeU(addressMode);
485 }
486 else ASSERT(false);
487 }
488
489 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
490 {
491 if(sampler < 4)
492 {
493 context->sampler[16 + sampler].setAddressingModeV(addressMode);
494 }
495 else ASSERT(false);
496 }
497
498 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
499 {
500 if(sampler < 4)
501 {
502 context->sampler[16 + sampler].setAddressingModeW(addressMode);
503 }
504 else ASSERT(false);
505 }
506
507 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
508 {
509 if(sampler < 4)
510 {
511 context->sampler[16 + sampler].setReadSRGB(sRGB);
512 }
513 else ASSERT(false);
514 }
515
516 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
517 {
518 if(sampler < 4)
519 {
520 context->sampler[16 + sampler].setMipmapLOD(bias);
521 }
522 else ASSERT(false);
523 }
524
525 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
526 {
527 if(sampler < 4)
528 {
529 context->sampler[16 + sampler].setBorderColor(borderColor);
530 }
531 else ASSERT(false);
532 }
533
534 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, unsigned int maxAnisotropy)
535 {
536 if(sampler < 4)
537 {
538 context->sampler[16 + sampler].setMaxAnisotropy(maxAnisotropy);
539 }
540 else ASSERT(false);
541 }
542
543 void VertexProcessor::setPointSize(float pointSize)
544 {
545 point.pointSize = replicate(pointSize);
546 }
547
548 void VertexProcessor::setPointSizeMin(float pointSizeMin)
549 {
550 point.pointSizeMin = pointSizeMin;
551 }
552
553 void VertexProcessor::setPointSizeMax(float pointSizeMax)
554 {
555 point.pointSizeMax = pointSizeMax;
556 }
557
558 void VertexProcessor::setPointScaleA(float pointScaleA)
559 {
560 point.pointScaleA = pointScaleA;
561 }
562
563 void VertexProcessor::setPointScaleB(float pointScaleB)
564 {
565 point.pointScaleB = pointScaleB;
566 }
567
568 void VertexProcessor::setPointScaleC(float pointScaleC)
569 {
570 point.pointScaleC = pointScaleC;
571 }
572
573 const Matrix &VertexProcessor::getModelTransform(int i)
574 {
575 updateTransform();
576 return PBVM[i];
577 }
578
579 const Matrix &VertexProcessor::getViewTransform()
580 {
581 updateTransform();
582 return PBV;
583 }
584
585 bool VertexProcessor::isFixedFunction()
586 {
587 return !context->vertexShader;
588 }
589
590 void VertexProcessor::setTransform(const Matrix &M, int i)
591 {
592 ff.transformT[i][0][0] = M[0][0];
593 ff.transformT[i][0][1] = M[1][0];
594 ff.transformT[i][0][2] = M[2][0];
595 ff.transformT[i][0][3] = M[3][0];
596
597 ff.transformT[i][1][0] = M[0][1];
598 ff.transformT[i][1][1] = M[1][1];
599 ff.transformT[i][1][2] = M[2][1];
600 ff.transformT[i][1][3] = M[3][1];
601
602 ff.transformT[i][2][0] = M[0][2];
603 ff.transformT[i][2][1] = M[1][2];
604 ff.transformT[i][2][2] = M[2][2];
605 ff.transformT[i][2][3] = M[3][2];
606
607 ff.transformT[i][3][0] = M[0][3];
608 ff.transformT[i][3][1] = M[1][3];
609 ff.transformT[i][3][2] = M[2][3];
610 ff.transformT[i][3][3] = M[3][3];
611 }
612
613 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
614 {
615 ff.cameraTransformT[i][0][0] = M[0][0];
616 ff.cameraTransformT[i][0][1] = M[1][0];
617 ff.cameraTransformT[i][0][2] = M[2][0];
618 ff.cameraTransformT[i][0][3] = M[3][0];
619
620 ff.cameraTransformT[i][1][0] = M[0][1];
621 ff.cameraTransformT[i][1][1] = M[1][1];
622 ff.cameraTransformT[i][1][2] = M[2][1];
623 ff.cameraTransformT[i][1][3] = M[3][1];
624
625 ff.cameraTransformT[i][2][0] = M[0][2];
626 ff.cameraTransformT[i][2][1] = M[1][2];
627 ff.cameraTransformT[i][2][2] = M[2][2];
628 ff.cameraTransformT[i][2][3] = M[3][2];
629
630 ff.cameraTransformT[i][3][0] = M[0][3];
631 ff.cameraTransformT[i][3][1] = M[1][3];
632 ff.cameraTransformT[i][3][2] = M[2][3];
633 ff.cameraTransformT[i][3][3] = M[3][3];
634 }
635
636 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
637 {
638 ff.normalTransformT[i][0][0] = M[0][0];
639 ff.normalTransformT[i][0][1] = M[1][0];
640 ff.normalTransformT[i][0][2] = M[2][0];
641 ff.normalTransformT[i][0][3] = M[3][0];
642
643 ff.normalTransformT[i][1][0] = M[0][1];
644 ff.normalTransformT[i][1][1] = M[1][1];
645 ff.normalTransformT[i][1][2] = M[2][1];
646 ff.normalTransformT[i][1][3] = M[3][1];
647
648 ff.normalTransformT[i][2][0] = M[0][2];
649 ff.normalTransformT[i][2][1] = M[1][2];
650 ff.normalTransformT[i][2][2] = M[2][2];
651 ff.normalTransformT[i][2][3] = M[3][2];
652
653 ff.normalTransformT[i][3][0] = M[0][3];
654 ff.normalTransformT[i][3][1] = M[1][3];
655 ff.normalTransformT[i][3][2] = M[2][3];
656 ff.normalTransformT[i][3][3] = M[3][3];
657 }
658
659 void VertexProcessor::updateTransform()
660 {
661 if(!updateMatrix) return;
662
663 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
664
665 if(updateProjectionMatrix)
666 {
667 PB = P * B;
668 PBV = PB * V;
669
670 for(int i = 0; i < activeMatrices; i++)
671 {
672 PBVM[i] = PBV * M[i];
673 updateModelMatrix[i] = false;
674 }
675
676 updateProjectionMatrix = false;
677 updateBaseMatrix = false;
678 updateViewMatrix = false;
679 }
680
681 if(updateBaseMatrix)
682 {
683 PB = P * B;
684 PBV = PB * V;
685
686 for(int i = 0; i < activeMatrices; i++)
687 {
688 PBVM[i] = PBV * M[i];
689 updateModelMatrix[i] = false;
690 }
691
692 updateBaseMatrix = false;
693 updateViewMatrix = false;
694 }
695
696 if(updateViewMatrix)
697 {
698 PBV = PB * V;
699
700 for(int i = 0; i < activeMatrices; i++)
701 {
702 PBVM[i] = PBV * M[i];
703 updateModelMatrix[i] = false;
704 }
705
706 updateViewMatrix = false;
707 }
708
709 for(int i = 0; i < activeMatrices; i++)
710 {
711 if(updateModelMatrix[i])
712 {
713 PBVM[i] = PBV * M[i];
714 updateModelMatrix[i] = false;
715 }
716 }
717
718 for(int i = 0; i < activeMatrices; i++)
719 {
720 setTransform(PBVM[i], i);
721 setCameraTransform(B * V * M[i], i);
722 setNormalTransform(~!(B * V * M[i]), i);
723 }
724
725 updateMatrix = false;
726 }
727
728 void VertexProcessor::setRoutineCacheSize(int cacheSize)
729 {
730 delete routineCache;
John Bauman66b8ab22014-05-06 15:57:45 -0400731 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536), precacheVertex ? "sw-vertex" : 0);
John Bauman89401822014-05-06 15:04:28 -0400732 }
733
734 const VertexProcessor::State VertexProcessor::update()
735 {
736 if(isFixedFunction())
737 {
738 updateTransform();
739
740 if(updateLighting)
741 {
742 for(int i = 0; i < 8; i++)
743 {
744 if(context->vertexLightActive(i))
745 {
746 // Light position in camera coordinates
747 setLightViewPosition(i, B * V * context->getLightPosition(i));
748 }
749 }
750
751 updateLighting = false;
752 }
753 }
754
755 State state;
756
757 if(context->vertexShader)
758 {
John Bauman19bac1e2014-05-06 15:23:49 -0400759 state.shaderID = context->vertexShader->getSerialID();
John Bauman89401822014-05-06 15:04:28 -0400760 }
761 else
762 {
John Bauman19bac1e2014-05-06 15:23:49 -0400763 state.shaderID = 0;
John Bauman89401822014-05-06 15:04:28 -0400764 }
765
766 state.fixedFunction = !context->vertexShader && context->pixelShaderVersion() < 0x0300;
767 state.shaderContainsTexldl = context->vertexShader ? context->vertexShader->containsTexldl() : false;
768 state.positionRegister = context->vertexShader ? context->vertexShader->positionRegister : Pos;
769 state.pointSizeRegister = context->vertexShader ? context->vertexShader->pointSizeRegister : Pts;
770
771 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
772 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
773 state.vertexNormalActive = context->vertexNormalActive();
774 state.normalizeNormals = context->normalizeNormalsActive();
775 state.vertexLightingActive = context->vertexLightingActive();
776 state.diffuseActive = context->diffuseActive();
777 state.specularActive = context->specularActive();
778 state.vertexSpecularActive = context->vertexSpecularActive();
779
780 state.vertexLightActive = context->vertexLightActive(0) << 0 |
781 context->vertexLightActive(1) << 1 |
782 context->vertexLightActive(2) << 2 |
783 context->vertexLightActive(3) << 3 |
784 context->vertexLightActive(4) << 4 |
785 context->vertexLightActive(5) << 5 |
786 context->vertexLightActive(6) << 6 |
787 context->vertexLightActive(7) << 7;
788
789 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
790 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
791 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
792 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
793 state.fogActive = context->fogActive();
794 state.vertexFogMode = context->vertexFogModeActive();
795 state.rangeFogActive = context->rangeFogActive();
796 state.localViewerActive = context->localViewerActive();
797 state.pointSizeActive = context->pointSizeActive();
798 state.pointScaleActive = context->pointScaleActive();
799
800 state.preTransformed = context->preTransformed;
John Bauman66b8ab22014-05-06 15:57:45 -0400801 state.superSampling = context->getSuperSampleCount() > 1;
802 state.multiSampling = context->getMultiSampleCount() > 1;
John Bauman89401822014-05-06 15:04:28 -0400803
804 for(int i = 0; i < 16; i++)
805 {
806 state.input[i].type = context->input[i].type;
807 state.input[i].count = context->input[i].count;
808 state.input[i].normalized = context->input[i].normalized;
809 }
810
811 if(!context->vertexShader)
812 {
813 for(int i = 0; i < 8; i++)
814 {
815 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
816 state.textureState[i].texGenActive = context->texGenActive(i);
817 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
818 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
819 }
820 }
821 else
822 {
823 for(unsigned int i = 0; i < 4; i++)
824 {
825 if(context->vertexShader->usesSampler(i))
826 {
827 state.samplerState[i] = context->sampler[16 + i].samplerState();
828 }
829 }
830 }
831
832 if(context->vertexShader) // FIXME: Also when pre-transformed?
833 {
834 for(int i = 0; i < 12; i++)
835 {
836 state.output[i].xWrite = context->vertexShader->output[i][0].active();
837 state.output[i].yWrite = context->vertexShader->output[i][1].active();
838 state.output[i].zWrite = context->vertexShader->output[i][2].active();
839 state.output[i].wWrite = context->vertexShader->output[i][3].active();
840 }
841 }
842 else if(!context->preTransformed || context->pixelShaderVersion() < 0x0300)
843 {
844 state.output[Pos].write = 0xF;
845
846 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
847 {
848 state.output[D0].write = 0xF;
849 }
850
851 if(context->specularActive())
852 {
853 state.output[D1].write = 0xF;
854 }
855
856 for(int stage = 0; stage < 8; stage++)
857 {
John Bauman19bac1e2014-05-06 15:23:49 -0400858 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
859 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
860 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
861 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
John Bauman89401822014-05-06 15:04:28 -0400862 }
863
864 if(context->fogActive())
865 {
866 state.output[Fog].xWrite = true;
867 }
868
869 if(context->pointSizeActive())
870 {
871 state.output[Pts].yWrite = true;
872 }
873 }
874 else
875 {
876 state.output[Pos].write = 0xF;
877
878 for(int i = 0; i < 2; i++)
879 {
880 if(context->input[Color0 + i])
881 {
882 state.output[D0 + i].write = 0xF;
883 }
884 }
885
886 for(int i = 0; i < 8; i++)
887 {
888 if(context->input[TexCoord0 + i])
889 {
890 state.output[T0 + i].write = 0xF;
891 }
892 }
893
John Bauman66b8ab22014-05-06 15:57:45 -0400894 if(context->input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400895 {
896 state.output[Pts].yWrite = true;
897 }
898 }
899
900 if(context->vertexShaderVersion() < 0x0300)
901 {
902 state.output[D0].clamp = 0xF;
903 state.output[D1].clamp = 0xF;
904 state.output[Fog].xClamp = true;
905 }
906
907 state.hash = state.computeHash();
908
909 return state;
910 }
911
912 Routine *VertexProcessor::routine(const State &state)
913 {
914 Routine *routine = routineCache->query(state);
915
916 if(!routine) // Create one
917 {
918 VertexRoutine *generator = 0;
919
920 if(state.fixedFunction)
921 {
922 generator = new VertexPipeline(state);
923 }
924 else
925 {
926 generator = new VertexProgram(state, context->vertexShader);
927 }
928
929 generator->generate();
930 routine = generator->getRoutine();
931 delete generator;
932
933 routineCache->add(state, routine);
934 }
935
936 return routine;
937 }
938}