1// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#include "VertexProcessor.hpp"
16
17#include "Shader/VertexPipeline.hpp"
18#include "Shader/VertexProgram.hpp"
19#include "Shader/VertexShader.hpp"
20#include "Shader/PixelShader.hpp"
21#include "Shader/Constants.hpp"
22#include "Common/Math.hpp"
23#include "Common/Debug.hpp"
24
25#include <cstring>
26
27namespace sw
28{
29 bool precacheVertex = false;
30
31 void VertexCache::clear()
32 {
33 for(int i = 0; i < 16; i++)
34 {
35 tag[i] = 0x80000000;
36 }
37 }
38
39 uint32_t VertexProcessor::States::computeHash()
40 {
41 uint32_t *state = reinterpret_cast<uint32_t*>(this);
42 uint32_t hash = 0;
43
44 for(unsigned int i = 0; i < sizeof(States) / sizeof(uint32_t); i++)
45 {
46 hash ^= state[i];
47 }
48
49 return hash;
50 }
51
52 bool VertexProcessor::State::operator==(const State &state) const
53 {
54 if(hash != state.hash)
55 {
56 return false;
57 }
58
59 static_assert(is_memcmparable<State>::value, "Cannot memcmp States");
60 return memcmp(static_cast<const States*>(this), static_cast<const States*>(&state), sizeof(States)) == 0;
61 }
62
63 VertexProcessor::TransformFeedbackInfo::TransformFeedbackInfo()
64 {
65 buffer = nullptr;
66 offset = 0;
67 reg = 0;
68 row = 0;
69 col = 0;
70 stride = 0;
71 }
72
73 VertexProcessor::UniformBufferInfo::UniformBufferInfo()
74 {
75 buffer = nullptr;
76 offset = 0;
77 }
78
79 VertexProcessor::VertexProcessor(Context *context) : context(context)
80 {
81 for(int i = 0; i < 12; i++)
82 {
83 M[i] = 1;
84 }
85
86 V = 1;
87 B = 1;
88 P = 0;
89 PB = 0;
90 PBV = 0;
91
92 for(int i = 0; i < 12; i++)
93 {
94 PBVM[i] = 0;
95 }
96
97 setLightingEnable(true);
98 setSpecularEnable(false);
99
100 for(int i = 0; i < 8; i++)
101 {
102 setLightEnable(i, false);
103 setLightPosition(i, 0);
104 }
105
106 updateMatrix = true;
107 updateViewMatrix = true;
108 updateBaseMatrix = true;
109 updateProjectionMatrix = true;
110 updateLighting = true;
111
112 for(int i = 0; i < 12; i++)
113 {
114 updateModelMatrix[i] = true;
115 }
116
117 routineCache = nullptr;
118 setRoutineCacheSize(1024);
119 }
120
121 VertexProcessor::~VertexProcessor()
122 {
123 delete routineCache;
124 routineCache = nullptr;
125 }
126
127 void VertexProcessor::setInputStream(int index, const Stream &stream)
128 {
129 context->input[index] = stream;
130 }
131
132 void VertexProcessor::resetInputStreams(bool preTransformed)
133 {
134 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
135 {
136 context->input[i].defaults();
137 }
138
139 context->preTransformed = preTransformed;
140 }
141
142 void VertexProcessor::setFloatConstant(unsigned int index, const float value[4])
143 {
144 if(index < VERTEX_UNIFORM_VECTORS)
145 {
146 c[index][0] = value[0];
147 c[index][1] = value[1];
148 c[index][2] = value[2];
149 c[index][3] = value[3];
150 }
151 else ASSERT(false);
152 }
153
154 void VertexProcessor::setIntegerConstant(unsigned int index, const int integer[4])
155 {
156 if(index < 16)
157 {
158 i[index][0] = integer[0];
159 i[index][1] = integer[1];
160 i[index][2] = integer[2];
161 i[index][3] = integer[3];
162 }
163 else ASSERT(false);
164 }
165
166 void VertexProcessor::setBooleanConstant(unsigned int index, int boolean)
167 {
168 if(index < 16)
169 {
170 b[index] = boolean != 0;
171 }
172 else ASSERT(false);
173 }
174
175 void VertexProcessor::setUniformBuffer(int index, sw::Resource* buffer, int offset)
176 {
177 uniformBufferInfo[index].buffer = buffer;
178 uniformBufferInfo[index].offset = offset;
179 }
180
181 void VertexProcessor::lockUniformBuffers(byte** u, sw::Resource* uniformBuffers[])
182 {
183 for(int i = 0; i < MAX_UNIFORM_BUFFER_BINDINGS; ++i)
184 {
185 u[i] = uniformBufferInfo[i].buffer ? static_cast<byte*>(uniformBufferInfo[i].buffer->lock(PUBLIC, PRIVATE)) + uniformBufferInfo[i].offset : nullptr;
186 uniformBuffers[i] = uniformBufferInfo[i].buffer;
187 }
188 }
189
190 void VertexProcessor::setTransformFeedbackBuffer(int index, sw::Resource* buffer, int offset, unsigned int reg, unsigned int row, unsigned int col, unsigned int stride)
191 {
192 transformFeedbackInfo[index].buffer = buffer;
193 transformFeedbackInfo[index].offset = offset;
194 transformFeedbackInfo[index].reg = reg;
195 transformFeedbackInfo[index].row = row;
196 transformFeedbackInfo[index].col = col;
197 transformFeedbackInfo[index].stride = stride;
198 }
199
200 void VertexProcessor::lockTransformFeedbackBuffers(byte** t, unsigned int* v, unsigned int* r, unsigned int* c, unsigned int* s, sw::Resource* transformFeedbackBuffers[])
201 {
202 for(int i = 0; i < MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS; ++i)
203 {
204 t[i] = transformFeedbackInfo[i].buffer ? static_cast<byte*>(transformFeedbackInfo[i].buffer->lock(PUBLIC, PRIVATE)) + transformFeedbackInfo[i].offset : nullptr;
205 transformFeedbackBuffers[i] = transformFeedbackInfo[i].buffer;
206 v[i] = transformFeedbackInfo[i].reg;
207 r[i] = transformFeedbackInfo[i].row;
208 c[i] = transformFeedbackInfo[i].col;
209 s[i] = transformFeedbackInfo[i].stride;
210 }
211 }
212
213 void VertexProcessor::setModelMatrix(const Matrix &M, int i)
214 {
215 if(i < 12)
216 {
217 this->M[i] = M;
218
219 updateMatrix = true;
220 updateModelMatrix[i] = true;
221 updateLighting = true;
222 }
223 else ASSERT(false);
224 }
225
226 void VertexProcessor::setViewMatrix(const Matrix &V)
227 {
228 this->V = V;
229
230 updateMatrix = true;
231 updateViewMatrix = true;
232 }
233
234 void VertexProcessor::setBaseMatrix(const Matrix &B)
235 {
236 this->B = B;
237
238 updateMatrix = true;
239 updateBaseMatrix = true;
240 }
241
242 void VertexProcessor::setProjectionMatrix(const Matrix &P)
243 {
244 this->P = P;
245 context->wBasedFog = (P[3][0] != 0.0f) || (P[3][1] != 0.0f) || (P[3][2] != 0.0f) || (P[3][3] != 1.0f);
246
247 updateMatrix = true;
248 updateProjectionMatrix = true;
249 }
250
251 void VertexProcessor::setLightingEnable(bool lightingEnable)
252 {
253 context->setLightingEnable(lightingEnable);
254
255 updateLighting = true;
256 }
257
258 void VertexProcessor::setLightEnable(unsigned int light, bool lightEnable)
259 {
260 if(light < 8)
261 {
262 context->setLightEnable(light, lightEnable);
263 }
264 else ASSERT(false);
265
266 updateLighting = true;
267 }
268
269 void VertexProcessor::setSpecularEnable(bool specularEnable)
270 {
271 context->setSpecularEnable(specularEnable);
272
273 updateLighting = true;
274 }
275
276 void VertexProcessor::setLightPosition(unsigned int light, const Point &lightPosition)
277 {
278 if(light < 8)
279 {
280 context->setLightPosition(light, lightPosition);
281 }
282 else ASSERT(false);
283
284 updateLighting = true;
285 }
286
287 void VertexProcessor::setLightDiffuse(unsigned int light, const Color<float> &lightDiffuse)
288 {
289 if(light < 8)
290 {
291 ff.lightDiffuse[light][0] = lightDiffuse.r;
292 ff.lightDiffuse[light][1] = lightDiffuse.g;
293 ff.lightDiffuse[light][2] = lightDiffuse.b;
294 ff.lightDiffuse[light][3] = lightDiffuse.a;
295 }
296 else ASSERT(false);
297 }
298
299 void VertexProcessor::setLightSpecular(unsigned int light, const Color<float> &lightSpecular)
300 {
301 if(light < 8)
302 {
303 ff.lightSpecular[light][0] = lightSpecular.r;
304 ff.lightSpecular[light][1] = lightSpecular.g;
305 ff.lightSpecular[light][2] = lightSpecular.b;
306 ff.lightSpecular[light][3] = lightSpecular.a;
307 }
308 else ASSERT(false);
309 }
310
311 void VertexProcessor::setLightAmbient(unsigned int light, const Color<float> &lightAmbient)
312 {
313 if(light < 8)
314 {
315 ff.lightAmbient[light][0] = lightAmbient.r;
316 ff.lightAmbient[light][1] = lightAmbient.g;
317 ff.lightAmbient[light][2] = lightAmbient.b;
318 ff.lightAmbient[light][3] = lightAmbient.a;
319 }
320 else ASSERT(false);
321 }
322
323 void VertexProcessor::setLightAttenuation(unsigned int light, float constant, float linear, float quadratic)
324 {
325 if(light < 8)
326 {
327 ff.attenuationConstant[light] = replicate(constant);
328 ff.attenuationLinear[light] = replicate(linear);
329 ff.attenuationQuadratic[light] = replicate(quadratic);
330 }
331 else ASSERT(false);
332 }
333
334 void VertexProcessor::setLightRange(unsigned int light, float lightRange)
335 {
336 if(light < 8)
337 {
338 ff.lightRange[light] = lightRange;
339 }
340 else ASSERT(false);
341 }
342
343 void VertexProcessor::setFogEnable(bool fogEnable)
344 {
345 context->fogEnable = fogEnable;
346 }
347
348 void VertexProcessor::setVertexFogMode(FogMode fogMode)
349 {
350 context->vertexFogMode = fogMode;
351 }
352
353 void VertexProcessor::setInstanceID(int instanceID)
354 {
355 context->instanceID = instanceID;
356 }
357
358 void VertexProcessor::setColorVertexEnable(bool colorVertexEnable)
359 {
360 context->setColorVertexEnable(colorVertexEnable);
361 }
362
363 void VertexProcessor::setDiffuseMaterialSource(MaterialSource diffuseMaterialSource)
364 {
365 context->setDiffuseMaterialSource(diffuseMaterialSource);
366 }
367
368 void VertexProcessor::setSpecularMaterialSource(MaterialSource specularMaterialSource)
369 {
370 context->setSpecularMaterialSource(specularMaterialSource);
371 }
372
373 void VertexProcessor::setAmbientMaterialSource(MaterialSource ambientMaterialSource)
374 {
375 context->setAmbientMaterialSource(ambientMaterialSource);
376 }
377
378 void VertexProcessor::setEmissiveMaterialSource(MaterialSource emissiveMaterialSource)
379 {
380 context->setEmissiveMaterialSource(emissiveMaterialSource);
381 }
382
383 void VertexProcessor::setGlobalAmbient(const Color<float> &globalAmbient)
384 {
385 ff.globalAmbient[0] = globalAmbient.r;
386 ff.globalAmbient[1] = globalAmbient.g;
387 ff.globalAmbient[2] = globalAmbient.b;
388 ff.globalAmbient[3] = globalAmbient.a;
389 }
390
391 void VertexProcessor::setMaterialEmission(const Color<float> &emission)
392 {
393 ff.materialEmission[0] = emission.r;
394 ff.materialEmission[1] = emission.g;
395 ff.materialEmission[2] = emission.b;
396 ff.materialEmission[3] = emission.a;
397 }
398
399 void VertexProcessor::setMaterialAmbient(const Color<float> &materialAmbient)
400 {
401 ff.materialAmbient[0] = materialAmbient.r;
402 ff.materialAmbient[1] = materialAmbient.g;
403 ff.materialAmbient[2] = materialAmbient.b;
404 ff.materialAmbient[3] = materialAmbient.a;
405 }
406
407 void VertexProcessor::setMaterialDiffuse(const Color<float> &diffuseColor)
408 {
409 ff.materialDiffuse[0] = diffuseColor.r;
410 ff.materialDiffuse[1] = diffuseColor.g;
411 ff.materialDiffuse[2] = diffuseColor.b;
412 ff.materialDiffuse[3] = diffuseColor.a;
413 }
414
415 void VertexProcessor::setMaterialSpecular(const Color<float> &specularColor)
416 {
417 ff.materialSpecular[0] = specularColor.r;
418 ff.materialSpecular[1] = specularColor.g;
419 ff.materialSpecular[2] = specularColor.b;
420 ff.materialSpecular[3] = specularColor.a;
421 }
422
423 void VertexProcessor::setMaterialShininess(float specularPower)
424 {
425 ff.materialShininess = specularPower;
426 }
427
428 void VertexProcessor::setLightViewPosition(unsigned int light, const Point &P)
429 {
430 if(light < 8)
431 {
432 ff.lightPosition[light][0] = P.x;
433 ff.lightPosition[light][1] = P.y;
434 ff.lightPosition[light][2] = P.z;
435 ff.lightPosition[light][3] = 1;
436 }
437 else ASSERT(false);
438 }
439
440 void VertexProcessor::setRangeFogEnable(bool enable)
441 {
442 context->rangeFogEnable = enable;
443 }
444
445 void VertexProcessor::setIndexedVertexBlendEnable(bool indexedVertexBlendEnable)
446 {
447 context->indexedVertexBlendEnable = indexedVertexBlendEnable;
448 }
449
450 void VertexProcessor::setVertexBlendMatrixCount(unsigned int vertexBlendMatrixCount)
451 {
452 if(vertexBlendMatrixCount <= 4)
453 {
454 context->vertexBlendMatrixCount = vertexBlendMatrixCount;
455 }
456 else ASSERT(false);
457 }
458
459 void VertexProcessor::setTextureWrap(unsigned int stage, int mask)
460 {
461 if(stage < TEXTURE_IMAGE_UNITS)
462 {
463 context->textureWrap[stage] = mask;
464 }
465 else ASSERT(false);
466
467 context->textureWrapActive = false;
468
469 for(int i = 0; i < TEXTURE_IMAGE_UNITS; i++)
470 {
471 context->textureWrapActive |= (context->textureWrap[i] != 0x00);
472 }
473 }
474
475 void VertexProcessor::setTexGen(unsigned int stage, TexGen texGen)
476 {
477 if(stage < 8)
478 {
479 context->texGen[stage] = texGen;
480 }
481 else ASSERT(false);
482 }
483
484 void VertexProcessor::setLocalViewer(bool localViewer)
485 {
486 context->localViewer = localViewer;
487 }
488
489 void VertexProcessor::setNormalizeNormals(bool normalizeNormals)
490 {
491 context->normalizeNormals = normalizeNormals;
492 }
493
494 void VertexProcessor::setTextureMatrix(int stage, const Matrix &T)
495 {
496 for(int i = 0; i < 4; i++)
497 {
498 for(int j = 0; j < 4; j++)
499 {
500 ff.textureTransform[stage][i][j] = T[i][j];
501 }
502 }
503 }
504
505 void VertexProcessor::setTextureTransform(int stage, int count, bool project)
506 {
507 context->textureTransformCount[stage] = count;
508 context->textureTransformProject[stage] = project;
509 }
510
511 void VertexProcessor::setTextureFilter(unsigned int sampler, FilterType textureFilter)
512 {
513 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
514 {
515 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setTextureFilter(textureFilter);
516 }
517 else ASSERT(false);
518 }
519
520 void VertexProcessor::setMipmapFilter(unsigned int sampler, MipmapType mipmapFilter)
521 {
522 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
523 {
524 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapFilter(mipmapFilter);
525 }
526 else ASSERT(false);
527 }
528
529 void VertexProcessor::setGatherEnable(unsigned int sampler, bool enable)
530 {
531 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
532 {
533 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setGatherEnable(enable);
534 }
535 else ASSERT(false);
536 }
537
538 void VertexProcessor::setAddressingModeU(unsigned int sampler, AddressingMode addressMode)
539 {
540 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
541 {
542 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeU(addressMode);
543 }
544 else ASSERT(false);
545 }
546
547 void VertexProcessor::setAddressingModeV(unsigned int sampler, AddressingMode addressMode)
548 {
549 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
550 {
551 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeV(addressMode);
552 }
553 else ASSERT(false);
554 }
555
556 void VertexProcessor::setAddressingModeW(unsigned int sampler, AddressingMode addressMode)
557 {
558 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
559 {
560 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setAddressingModeW(addressMode);
561 }
562 else ASSERT(false);
563 }
564
565 void VertexProcessor::setReadSRGB(unsigned int sampler, bool sRGB)
566 {
567 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
568 {
569 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setReadSRGB(sRGB);
570 }
571 else ASSERT(false);
572 }
573
574 void VertexProcessor::setMipmapLOD(unsigned int sampler, float bias)
575 {
576 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
577 {
578 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMipmapLOD(bias);
579 }
580 else ASSERT(false);
581 }
582
583 void VertexProcessor::setBorderColor(unsigned int sampler, const Color<float> &borderColor)
584 {
585 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
586 {
587 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBorderColor(borderColor);
588 }
589 else ASSERT(false);
590 }
591
592 void VertexProcessor::setMaxAnisotropy(unsigned int sampler, float maxAnisotropy)
593 {
594 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
595 {
596 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxAnisotropy(maxAnisotropy);
597 }
598 else ASSERT(false);
599 }
600
601 void VertexProcessor::setHighPrecisionFiltering(unsigned int sampler, bool highPrecisionFiltering)
602 {
603 if(sampler < TEXTURE_IMAGE_UNITS)
604 {
605 context->sampler[sampler].setHighPrecisionFiltering(highPrecisionFiltering);
606 }
607 else ASSERT(false);
608 }
609
610 void VertexProcessor::setSwizzleR(unsigned int sampler, SwizzleType swizzleR)
611 {
612 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
613 {
614 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleR(swizzleR);
615 }
616 else ASSERT(false);
617 }
618
619 void VertexProcessor::setSwizzleG(unsigned int sampler, SwizzleType swizzleG)
620 {
621 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
622 {
623 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleG(swizzleG);
624 }
625 else ASSERT(false);
626 }
627
628 void VertexProcessor::setSwizzleB(unsigned int sampler, SwizzleType swizzleB)
629 {
630 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
631 {
632 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleB(swizzleB);
633 }
634 else ASSERT(false);
635 }
636
637 void VertexProcessor::setSwizzleA(unsigned int sampler, SwizzleType swizzleA)
638 {
639 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
640 {
641 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setSwizzleA(swizzleA);
642 }
643 else ASSERT(false);
644 }
645
646 void VertexProcessor::setCompareFunc(unsigned int sampler, CompareFunc compFunc)
647 {
648 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
649 {
650 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setCompareFunc(compFunc);
651 }
652 else ASSERT(false);
653 }
654
655 void VertexProcessor::setBaseLevel(unsigned int sampler, int baseLevel)
656 {
657 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
658 {
659 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setBaseLevel(baseLevel);
660 }
661 else ASSERT(false);
662 }
663
664 void VertexProcessor::setMaxLevel(unsigned int sampler, int maxLevel)
665 {
666 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
667 {
668 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLevel(maxLevel);
669 }
670 else ASSERT(false);
671 }
672
673 void VertexProcessor::setMinLod(unsigned int sampler, float minLod)
674 {
675 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
676 {
677 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMinLod(minLod);
678 }
679 else ASSERT(false);
680 }
681
682 void VertexProcessor::setMaxLod(unsigned int sampler, float maxLod)
683 {
684 if(sampler < VERTEX_TEXTURE_IMAGE_UNITS)
685 {
686 context->sampler[TEXTURE_IMAGE_UNITS + sampler].setMaxLod(maxLod);
687 }
688 else ASSERT(false);
689 }
690
691 void VertexProcessor::setSyncRequired(unsigned int sampler, bool isSincRequired)
692 {
693 if(sampler < TEXTURE_IMAGE_UNITS)
694 {
695 context->sampler[sampler].setSyncRequired(isSincRequired);
696 }
697 else ASSERT(false);
698 }
699
700 void VertexProcessor::setPointSize(float pointSize)
701 {
702 point.pointSize = replicate(pointSize);
703 }
704
705 void VertexProcessor::setPointSizeMin(float pointSizeMin)
706 {
707 point.pointSizeMin = pointSizeMin;
708 }
709
710 void VertexProcessor::setPointSizeMax(float pointSizeMax)
711 {
712 point.pointSizeMax = pointSizeMax;
713 }
714
715 void VertexProcessor::setPointScaleA(float pointScaleA)
716 {
717 point.pointScaleA = pointScaleA;
718 }
719
720 void VertexProcessor::setPointScaleB(float pointScaleB)
721 {
722 point.pointScaleB = pointScaleB;
723 }
724
725 void VertexProcessor::setPointScaleC(float pointScaleC)
726 {
727 point.pointScaleC = pointScaleC;
728 }
729
730 void VertexProcessor::setTransformFeedbackQueryEnabled(bool enable)
731 {
732 context->transformFeedbackQueryEnabled = enable;
733 }
734
735 void VertexProcessor::enableTransformFeedback(uint64_t enable)
736 {
737 context->transformFeedbackEnabled = enable;
738 }
739
740 const Matrix &VertexProcessor::getModelTransform(int i)
741 {
742 updateTransform();
743 return PBVM[i];
744 }
745
746 const Matrix &VertexProcessor::getViewTransform()
747 {
748 updateTransform();
749 return PBV;
750 }
751
752 bool VertexProcessor::isFixedFunction()
753 {
754 return !context->vertexShader;
755 }
756
757 void VertexProcessor::setTransform(const Matrix &M, int i)
758 {
759 ff.transformT[i][0][0] = M[0][0];
760 ff.transformT[i][0][1] = M[1][0];
761 ff.transformT[i][0][2] = M[2][0];
762 ff.transformT[i][0][3] = M[3][0];
763
764 ff.transformT[i][1][0] = M[0][1];
765 ff.transformT[i][1][1] = M[1][1];
766 ff.transformT[i][1][2] = M[2][1];
767 ff.transformT[i][1][3] = M[3][1];
768
769 ff.transformT[i][2][0] = M[0][2];
770 ff.transformT[i][2][1] = M[1][2];
771 ff.transformT[i][2][2] = M[2][2];
772 ff.transformT[i][2][3] = M[3][2];
773
774 ff.transformT[i][3][0] = M[0][3];
775 ff.transformT[i][3][1] = M[1][3];
776 ff.transformT[i][3][2] = M[2][3];
777 ff.transformT[i][3][3] = M[3][3];
778 }
779
780 void VertexProcessor::setCameraTransform(const Matrix &M, int i)
781 {
782 ff.cameraTransformT[i][0][0] = M[0][0];
783 ff.cameraTransformT[i][0][1] = M[1][0];
784 ff.cameraTransformT[i][0][2] = M[2][0];
785 ff.cameraTransformT[i][0][3] = M[3][0];
786
787 ff.cameraTransformT[i][1][0] = M[0][1];
788 ff.cameraTransformT[i][1][1] = M[1][1];
789 ff.cameraTransformT[i][1][2] = M[2][1];
790 ff.cameraTransformT[i][1][3] = M[3][1];
791
792 ff.cameraTransformT[i][2][0] = M[0][2];
793 ff.cameraTransformT[i][2][1] = M[1][2];
794 ff.cameraTransformT[i][2][2] = M[2][2];
795 ff.cameraTransformT[i][2][3] = M[3][2];
796
797 ff.cameraTransformT[i][3][0] = M[0][3];
798 ff.cameraTransformT[i][3][1] = M[1][3];
799 ff.cameraTransformT[i][3][2] = M[2][3];
800 ff.cameraTransformT[i][3][3] = M[3][3];
801 }
802
803 void VertexProcessor::setNormalTransform(const Matrix &M, int i)
804 {
805 ff.normalTransformT[i][0][0] = M[0][0];
806 ff.normalTransformT[i][0][1] = M[1][0];
807 ff.normalTransformT[i][0][2] = M[2][0];
808 ff.normalTransformT[i][0][3] = M[3][0];
809
810 ff.normalTransformT[i][1][0] = M[0][1];
811 ff.normalTransformT[i][1][1] = M[1][1];
812 ff.normalTransformT[i][1][2] = M[2][1];
813 ff.normalTransformT[i][1][3] = M[3][1];
814
815 ff.normalTransformT[i][2][0] = M[0][2];
816 ff.normalTransformT[i][2][1] = M[1][2];
817 ff.normalTransformT[i][2][2] = M[2][2];
818 ff.normalTransformT[i][2][3] = M[3][2];
819
820 ff.normalTransformT[i][3][0] = M[0][3];
821 ff.normalTransformT[i][3][1] = M[1][3];
822 ff.normalTransformT[i][3][2] = M[2][3];
823 ff.normalTransformT[i][3][3] = M[3][3];
824 }
825
826 void VertexProcessor::updateTransform()
827 {
828 if(!updateMatrix) return;
829
830 int activeMatrices = context->indexedVertexBlendEnable ? 12 : max(context->vertexBlendMatrixCount, 1);
831
832 if(updateProjectionMatrix)
833 {
834 PB = P * B;
835 PBV = PB * V;
836
837 for(int i = 0; i < activeMatrices; i++)
838 {
839 PBVM[i] = PBV * M[i];
840 updateModelMatrix[i] = false;
841 }
842
843 updateProjectionMatrix = false;
844 updateBaseMatrix = false;
845 updateViewMatrix = false;
846 }
847
848 if(updateBaseMatrix)
849 {
850 PB = P * B;
851 PBV = PB * V;
852
853 for(int i = 0; i < activeMatrices; i++)
854 {
855 PBVM[i] = PBV * M[i];
856 updateModelMatrix[i] = false;
857 }
858
859 updateBaseMatrix = false;
860 updateViewMatrix = false;
861 }
862
863 if(updateViewMatrix)
864 {
865 PBV = PB * V;
866
867 for(int i = 0; i < activeMatrices; i++)
868 {
869 PBVM[i] = PBV * M[i];
870 updateModelMatrix[i] = false;
871 }
872
873 updateViewMatrix = false;
874 }
875
876 for(int i = 0; i < activeMatrices; i++)
877 {
878 if(updateModelMatrix[i])
879 {
880 PBVM[i] = PBV * M[i];
881 updateModelMatrix[i] = false;
882 }
883 }
884
885 for(int i = 0; i < activeMatrices; i++)
886 {
887 setTransform(PBVM[i], i);
888 setCameraTransform(B * V * M[i], i);
889 setNormalTransform(~!(B * V * M[i]), i);
890 }
891
892 updateMatrix = false;
893 }
894
895 void VertexProcessor::setRoutineCacheSize(int cacheSize)
896 {
897 delete routineCache;
898 routineCache = new RoutineCache<State>(clamp(cacheSize, 1, 65536));
899 }
900
901 const VertexProcessor::State VertexProcessor::update(DrawType drawType)
902 {
903 if(isFixedFunction())
904 {
905 updateTransform();
906
907 if(updateLighting)
908 {
909 for(int i = 0; i < 8; i++)
910 {
911 if(context->vertexLightActive(i))
912 {
913 // Light position in camera coordinates
914 setLightViewPosition(i, B * V * context->getLightPosition(i));
915 }
916 }
917
918 updateLighting = false;
919 }
920 }
921
922 State state;
923
924 if(context->vertexShader)
925 {
926 state.shaderID = context->vertexShader->getSerialID();
927 }
928 else
929 {
930 state.shaderID = 0;
931 }
932
933 state.fixedFunction = !context->vertexShader && context->pixelShaderModel() < 0x0300;
934 state.textureSampling = context->vertexShader ? context->vertexShader->containsTextureSampling() : false;
935 state.positionRegister = context->vertexShader ? context->vertexShader->getPositionRegister() : Pos;
936 state.pointSizeRegister = context->vertexShader ? context->vertexShader->getPointSizeRegister() : Pts;
937
938 state.vertexBlendMatrixCount = context->vertexBlendMatrixCountActive();
939 state.indexedVertexBlendEnable = context->indexedVertexBlendActive();
940 state.vertexNormalActive = context->vertexNormalActive();
941 state.normalizeNormals = context->normalizeNormalsActive();
942 state.vertexLightingActive = context->vertexLightingActive();
943 state.diffuseActive = context->diffuseActive();
944 state.specularActive = context->specularActive();
945 state.vertexSpecularActive = context->vertexSpecularActive();
946
947 state.vertexLightActive = context->vertexLightActive(0) << 0 |
948 context->vertexLightActive(1) << 1 |
949 context->vertexLightActive(2) << 2 |
950 context->vertexLightActive(3) << 3 |
951 context->vertexLightActive(4) << 4 |
952 context->vertexLightActive(5) << 5 |
953 context->vertexLightActive(6) << 6 |
954 context->vertexLightActive(7) << 7;
955
956 state.vertexDiffuseMaterialSourceActive = context->vertexDiffuseMaterialSourceActive();
957 state.vertexSpecularMaterialSourceActive = context->vertexSpecularMaterialSourceActive();
958 state.vertexAmbientMaterialSourceActive = context->vertexAmbientMaterialSourceActive();
959 state.vertexEmissiveMaterialSourceActive = context->vertexEmissiveMaterialSourceActive();
960 state.fogActive = context->fogActive();
961 state.vertexFogMode = context->vertexFogModeActive();
962 state.rangeFogActive = context->rangeFogActive();
963 state.localViewerActive = context->localViewerActive();
964 state.pointSizeActive = context->pointSizeActive();
965 state.pointScaleActive = context->pointScaleActive();
966
967 state.preTransformed = context->preTransformed;
968 state.superSampling = context->getSuperSampleCount() > 1;
969
970 state.transformFeedbackQueryEnabled = context->transformFeedbackQueryEnabled;
971 state.transformFeedbackEnabled = context->transformFeedbackEnabled;
972
973 // Note: Quads aren't handled for verticesPerPrimitive, but verticesPerPrimitive is used for transform feedback,
974 // which is an OpenGL ES 3.0 feature, and OpenGL ES 3.0 doesn't support quads as a primitive type.
975 DrawType type = static_cast<DrawType>(static_cast<unsigned int>(drawType) & 0xF);
976 state.verticesPerPrimitive = 1 + (type >= DRAW_LINELIST) + (type >= DRAW_TRIANGLELIST);
977
978 for(int i = 0; i < MAX_VERTEX_INPUTS; i++)
979 {
980 state.input[i].type = context->input[i].type;
981 state.input[i].count = context->input[i].count;
982 state.input[i].normalized = context->input[i].normalized;
983 state.input[i].attribType = context->vertexShader ? context->vertexShader->getAttribType(i) : VertexShader::ATTRIBTYPE_FLOAT;
984 }
985
986 if(!context->vertexShader)
987 {
988 for(int i = 0; i < 8; i++)
989 {
990 // state.textureState[i].vertexTextureActive = context->vertexTextureActive(i, 0);
991 state.textureState[i].texGenActive = context->texGenActive(i);
992 state.textureState[i].textureTransformCountActive = context->textureTransformCountActive(i);
993 state.textureState[i].texCoordIndexActive = context->texCoordIndexActive(i);
994 }
995 }
996 else
997 {
998 for(unsigned int i = 0; i < VERTEX_TEXTURE_IMAGE_UNITS; i++)
999 {
1000 if(context->vertexShader->usesSampler(i))
1001 {
1002 state.sampler[i] = context->sampler[TEXTURE_IMAGE_UNITS + i].samplerState();
1003 }
1004 }
1005 }
1006
1007 if(context->vertexShader) // FIXME: Also when pre-transformed?
1008 {
1009 for(int i = 0; i < MAX_VERTEX_OUTPUTS; i++)
1010 {
1011 state.output[i].xWrite = context->vertexShader->getOutput(i, 0).active();
1012 state.output[i].yWrite = context->vertexShader->getOutput(i, 1).active();
1013 state.output[i].zWrite = context->vertexShader->getOutput(i, 2).active();
1014 state.output[i].wWrite = context->vertexShader->getOutput(i, 3).active();
1015 }
1016 }
1017 else if(!context->preTransformed || context->pixelShaderModel() < 0x0300)
1018 {
1019 state.output[Pos].write = 0xF;
1020
1021 if(context->diffuseActive() && (context->lightingEnable || context->input[Color0]))
1022 {
1023 state.output[C0].write = 0xF;
1024 }
1025
1026 if(context->specularActive())
1027 {
1028 state.output[C1].write = 0xF;
1029 }
1030
1031 for(int stage = 0; stage < 8; stage++)
1032 {
1033 if(context->texCoordActive(stage, 0)) state.output[T0 + stage].write |= 0x01;
1034 if(context->texCoordActive(stage, 1)) state.output[T0 + stage].write |= 0x02;
1035 if(context->texCoordActive(stage, 2)) state.output[T0 + stage].write |= 0x04;
1036 if(context->texCoordActive(stage, 3)) state.output[T0 + stage].write |= 0x08;
1037 }
1038
1039 if(context->fogActive())
1040 {
1041 state.output[Fog].xWrite = true;
1042 }
1043
1044 if(context->pointSizeActive())
1045 {
1046 state.output[Pts].yWrite = true;
1047 }
1048 }
1049 else
1050 {
1051 state.output[Pos].write = 0xF;
1052
1053 for(int i = 0; i < 2; i++)
1054 {
1055 if(context->input[Color0 + i])
1056 {
1057 state.output[C0 + i].write = 0xF;
1058 }
1059 }
1060
1061 for(int i = 0; i < 8; i++)
1062 {
1063 if(context->input[TexCoord0 + i])
1064 {
1065 state.output[T0 + i].write = 0xF;
1066 }
1067 }
1068
1069 if(context->input[PointSize])
1070 {
1071 state.output[Pts].yWrite = true;
1072 }
1073 }
1074
1075 if(context->vertexShaderModel() < 0x0300)
1076 {
1077 state.output[C0].clamp = 0xF;
1078 state.output[C1].clamp = 0xF;
1079 state.output[Fog].xClamp = true;
1080 }
1081
1082 state.hash = state.computeHash();
1083
1084 return state;
1085 }
1086
1087 std::shared_ptr<Routine> VertexProcessor::routine(const State &state)
1088 {
1089 auto routine = routineCache->query(state);
1090
1091 if(!routine) // Create one
1092 {
1093 VertexRoutine *generator = nullptr;
1094
1095 if(state.fixedFunction)
1096 {
1097 generator = new VertexPipeline(state);
1098 }
1099 else
1100 {
1101 generator = new VertexProgram(state, context->vertexShader);
1102 }
1103
1104 generator->generate();
1105 routine = (*generator)("VertexRoutine_%0.8X", state.shaderID);
1106 delete generator;
1107
1108 routineCache->add(state, routine);
1109 }
1110
1111 return routine;
1112 }
1113}
1114