1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
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
7 // http://www.apache.org/licenses/LICENSE-2.0
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.
15 #include "VertexPipeline.hpp"
18 #include "Renderer.hpp"
30 extern bool secondaryColor;
32 VertexPipeline::VertexPipeline(const VertexProcessor::State &state) : VertexRoutine(state, 0)
36 VertexPipeline::~VertexPipeline()
40 Vector4f VertexPipeline::transformBlend(const Register &src, const Pointer<Byte> &matrix, bool homogeneous)
44 if(state.vertexBlendMatrixCount == 0)
46 dst = transform(src, matrix, homogeneous);
55 if(state.indexedVertexBlendEnable)
57 for(int i = 0; i < 4; i++)
59 Float4 B = v[BlendIndices].x;
64 case 0: indices = As<UInt>(Float(B.x)); break;
65 case 1: indices = As<UInt>(Float(B.y)); break;
66 case 2: indices = As<UInt>(Float(B.z)); break;
67 case 3: indices = As<UInt>(Float(B.w)); break;
70 index0[i] = (indices & 0x000000FF) << 6;
71 index1[i] = (indices & 0x0000FF00) >> 2;
72 index2[i] = (indices & 0x00FF0000) >> 10;
73 index3[i] = (indices & 0xFF000000) >> 18;
78 for(int i = 0; i < 4; i++)
92 switch(state.vertexBlendMatrixCount)
94 case 4: weight2 = v[BlendWeight].z;
95 case 3: weight1 = v[BlendWeight].y;
96 case 2: weight0 = v[BlendWeight].x;
101 if(state.vertexBlendMatrixCount == 1)
103 dst = transform(src, matrix, index0, homogeneous);
105 else if(state.vertexBlendMatrixCount == 2)
107 weight1 = Float4(1.0f) - weight0;
112 pos0 = transform(src, matrix, index0, homogeneous);
113 pos1 = transform(src, matrix, index1, homogeneous);
115 dst.x = pos0.x * weight0 + pos1.x * weight1; // FIXME: Vector4f operators
116 dst.y = pos0.y * weight0 + pos1.y * weight1;
117 dst.z = pos0.z * weight0 + pos1.z * weight1;
118 dst.w = pos0.w * weight0 + pos1.w * weight1;
120 else if(state.vertexBlendMatrixCount == 3)
122 weight2 = Float4(1.0f) - (weight0 + weight1);
128 pos0 = transform(src, matrix, index0, homogeneous);
129 pos1 = transform(src, matrix, index1, homogeneous);
130 pos2 = transform(src, matrix, index2, homogeneous);
132 dst.x = pos0.x * weight0 + pos1.x * weight1 + pos2.x * weight2;
133 dst.y = pos0.y * weight0 + pos1.y * weight1 + pos2.y * weight2;
134 dst.z = pos0.z * weight0 + pos1.z * weight1 + pos2.z * weight2;
135 dst.w = pos0.w * weight0 + pos1.w * weight1 + pos2.w * weight2;
137 else if(state.vertexBlendMatrixCount == 4)
139 weight3 = Float4(1.0f) - (weight0 + weight1 + weight2);
146 pos0 = transform(src, matrix, index0, homogeneous);
147 pos1 = transform(src, matrix, index1, homogeneous);
148 pos2 = transform(src, matrix, index2, homogeneous);
149 pos3 = transform(src, matrix, index3, homogeneous);
151 dst.x = pos0.x * weight0 + pos1.x * weight1 + pos2.x * weight2 + pos3.x * weight3;
152 dst.y = pos0.y * weight0 + pos1.y * weight1 + pos2.y * weight2 + pos3.y * weight3;
153 dst.z = pos0.z * weight0 + pos1.z * weight1 + pos2.z * weight2 + pos3.z * weight3;
154 dst.w = pos0.w * weight0 + pos1.w * weight1 + pos2.w * weight2 + pos3.w * weight3;
161 void VertexPipeline::pipeline()
166 if(!state.preTransformed)
168 position = transformBlend(v[Position], Pointer<Byte>(data + OFFSET(DrawData,ff.transformT)), true);
172 position = v[PositionT];
175 o[Pos].x = position.x;
176 o[Pos].y = position.y;
177 o[Pos].z = position.z;
178 o[Pos].w = position.w;
180 Vector4f vertexPosition = transformBlend(v[Position], Pointer<Byte>(data + OFFSET(DrawData,ff.cameraTransformT)), true);
182 if(state.vertexNormalActive)
184 normal = transformBlend(v[Normal], Pointer<Byte>(data + OFFSET(DrawData,ff.normalTransformT)), false);
186 if(state.normalizeNormals)
188 normal = normalize(normal);
192 if(!state.vertexLightingActive)
194 // FIXME: Don't process if not used at all
195 if(state.diffuseActive && state.input[Color0])
197 Vector4f diffuse = v[Color0];
206 o[C0].x = Float4(1.0f);
207 o[C0].y = Float4(1.0f);
208 o[C0].z = Float4(1.0f);
209 o[C0].w = Float4(1.0f);
212 // FIXME: Don't process if not used at all
213 if(state.specularActive && state.input[Color1])
215 Vector4f specular = v[Color1];
217 o[C1].x = specular.x;
218 o[C1].y = specular.y;
219 o[C1].z = specular.z;
220 o[C1].w = specular.w;
224 o[C1].x = Float4(0.0f);
225 o[C1].y = Float4(0.0f);
226 o[C1].z = Float4(0.0f);
227 o[C1].w = Float4(1.0f);
232 o[C0].x = Float4(0.0f);
233 o[C0].y = Float4(0.0f);
234 o[C0].z = Float4(0.0f);
235 o[C0].w = Float4(0.0f);
237 o[C1].x = Float4(0.0f);
238 o[C1].y = Float4(0.0f);
239 o[C1].z = Float4(0.0f);
240 o[C1].w = Float4(0.0f);
243 Float4 globalAmbient = *Pointer<Float4>(data + OFFSET(DrawData,ff.globalAmbient)); // FIXME: Unpack
245 ambient.x = globalAmbient.x;
246 ambient.y = globalAmbient.y;
247 ambient.z = globalAmbient.z;
249 for(int i = 0; i < 8; i++)
251 if(!(state.vertexLightActive & (1 << i)))
256 Vector4f L; // Light vector
257 Float4 att; // Attenuation
261 Float4 d; // Distance
263 L.x = L.y = L.z = *Pointer<Float4>(data + OFFSET(DrawData,ff.lightPosition[i])); // FIXME: Unpack
268 L.x -= vertexPosition.x;
269 L.y -= vertexPosition.y;
270 L.z -= vertexPosition.z;
272 d = RcpSqrt_pp(d); // FIXME: Sufficient precision?
276 d = Rcp_pp(d); // FIXME: Sufficient precision?
278 Float4 q = *Pointer<Float4>(data + OFFSET(DrawData,ff.attenuationQuadratic[i]));
279 Float4 l = *Pointer<Float4>(data + OFFSET(DrawData,ff.attenuationLinear[i]));
280 Float4 c = *Pointer<Float4>(data + OFFSET(DrawData,ff.attenuationConstant[i]));
282 att = Rcp_pp((q * d + l) * d + c);
287 Float4 lightAmbient = *Pointer<Float4>(data + OFFSET(DrawData,ff.lightAmbient[i])); // FIXME: Unpack
289 ambient.x = ambient.x + lightAmbient.x * att;
290 ambient.y = ambient.y + lightAmbient.y * att;
291 ambient.z = ambient.z + lightAmbient.z * att;
295 if(state.vertexNormalActive)
299 dot = dot3(L, normal);
300 dot = Max(dot, Float4(0.0f));
305 if(state.vertexDiffuseMaterialSourceActive == MATERIAL_MATERIAL)
307 diff.x = diff.y = diff.z = *Pointer<Float4>(data + OFFSET(DrawData,ff.materialDiffuse)); // FIXME: Unpack
308 diff.x = diff.x.xxxx;
309 diff.y = diff.y.yyyy;
310 diff.z = diff.z.zzzz;
312 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR1)
316 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR2)
322 Float4 lightDiffuse = *Pointer<Float4>(data + OFFSET(DrawData,ff.lightDiffuse[i]));
324 o[C0].x = o[C0].x + diff.x * dot * lightDiffuse.x; // FIXME: Clamp first?
325 o[C0].y = o[C0].y + diff.y * dot * lightDiffuse.y; // FIXME: Clamp first?
326 o[C0].z = o[C0].z + diff.z * dot * lightDiffuse.z; // FIXME: Clamp first?
330 if(state.vertexSpecularActive)
333 Vector4f C; // Camera vector
336 pow = *Pointer<Float>(data + OFFSET(DrawData,ff.materialShininess));
338 S.x = Float4(0.0f) - vertexPosition.x;
339 S.y = Float4(0.0f) - vertexPosition.y;
340 S.z = Float4(0.0f) - vertexPosition.z;
348 Float4 dot = Max(dot3(C, normal), Float4(0.0f)); // FIXME: max(dot3(C, normal), 0)
350 Float4 P = power(dot, pow);
355 if(state.vertexSpecularMaterialSourceActive == MATERIAL_MATERIAL)
357 Float4 materialSpecular = *Pointer<Float4>(data + OFFSET(DrawData,ff.materialSpecular)); // FIXME: Unpack
359 spec.x = materialSpecular.x;
360 spec.y = materialSpecular.y;
361 spec.z = materialSpecular.z;
363 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR1)
367 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR2)
373 Float4 lightSpecular = *Pointer<Float4>(data + OFFSET(DrawData,ff.lightSpecular[i]));
375 spec.x *= lightSpecular.x;
376 spec.y *= lightSpecular.y;
377 spec.z *= lightSpecular.z;
383 spec.x = Max(spec.x, Float4(0.0f));
384 spec.y = Max(spec.y, Float4(0.0f));
385 spec.z = Max(spec.z, Float4(0.0f));
389 o[C1].x = o[C1].x + spec.x;
390 o[C1].y = o[C1].y + spec.y;
391 o[C1].z = o[C1].z + spec.z;
395 o[C0].x = o[C0].x + spec.x;
396 o[C0].y = o[C0].y + spec.y;
397 o[C0].z = o[C0].z + spec.z;
402 if(state.vertexAmbientMaterialSourceActive == MATERIAL_MATERIAL)
404 Float4 materialAmbient = *Pointer<Float4>(data + OFFSET(DrawData,ff.materialAmbient)); // FIXME: Unpack
406 ambient.x = ambient.x * materialAmbient.x;
407 ambient.y = ambient.y * materialAmbient.y;
408 ambient.z = ambient.z * materialAmbient.z;
410 else if(state.vertexAmbientMaterialSourceActive == MATERIAL_COLOR1)
412 Vector4f materialDiffuse = v[Color0];
414 ambient.x = ambient.x * materialDiffuse.x;
415 ambient.y = ambient.y * materialDiffuse.y;
416 ambient.z = ambient.z * materialDiffuse.z;
418 else if(state.vertexAmbientMaterialSourceActive == MATERIAL_COLOR2)
420 Vector4f materialSpecular = v[Color1];
422 ambient.x = ambient.x * materialSpecular.x;
423 ambient.y = ambient.y * materialSpecular.y;
424 ambient.z = ambient.z * materialSpecular.z;
428 o[C0].x = o[C0].x + ambient.x;
429 o[C0].y = o[C0].y + ambient.y;
430 o[C0].z = o[C0].z + ambient.z;
433 if(state.vertexEmissiveMaterialSourceActive == MATERIAL_MATERIAL)
435 Float4 materialEmission = *Pointer<Float4>(data + OFFSET(DrawData,ff.materialEmission)); // FIXME: Unpack
437 o[C0].x = o[C0].x + materialEmission.x;
438 o[C0].y = o[C0].y + materialEmission.y;
439 o[C0].z = o[C0].z + materialEmission.z;
441 else if(state.vertexEmissiveMaterialSourceActive == MATERIAL_COLOR1)
443 Vector4f materialSpecular = v[Color0];
445 o[C0].x = o[C0].x + materialSpecular.x;
446 o[C0].y = o[C0].y + materialSpecular.y;
447 o[C0].z = o[C0].z + materialSpecular.z;
449 else if(state.vertexEmissiveMaterialSourceActive == MATERIAL_COLOR2)
451 Vector4f materialSpecular = v[Color1];
453 o[C0].x = o[C0].x + materialSpecular.x;
454 o[C0].y = o[C0].y + materialSpecular.y;
455 o[C0].z = o[C0].z + materialSpecular.z;
459 // Diffuse alpha component
460 if(state.vertexDiffuseMaterialSourceActive == MATERIAL_MATERIAL)
462 o[C0].w = Float4(*Pointer<Float4>(data + OFFSET(DrawData,ff.materialDiffuse[0]))).wwww; // FIXME: Unpack
464 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR1)
466 Vector4f alpha = v[Color0];
469 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR2)
471 Vector4f alpha = v[Color1];
476 if(state.vertexSpecularActive)
478 // Specular alpha component
479 if(state.vertexSpecularMaterialSourceActive == MATERIAL_MATERIAL)
481 o[C1].w = Float4(*Pointer<Float4>(data + OFFSET(DrawData,ff.materialSpecular[3]))).wwww; // FIXME: Unpack
483 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR1)
485 Vector4f alpha = v[Color0];
488 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR2)
490 Vector4f alpha = v[Color1];
501 if(!state.rangeFogActive)
503 f = Abs(vertexPosition.z);
507 f = Sqrt(dot3(vertexPosition, vertexPosition)); // FIXME: f = length(vertexPosition);
510 switch(state.vertexFogMode)
513 if(state.specularActive)
519 o[Fog].x = Float4(0.0f);
523 o[Fog].x = f * *Pointer<Float4>(data + OFFSET(DrawData,fog.scale)) + *Pointer<Float4>(data + OFFSET(DrawData,fog.offset));
526 o[Fog].x = exponential2(f * *Pointer<Float4>(data + OFFSET(DrawData,fog.densityE)), true);
529 o[Fog].x = exponential2((f * f) * *Pointer<Float4>(data + OFFSET(DrawData,fog.density2E)), true);
536 for(int stage = 0; stage < 8; stage++)
538 processTextureCoordinate(stage, normal, position);
544 void VertexPipeline::processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position)
546 if(state.output[T0 + stage].write)
548 int i = state.textureState[stage].texCoordIndexActive;
550 switch(state.textureState[stage].texGenActive)
554 Vector4f &&varying = v[TexCoord0 + i];
556 o[T0 + stage].x = varying.x;
557 o[T0 + stage].y = varying.y;
558 o[T0 + stage].z = varying.z;
559 o[T0 + stage].w = varying.w;
562 case TEXGEN_PASSTHRU:
564 Vector4f &&varying = v[TexCoord0 + i];
566 o[T0 + stage].x = varying.x;
567 o[T0 + stage].y = varying.y;
568 o[T0 + stage].z = varying.z;
569 o[T0 + stage].w = varying.w;
571 if(state.input[TexCoord0 + i])
573 switch(state.input[TexCoord0 + i].count)
576 o[T0 + stage].y = Float4(1.0f);
577 o[T0 + stage].z = Float4(0.0f);
578 o[T0 + stage].w = Float4(0.0f);
581 o[T0 + stage].z = Float4(1.0f);
582 o[T0 + stage].w = Float4(0.0f);
585 o[T0 + stage].w = Float4(1.0f);
597 Vector4f Nc; // Normal vector in camera space
599 if(state.vertexNormalActive)
612 o[T0 + stage].x = Nc.x;
613 o[T0 + stage].y = Nc.y;
614 o[T0 + stage].z = Nc.z;
615 o[T0 + stage].w = Nc.w;
618 case TEXGEN_POSITION:
620 Vector4f Pn = transformBlend(v[Position], Pointer<Byte>(data + OFFSET(DrawData,ff.cameraTransformT)), true); // Position in camera space
624 o[T0 + stage].x = Pn.x;
625 o[T0 + stage].y = Pn.y;
626 o[T0 + stage].z = Pn.z;
627 o[T0 + stage].w = Pn.w;
630 case TEXGEN_REFLECTION:
632 Vector4f R; // Reflection vector
634 if(state.vertexNormalActive)
636 Vector4f Nc; // Normal vector in camera space
640 if(state.localViewerActive)
642 Vector4f Ec; // Eye vector in camera space
645 Ec = transformBlend(v[Position], Pointer<Byte>(data + OFFSET(DrawData,ff.cameraTransformT)), true);
648 // R = E - 2 * N * (E . N)
649 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
651 R.x = Ec.x - Nc.x * dot;
652 R.y = Ec.y - Nc.y * dot;
653 R.z = Ec.z - Nc.z * dot;
659 // w = 1 - 2 * Nz * Nz
661 R.x = -Float4(2.0f) * Nc.z * Nc.x;
662 R.y = -Float4(2.0f) * Nc.z * Nc.y;
663 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
675 o[T0 + stage].x = R.x;
676 o[T0 + stage].y = R.y;
677 o[T0 + stage].z = R.z;
678 o[T0 + stage].w = R.w;
681 case TEXGEN_SPHEREMAP:
683 Vector4f R; // Reflection vector
685 if(state.vertexNormalActive)
687 Vector4f Nc; // Normal vector in camera space
691 if(state.localViewerActive)
693 Vector4f Ec; // Eye vector in camera space
696 Ec = transformBlend(v[Position], Pointer<Byte>(data + OFFSET(DrawData,ff.cameraTransformT)), true);
699 // R = E - 2 * N * (E . N)
700 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
702 R.x = Ec.x - Nc.x * dot;
703 R.y = Ec.y - Nc.y * dot;
704 R.z = Ec.z - Nc.z * dot;
710 // w = 1 - 2 * Nz * Nz
712 R.x = -Float4(2.0f) * Nc.z * Nc.x;
713 R.y = -Float4(2.0f) * Nc.z * Nc.y;
714 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
726 R.x = Float4(0.5f) * R.x + Float4(0.5f);
727 R.y = Float4(0.5f) * R.y + Float4(0.5f);
732 o[T0 + stage].x = R.x;
733 o[T0 + stage].y = R.y;
734 o[T0 + stage].z = R.z;
735 o[T0 + stage].w = R.w;
750 T.x = o[T0 + stage].x;
751 T.y = o[T0 + stage].y;
752 T.z = o[T0 + stage].z;
753 T.w = o[T0 + stage].w;
755 switch(state.textureState[stage].textureTransformCountActive)
758 texTrans3.x = texTrans3.y = texTrans3.z = texTrans3.w = *Pointer<Float4>(data + OFFSET(DrawData,ff.textureTransform[stage][3])); // FIXME: Unpack
759 texTrans3.x = texTrans3.x.xxxx;
760 texTrans3.y = texTrans3.y.yyyy;
761 texTrans3.z = texTrans3.z.zzzz;
762 texTrans3.w = texTrans3.w.wwww;
763 t.w = dot4(T, texTrans3);
765 texTrans2.x = texTrans2.y = texTrans2.z = texTrans2.w = *Pointer<Float4>(data + OFFSET(DrawData,ff.textureTransform[stage][2])); // FIXME: Unpack
766 texTrans2.x = texTrans2.x.xxxx;
767 texTrans2.y = texTrans2.y.yyyy;
768 texTrans2.z = texTrans2.z.zzzz;
769 texTrans2.w = texTrans2.w.wwww;
770 t.z = dot4(T, texTrans2);
772 texTrans1.x = texTrans1.y = texTrans1.z = texTrans1.w = *Pointer<Float4>(data + OFFSET(DrawData,ff.textureTransform[stage][1])); // FIXME: Unpack
773 texTrans1.x = texTrans1.x.xxxx;
774 texTrans1.y = texTrans1.y.yyyy;
775 texTrans1.z = texTrans1.z.zzzz;
776 texTrans1.w = texTrans1.w.wwww;
777 t.y = dot4(T, texTrans1);
779 texTrans0.x = texTrans0.y = texTrans0.z = texTrans0.w = *Pointer<Float4>(data + OFFSET(DrawData,ff.textureTransform[stage][0])); // FIXME: Unpack
780 texTrans0.x = texTrans0.x.xxxx;
781 texTrans0.y = texTrans0.y.yyyy;
782 texTrans0.z = texTrans0.z.zzzz;
783 texTrans0.w = texTrans0.w.wwww;
784 t.x = dot4(T, texTrans0);
786 o[T0 + stage].x = t.x;
787 o[T0 + stage].y = t.y;
788 o[T0 + stage].z = t.z;
789 o[T0 + stage].w = t.w;
798 void VertexPipeline::processPointSize()
800 if(!state.pointSizeActive)
802 return; // Use global pointsize
805 if(state.input[PointSize])
807 o[Pts].y = v[PointSize].x;
811 o[Pts].y = *Pointer<Float4>(data + OFFSET(DrawData,point.pointSize));
814 if(state.pointScaleActive && !state.preTransformed)
816 Vector4f p = transformBlend(v[Position], Pointer<Byte>(data + OFFSET(DrawData,ff.cameraTransformT)), true);
818 Float4 d = Sqrt(dot3(p, p)); // FIXME: length(p);
820 Float4 A = *Pointer<Float>(data + OFFSET(DrawData,point.pointScaleA)); // FIXME: Unpack
821 Float4 B = *Pointer<Float>(data + OFFSET(DrawData,point.pointScaleB)); // FIXME: Unpack
822 Float4 C = *Pointer<Float>(data + OFFSET(DrawData,point.pointScaleC)); // FIXME: Unpack
824 A = RcpSqrt_pp(A + d * (B + d * C));
826 o[Pts].y = o[Pts].y * Float4(*Pointer<Float>(data + OFFSET(DrawData,viewportHeight))) * A; // FIXME: Unpack
830 Vector4f VertexPipeline::transform(const Register &src, const Pointer<Byte> &matrix, bool homogeneous)
838 for(int j = 0; j < 4; j++)
840 for(int i = 0; i < 4; i++)
842 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
843 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
844 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
845 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
849 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + src.w * m[0][3];
850 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + src.w * m[1][3];
851 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + src.w * m[2][3];
852 dst.w = src.x * m[3][0] + src.y * m[3][1] + src.z * m[3][2] + src.w * m[3][3];
858 for(int j = 0; j < 3; j++)
860 for(int i = 0; i < 3; i++)
862 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
863 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
864 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
865 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
869 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
870 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
871 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
877 Vector4f VertexPipeline::transform(const Register &src, const Pointer<Byte> &matrix, UInt index[4], bool homogeneous)
885 for(int j = 0; j < 4; j++)
887 for(int i = 0; i < 4; i++)
889 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
890 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
891 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
892 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
896 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + m[0][3];
897 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + m[1][3];
898 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + m[2][3];
899 dst.w = src.x * m[3][0] + src.y * m[3][1] + src.z * m[3][2] + m[3][3];
905 for(int j = 0; j < 3; j++)
907 for(int i = 0; i < 3; i++)
909 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
910 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
911 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
912 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
916 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
917 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
918 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
924 Vector4f VertexPipeline::normalize(Vector4f &src)
928 Float4 rcpLength = RcpSqrt_pp(dot3(src, src));
930 dst.x = src.x * rcpLength;
931 dst.y = src.y * rcpLength;
932 dst.z = src.z * rcpLength;
937 Float4 VertexPipeline::power(Float4 &src0, Float4 &src1)
943 dst = Float4(As<Int4>(dst) - As<Int4>(Float4(1.0f)));
947 dst = As<Float4>(Int4(dst) + As<Int4>(Float4(1.0f)));
948 dst = RcpSqrt_pp(dst);
949 dst = RcpSqrt_pp(dst);