blob: f212b1822927173aa660cc70a53f5e39197d7eeb [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{
Nicolas Capens44ffb652015-08-04 16:11:24 -040027 extern bool secondaryColor;
28
John Bauman19bac1e2014-05-06 15:23:49 -040029 VertexPipeline::VertexPipeline(const VertexProcessor::State &state) : VertexRoutine(state, 0)
John Bauman89401822014-05-06 15:04:28 -040030 {
31 }
32
33 VertexPipeline::~VertexPipeline()
34 {
35 }
36
Nicolas Capensb4fb3672016-01-15 17:02:41 -050037 Vector4f VertexPipeline::transformBlend(const Register &src, const Pointer<Byte> &matrix, bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -040038 {
John Bauman19bac1e2014-05-06 15:23:49 -040039 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -040040
41 if(state.vertexBlendMatrixCount == 0)
42 {
43 dst = transform(src, matrix, homogeneous);
44 }
45 else
46 {
47 UInt index0[4];
48 UInt index1[4];
49 UInt index2[4];
50 UInt index3[4];
51
52 if(state.indexedVertexBlendEnable)
53 {
54 for(int i = 0; i < 4; i++)
55 {
John Bauman19bac1e2014-05-06 15:23:49 -040056 Float4 B = r.v[BlendIndices].x;
John Bauman89401822014-05-06 15:04:28 -040057 UInt indices;
Nicolas Capensb4fb3672016-01-15 17:02:41 -050058
John Bauman89401822014-05-06 15:04:28 -040059 switch(i)
60 {
John Bauman19bac1e2014-05-06 15:23:49 -040061 case 0: indices = As<UInt>(Float(B.x)); break;
62 case 1: indices = As<UInt>(Float(B.y)); break;
63 case 2: indices = As<UInt>(Float(B.z)); break;
64 case 3: indices = As<UInt>(Float(B.w)); break;
John Bauman89401822014-05-06 15:04:28 -040065 }
66
John Bauman66b8ab22014-05-06 15:57:45 -040067 index0[i] = (indices & 0x000000FF) << 6;
68 index1[i] = (indices & 0x0000FF00) >> 2;
69 index2[i] = (indices & 0x00FF0000) >> 10;
70 index3[i] = (indices & 0xFF000000) >> 18;
John Bauman89401822014-05-06 15:04:28 -040071 }
72 }
73 else
74 {
75 for(int i = 0; i < 4; i++)
76 {
John Bauman66b8ab22014-05-06 15:57:45 -040077 index0[i] = 0 * 64;
78 index1[i] = 1 * 64;
79 index2[i] = 2 * 64;
80 index3[i] = 3 * 64;
John Bauman89401822014-05-06 15:04:28 -040081 }
82 }
83
84 Float4 weight0;
85 Float4 weight1;
86 Float4 weight2;
87 Float4 weight3;
88
89 switch(state.vertexBlendMatrixCount)
90 {
91 case 4: weight2 = r.v[BlendWeight].z;
92 case 3: weight1 = r.v[BlendWeight].y;
93 case 2: weight0 = r.v[BlendWeight].x;
94 case 1:
95 break;
96 }
97
98 if(state.vertexBlendMatrixCount == 1)
99 {
100 dst = transform(src, matrix, index0, homogeneous);
101 }
102 else if(state.vertexBlendMatrixCount == 2)
103 {
104 weight1 = Float4(1.0f) - weight0;
105
John Bauman19bac1e2014-05-06 15:23:49 -0400106 Vector4f pos0;
107 Vector4f pos1;
John Bauman89401822014-05-06 15:04:28 -0400108
109 pos0 = transform(src, matrix, index0, homogeneous);
110 pos1 = transform(src, matrix, index1, homogeneous);
111
John Bauman19bac1e2014-05-06 15:23:49 -0400112 dst.x = pos0.x * weight0 + pos1.x * weight1; // FIXME: Vector4f operators
John Bauman89401822014-05-06 15:04:28 -0400113 dst.y = pos0.y * weight0 + pos1.y * weight1;
114 dst.z = pos0.z * weight0 + pos1.z * weight1;
115 dst.w = pos0.w * weight0 + pos1.w * weight1;
116 }
117 else if(state.vertexBlendMatrixCount == 3)
118 {
119 weight2 = Float4(1.0f) - (weight0 + weight1);
120
John Bauman19bac1e2014-05-06 15:23:49 -0400121 Vector4f pos0;
122 Vector4f pos1;
123 Vector4f pos2;
John Bauman89401822014-05-06 15:04:28 -0400124
125 pos0 = transform(src, matrix, index0, homogeneous);
126 pos1 = transform(src, matrix, index1, homogeneous);
127 pos2 = transform(src, matrix, index2, homogeneous);
128
129 dst.x = pos0.x * weight0 + pos1.x * weight1 + pos2.x * weight2;
130 dst.y = pos0.y * weight0 + pos1.y * weight1 + pos2.y * weight2;
131 dst.z = pos0.z * weight0 + pos1.z * weight1 + pos2.z * weight2;
132 dst.w = pos0.w * weight0 + pos1.w * weight1 + pos2.w * weight2;
133 }
134 else if(state.vertexBlendMatrixCount == 4)
135 {
136 weight3 = Float4(1.0f) - (weight0 + weight1 + weight2);
137
John Bauman19bac1e2014-05-06 15:23:49 -0400138 Vector4f pos0;
139 Vector4f pos1;
140 Vector4f pos2;
141 Vector4f pos3;
John Bauman89401822014-05-06 15:04:28 -0400142
143 pos0 = transform(src, matrix, index0, homogeneous);
144 pos1 = transform(src, matrix, index1, homogeneous);
145 pos2 = transform(src, matrix, index2, homogeneous);
146 pos3 = transform(src, matrix, index3, homogeneous);
147
148 dst.x = pos0.x * weight0 + pos1.x * weight1 + pos2.x * weight2 + pos3.x * weight3;
149 dst.y = pos0.y * weight0 + pos1.y * weight1 + pos2.y * weight2 + pos3.y * weight3;
150 dst.z = pos0.z * weight0 + pos1.z * weight1 + pos2.z * weight2 + pos3.z * weight3;
151 dst.w = pos0.w * weight0 + pos1.w * weight1 + pos2.w * weight2 + pos3.w * weight3;
152 }
153 }
154
155 return dst;
156 }
157
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500158 void VertexPipeline::pipeline()
John Bauman89401822014-05-06 15:04:28 -0400159 {
John Bauman19bac1e2014-05-06 15:23:49 -0400160 Vector4f position;
161 Vector4f normal;
John Bauman89401822014-05-06 15:04:28 -0400162
163 if(!state.preTransformed)
164 {
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500165 position = transformBlend(r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.transformT)), true);
John Bauman89401822014-05-06 15:04:28 -0400166 }
167 else
168 {
169 position = r.v[PositionT];
170 }
171
John Bauman19bac1e2014-05-06 15:23:49 -0400172 r.o[Pos].x = position.x;
173 r.o[Pos].y = position.y;
174 r.o[Pos].z = position.z;
175 r.o[Pos].w = position.w;
John Bauman89401822014-05-06 15:04:28 -0400176
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500177 Vector4f vertexPosition = transformBlend(r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400178
John Bauman89401822014-05-06 15:04:28 -0400179 if(state.vertexNormalActive)
180 {
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500181 normal = transformBlend(r.v[Normal], Pointer<Byte>(r.data + OFFSET(DrawData,ff.normalTransformT)), false);
John Bauman89401822014-05-06 15:04:28 -0400182
183 if(state.normalizeNormals)
184 {
185 normal = normalize(normal);
186 }
187 }
188
189 if(!state.vertexLightingActive)
190 {
191 // FIXME: Don't process if not used at all
192 if(state.diffuseActive && state.input[Color0])
193 {
John Bauman19bac1e2014-05-06 15:23:49 -0400194 Vector4f diffuse = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400195
John Bauman19bac1e2014-05-06 15:23:49 -0400196 r.o[D0].x = diffuse.x;
197 r.o[D0].y = diffuse.y;
198 r.o[D0].z = diffuse.z;
199 r.o[D0].w = diffuse.w;
John Bauman89401822014-05-06 15:04:28 -0400200 }
201 else
202 {
John Bauman19bac1e2014-05-06 15:23:49 -0400203 r.o[D0].x = Float4(1.0f);
204 r.o[D0].y = Float4(1.0f);
205 r.o[D0].z = Float4(1.0f);
206 r.o[D0].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400207 }
208
209 // FIXME: Don't process if not used at all
210 if(state.specularActive && state.input[Color1])
211 {
John Bauman19bac1e2014-05-06 15:23:49 -0400212 Vector4f specular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400213
John Bauman19bac1e2014-05-06 15:23:49 -0400214 r.o[D1].x = specular.x;
215 r.o[D1].y = specular.y;
216 r.o[D1].z = specular.z;
217 r.o[D1].w = specular.w;
John Bauman89401822014-05-06 15:04:28 -0400218 }
219 else
220 {
John Bauman19bac1e2014-05-06 15:23:49 -0400221 r.o[D1].x = Float4(0.0f);
222 r.o[D1].y = Float4(0.0f);
223 r.o[D1].z = Float4(0.0f);
224 r.o[D1].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400225 }
226 }
227 else
228 {
John Bauman19bac1e2014-05-06 15:23:49 -0400229 r.o[D0].x = Float4(0.0f);
230 r.o[D0].y = Float4(0.0f);
231 r.o[D0].z = Float4(0.0f);
232 r.o[D0].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400233
John Bauman19bac1e2014-05-06 15:23:49 -0400234 r.o[D1].x = Float4(0.0f);
235 r.o[D1].y = Float4(0.0f);
236 r.o[D1].z = Float4(0.0f);
237 r.o[D1].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400238
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400239 Vector4f ambient;
240 Float4 globalAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.globalAmbient)); // FIXME: Unpack
241
242 ambient.x = globalAmbient.x;
243 ambient.y = globalAmbient.y;
244 ambient.z = globalAmbient.z;
John Bauman89401822014-05-06 15:04:28 -0400245
John Bauman89401822014-05-06 15:04:28 -0400246 for(int i = 0; i < 8; i++)
247 {
248 if(!(state.vertexLightActive & (1 << i)))
249 {
250 continue;
251 }
252
John Bauman19bac1e2014-05-06 15:23:49 -0400253 Vector4f L; // Light vector
John Bauman89401822014-05-06 15:04:28 -0400254 Float4 att; // Attenuation
255
256 // Attenuation
257 {
258 Float4 d; // Distance
259
260 L.x = L.y = L.z = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightPosition[i])); // FIXME: Unpack
261 L.x = L.x.xxxx;
262 L.y = L.y.yyyy;
263 L.z = L.z.zzzz;
264
265 L.x -= vertexPosition.x;
266 L.y -= vertexPosition.y;
267 L.z -= vertexPosition.z;
268 d = dot3(L, L);
269 d = RcpSqrt_pp(d); // FIXME: Sufficient precision?
270 L.x *= d;
271 L.y *= d;
272 L.z *= d;
273 d = Rcp_pp(d); // FIXME: Sufficient precision?
274
275 Float4 q = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.attenuationQuadratic[i]));
276 Float4 l = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.attenuationLinear[i]));
277 Float4 c = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.attenuationConstant[i]));
278
279 att = Rcp_pp((q * d + l) * d + c);
280 }
281
282 // Ambient per light
283 {
284 Float4 lightAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightAmbient[i])); // FIXME: Unpack
285
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400286 ambient.x = ambient.x + lightAmbient.x * att;
287 ambient.y = ambient.y + lightAmbient.y * att;
288 ambient.z = ambient.z + lightAmbient.z * att;
John Bauman89401822014-05-06 15:04:28 -0400289 }
290
291 // Diffuse
292 if(state.vertexNormalActive)
293 {
294 Float4 dot;
295
296 dot = dot3(L, normal);
John Bauman19bac1e2014-05-06 15:23:49 -0400297 dot = Max(dot, Float4(0.0f));
John Bauman89401822014-05-06 15:04:28 -0400298 dot *= att;
299
John Bauman19bac1e2014-05-06 15:23:49 -0400300 Vector4f diff;
John Bauman89401822014-05-06 15:04:28 -0400301
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400302 if(state.vertexDiffuseMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400303 {
304 diff.x = diff.y = diff.z = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialDiffuse)); // FIXME: Unpack
305 diff.x = diff.x.xxxx;
306 diff.y = diff.y.yyyy;
307 diff.z = diff.z.zzzz;
308 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400309 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400310 {
311 diff = r.v[Color0];
312 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400313 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400314 {
315 diff = r.v[Color1];
316 }
317 else ASSERT(false);
318
319 Float4 lightDiffuse = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightDiffuse[i]));
320
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400321 r.o[D0].x = r.o[D0].x + diff.x * dot * lightDiffuse.x; // FIXME: Clamp first?
322 r.o[D0].y = r.o[D0].y + diff.y * dot * lightDiffuse.y; // FIXME: Clamp first?
323 r.o[D0].z = r.o[D0].z + diff.z * dot * lightDiffuse.z; // FIXME: Clamp first?
John Bauman89401822014-05-06 15:04:28 -0400324 }
325
326 // Specular
327 if(state.vertexSpecularActive)
328 {
John Bauman19bac1e2014-05-06 15:23:49 -0400329 Vector4f S;
330 Vector4f C; // Camera vector
John Bauman89401822014-05-06 15:04:28 -0400331 Float4 pow;
332
333 pow = *Pointer<Float>(r.data + OFFSET(DrawData,ff.materialShininess));
334
John Bauman19bac1e2014-05-06 15:23:49 -0400335 S.x = Float4(0.0f) - vertexPosition.x;
336 S.y = Float4(0.0f) - vertexPosition.y;
337 S.z = Float4(0.0f) - vertexPosition.z;
John Bauman89401822014-05-06 15:04:28 -0400338 C = normalize(S);
339
340 S.x = L.x + C.x;
341 S.y = L.y + C.y;
342 S.z = L.z + C.z;
343 C = normalize(S);
344
345 Float4 dot = Max(dot3(C, normal), Float4(0.0f)); // FIXME: max(dot3(C, normal), 0)
346
347 Float4 P = power(dot, pow);
348 P *= att;
349
John Bauman19bac1e2014-05-06 15:23:49 -0400350 Vector4f spec;
John Bauman89401822014-05-06 15:04:28 -0400351
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400352 if(state.vertexSpecularMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400353 {
354 Float4 materialSpecular = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialSpecular)); // FIXME: Unpack
355
356 spec.x = materialSpecular.x;
357 spec.y = materialSpecular.y;
358 spec.z = materialSpecular.z;
359 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400360 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400361 {
362 spec = r.v[Color0];
363 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400364 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400365 {
366 spec = r.v[Color1];
367 }
368 else ASSERT(false);
369
370 Float4 lightSpecular = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.lightSpecular[i]));
371
372 spec.x *= lightSpecular.x;
373 spec.y *= lightSpecular.y;
374 spec.z *= lightSpecular.z;
375
376 spec.x *= P;
377 spec.y *= P;
378 spec.z *= P;
379
John Bauman19bac1e2014-05-06 15:23:49 -0400380 spec.x = Max(spec.x, Float4(0.0f));
381 spec.y = Max(spec.y, Float4(0.0f));
382 spec.z = Max(spec.z, Float4(0.0f));
John Bauman89401822014-05-06 15:04:28 -0400383
Nicolas Capens44ffb652015-08-04 16:11:24 -0400384 if(secondaryColor)
385 {
386 r.o[D1].x = r.o[D1].x + spec.x;
387 r.o[D1].y = r.o[D1].y + spec.y;
388 r.o[D1].z = r.o[D1].z + spec.z;
389 }
390 else
391 {
392 r.o[D0].x = r.o[D0].x + spec.x;
393 r.o[D0].y = r.o[D0].y + spec.y;
394 r.o[D0].z = r.o[D0].z + spec.z;
395 }
John Bauman89401822014-05-06 15:04:28 -0400396 }
397 }
398
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400399 if(state.vertexAmbientMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400400 {
401 Float4 materialAmbient = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialAmbient)); // FIXME: Unpack
402
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400403 ambient.x = ambient.x * materialAmbient.x;
404 ambient.y = ambient.y * materialAmbient.y;
405 ambient.z = ambient.z * materialAmbient.z;
John Bauman89401822014-05-06 15:04:28 -0400406 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400407 else if(state.vertexAmbientMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400408 {
John Bauman19bac1e2014-05-06 15:23:49 -0400409 Vector4f materialDiffuse = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400410
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400411 ambient.x = ambient.x * materialDiffuse.x;
412 ambient.y = ambient.y * materialDiffuse.y;
413 ambient.z = ambient.z * materialDiffuse.z;
John Bauman89401822014-05-06 15:04:28 -0400414 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400415 else if(state.vertexAmbientMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400416 {
John Bauman19bac1e2014-05-06 15:23:49 -0400417 Vector4f materialSpecular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400418
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400419 ambient.x = ambient.x * materialSpecular.x;
420 ambient.y = ambient.y * materialSpecular.y;
421 ambient.z = ambient.z * materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400422 }
423 else ASSERT(false);
424
Nicolas Capens6aea1b22015-08-05 00:05:20 -0400425 r.o[D0].x = r.o[D0].x + ambient.x;
426 r.o[D0].y = r.o[D0].y + ambient.y;
427 r.o[D0].z = r.o[D0].z + ambient.z;
John Bauman89401822014-05-06 15:04:28 -0400428
429 // Emissive
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400430 if(state.vertexEmissiveMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400431 {
432 Float4 materialEmission = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialEmission)); // FIXME: Unpack
433
John Bauman19bac1e2014-05-06 15:23:49 -0400434 r.o[D0].x = r.o[D0].x + materialEmission.x;
435 r.o[D0].y = r.o[D0].y + materialEmission.y;
436 r.o[D0].z = r.o[D0].z + materialEmission.z;
John Bauman89401822014-05-06 15:04:28 -0400437 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400438 else if(state.vertexEmissiveMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400439 {
John Bauman19bac1e2014-05-06 15:23:49 -0400440 Vector4f materialSpecular = r.v[Color0];
John Bauman89401822014-05-06 15:04:28 -0400441
John Bauman19bac1e2014-05-06 15:23:49 -0400442 r.o[D0].x = r.o[D0].x + materialSpecular.x;
443 r.o[D0].y = r.o[D0].y + materialSpecular.y;
444 r.o[D0].z = r.o[D0].z + materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400445 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400446 else if(state.vertexEmissiveMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400447 {
John Bauman19bac1e2014-05-06 15:23:49 -0400448 Vector4f materialSpecular = r.v[Color1];
John Bauman89401822014-05-06 15:04:28 -0400449
John Bauman19bac1e2014-05-06 15:23:49 -0400450 r.o[D0].x = r.o[D0].x + materialSpecular.x;
451 r.o[D0].y = r.o[D0].y + materialSpecular.y;
452 r.o[D0].z = r.o[D0].z + materialSpecular.z;
John Bauman89401822014-05-06 15:04:28 -0400453 }
454 else ASSERT(false);
455
456 // Diffuse alpha component
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400457 if(state.vertexDiffuseMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400458 {
John Bauman19bac1e2014-05-06 15:23:49 -0400459 r.o[D0].w = Float4(*Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialDiffuse[0]))).wwww; // FIXME: Unpack
John Bauman89401822014-05-06 15:04:28 -0400460 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400461 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400462 {
John Bauman19bac1e2014-05-06 15:23:49 -0400463 Vector4f alpha = r.v[Color0];
464 r.o[D0].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400465 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400466 else if(state.vertexDiffuseMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400467 {
John Bauman19bac1e2014-05-06 15:23:49 -0400468 Vector4f alpha = r.v[Color1];
469 r.o[D0].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400470 }
471 else ASSERT(false);
472
473 if(state.vertexSpecularActive)
474 {
475 // Specular alpha component
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400476 if(state.vertexSpecularMaterialSourceActive == MATERIAL_MATERIAL)
John Bauman89401822014-05-06 15:04:28 -0400477 {
John Bauman19bac1e2014-05-06 15:23:49 -0400478 r.o[D1].w = Float4(*Pointer<Float4>(r.data + OFFSET(DrawData,ff.materialSpecular[3]))).wwww; // FIXME: Unpack
John Bauman89401822014-05-06 15:04:28 -0400479 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400480 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR1)
John Bauman89401822014-05-06 15:04:28 -0400481 {
John Bauman19bac1e2014-05-06 15:23:49 -0400482 Vector4f alpha = r.v[Color0];
483 r.o[D1].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400484 }
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400485 else if(state.vertexSpecularMaterialSourceActive == MATERIAL_COLOR2)
John Bauman89401822014-05-06 15:04:28 -0400486 {
John Bauman19bac1e2014-05-06 15:23:49 -0400487 Vector4f alpha = r.v[Color1];
488 r.o[D1].w = alpha.w;
John Bauman89401822014-05-06 15:04:28 -0400489 }
490 else ASSERT(false);
491 }
492 }
493
494 if(state.fogActive)
495 {
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400496 Float4 f;
497
498 if(!state.rangeFogActive)
499 {
500 f = Abs(vertexPosition.z);
501 }
502 else
503 {
504 f = Sqrt(dot3(vertexPosition, vertexPosition)); // FIXME: f = length(vertexPosition);
505 }
506
John Bauman89401822014-05-06 15:04:28 -0400507 switch(state.vertexFogMode)
508 {
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400509 case FOG_NONE:
John Bauman89401822014-05-06 15:04:28 -0400510 if(state.specularActive)
511 {
John Bauman19bac1e2014-05-06 15:23:49 -0400512 r.o[Fog].x = r.o[D1].w;
John Bauman89401822014-05-06 15:04:28 -0400513 }
514 else
515 {
John Bauman19bac1e2014-05-06 15:23:49 -0400516 r.o[Fog].x = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400517 }
518 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400519 case FOG_LINEAR:
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400520 r.o[Fog].x = f * *Pointer<Float4>(r.data + OFFSET(DrawData,fog.scale)) + *Pointer<Float4>(r.data + OFFSET(DrawData,fog.offset));
521 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400522 case FOG_EXP:
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400523 r.o[Fog].x = exponential2(f * *Pointer<Float4>(r.data + OFFSET(DrawData,fog.densityE)), true);
524 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400525 case FOG_EXP2:
Nicolas Capensa36f3f92015-08-04 15:34:26 -0400526 r.o[Fog].x = exponential2((f * f) * *Pointer<Float4>(r.data + OFFSET(DrawData,fog.density2E)), true);
John Bauman89401822014-05-06 15:04:28 -0400527 break;
528 default:
529 ASSERT(false);
530 }
531 }
532
533 for(int stage = 0; stage < 8; stage++)
534 {
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500535 processTextureCoordinate(stage, normal, position);
John Bauman89401822014-05-06 15:04:28 -0400536 }
537
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500538 processPointSize();
John Bauman89401822014-05-06 15:04:28 -0400539 }
540
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500541 void VertexPipeline::processTextureCoordinate(int stage, Vector4f &normal, Vector4f &position)
John Bauman89401822014-05-06 15:04:28 -0400542 {
543 if(state.output[T0 + stage].write)
544 {
545 int i = state.textureState[stage].texCoordIndexActive;
546
547 switch(state.textureState[stage].texGenActive)
548 {
Nicolas Capens70583fa2015-05-14 18:17:14 -0400549 case TEXGEN_NONE:
550 {
551 Vector4f v = r.v[TexCoord0 + i];
552
553 r.o[T0 + stage].x = v.x;
554 r.o[T0 + stage].y = v.y;
555 r.o[T0 + stage].z = v.z;
556 r.o[T0 + stage].w = v.w;
557 }
558 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400559 case TEXGEN_PASSTHRU:
John Bauman89401822014-05-06 15:04:28 -0400560 {
John Bauman19bac1e2014-05-06 15:23:49 -0400561 Vector4f v = r.v[TexCoord0 + i];
John Bauman89401822014-05-06 15:04:28 -0400562
John Bauman19bac1e2014-05-06 15:23:49 -0400563 r.o[T0 + stage].x = v.x;
564 r.o[T0 + stage].y = v.y;
565 r.o[T0 + stage].z = v.z;
566 r.o[T0 + stage].w = v.w;
John Bauman89401822014-05-06 15:04:28 -0400567
John Bauman19bac1e2014-05-06 15:23:49 -0400568 if(state.input[TexCoord0 + i])
John Bauman89401822014-05-06 15:04:28 -0400569 {
570 switch(state.input[TexCoord0 + i].count)
571 {
572 case 1:
John Bauman19bac1e2014-05-06 15:23:49 -0400573 r.o[T0 + stage].y = Float4(1.0f);
574 r.o[T0 + stage].z = Float4(0.0f);
575 r.o[T0 + stage].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400576 break;
577 case 2:
John Bauman19bac1e2014-05-06 15:23:49 -0400578 r.o[T0 + stage].z = Float4(1.0f);
579 r.o[T0 + stage].w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400580 break;
581 case 3:
John Bauman19bac1e2014-05-06 15:23:49 -0400582 r.o[T0 + stage].w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400583 break;
584 case 4:
585 break;
586 default:
587 ASSERT(false);
588 }
589 }
John Bauman89401822014-05-06 15:04:28 -0400590 }
591 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400592 case TEXGEN_NORMAL:
John Bauman89401822014-05-06 15:04:28 -0400593 {
John Bauman19bac1e2014-05-06 15:23:49 -0400594 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400595
596 if(state.vertexNormalActive)
597 {
598 Nc = normal;
599 }
600 else
601 {
John Bauman19bac1e2014-05-06 15:23:49 -0400602 Nc.x = Float4(0.0f);
603 Nc.y = Float4(0.0f);
604 Nc.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400605 }
606
John Bauman19bac1e2014-05-06 15:23:49 -0400607 Nc.w = Float4(1.0f);
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500608
John Bauman19bac1e2014-05-06 15:23:49 -0400609 r.o[T0 + stage].x = Nc.x;
610 r.o[T0 + stage].y = Nc.y;
611 r.o[T0 + stage].z = Nc.z;
612 r.o[T0 + stage].w = Nc.w;
John Bauman89401822014-05-06 15:04:28 -0400613 }
614 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400615 case TEXGEN_POSITION:
John Bauman89401822014-05-06 15:04:28 -0400616 {
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500617 Vector4f Pn = transformBlend(r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true); // Position in camera space
John Bauman89401822014-05-06 15:04:28 -0400618
John Bauman19bac1e2014-05-06 15:23:49 -0400619 Pn.w = Float4(1.0f);
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500620
John Bauman19bac1e2014-05-06 15:23:49 -0400621 r.o[T0 + stage].x = Pn.x;
622 r.o[T0 + stage].y = Pn.y;
623 r.o[T0 + stage].z = Pn.z;
624 r.o[T0 + stage].w = Pn.w;
John Bauman89401822014-05-06 15:04:28 -0400625 }
626 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400627 case TEXGEN_REFLECTION:
John Bauman89401822014-05-06 15:04:28 -0400628 {
John Bauman19bac1e2014-05-06 15:23:49 -0400629 Vector4f R; // Reflection vector
John Bauman89401822014-05-06 15:04:28 -0400630
631 if(state.vertexNormalActive)
632 {
John Bauman19bac1e2014-05-06 15:23:49 -0400633 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400634
635 Nc = normal;
636
637 if(state.localViewerActive)
638 {
John Bauman19bac1e2014-05-06 15:23:49 -0400639 Vector4f Ec; // Eye vector in camera space
640 Vector4f N2;
John Bauman89401822014-05-06 15:04:28 -0400641
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500642 Ec = transformBlend(r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
John Bauman89401822014-05-06 15:04:28 -0400643 Ec = normalize(Ec);
644
645 // R = E - 2 * N * (E . N)
John Bauman19bac1e2014-05-06 15:23:49 -0400646 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
John Bauman89401822014-05-06 15:04:28 -0400647
648 R.x = Ec.x - Nc.x * dot;
649 R.y = Ec.y - Nc.y * dot;
650 R.z = Ec.z - Nc.z * dot;
651 }
652 else
653 {
654 // u = -2 * Nz * Nx
655 // v = -2 * Nz * Ny
656 // w = 1 - 2 * Nz * Nz
657
John Bauman19bac1e2014-05-06 15:23:49 -0400658 R.x = -Float4(2.0f) * Nc.z * Nc.x;
659 R.y = -Float4(2.0f) * Nc.z * Nc.y;
660 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
John Bauman89401822014-05-06 15:04:28 -0400661 }
662 }
663 else
664 {
John Bauman19bac1e2014-05-06 15:23:49 -0400665 R.x = Float4(0.0f);
666 R.y = Float4(0.0f);
667 R.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400668 }
669
John Bauman19bac1e2014-05-06 15:23:49 -0400670 R.w = Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400671
John Bauman19bac1e2014-05-06 15:23:49 -0400672 r.o[T0 + stage].x = R.x;
673 r.o[T0 + stage].y = R.y;
674 r.o[T0 + stage].z = R.z;
675 r.o[T0 + stage].w = R.w;
John Bauman89401822014-05-06 15:04:28 -0400676 }
677 break;
Nicolas Capensa0f4be82014-10-22 14:35:30 -0400678 case TEXGEN_SPHEREMAP:
John Bauman89401822014-05-06 15:04:28 -0400679 {
John Bauman19bac1e2014-05-06 15:23:49 -0400680 Vector4f R; // Reflection vector
John Bauman89401822014-05-06 15:04:28 -0400681
682 if(state.vertexNormalActive)
683 {
John Bauman19bac1e2014-05-06 15:23:49 -0400684 Vector4f Nc; // Normal vector in camera space
John Bauman89401822014-05-06 15:04:28 -0400685
686 Nc = normal;
687
688 if(state.localViewerActive)
689 {
John Bauman19bac1e2014-05-06 15:23:49 -0400690 Vector4f Ec; // Eye vector in camera space
691 Vector4f N2;
John Bauman89401822014-05-06 15:04:28 -0400692
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500693 Ec = transformBlend(r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
John Bauman89401822014-05-06 15:04:28 -0400694 Ec = normalize(Ec);
695
696 // R = E - 2 * N * (E . N)
John Bauman19bac1e2014-05-06 15:23:49 -0400697 Float4 dot = Float4(2.0f) * dot3(Ec, Nc);
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500698
John Bauman89401822014-05-06 15:04:28 -0400699 R.x = Ec.x - Nc.x * dot;
700 R.y = Ec.y - Nc.y * dot;
701 R.z = Ec.z - Nc.z * dot;
702 }
703 else
704 {
705 // u = -2 * Nz * Nx
706 // v = -2 * Nz * Ny
707 // w = 1 - 2 * Nz * Nz
708
John Bauman19bac1e2014-05-06 15:23:49 -0400709 R.x = -Float4(2.0f) * Nc.z * Nc.x;
710 R.y = -Float4(2.0f) * Nc.z * Nc.y;
711 R.z = Float4(1.0f) - Float4(2.0f) * Nc.z * Nc.z;
John Bauman89401822014-05-06 15:04:28 -0400712 }
713 }
714 else
715 {
John Bauman19bac1e2014-05-06 15:23:49 -0400716 R.x = Float4(0.0f);
717 R.y = Float4(0.0f);
718 R.z = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400719 }
720
John Bauman19bac1e2014-05-06 15:23:49 -0400721 R.z -= Float4(1.0f);
John Bauman89401822014-05-06 15:04:28 -0400722 R = normalize(R);
John Bauman19bac1e2014-05-06 15:23:49 -0400723 R.x = Float4(0.5f) * R.x + Float4(0.5f);
724 R.y = Float4(0.5f) * R.y + Float4(0.5f);
John Bauman89401822014-05-06 15:04:28 -0400725
John Bauman19bac1e2014-05-06 15:23:49 -0400726 R.z = Float4(1.0f);
727 R.w = Float4(0.0f);
John Bauman89401822014-05-06 15:04:28 -0400728
John Bauman19bac1e2014-05-06 15:23:49 -0400729 r.o[T0 + stage].x = R.x;
730 r.o[T0 + stage].y = R.y;
731 r.o[T0 + stage].z = R.z;
732 r.o[T0 + stage].w = R.w;
John Bauman89401822014-05-06 15:04:28 -0400733 }
734 break;
735 default:
736 ASSERT(false);
737 }
738
John Bauman19bac1e2014-05-06 15:23:49 -0400739 Vector4f texTrans0;
740 Vector4f texTrans1;
741 Vector4f texTrans2;
742 Vector4f texTrans3;
John Bauman89401822014-05-06 15:04:28 -0400743
John Bauman19bac1e2014-05-06 15:23:49 -0400744 Vector4f T;
745 Vector4f t;
John Bauman89401822014-05-06 15:04:28 -0400746
John Bauman19bac1e2014-05-06 15:23:49 -0400747 T.x = r.o[T0 + stage].x;
748 T.y = r.o[T0 + stage].y;
749 T.z = r.o[T0 + stage].z;
750 T.w = r.o[T0 + stage].w;
John Bauman89401822014-05-06 15:04:28 -0400751
752 switch(state.textureState[stage].textureTransformCountActive)
753 {
754 case 4:
755 texTrans3.x = texTrans3.y = texTrans3.z = texTrans3.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][3])); // FIXME: Unpack
756 texTrans3.x = texTrans3.x.xxxx;
757 texTrans3.y = texTrans3.y.yyyy;
758 texTrans3.z = texTrans3.z.zzzz;
759 texTrans3.w = texTrans3.w.wwww;
760 t.w = dot4(T, texTrans3);
761 case 3:
762 texTrans2.x = texTrans2.y = texTrans2.z = texTrans2.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][2])); // FIXME: Unpack
763 texTrans2.x = texTrans2.x.xxxx;
764 texTrans2.y = texTrans2.y.yyyy;
765 texTrans2.z = texTrans2.z.zzzz;
766 texTrans2.w = texTrans2.w.wwww;
767 t.z = dot4(T, texTrans2);
768 case 2:
769 texTrans1.x = texTrans1.y = texTrans1.z = texTrans1.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][1])); // FIXME: Unpack
770 texTrans1.x = texTrans1.x.xxxx;
771 texTrans1.y = texTrans1.y.yyyy;
772 texTrans1.z = texTrans1.z.zzzz;
773 texTrans1.w = texTrans1.w.wwww;
774 t.y = dot4(T, texTrans1);
775 case 1:
776 texTrans0.x = texTrans0.y = texTrans0.z = texTrans0.w = *Pointer<Float4>(r.data + OFFSET(DrawData,ff.textureTransform[stage][0])); // FIXME: Unpack
777 texTrans0.x = texTrans0.x.xxxx;
778 texTrans0.y = texTrans0.y.yyyy;
779 texTrans0.z = texTrans0.z.zzzz;
780 texTrans0.w = texTrans0.w.wwww;
781 t.x = dot4(T, texTrans0);
782
John Bauman19bac1e2014-05-06 15:23:49 -0400783 r.o[T0 + stage].x = t.x;
784 r.o[T0 + stage].y = t.y;
785 r.o[T0 + stage].z = t.z;
786 r.o[T0 + stage].w = t.w;
John Bauman89401822014-05-06 15:04:28 -0400787 case 0:
788 break;
789 default:
790 ASSERT(false);
791 }
792 }
793 }
794
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500795 void VertexPipeline::processPointSize()
John Bauman89401822014-05-06 15:04:28 -0400796 {
797 if(!state.pointSizeActive)
798 {
799 return; // Use global pointsize
800 }
801
John Bauman66b8ab22014-05-06 15:57:45 -0400802 if(state.input[PointSize])
John Bauman89401822014-05-06 15:04:28 -0400803 {
John Bauman66b8ab22014-05-06 15:57:45 -0400804 r.o[Pts].y = r.v[PointSize].x;
John Bauman89401822014-05-06 15:04:28 -0400805 }
806 else
807 {
John Bauman19bac1e2014-05-06 15:23:49 -0400808 r.o[Pts].y = *Pointer<Float4>(r.data + OFFSET(DrawData,point.pointSize));
John Bauman89401822014-05-06 15:04:28 -0400809 }
810
811 if(state.pointScaleActive && !state.preTransformed)
812 {
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500813 Vector4f p = transformBlend(r.v[Position], Pointer<Byte>(r.data + OFFSET(DrawData,ff.cameraTransformT)), true);
John Bauman89401822014-05-06 15:04:28 -0400814
815 Float4 d = Sqrt(dot3(p, p)); // FIXME: length(p);
816
817 Float4 A = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleA)); // FIXME: Unpack
818 Float4 B = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleB)); // FIXME: Unpack
819 Float4 C = *Pointer<Float>(r.data + OFFSET(DrawData,point.pointScaleC)); // FIXME: Unpack
820
821 A = RcpSqrt_pp(A + d * (B + d * C));
822
John Bauman19bac1e2014-05-06 15:23:49 -0400823 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 -0400824 }
825 }
826
John Bauman66b8ab22014-05-06 15:57:45 -0400827 Vector4f VertexPipeline::transform(const Register &src, const Pointer<Byte> &matrix, bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -0400828 {
John Bauman19bac1e2014-05-06 15:23:49 -0400829 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400830
831 if(homogeneous)
832 {
833 Float4 m[4][4];
834
835 for(int j = 0; j < 4; j++)
836 {
837 for(int i = 0; i < 4; i++)
838 {
839 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
840 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
841 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
842 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
843 }
844 }
845
Nicolas Capens48621bd2015-08-03 15:33:44 -0400846 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + src.w * m[0][3];
847 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + src.w * m[1][3];
848 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + src.w * m[2][3];
849 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 -0400850 }
851 else
852 {
853 Float4 m[3][3];
854
855 for(int j = 0; j < 3; j++)
856 {
857 for(int i = 0; i < 3; i++)
858 {
859 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j);
860 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j);
861 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j);
862 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j);
863 }
864 }
865
866 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
867 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
868 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
869 }
870
871 return dst;
872 }
873
John Bauman66b8ab22014-05-06 15:57:45 -0400874 Vector4f VertexPipeline::transform(const Register &src, const Pointer<Byte> &matrix, UInt index[4], bool homogeneous)
John Bauman89401822014-05-06 15:04:28 -0400875 {
John Bauman19bac1e2014-05-06 15:23:49 -0400876 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400877
878 if(homogeneous)
879 {
880 Float4 m[4][4];
881
882 for(int j = 0; j < 4; j++)
883 {
884 for(int i = 0; i < 4; i++)
885 {
886 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
887 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
888 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
889 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
890 }
891 }
892
893 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2] + m[0][3];
894 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2] + m[1][3];
895 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2] + m[2][3];
896 dst.w = src.x * m[3][0] + src.y * m[3][1] + src.z * m[3][2] + m[3][3];
897 }
898 else
899 {
900 Float4 m[3][3];
901
902 for(int j = 0; j < 3; j++)
903 {
904 for(int i = 0; i < 3; i++)
905 {
906 m[j][i].x = *Pointer<Float>(matrix + 16 * i + 4 * j + index[0]);
907 m[j][i].y = *Pointer<Float>(matrix + 16 * i + 4 * j + index[1]);
908 m[j][i].z = *Pointer<Float>(matrix + 16 * i + 4 * j + index[2]);
909 m[j][i].w = *Pointer<Float>(matrix + 16 * i + 4 * j + index[3]);
910 }
911 }
912
913 dst.x = src.x * m[0][0] + src.y * m[0][1] + src.z * m[0][2];
914 dst.y = src.x * m[1][0] + src.y * m[1][1] + src.z * m[1][2];
915 dst.z = src.x * m[2][0] + src.y * m[2][1] + src.z * m[2][2];
916 }
917
918 return dst;
919 }
920
John Bauman19bac1e2014-05-06 15:23:49 -0400921 Vector4f VertexPipeline::normalize(Vector4f &src)
John Bauman89401822014-05-06 15:04:28 -0400922 {
John Bauman19bac1e2014-05-06 15:23:49 -0400923 Vector4f dst;
John Bauman89401822014-05-06 15:04:28 -0400924
925 Float4 rcpLength = RcpSqrt_pp(dot3(src, src));
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500926
John Bauman89401822014-05-06 15:04:28 -0400927 dst.x = src.x * rcpLength;
928 dst.y = src.y * rcpLength;
929 dst.z = src.z * rcpLength;
930
931 return dst;
932 }
933
934 Float4 VertexPipeline::power(Float4 &src0, Float4 &src1)
935 {
936 Float4 dst = src0;
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500937
John Bauman89401822014-05-06 15:04:28 -0400938 dst = dst * dst;
939 dst = dst * dst;
John Bauman19bac1e2014-05-06 15:23:49 -0400940 dst = Float4(As<Int4>(dst) - As<Int4>(Float4(1.0f)));
Nicolas Capensb4fb3672016-01-15 17:02:41 -0500941
John Bauman89401822014-05-06 15:04:28 -0400942 dst *= src1;
943
John Bauman19bac1e2014-05-06 15:23:49 -0400944 dst = As<Float4>(Int4(dst) + As<Int4>(Float4(1.0f)));
John Bauman89401822014-05-06 15:04:28 -0400945 dst = RcpSqrt_pp(dst);
946 dst = RcpSqrt_pp(dst);
947
948 return dst;
949 }
950}