blob: f54852f5aa5219b61135e24c8746efcde88bcf91 [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 "VertexPipeline.hpp"
13
14#include "Vertex.hpp"
15#include "Renderer.hpp"
16#include "Debug.hpp"
17
18#include <string.h>
19#include <stdlib.h>
20#include <stdio.h>
21
22#undef max
23#undef min
24
25namespace sw
26{
John Bauman19bac1e2014-05-06 15:23:49 -040027 VertexPipeline::VertexPipeline(const VertexProcessor::State &state) : VertexRoutine(state, 0)
John Bauman89401822014-05-06 15:04:28 -040028 {
29 }
30
31 VertexPipeline::~VertexPipeline()
32 {
33 }
34
John Bauman66b8ab22014-05-06 15:57:45 -040035 Vector4f VertexPipeline::transformBlend(Registers &r, const Register &src, const Pointer<Byte> &matrix, bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -040036 {
John Bauman19bac1e2014-05-06 15:23:49 -040037 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -040038
39 if(state.vertexBlendMatrixCount == 0)
40 {
41 dst = transform(src, matrix, homogeneous);
42 }
43 else
44 {
45 UInt index0[4];
46 UInt index1[4];
47 UInt index2[4];
48 UInt index3[4];
49
50 if(state.indexedVertexBlendEnable)
51 {
52 for(int i = 0; i < 4; i++)
53 {
John Bauman19bac1e2014-05-06 15:23:49 -040054 Float4 B = r.v[BlendIndices].x;
John Bauman89401822014-05-06 15:04:28 -040055 UInt indices;
56
57 switch(i)
58 {
John Bauman19bac1e2014-05-06 15:23:49 -040059 case 0: indices = As<UInt>(Float(B.x)); break;
60 case 1: indices = As<UInt>(Float(B.y)); break;
61 case 2: indices = As<UInt>(Float(B.z)); break;
62 case 3: indices = As<UInt>(Float(B.w)); break;
John Bauman89401822014-05-06 15:04:28 -040063 }
64
John Bauman66b8ab22014-05-06 15:57:45 -040065 index0[i] = (indices & 0x000000FF) << 6;
66 index1[i] = (indices & 0x0000FF00) >> 2;
67 index2[i] = (indices & 0x00FF0000) >> 10;
68 index3[i] = (indices & 0xFF000000) >> 18;
John Bauman89401822014-05-06 15:04:28 -040069 }
70 }
71 else
72 {
73 for(int i = 0; i < 4; i++)
74 {
John Bauman66b8ab22014-05-06 15:57:45 -040075 index0[i] = 0 * 64;
76 index1[i] = 1 * 64;
77 index2[i] = 2 * 64;
78 index3[i] = 3 * 64;
John Bauman89401822014-05-06 15:04:28 -040079 }
80 }
81
82 Float4 weight0;
83 Float4 weight1;
84 Float4 weight2;
85 Float4 weight3;
86
87 switch(state.vertexBlendMatrixCount)
88 {
89 case 4: weight2 = r.v[BlendWeight].z;
90 case 3: weight1 = r.v[BlendWeight].y;
91 case 2: weight0 = r.v[BlendWeight].x;
92 case 1:
93 break;
94 }
95
96 if(state.vertexBlendMatrixCount == 1)
97 {
98 dst = transform(src, matrix, index0, homogeneous);
99 }
100 else if(state.vertexBlendMatrixCount == 2)
101 {
102 weight1 = Float4(1.0f) - weight0;
103
John Bauman19bac1e2014-05-06 15:23:49 -0400104 Vector4f pos0;
105 Vector4f pos1;
John Bauman89401822014-05-06 15:04:28 -0400106
107 pos0 = transform(src, matrix, index0, homogeneous);
108 pos1 = transform(src, matrix, index1, homogeneous);
109
John Bauman19bac1e2014-05-06 15:23:49 -0400110 dst.x = pos0.x * weight0 + pos1.x * weight1; // FIXME: Vector4f operators
John Bauman89401822014-05-06 15:04:28 -0400111 dst.y = pos0.y * weight0 + pos1.y * weight1;
112 dst.z = pos0.z * weight0 + pos1.z * weight1;
113 dst.w = pos0.w * weight0 + pos1.w * weight1;
114 }
115 else if(state.vertexBlendMatrixCount == 3)
116 {
117 weight2 = Float4(1.0f) - (weight0 + weight1);
118
John Bauman19bac1e2014-05-06 15:23:49 -0400119 Vector4f pos0;
120 Vector4f pos1;
121 Vector4f pos2;
John Bauman89401822014-05-06 15:04:28 -0400122
123 pos0 = transform(src, matrix, index0, homogeneous);
124 pos1 = transform(src, matrix, index1, homogeneous);
125 pos2 = transform(src, matrix, index2, homogeneous);
126
127 dst.x = pos0.x * weight0 + pos1.x * weight1 + pos2.x * weight2;
128 dst.y = pos0.y * weight0 + pos1.y * weight1 + pos2.y * weight2;
129 dst.z = pos0.z * weight0 + pos1.z * weight1 + pos2.z * weight2;
130 dst.w = pos0.w * weight0 + pos1.w * weight1 + pos2.w * weight2;
131 }
132 else if(state.vertexBlendMatrixCount == 4)
133 {
134 weight3 = Float4(1.0f) - (weight0 + weight1 + weight2);
135
John Bauman19bac1e2014-05-06 15:23:49 -0400136 Vector4f pos0;
137 Vector4f pos1;
138 Vector4f pos2;
139 Vector4f pos3;
John Bauman89401822014-05-06 15:04:28 -0400140
141 pos0 = transform(src, matrix, index0, homogeneous);
142 pos1 = transform(src, matrix, index1, homogeneous);
143 pos2 = transform(src, matrix, index2, homogeneous);
144 pos3 = transform(src, matrix, index3, homogeneous);
145
146 dst.x = pos0.x * weight0 + pos1.x * weight1 + pos2.x * weight2 + pos3.x * weight3;
147 dst.y = pos0.y * weight0 + pos1.y * weight1 + pos2.y * weight2 + pos3.y * weight3;
148 dst.z = pos0.z * weight0 + pos1.z * weight1 + pos2.z * weight2 + pos3.z * weight3;
149 dst.w = pos0.w * weight0 + pos1.w * weight1 + pos2.w * weight2 + pos3.w * weight3;
150 }
151 }
152
153 return dst;
154 }
155
156 void VertexPipeline::pipeline(Registers &r)
157 {
John Bauman19bac1e2014-05-06 15:23:49 -0400158 Vector4f position;
159 Vector4f normal;
John Bauman89401822014-05-06 15:04:28 -0400160
161 if(!state.preTransformed)
162 {
163 position = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.transformT)), true);
164 }
165 else
166 {
167 position = r.v[PositionT];
168 }
169
John Bauman19bac1e2014-05-06 15:23:49 -0400170 r.o[Pos].x = position.x;
171 r.o[Pos].y = position.y;
172 r.o[Pos].z = position.z;
173 r.o[Pos].w = position.w;
John Bauman89401822014-05-06 15:04:28 -0400174
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400175 Vector4f vertexPosition = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
176
John Bauman89401822014-05-06 15:04:28 -0400177 if(state.vertexNormalActive)
178 {
179 normal = transformBlend(r, r.v[Normal], Pointer<Byte>(r.data + OFFSET(DrawData,ff.normalTransformT)), false);
180
181 if(state.normalizeNormals)
182 {
183 normal = normalize(normal);
184 }
185 }
186
187 if(!state.vertexLightingActive)
188 {
189 // FIXME: Don't process if not used at all
190 if(state.diffuseActive && state.input[Color0])
191 {
John Bauman19bac1e2014-05-06 15:23:49 -0400192 Vector4f diffuse = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400193
John Bauman19bac1e2014-05-06 15:23:49 -0400194 r.o[D0].x = diffuse.x;
195 r.o[D0].y = diffuse.y;
196 r.o[D0].z = diffuse.z;
197 r.o[D0].w = diffuse.w;
John Bauman89401822014-05-06 15:04:28 -0400198 }
199 else
200 {
John Bauman19bac1e2014-05-06 15:23:49 -0400201 r.o[D0].x = Float4(1.0f);
202 r.o[D0].y = Float4(1.0f);
203 r.o[D0].z = Float4(1.0f);
204 r.o[D0].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400205 }
206
207 // FIXME: Don't process if not used at all
208 if(state.specularActive && state.input[Color1])
209 {
John Bauman19bac1e2014-05-06 15:23:49 -0400210 Vector4f specular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400211
John Bauman19bac1e2014-05-06 15:23:49 -0400212 r.o[D1].x = specular.x;
213 r.o[D1].y = specular.y;
214 r.o[D1].z = specular.z;
215 r.o[D1].w = specular.w;
John Bauman89401822014-05-06 15:04:28 -0400216 }
217 else
218 {
John Bauman19bac1e2014-05-06 15:23:49 -0400219 r.o[D1].x = Float4(0.0f);
220 r.o[D1].y = Float4(0.0f);
221 r.o[D1].z = Float4(0.0f);
222 r.o[D1].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400223 }
224 }
225 else
226 {
John Bauman19bac1e2014-05-06 15:23:49 -0400227 r.o[D0].x = Float4(0.0f);
228 r.o[D0].y = Float4(0.0f);
229 r.o[D0].z = Float4(0.0f);
230 r.o[D0].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400231
John Bauman19bac1e2014-05-06 15:23:49 -0400232 r.o[D1].x = Float4(0.0f);
233 r.o[D1].y = Float4(0.0f);
234 r.o[D1].z = Float4(0.0f);
235 r.o[D1].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400236
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400237 Vector4f ambient;
238 Float4 globalAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.globalAmbient)); // FIXME: Unpack
239
240 ambient.x = globalAmbient.x;
241 ambient.y = globalAmbient.y;
242 ambient.z = globalAmbient.z;
John Bauman89401822014-05-06 15:04:28 -0400243
John Bauman89401822014-05-06 15:04:28 -0400244 for(int i = 0; i < 8; i++)
245 {
246 if(!(state.vertexLightActive & (1 << i)))
247 {
248 continue;
249 }
250
John Bauman19bac1e2014-05-06 15:23:49 -0400251 Vector4f L; // Light vector
John Bauman89401822014-05-06 15:04:28 -0400252 Float4 att; // Attenuation
253
254 // Attenuation
255 {
256 Float4 d; // Distance
257
258 L.x = L.y = L.z = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightPosition[i])); // FIXME: Unpack
259 L.x = L.x.xxxx;
260 L.y = L.y.yyyy;
261 L.z = L.z.zzzz;
262
263 L.x -= vertexPosition.x;
264 L.y -= vertexPosition.y;
265 L.z -= vertexPosition.z;
266 d = dot3(L, L);
267 d = RcpSqrt_pp(d); // FIXME: Sufficient precision?
268 L.x *= d;
269 L.y *= d;
270 L.z *= d;
271 d = Rcp_pp(d); // FIXME: Sufficient precision?
272
273 Float4 q = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.attenuationQuadratic[i]));
274 Float4 l = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.attenuationLinear[i]));
275 Float4 c = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.attenuationConstant[i]));
276
277 att = Rcp_pp((q * d + l) * d + c);
278 }
279
280 // Ambient per light
281 {
282 Float4 lightAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightAmbient[i])); // FIXME: Unpack
283
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400284 ambient.x = ambient.x + lightAmbient.x * att;
285 ambient.y = ambient.y + lightAmbient.y * att;
286 ambient.z = ambient.z + lightAmbient.z * att;
John Bauman89401822014-05-06 15:04:28 -0400287 }
288
289 // Diffuse
290 if(state.vertexNormalActive)
291 {
292 Float4 dot;
293
294 dot = dot3(L, normal);
John Bauman19bac1e2014-05-06 15:23:49 -0400295 dot = Max(dot, Float4(0.0f));
John Bauman89401822014-05-06 15:04:28 -0400296 dot *= att;
297
John Bauman19bac1e2014-05-06 15:23:49 -0400298 Vector4f diff;
John Bauman89401822014-05-06 15:04:28 -0400299
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400300 if(state.vertexDiffuseMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400301 {
302 diff.x = diff.y = diff.z = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialDiffuse)); // FIXME: Unpack
303 diff.x = diff.x.xxxx;
304 diff.y = diff.y.yyyy;
305 diff.z = diff.z.zzzz;
306 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400307 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400308 {
309 diff = r.v[Color0];
310 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400311 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400312 {
313 diff = r.v[Color1];
314 }
315 else ASSERT(false);
316
317 Float4 lightDiffuse = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightDiffuse[i]));
318
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400319 r.o[D0].x = r.o[D0].x + diff.x * dot * lightDiffuse.x; // FIXME: Clamp first?
320 r.o[D0].y = r.o[D0].y + diff.y * dot * lightDiffuse.y; // FIXME: Clamp first?
321 r.o[D0].z = r.o[D0].z + diff.z * dot * lightDiffuse.z; // FIXME: Clamp first?
John Bauman89401822014-05-06 15:04:28 -0400322 }
323
324 // Specular
325 if(state.vertexSpecularActive)
326 {
John Bauman19bac1e2014-05-06 15:23:49 -0400327 Vector4f S;
328 Vector4f C; // Camera vector
John Bauman89401822014-05-06 15:04:28 -0400329 Float4 pow;
330
331 pow = *Pointer<Float>(r.data + OFFSET(DrawData,ff.materialShininess));
332
John Bauman19bac1e2014-05-06 15:23:49 -0400333 S.x = Float4(0.0f) - vertexPosition.x;
334 S.y = Float4(0.0f) - vertexPosition.y;
335 S.z = Float4(0.0f) - vertexPosition.z;
John Bauman89401822014-05-06 15:04:28 -0400336 C = normalize(S);
337
338 S.x = L.x + C.x;
339 S.y = L.y + C.y;
340 S.z = L.z + C.z;
341 C = normalize(S);
342
343 Float4 dot = Max(dot3(C, normal), Float4(0.0f)); // FIXME: max(dot3(C, normal), 0)
344
345 Float4 P = power(dot, pow);
346 P *= att;
347
John Bauman19bac1e2014-05-06 15:23:49 -0400348 Vector4f spec;
John Bauman89401822014-05-06 15:04:28 -0400349
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400350 if(state.vertexSpecularMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400351 {
352 Float4 materialSpecular = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialSpecular)); // FIXME: Unpack
353
354 spec.x = materialSpecular.x;
355 spec.y = materialSpecular.y;
356 spec.z = materialSpecular.z;
357 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400358 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400359 {
360 spec = r.v[Color0];
361 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400362 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400363 {
364 spec = r.v[Color1];
365 }
366 else ASSERT(false);
367
368 Float4 lightSpecular = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightSpecular[i]));
369
370 spec.x *= lightSpecular.x;
371 spec.y *= lightSpecular.y;
372 spec.z *= lightSpecular.z;
373
374 spec.x *= P;
375 spec.y *= P;
376 spec.z *= P;
377
John Bauman19bac1e2014-05-06 15:23:49 -0400378 spec.x = Max(spec.x, Float4(0.0f));
379 spec.y = Max(spec.y, Float4(0.0f));
380 spec.z = Max(spec.z, Float4(0.0f));
John Bauman89401822014-05-06 15:04:28 -0400381
John Bauman19bac1e2014-05-06 15:23:49 -0400382 r.o[D1].x = r.o[D1].x + spec.x;
383 r.o[D1].y = r.o[D1].y + spec.y;
384 r.o[D1].z = r.o[D1].z + spec.z;
John Bauman89401822014-05-06 15:04:28 -0400385 }
386 }
387
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400388 if(state.vertexAmbientMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400389 {
390 Float4 materialAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialAmbient)); // FIXME: Unpack
391
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400392 ambient.x = ambient.x * materialAmbient.x;
393 ambient.y = ambient.y * materialAmbient.y;
394 ambient.z = ambient.z * materialAmbient.z;
John Bauman89401822014-05-06 15:04:28 -0400395 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400396 else if(state.vertexAmbientMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400397 {
John Bauman19bac1e2014-05-06 15:23:49 -0400398 Vector4f materialDiffuse = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400399
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400400 ambient.x = ambient.x * materialDiffuse.x;
401 ambient.y = ambient.y * materialDiffuse.y;
402 ambient.z = ambient.z * materialDiffuse.z;
John Bauman89401822014-05-06 15:04:28 -0400403 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400404 else if(state.vertexAmbientMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400405 {
John Bauman19bac1e2014-05-06 15:23:49 -0400406 Vector4f materialSpecular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400407
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400408 ambient.x = ambient.x * materialSpecular.x;
409 ambient.y = ambient.y * materialSpecular.y;
410 ambient.z = ambient.z * materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400411 }
412 else ASSERT(false);
413
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400414 r.o[D0].x = r.o[D0].x + ambient.x;
415 r.o[D0].y = r.o[D0].y + ambient.y;
416 r.o[D0].z = r.o[D0].z + ambient.z;
John Bauman89401822014-05-06 15:04:28 -0400417
418 // Emissive
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400419 if(state.vertexEmissiveMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400420 {
421 Float4 materialEmission = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialEmission)); // FIXME: Unpack
422
John Bauman19bac1e2014-05-06 15:23:49 -0400423 r.o[D0].x = r.o[D0].x + materialEmission.x;
424 r.o[D0].y = r.o[D0].y + materialEmission.y;
425 r.o[D0].z = r.o[D0].z + materialEmission.z;
John Bauman89401822014-05-06 15:04:28 -0400426 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400427 else if(state.vertexEmissiveMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400428 {
John Bauman19bac1e2014-05-06 15:23:49 -0400429 Vector4f materialSpecular = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400430
John Bauman19bac1e2014-05-06 15:23:49 -0400431 r.o[D0].x = r.o[D0].x + materialSpecular.x;
432 r.o[D0].y = r.o[D0].y + materialSpecular.y;
433 r.o[D0].z = r.o[D0].z + materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400434 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400435 else if(state.vertexEmissiveMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400436 {
John Bauman19bac1e2014-05-06 15:23:49 -0400437 Vector4f materialSpecular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400438
John Bauman19bac1e2014-05-06 15:23:49 -0400439 r.o[D0].x = r.o[D0].x + materialSpecular.x;
440 r.o[D0].y = r.o[D0].y + materialSpecular.y;
441 r.o[D0].z = r.o[D0].z + materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400442 }
443 else ASSERT(false);
444
445 // Diffuse alpha component
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400446 if(state.vertexDiffuseMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400447 {
John Bauman19bac1e2014-05-06 15:23:49 -0400448 r.o[D0].w = Float4(*Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialDiffuse[0]))).wwww; // FIXME: Unpack
John Bauman89401822014-05-06 15:04:28 -0400449 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400450 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400451 {
John Bauman19bac1e2014-05-06 15:23:49 -0400452 Vector4f alpha = r.v[Color0];
453 r.o[D0].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400454 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400455 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400456 {
John Bauman19bac1e2014-05-06 15:23:49 -0400457 Vector4f alpha = r.v[Color1];
458 r.o[D0].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400459 }
460 else ASSERT(false);
461
462 if(state.vertexSpecularActive)
463 {
464 // Specular alpha component
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400465 if(state.vertexSpecularMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400466 {
John Bauman19bac1e2014-05-06 15:23:49 -0400467 r.o[D1].w = Float4(*Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialSpecular[3]))).wwww; // FIXME: Unpack
John Bauman89401822014-05-06 15:04:28 -0400468 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400469 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400470 {
John Bauman19bac1e2014-05-06 15:23:49 -0400471 Vector4f alpha = r.v[Color0];
472 r.o[D1].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400473 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400474 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400475 {
John Bauman19bac1e2014-05-06 15:23:49 -0400476 Vector4f alpha = r.v[Color1];
477 r.o[D1].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400478 }
479 else ASSERT(false);
480 }
481 }
482
483 if(state.fogActive)
484 {
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400485 Float4 f;
486
487 if(!state.rangeFogActive)
488 {
489 f = Abs(vertexPosition.z);
490 }
491 else
492 {
493 f = Sqrt(dot3(vertexPosition, vertexPosition)); // FIXME: f = length(vertexPosition);
494 }
495
John Bauman89401822014-05-06 15:04:28 -0400496 switch(state.vertexFogMode)
497 {
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400498 case FOG_NONE:
John Bauman89401822014-05-06 15:04:28 -0400499 if(state.specularActive)
500 {
John Bauman19bac1e2014-05-06 15:23:49 -0400501 r.o[Fog].x = r.o[D1].w;
John Bauman89401822014-05-06 15:04:28 -0400502 }
503 else
504 {
John Bauman19bac1e2014-05-06 15:23:49 -0400505 r.o[Fog].x = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400506 }
507 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400508 case FOG_LINEAR:
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400509 r.o[Fog].x = f * *Pointer<Float4>(r.data + OFFSET(DrawData,fog.scale)) + *Pointer<Float4>(r.data + OFFSET(DrawData,fog.offset));
510 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400511 case FOG_EXP:
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400512 r.o[Fog].x = exponential2(f * *Pointer<Float4>(r.data + OFFSET(DrawData,fog.densityE)), true);
513 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400514 case FOG_EXP2:
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400515 r.o[Fog].x = exponential2((f * f) * *Pointer<Float4>(r.data + OFFSET(DrawData,fog.density2E)), true);
John Bauman89401822014-05-06 15:04:28 -0400516 break;
517 default:
518 ASSERT(false);
519 }
520 }
521
522 for(int stage = 0; stage < 8; stage++)
523 {
524 processTextureCoordinate(r, stage, normal, position);
525 }
526
527 processPointSize(r);
528 }
529
John Bauman19bac1e2014-05-06 15:23:49 -0400530 void VertexPipeline::processTextureCoordinate(Registers &r, int stage, Vector4f &normal, Vector4f &position)
John Bauman89401822014-05-06 15:04:28 -0400531 {
532 if(state.output[T0 + stage].write)
533 {
534 int i = state.textureState[stage].texCoordIndexActive;
535
536 switch(state.textureState[stage].texGenActive)
537 {
Nicolas Capens70583fa2015-05-14 18:17:14 -0400538 case TEXGEN_NONE:
539 {
540 Vector4f v = r.v[TexCoord0 + i];
541
542 r.o[T0 + stage].x = v.x;
543 r.o[T0 + stage].y = v.y;
544 r.o[T0 + stage].z = v.z;
545 r.o[T0 + stage].w = v.w;
546 }
547 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400548 case TEXGEN_PASSTHRU:
John Bauman89401822014-05-06 15:04:28 -0400549 {
John Bauman19bac1e2014-05-06 15:23:49 -0400550 Vector4f v = r.v[TexCoord0 + i];
John Bauman89401822014-05-06 15:04:28 -0400551
John Bauman19bac1e2014-05-06 15:23:49 -0400552 r.o[T0 + stage].x = v.x;
553 r.o[T0 + stage].y = v.y;
554 r.o[T0 + stage].z = v.z;
555 r.o[T0 + stage].w = v.w;
John Bauman89401822014-05-06 15:04:28 -0400556
John Bauman19bac1e2014-05-06 15:23:49 -0400557 if(state.input[TexCoord0 + i])
John Bauman89401822014-05-06 15:04:28 -0400558 {
559 switch(state.input[TexCoord0 + i].count)
560 {
561 case 1:
John Bauman19bac1e2014-05-06 15:23:49 -0400562 r.o[T0 + stage].y = Float4(1.0f);
563 r.o[T0 + stage].z = Float4(0.0f);
564 r.o[T0 + stage].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400565 break;
566 case 2:
John Bauman19bac1e2014-05-06 15:23:49 -0400567 r.o[T0 + stage].z = Float4(1.0f);
568 r.o[T0 + stage].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400569 break;
570 case 3:
John Bauman19bac1e2014-05-06 15:23:49 -0400571 r.o[T0 + stage].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400572 break;
573 case 4:
574 break;
575 default:
576 ASSERT(false);
577 }
578 }
John Bauman89401822014-05-06 15:04:28 -0400579 }
580 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400581 case TEXGEN_NORMAL:
John Bauman89401822014-05-06 15:04:28 -0400582 {
John Bauman19bac1e2014-05-06 15:23:49 -0400583 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400584
585 if(state.vertexNormalActive)
586 {
587 Nc = normal;
588 }
589 else
590 {
John Bauman19bac1e2014-05-06 15:23:49 -0400591 Nc.x = Float4(0.0f);
592 Nc.y = Float4(0.0f);
593 Nc.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400594 }
595
John Bauman19bac1e2014-05-06 15:23:49 -0400596 Nc.w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400597
John Bauman19bac1e2014-05-06 15:23:49 -0400598 r.o[T0 + stage].x = Nc.x;
599 r.o[T0 + stage].y = Nc.y;
600 r.o[T0 + stage].z = Nc.z;
601 r.o[T0 + stage].w = Nc.w;
John Bauman89401822014-05-06 15:04:28 -0400602 }
603 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400604 case TEXGEN_POSITION:
John Bauman89401822014-05-06 15:04:28 -0400605 {
John Bauman19bac1e2014-05-06 15:23:49 -0400606 Vector4f Pn = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true); // Position in camera space
John Bauman89401822014-05-06 15:04:28 -0400607
John Bauman19bac1e2014-05-06 15:23:49 -0400608 Pn.w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400609
John Bauman19bac1e2014-05-06 15:23:49 -0400610 r.o[T0 + stage].x = Pn.x;
611 r.o[T0 + stage].y = Pn.y;
612 r.o[T0 + stage].z = Pn.z;
613 r.o[T0 + stage].w = Pn.w;
John Bauman89401822014-05-06 15:04:28 -0400614 }
615 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400616 case TEXGEN_REFLECTION:
John Bauman89401822014-05-06 15:04:28 -0400617 {
John Bauman19bac1e2014-05-06 15:23:49 -0400618 Vector4f R; // Reflection vector
John Bauman89401822014-05-06 15:04:28 -0400619
620 if(state.vertexNormalActive)
621 {
John Bauman19bac1e2014-05-06 15:23:49 -0400622 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400623
624 Nc = normal;
625
626 if(state.localViewerActive)
627 {
John Bauman19bac1e2014-05-06 15:23:49 -0400628 Vector4f Ec; // Eye vector in camera space
629 Vector4f N2;
John Bauman89401822014-05-06 15:04:28 -0400630
631 Ec = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
632 Ec = normalize(Ec);
633
634 // R = E - 2 * N * (E . N)
John Bauman19bac1e2014-05-06 15:23:49 -0400635 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
John Bauman89401822014-05-06 15:04:28 -0400636
637 R.x = Ec.x - Nc.x * dot;
638 R.y = Ec.y - Nc.y * dot;
639 R.z = Ec.z - Nc.z * dot;
640 }
641 else
642 {
643 // u = -2 * Nz * Nx
644 // v = -2 * Nz * Ny
645 // w = 1 - 2 * Nz * Nz
646
John Bauman19bac1e2014-05-06 15:23:49 -0400647 R.x = -Float4(2.0f) * Nc.z * Nc.x;
648 R.y = -Float4(2.0f) * Nc.z * Nc.y;
649 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
John Bauman89401822014-05-06 15:04:28 -0400650 }
651 }
652 else
653 {
John Bauman19bac1e2014-05-06 15:23:49 -0400654 R.x = Float4(0.0f);
655 R.y = Float4(0.0f);
656 R.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400657 }
658
John Bauman19bac1e2014-05-06 15:23:49 -0400659 R.w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400660
John Bauman19bac1e2014-05-06 15:23:49 -0400661 r.o[T0 + stage].x = R.x;
662 r.o[T0 + stage].y = R.y;
663 r.o[T0 + stage].z = R.z;
664 r.o[T0 + stage].w = R.w;
John Bauman89401822014-05-06 15:04:28 -0400665 }
666 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400667 case TEXGEN_SPHEREMAP:
John Bauman89401822014-05-06 15:04:28 -0400668 {
John Bauman19bac1e2014-05-06 15:23:49 -0400669 Vector4f R; // Reflection vector
John Bauman89401822014-05-06 15:04:28 -0400670
671 if(state.vertexNormalActive)
672 {
John Bauman19bac1e2014-05-06 15:23:49 -0400673 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400674
675 Nc = normal;
676
677 if(state.localViewerActive)
678 {
John Bauman19bac1e2014-05-06 15:23:49 -0400679 Vector4f Ec; // Eye vector in camera space
680 Vector4f N2;
John Bauman89401822014-05-06 15:04:28 -0400681
682 Ec = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
683 Ec = normalize(Ec);
684
685 // R = E - 2 * N * (E . N)
John Bauman19bac1e2014-05-06 15:23:49 -0400686 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
John Bauman89401822014-05-06 15:04:28 -0400687
688 R.x = Ec.x - Nc.x * dot;
689 R.y = Ec.y - Nc.y * dot;
690 R.z = Ec.z - Nc.z * dot;
691 }
692 else
693 {
694 // u = -2 * Nz * Nx
695 // v = -2 * Nz * Ny
696 // w = 1 - 2 * Nz * Nz
697
John Bauman19bac1e2014-05-06 15:23:49 -0400698 R.x = -Float4(2.0f) * Nc.z * Nc.x;
699 R.y = -Float4(2.0f) * Nc.z * Nc.y;
700 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
John Bauman89401822014-05-06 15:04:28 -0400701 }
702 }
703 else
704 {
John Bauman19bac1e2014-05-06 15:23:49 -0400705 R.x = Float4(0.0f);
706 R.y = Float4(0.0f);
707 R.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400708 }
709
John Bauman19bac1e2014-05-06 15:23:49 -0400710 R.z -= Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400711 R = normalize(R);
John Bauman19bac1e2014-05-06 15:23:49 -0400712 R.x = Float4(0.5f) * R.x + Float4(0.5f);
713 R.y = Float4(0.5f) * R.y + Float4(0.5f);
John Bauman89401822014-05-06 15:04:28 -0400714
John Bauman19bac1e2014-05-06 15:23:49 -0400715 R.z = Float4(1.0f);
716 R.w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400717
John Bauman19bac1e2014-05-06 15:23:49 -0400718 r.o[T0 + stage].x = R.x;
719 r.o[T0 + stage].y = R.y;
720 r.o[T0 + stage].z = R.z;
721 r.o[T0 + stage].w = R.w;
John Bauman89401822014-05-06 15:04:28 -0400722 }
723 break;
724 default:
725 ASSERT(false);
726 }
727
John Bauman19bac1e2014-05-06 15:23:49 -0400728 Vector4f texTrans0;
729 Vector4f texTrans1;
730 Vector4f texTrans2;
731 Vector4f texTrans3;
John Bauman89401822014-05-06 15:04:28 -0400732
John Bauman19bac1e2014-05-06 15:23:49 -0400733 Vector4f T;
734 Vector4f t;
John Bauman89401822014-05-06 15:04:28 -0400735
John Bauman19bac1e2014-05-06 15:23:49 -0400736 T.x = r.o[T0 + stage].x;
737 T.y = r.o[T0 + stage].y;
738 T.z = r.o[T0 + stage].z;
739 T.w = r.o[T0 + stage].w;
John Bauman89401822014-05-06 15:04:28 -0400740
741 switch(state.textureState[stage].textureTransformCountActive)
742 {
743 case 4:
744 texTrans3.x = texTrans3.y = texTrans3.z = texTrans3.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][3])); // FIXME: Unpack
745 texTrans3.x = texTrans3.x.xxxx;
746 texTrans3.y = texTrans3.y.yyyy;
747 texTrans3.z = texTrans3.z.zzzz;
748 texTrans3.w = texTrans3.w.wwww;
749 t.w = dot4(T, texTrans3);
750 case 3:
751 texTrans2.x = texTrans2.y = texTrans2.z = texTrans2.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][2])); // FIXME: Unpack
752 texTrans2.x = texTrans2.x.xxxx;
753 texTrans2.y = texTrans2.y.yyyy;
754 texTrans2.z = texTrans2.z.zzzz;
755 texTrans2.w = texTrans2.w.wwww;
756 t.z = dot4(T, texTrans2);
757 case 2:
758 texTrans1.x = texTrans1.y = texTrans1.z = texTrans1.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][1])); // FIXME: Unpack
759 texTrans1.x = texTrans1.x.xxxx;
760 texTrans1.y = texTrans1.y.yyyy;
761 texTrans1.z = texTrans1.z.zzzz;
762 texTrans1.w = texTrans1.w.wwww;
763 t.y = dot4(T, texTrans1);
764 case 1:
765 texTrans0.x = texTrans0.y = texTrans0.z = texTrans0.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][0])); // FIXME: Unpack
766 texTrans0.x = texTrans0.x.xxxx;
767 texTrans0.y = texTrans0.y.yyyy;
768 texTrans0.z = texTrans0.z.zzzz;
769 texTrans0.w = texTrans0.w.wwww;
770 t.x = dot4(T, texTrans0);
771
John Bauman19bac1e2014-05-06 15:23:49 -0400772 r.o[T0 + stage].x = t.x;
773 r.o[T0 + stage].y = t.y;
774 r.o[T0 + stage].z = t.z;
775 r.o[T0 + stage].w = t.w;
John Bauman89401822014-05-06 15:04:28 -0400776 case 0:
777 break;
778 default:
779 ASSERT(false);
780 }
781 }
782 }
783
784 void VertexPipeline::processPointSize(Registers &r)
785 {
786 if(!state.pointSizeActive)
787 {
788 return; // Use global pointsize
789 }
790
John Bauman66b8ab22014-05-06 15:57:45 -0400791 if(state.input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400792 {
John Bauman66b8ab22014-05-06 15:57:45 -0400793 r.o[Pts].y = r.v[PointSize].x;
John Bauman89401822014-05-06 15:04:28 -0400794 }
795 else
796 {
John Bauman19bac1e2014-05-06 15:23:49 -0400797 r.o[Pts].y = *Pointer<Float4>(r.data + OFFSET(DrawData,point.pointSize));
John Bauman89401822014-05-06 15:04:28 -0400798 }
799
800 if(state.pointScaleActive && !state.preTransformed)
801 {
John Bauman19bac1e2014-05-06 15:23:49 -0400802 Vector4f p = transformBlend(r, r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
John Bauman89401822014-05-06 15:04:28 -0400803
804 Float4 d = Sqrt(dot3(p, p)); // FIXME: length(p);
805
806 Float4 A = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleA)); // FIXME: Unpack
807 Float4 B = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleB)); // FIXME: Unpack
808 Float4 C = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleC)); // FIXME: Unpack
809
810 A = RcpSqrt_pp(A + d * (B + d * C));
811
John Bauman19bac1e2014-05-06 15:23:49 -0400812 r.o[Pts].y = r.o[Pts].y * Float4(*Pointer<Float>(r.data + OFFSET(DrawData,viewportHeight))) * A; // FIXME: Unpack
John Bauman89401822014-05-06 15:04:28 -0400813 }
814 }
815
John Bauman66b8ab22014-05-06 15:57:45 -0400816 Vector4f VertexPipeline::transform(const Register &src, const Pointer<Byte> &matrix, bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -0400817 {
John Bauman19bac1e2014-05-06 15:23:49 -0400818 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400819
820 if(homogeneous)
821 {
822 Float4 m[4][4];
823
824 for(int j = 0; j < 4; j++)
825 {
826 for(int i = 0; i < 4; i++)
827 {
828 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
829 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
830 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
831 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
832 }
833 }
834
Nicolas Capens48621bd2015-08-03 15:33:44 -0400835 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + src.w * m[0][3];
836 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + src.w * m[1][3];
837 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + src.w * m[2][3];
838 dst.w = src.x * m[3][0] + src.y * m[3][1] + src.z * m[3][2] + src.w * m[3][3];
John Bauman89401822014-05-06 15:04:28 -0400839 }
840 else
841 {
842 Float4 m[3][3];
843
844 for(int j = 0; j < 3; j++)
845 {
846 for(int i = 0; i < 3; i++)
847 {
848 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
849 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
850 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
851 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
852 }
853 }
854
855 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
856 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
857 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
858 }
859
860 return dst;
861 }
862
John Bauman66b8ab22014-05-06 15:57:45 -0400863 Vector4f VertexPipeline::transform(const Register &src, const Pointer<Byte> &matrix, UInt index[4], bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -0400864 {
John Bauman19bac1e2014-05-06 15:23:49 -0400865 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400866
867 if(homogeneous)
868 {
869 Float4 m[4][4];
870
871 for(int j = 0; j < 4; j++)
872 {
873 for(int i = 0; i < 4; i++)
874 {
875 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
876 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
877 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
878 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
879 }
880 }
881
882 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + m[0][3];
883 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + m[1][3];
884 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + m[2][3];
885 dst.w = src.x * m[3][0] + src.y * m[3][1] + src.z * m[3][2] + m[3][3];
886 }
887 else
888 {
889 Float4 m[3][3];
890
891 for(int j = 0; j < 3; j++)
892 {
893 for(int i = 0; i < 3; i++)
894 {
895 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
896 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
897 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
898 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
899 }
900 }
901
902 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
903 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
904 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
905 }
906
907 return dst;
908 }
909
John Bauman19bac1e2014-05-06 15:23:49 -0400910 Vector4f VertexPipeline::normalize(Vector4f &src)
John Bauman89401822014-05-06 15:04:28 -0400911 {
John Bauman19bac1e2014-05-06 15:23:49 -0400912 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400913
914 Float4 rcpLength = RcpSqrt_pp(dot3(src, src));
915
916 dst.x = src.x * rcpLength;
917 dst.y = src.y * rcpLength;
918 dst.z = src.z * rcpLength;
919
920 return dst;
921 }
922
923 Float4 VertexPipeline::power(Float4 &src0, Float4 &src1)
924 {
925 Float4 dst = src0;
926
927 dst = dst * dst;
928 dst = dst * dst;
John Bauman19bac1e2014-05-06 15:23:49 -0400929 dst = Float4(As<Int4>(dst) - As<Int4>(Float4(1.0f)));
John Bauman89401822014-05-06 15:04:28 -0400930
931 dst *= src1;
932
John Bauman19bac1e2014-05-06 15:23:49 -0400933 dst = As<Float4>(Int4(dst) + As<Int4>(Float4(1.0f)));
John Bauman89401822014-05-06 15:04:28 -0400934 dst = RcpSqrt_pp(dst);
935 dst = RcpSqrt_pp(dst);
936
937 return dst;
938 }
939}